uottun: support local udp 2 udp forwarding when there are no remote forwarders

This commit is contained in:
nadoo 2018-01-11 23:14:09 +08:00
parent ff632f23a6
commit 1368cf7770
4 changed files with 18 additions and 10 deletions

View File

@ -48,7 +48,8 @@ General:
TODO: TODO:
- [x] UDP over TCP Tunnel (client <--udp--> glider/uottun <--tcp--> ss <--udp--> target) - [x] UDP over TCP Tunnel (client <--udp--> glider/uottun <--tcp--> ss <--udp--> target)
- [ ] Transparent UDP proxy (linux tproxy) - [ ] Transparent UDP proxy (iptables tproxy)
- [ ] DNS Cache
- [ ] TUN/TAP device support - [ ] TUN/TAP device support
- [ ] Code refactoring: support proxy registering so it can be pluggable - [ ] Code refactoring: support proxy registering so it can be pluggable
- [ ] Conditional compilation so we can abandon needless proxy type and get a smaller binary size - [ ] Conditional compilation so we can abandon needless proxy type and get a smaller binary size

1
dns.go
View File

@ -279,6 +279,7 @@ func (s *DNS) ServeTCP(c net.Conn) {
} }
// Exchange handles request msg and returns response msg // Exchange handles request msg and returns response msg
// TODO: multiple questions support, parse header to get the number of questions
func (s *DNS) Exchange(reqLen uint16, reqMsg []byte, addr string) (respLen uint16, respMsg []byte, err error) { func (s *DNS) Exchange(reqLen uint16, reqMsg []byte, addr string) (respLen uint16, respMsg []byte, err error) {
// fmt.Printf("\ndns req len %d:\n%s\n", reqLen, hex.Dump(reqMsg[:])) // fmt.Printf("\ndns req len %d:\n%s\n", reqLen, hex.Dump(reqMsg[:]))
query, err := parseQuestion(reqMsg) query, err := parseQuestion(reqMsg)

1
ss.go
View File

@ -209,7 +209,6 @@ func (s *SS) ListenAndServeUDP() {
// Dial connects to the address addr on the network net via the proxy. // Dial connects to the address addr on the network net via the proxy.
func (s *SS) Dial(network, addr string) (net.Conn, error) { func (s *SS) Dial(network, addr string) (net.Conn, error) {
target := ParseAddr(addr) target := ParseAddr(addr)
if target == nil { if target == nil {
return nil, errors.New("Unable to parse address: " + addr) return nil, errors.New("Unable to parse address: " + addr)

View File

@ -3,6 +3,7 @@ package main
import ( import (
"io/ioutil" "io/ioutil"
"net" "net"
"time"
) )
// UoTTun udp over tcp tunnel // UoTTun udp over tcp tunnel
@ -26,7 +27,6 @@ func NewUoTTun(addr, raddr string, sDialer Dialer) (*UoTTun, error) {
// ListenAndServe . // ListenAndServe .
func (s *UoTTun) ListenAndServe() { func (s *UoTTun) ListenAndServe() {
c, err := net.ListenPacket("udp", s.addr) c, err := net.ListenPacket("udp", s.addr)
if err != nil { if err != nil {
logf("proxy-uottun failed to listen on %s: %v", s.addr, err) logf("proxy-uottun failed to listen on %s: %v", s.addr, err)
@ -55,14 +55,21 @@ func (s *UoTTun) ListenAndServe() {
rc.Write(buf[:n]) rc.Write(buf[:n])
// no remote forwarder
if urc, ok := rc.(*net.UDPConn); ok {
go func() {
timedCopy(c, clientAddr, urc, 5*time.Minute, false)
urc.Close()
}()
} else { // remote forwarder, udp over tcp
resp, err := ioutil.ReadAll(rc) resp, err := ioutil.ReadAll(rc)
if err != nil { if err != nil {
logf("error in ioutil.ReadAll: %s\n", err) logf("error in ioutil.ReadAll: %s\n", err)
return return
} }
rc.Close() rc.Close()
c.WriteTo(resp, clientAddr) c.WriteTo(resp, clientAddr)
}
logf("proxy-uottun %s <-> %s", clientAddr, s.raddr) logf("proxy-uottun %s <-> %s", clientAddr, s.raddr)
}() }()