From 47406ce4ce69e0b1df29e6caa7afdda6c2edd4c4 Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Tue, 12 Mar 2019 23:32:23 +0800 Subject: [PATCH] udptun: fixed a bug in nat mapping. #91 --- README.md | 2 +- conf.go | 2 +- dns/cache.go | 12 ++++++------ dns/client.go | 22 ++++++++++----------- dns/message.go | 44 +++++++++++++++++++++--------------------- dns/server.go | 12 ++++++------ go.mod | 8 ++++---- go.sum | 19 ++++++++++++++++++ proxy/udptun/udptun.go | 28 +++++++++++++-------------- 9 files changed, 84 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 55f5dad..a79a3c6 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ Available Schemes: Available schemes for different modes: listen: mixed ss socks5 http redir redir6 tcptun udptun uottun tls unix kcp - forward: ss socks5 http ssr vmess tls ws unix kcp simple-bfs + forward: reject ss socks5 http ssr vmess tls ws unix kcp simple-bfs SS scheme: ss://method:pass@host:port diff --git a/conf.go b/conf.go index abc9d4b..c2d7a32 100644 --- a/conf.go +++ b/conf.go @@ -128,7 +128,7 @@ func usage() { fmt.Fprintf(os.Stderr, "Available schemes for different modes:\n") fmt.Fprintf(os.Stderr, " listen: mixed ss socks5 http redir redir6 tcptun udptun uottun tls unix kcp\n") - fmt.Fprintf(os.Stderr, " forward: ss socks5 http ssr vmess tls ws unix kcp simple-bfs\n") + fmt.Fprintf(os.Stderr, " forward: reject ss socks5 http ssr vmess tls ws unix kcp simple-bfs\n") fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "SS scheme:\n") diff --git a/dns/cache.go b/dns/cache.go index e3d7b0f..80e6e9e 100644 --- a/dns/cache.go +++ b/dns/cache.go @@ -5,7 +5,7 @@ import ( "time" ) -// LongTTL is 50 years duration in seconds, used for none-expired items +// LongTTL is 50 years duration in seconds, used for none-expired items. const LongTTL = 50 * 365 * 24 * 3600 type item struct { @@ -13,13 +13,13 @@ type item struct { expire time.Time } -// Cache is the struct of cache +// Cache is the struct of cache. type Cache struct { m map[string]*item l sync.RWMutex } -// NewCache returns a new cache +// NewCache returns a new cache. func NewCache() (c *Cache) { c = &Cache{m: make(map[string]*item)} go func() { @@ -36,12 +36,12 @@ func NewCache() (c *Cache) { return } -// Len returns the length of cache +// Len returns the length of cache. func (c *Cache) Len() int { return len(c.m) } -// Put an item into cache, invalid after ttl seconds +// Put an item into cache, invalid after ttl seconds. func (c *Cache) Put(k string, v []byte, ttl int) { if len(v) != 0 { c.l.Lock() @@ -55,7 +55,7 @@ func (c *Cache) Put(k string, v []byte, ttl int) { } } -// Get an item from cache +// Get an item from cache. func (c *Cache) Get(k string) (v []byte) { c.l.RLock() if it, ok := c.m[k]; ok { diff --git a/dns/client.go b/dns/client.go index 71259aa..b7c1b4e 100644 --- a/dns/client.go +++ b/dns/client.go @@ -13,10 +13,10 @@ import ( "github.com/nadoo/glider/proxy" ) -// HandleFunc function handles the dns TypeA or TypeAAAA answer +// HandleFunc function handles the dns TypeA or TypeAAAA answer. type HandleFunc func(Domain, ip string) error -// Config for dns +// Config for dns. type Config struct { Servers []string Timeout int @@ -26,7 +26,7 @@ type Config struct { AlwaysTCP bool } -// Client is a dns client struct +// Client is a dns client struct. type Client struct { dialer proxy.Dialer cache *Cache @@ -36,7 +36,7 @@ type Client struct { handlers []HandleFunc } -// NewClient returns a new dns client +// NewClient returns a new dns client. func NewClient(dialer proxy.Dialer, config *Config) (*Client, error) { c := &Client{ dialer: dialer, @@ -54,7 +54,7 @@ func NewClient(dialer proxy.Dialer, config *Config) (*Client, error) { return c, nil } -// Exchange handles request msg and returns response msg +// Exchange handles request message and returns response message. // reqBytes = reqLen + reqMsg func (c *Client) Exchange(reqBytes []byte, clientAddr string, preferTCP bool) ([]byte, error) { req, err := UnmarshalMessage(reqBytes[2:]) @@ -122,7 +122,7 @@ func (c *Client) Exchange(reqBytes []byte, clientAddr string, preferTCP bool) ([ return respBytes, nil } -// exchange choose a upstream dns server based on qname, communicate with it on the network +// exchange choose a upstream dns server based on qname, communicate with it on the network. func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (server, network string, respBytes []byte, err error) { // use tcp to connect upstream server default network = "tcp" @@ -170,7 +170,7 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (server return server, network, respBytes, err } -// exchangeTCP exchange with server over tcp +// exchangeTCP exchange with server over tcp. func (c *Client) exchangeTCP(rc net.Conn, reqBytes []byte) ([]byte, error) { if _, err := rc.Write(reqBytes); err != nil { log.F("[dns] failed to write req message: %v", err) @@ -195,7 +195,7 @@ func (c *Client) exchangeTCP(rc net.Conn, reqBytes []byte) ([]byte, error) { return respBytes, nil } -// exchangeUDP exchange with server over udp +// exchangeUDP exchange with server over udp. func (c *Client) exchangeUDP(rc net.Conn, reqBytes []byte) ([]byte, error) { if _, err := rc.Write(reqBytes[2:]); err != nil { log.F("[dns] failed to write req message: %v", err) @@ -212,7 +212,7 @@ func (c *Client) exchangeUDP(rc net.Conn, reqBytes []byte) ([]byte, error) { return reqBytes[:2+n], nil } -// SetServers sets upstream dns servers for the given domain +// SetServers sets upstream dns servers for the given domain. func (c *Client) SetServers(domain string, servers ...string) { c.upServerMap[domain] = append(c.upServerMap[domain], servers...) } @@ -232,7 +232,7 @@ func (c *Client) GetServers(domain string) []string { return c.upServers } -// AddHandler adds a custom handler to handle the resolved result (A and AAAA) +// AddHandler adds a custom handler to handle the resolved result (A and AAAA). func (c *Client) AddHandler(h HandleFunc) { c.handlers = append(c.handlers, h) } @@ -258,7 +258,7 @@ func (c *Client) AddRecord(record string) error { return nil } -// GenResponse generates a dns response message for the given domani an ip address +// GenResponse generates a dns response message for the given domain and ip address. func (c *Client) GenResponse(domain string, ip string) (*Message, error) { ipb := net.ParseIP(ip) if ipb == nil { diff --git a/dns/message.go b/dns/message.go index 1a57ebb..efc0f23 100644 --- a/dns/message.go +++ b/dns/message.go @@ -16,7 +16,7 @@ import ( // the header. const UDPMaxLen = 512 -// HeaderLen is the length of dns msg header +// HeaderLen is the length of dns msg header. const HeaderLen = 12 // Message types @@ -25,7 +25,7 @@ const ( Response = 1 ) -// QType . +// Query types const ( QTypeA uint16 = 1 //ipv4 QTypeAAAA uint16 = 28 ///ipv6 @@ -62,7 +62,7 @@ type Message struct { unMarshaled []byte } -// NewMessage returns a new message +// NewMessage returns a new message. func NewMessage(id uint16, msgType int) *Message { if id == 0 { id = uint16(rand.Uint32()) @@ -74,20 +74,20 @@ func NewMessage(id uint16, msgType int) *Message { return m } -// SetQuestion sets a question to dns message, +// SetQuestion sets a question to dns message. func (m *Message) SetQuestion(q *Question) error { m.Question = q m.Header.SetQdcount(1) return nil } -// AddAnswer adds an answer to dns message +// AddAnswer adds an answer to dns message. func (m *Message) AddAnswer(rr *RR) error { m.Answers = append(m.Answers, rr) return nil } -// Marshal marshals message struct to []byte +// Marshal marshals message struct to []byte. func (m *Message) Marshal() ([]byte, error) { var buf bytes.Buffer @@ -117,7 +117,7 @@ func (m *Message) Marshal() ([]byte, error) { return buf.Bytes(), nil } -// UnmarshalMessage unmarshals []bytes to Message +// UnmarshalMessage unmarshals []bytes to Message. func UnmarshalMessage(b []byte) (*Message, error) { if len(b) < HeaderLen { return nil, errors.New("UnmarshalMessage: not enough data") @@ -183,22 +183,22 @@ type Header struct { ARCOUNT uint16 } -// SetMsgType . +// SetMsgType sets the message type. func (h *Header) SetMsgType(qr int) { h.Bits |= uint16(qr) << 15 } -// SetTC . +// SetTC sets the tc flag. func (h *Header) SetTC(tc int) { h.Bits |= uint16(tc) << 9 } -// SetQdcount sets query count, most dns servers only support 1 query per request +// SetQdcount sets query count, most dns servers only support 1 query per request. func (h *Header) SetQdcount(qdcount int) { h.QDCOUNT = uint16(qdcount) } -// SetAncount sets answers count +// SetAncount sets answers count. func (h *Header) SetAncount(ancount int) { h.ANCOUNT = uint16(ancount) } @@ -208,14 +208,14 @@ func (h *Header) setFlag(QR uint16, Opcode uint16, AA uint16, h.Bits = QR<<15 + Opcode<<11 + AA<<10 + TC<<9 + RD<<8 + RA<<7 + RCODE } -// Marshal marshals header struct to []byte +// Marshal marshals header struct to []byte. func (h *Header) Marshal() ([]byte, error) { var buf bytes.Buffer err := binary.Write(&buf, binary.BigEndian, h) return buf.Bytes(), err } -// UnmarshalHeader unmarshals []bytes to Header +// UnmarshalHeader unmarshals []bytes to Header. func UnmarshalHeader(b []byte, h *Header) error { if h == nil { return errors.New("unmarshal header must not be nil") @@ -258,7 +258,7 @@ type Question struct { QCLASS uint16 } -// NewQuestion returns a new dns question +// NewQuestion returns a new dns question. func NewQuestion(qtype uint16, domain string) *Question { return &Question{ QNAME: domain, @@ -267,7 +267,7 @@ func NewQuestion(qtype uint16, domain string) *Question { } } -// Marshal marshals Question struct to []byte +// Marshal marshals Question struct to []byte. func (q *Question) Marshal() ([]byte, error) { var buf bytes.Buffer @@ -278,7 +278,7 @@ func (q *Question) Marshal() ([]byte, error) { return buf.Bytes(), nil } -// UnmarshalQuestion unmarshals []bytes to Question +// UnmarshalQuestion unmarshals []bytes to Question. func (m *Message) UnmarshalQuestion(b []byte, q *Question) (n int, err error) { if q == nil { return 0, errors.New("unmarshal question must not be nil") @@ -339,13 +339,13 @@ type RR struct { IP string } -// NewRR returns a new dns rr +// NewRR returns a new dns rr. func NewRR() *RR { rr := &RR{} return rr } -// Marshal marshals RR struct to []byte +// Marshal marshals RR struct to []byte. func (rr *RR) Marshal() ([]byte, error) { var buf bytes.Buffer @@ -359,7 +359,7 @@ func (rr *RR) Marshal() ([]byte, error) { return buf.Bytes(), nil } -// UnmarshalRR unmarshals []bytes to RR +// UnmarshalRR unmarshals []bytes to RR. func (m *Message) UnmarshalRR(start int, rr *RR) (n int, err error) { if rr == nil { return 0, errors.New("unmarshal rr must not be nil") @@ -399,7 +399,7 @@ func (m *Message) UnmarshalRR(start int, rr *RR) (n int, err error) { return n, nil } -// MarshalDomain marshals domain string struct to []byte +// MarshalDomain marshals domain string struct to []byte. func MarshalDomain(domain string) []byte { var buf bytes.Buffer @@ -412,7 +412,7 @@ func MarshalDomain(domain string) []byte { return buf.Bytes() } -// UnmarshalDomain gets domain from bytes +// UnmarshalDomain gets domain from bytes. func (m *Message) UnmarshalDomain(b []byte) (string, int, error) { var idx, size int var labels = []string{} @@ -457,7 +457,7 @@ func (m *Message) UnmarshalDomain(b []byte) (string, int, error) { return domain, idx, nil } -// UnmarshalDomainPoint gets domain from offset point +// UnmarshalDomainPoint gets domain from offset point. func (m *Message) UnmarshalDomainPoint(offset int) (string, error) { if offset > len(m.unMarshaled) { return "", errors.New("UnmarshalDomainPoint: offset larger than msg length") diff --git a/dns/server.go b/dns/server.go index 2adbb80..ffddc39 100644 --- a/dns/server.go +++ b/dns/server.go @@ -14,14 +14,14 @@ import ( // conn timeout, seconds const timeout = 30 -// Server is a dns server struct +// Server is a dns server struct. type Server struct { addr string // Client is used to communicate with upstream dns servers *Client } -// NewServer returns a new dns server +// NewServer returns a new dns server. func NewServer(addr string, dialer proxy.Dialer, config *Config) (*Server, error) { c, err := NewClient(dialer, config) s := &Server{ @@ -32,7 +32,7 @@ func NewServer(addr string, dialer proxy.Dialer, config *Config) (*Server, error return s, err } -// Start starts the dns forwarding server +// Start starts the dns forwarding server. // We use WaitGroup here to ensure both udp and tcp serer are completly running, // so we can start any other services later, since they may rely on dns service. func (s *Server) Start() { @@ -43,7 +43,7 @@ func (s *Server) Start() { wg.Wait() } -// ListenAndServeUDP . +// ListenAndServeUDP listen and serves on udp port. func (s *Server) ListenAndServeUDP(wg *sync.WaitGroup) { c, err := net.ListenPacket("udp", s.addr) wg.Done() @@ -88,7 +88,7 @@ func (s *Server) ListenAndServeUDP(wg *sync.WaitGroup) { } -// ListenAndServeTCP . +// ListenAndServeTCP listen and serves on tcp port. func (s *Server) ListenAndServeTCP(wg *sync.WaitGroup) { l, err := net.Listen("tcp", s.addr) wg.Done() @@ -110,7 +110,7 @@ func (s *Server) ListenAndServeTCP(wg *sync.WaitGroup) { } } -// ServeTCP . +// ServeTCP serves a tcp connection. func (s *Server) ServeTCP(c net.Conn) { defer c.Close() diff --git a/go.mod b/go.mod index a0054e7..d5f321d 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152 // indirect github.com/ebfe/rc2 v0.0.0-20131011165748-24b9757f5521 // indirect github.com/klauspost/cpuid v1.2.0 // indirect - github.com/klauspost/reedsolomon v1.9.0 // indirect + github.com/klauspost/reedsolomon v1.9.1 // indirect github.com/nadoo/conflag v0.2.0 github.com/nadoo/go-shadowsocks2 v0.1.0 github.com/pkg/errors v0.8.1 // indirect @@ -19,9 +19,9 @@ require ( github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect github.com/tjfoc/gmsm v1.0.1 // indirect github.com/xtaci/kcp-go v5.0.7+incompatible - golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 - golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 // indirect - golang.org/x/sys v0.0.0-20190306220723-b294cbcfc56d // indirect + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 + golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect + golang.org/x/sys v0.0.0-20190312061237-fead79001313 // indirect ) // Replace dependency modules with local developing copy diff --git a/go.sum b/go.sum index e618779..aa60bf7 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/reedsolomon v1.9.0 h1:usyTY5K7D2B6WOHn2jmpB7ky8Qom96mShZmmq3OW4JU= github.com/klauspost/reedsolomon v1.9.0/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= +github.com/klauspost/reedsolomon v1.9.1 h1:kYrT1MlR4JH6PqOpC+okdb9CDTcwEC/BqpzK4WFyXL8= +github.com/klauspost/reedsolomon v1.9.1/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= github.com/nadoo/conflag v0.1.0 h1:m9xSrL0UILGXPCZW66mhW57V2D2IraVpWLNIr2Op8X8= github.com/nadoo/conflag v0.1.0/go.mod h1:C3xchp3tIA3J2haACChSHFrlih7w00f31DXfjVUQa+0= github.com/nadoo/conflag v0.2.0 h1:xao13tYqfD+5bjQ1A/jT2kBL8tUcVpFhq3seuN5kpeM= @@ -34,8 +36,16 @@ github.com/xtaci/kcp-go v5.0.7+incompatible h1:zs9tc8XRID0m+aetu3qPWZFyRt2UIMqbX github.com/xtaci/kcp-go v5.0.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 h1:fY7Dsw114eJN4boqzVSbpVHO6rTdhq6/GnXeu+PKnzU= golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190310074541-c10a0554eabf h1:J7RqX9u0J9ZB37CGaFc2VC+QZZT6E6jnDbrboEFVo0U= +golang.org/x/net v0.0.0-20190310074541-c10a0554eabf/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311031020-56fb01167e7d h1:vQJbQvu6+H699vOmHa20TEBI9nEqroRbMtf/9biIE3A= +golang.org/x/net v0.0.0-20190311031020-56fb01167e7d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ= golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -51,3 +61,12 @@ golang.org/x/sys v0.0.0-20190306155319-3e9a981b8ddb h1:xIUJ1YHSR/6NhHkg597Yw0jPK golang.org/x/sys v0.0.0-20190306155319-3e9a981b8ddb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190306220723-b294cbcfc56d h1:4Ew1XHJYjwX6RiE8SgSymqS1zCRQyGpcAnVfbpEuXfE= golang.org/x/sys v0.0.0-20190306220723-b294cbcfc56d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190308023053-584f3b12f43e h1:K7CV15oJ823+HLXQ+M7MSMrUg8LjfqY7O3naO+8Pp/I= +golang.org/x/sys v0.0.0-20190308023053-584f3b12f43e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa h1:lqti/xP+yD/6zH5TqEwx2MilNIJY5Vbc6Qr8J3qyPIQ= +golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190311152110-c8c8c57fd1e1 h1:FQNj2xvjQ1lgFyzbSybGZr792Y8Dy95D7uuqnZAzNaA= +golang.org/x/sys v0.0.0-20190311152110-c8c8c57fd1e1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/proxy/udptun/udptun.go b/proxy/udptun/udptun.go index 4d43045..31976a1 100644 --- a/proxy/udptun/udptun.go +++ b/proxy/udptun/udptun.go @@ -12,23 +12,23 @@ import ( "github.com/nadoo/glider/proxy" ) -// UDPTun struct +// UDPTun is a base udptun struct. type UDPTun struct { dialer proxy.Dialer addr string - - raddr string + taddr string // tunnel addr + uaddr *net.UDPAddr // tunnel addr } func init() { proxy.RegisterServer("udptun", NewUDPTunServer) } -// NewUDPTun returns a UDPTun proxy +// NewUDPTun returns a UDPTun proxy. func NewUDPTun(s string, dialer proxy.Dialer) (*UDPTun, error) { u, err := url.Parse(s) if err != nil { - log.F("parse err: %s", err) + log.F("[udptun] parse err: %s", err) return nil, err } @@ -38,18 +38,19 @@ func NewUDPTun(s string, dialer proxy.Dialer) (*UDPTun, error) { p := &UDPTun{ dialer: dialer, addr: d[0], - raddr: d[1], + taddr: d[1], } - return p, nil + p.uaddr, err = net.ResolveUDPAddr("udp", p.taddr) + return p, err } -// NewUDPTunServer returns a udp tunnel server +// NewUDPTunServer returns a udp tunnel server. func NewUDPTunServer(s string, dialer proxy.Dialer) (proxy.Server, error) { return NewUDPTun(s, dialer) } -// ListenAndServe . +// ListenAndServe listen and serves on the given address. func (s *UDPTun) ListenAndServe() { c, err := net.ListenPacket("udp", s.addr) if err != nil { @@ -71,12 +72,11 @@ func (s *UDPTun) ListenAndServe() { } var pc net.PacketConn - var writeAddr net.Addr v, ok := nm.Load(raddr.String()) if !ok && v == nil { - pc, writeAddr, err = s.dialer.DialUDP("udp", s.raddr) + pc, _, err = s.dialer.DialUDP("udp", s.taddr) if err != nil { log.F("[udptun] remote dial error: %v", err) continue @@ -94,18 +94,18 @@ func (s *UDPTun) ListenAndServe() { pc = v.(net.PacketConn) } - _, err = pc.WriteTo(buf[:n], writeAddr) + _, err = pc.WriteTo(buf[:n], s.uaddr) if err != nil { log.F("[udptun] remote write error: %v", err) continue } - log.F("[udptun] %s <-> %s", raddr, s.raddr) + log.F("[udptun] %s <-> %s", raddr, s.taddr) } } -// Serve . +// Serve serves a net.Conn, can not be called directly. func (s *UDPTun) Serve(c net.Conn) { log.F("[udptun] func Serve: can not be called directly") }