From c6e82884b4922b5fcbfbce669e12c63e638683f0 Mon Sep 17 00:00:00 2001 From: gVisor bot Date: Fri, 12 Jun 2020 23:39:03 +0800 Subject: [PATCH] Change: local resolve DNS in UDP request due to TURN failed --- adapters/outbound/base.go | 9 ++------- adapters/outbound/direct.go | 12 ------------ adapters/outbound/shadowsocks.go | 8 -------- adapters/outbound/socks5.go | 8 -------- adapters/outbound/trojan.go | 11 +---------- adapters/outbound/vmess.go | 4 ---- constant/adapters.go | 3 ++- dns/util.go | 7 ++----- tunnel/connection.go | 21 ++++++++++++++++++--- tunnel/tracker.go | 8 -------- 10 files changed, 25 insertions(+), 66 deletions(-) diff --git a/adapters/outbound/base.go b/adapters/outbound/base.go index dddd852e..2c380a41 100644 --- a/adapters/outbound/base.go +++ b/adapters/outbound/base.go @@ -78,13 +78,8 @@ func NewConn(c net.Conn, a C.ProxyAdapter) C.Conn { return &conn{c, []string{a.Name()}} } -type PacketConn interface { - net.PacketConn - WriteWithMetadata(p []byte, metadata *C.Metadata) (n int, err error) -} - type packetConn struct { - PacketConn + net.PacketConn chain C.Chain } @@ -96,7 +91,7 @@ func (c *packetConn) AppendToChains(a C.ProxyAdapter) { c.chain = append(c.chain, a.Name()) } -func newPacketConn(pc PacketConn, a C.ProxyAdapter) C.PacketConn { +func newPacketConn(pc net.PacketConn, a C.ProxyAdapter) C.PacketConn { return &packetConn{pc, []string{a.Name()}} } diff --git a/adapters/outbound/direct.go b/adapters/outbound/direct.go index 9e896c3a..5273a593 100644 --- a/adapters/outbound/direct.go +++ b/adapters/outbound/direct.go @@ -5,7 +5,6 @@ import ( "net" "github.com/Dreamacro/clash/component/dialer" - "github.com/Dreamacro/clash/component/resolver" C "github.com/Dreamacro/clash/constant" ) @@ -36,17 +35,6 @@ type directPacketConn struct { net.PacketConn } -func (dp *directPacketConn) WriteWithMetadata(p []byte, metadata *C.Metadata) (n int, err error) { - if !metadata.Resolved() { - ip, err := resolver.ResolveIP(metadata.Host) - if err != nil { - return 0, err - } - metadata.DstIP = ip - } - return dp.WriteTo(p, metadata.UDPAddr()) -} - func NewDirect() *Direct { return &Direct{ Base: &Base{ diff --git a/adapters/outbound/shadowsocks.go b/adapters/outbound/shadowsocks.go index fdf5ca0e..8a620464 100644 --- a/adapters/outbound/shadowsocks.go +++ b/adapters/outbound/shadowsocks.go @@ -197,14 +197,6 @@ func (spc *ssPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) { return spc.PacketConn.WriteTo(packet[3:], spc.rAddr) } -func (spc *ssPacketConn) WriteWithMetadata(p []byte, metadata *C.Metadata) (n int, err error) { - packet, err := socks5.EncodeUDPPacket(socks5.ParseAddr(metadata.RemoteAddress()), p) - if err != nil { - return - } - return spc.PacketConn.WriteTo(packet[3:], spc.rAddr) -} - func (spc *ssPacketConn) ReadFrom(b []byte) (int, net.Addr, error) { n, _, e := spc.PacketConn.ReadFrom(b) if e != nil { diff --git a/adapters/outbound/socks5.go b/adapters/outbound/socks5.go index 315b05b2..78a59468 100644 --- a/adapters/outbound/socks5.go +++ b/adapters/outbound/socks5.go @@ -164,14 +164,6 @@ func (uc *socksPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) { return uc.PacketConn.WriteTo(packet, uc.rAddr) } -func (uc *socksPacketConn) WriteWithMetadata(p []byte, metadata *C.Metadata) (n int, err error) { - packet, err := socks5.EncodeUDPPacket(socks5.ParseAddr(metadata.RemoteAddress()), p) - if err != nil { - return - } - return uc.PacketConn.WriteTo(packet, uc.rAddr) -} - func (uc *socksPacketConn) ReadFrom(b []byte) (int, net.Addr, error) { n, _, e := uc.PacketConn.ReadFrom(b) if e != nil { diff --git a/adapters/outbound/trojan.go b/adapters/outbound/trojan.go index ab154b32..7b61b573 100644 --- a/adapters/outbound/trojan.go +++ b/adapters/outbound/trojan.go @@ -71,7 +71,7 @@ func (t *Trojan) DialUDP(metadata *C.Metadata) (C.PacketConn, error) { } pc := t.instance.PacketConn(c) - return newPacketConn(&trojanPacketConn{pc, c}, t), err + return newPacketConn(pc, t), err } func (t *Trojan) MarshalJSON() ([]byte, error) { @@ -105,12 +105,3 @@ func NewTrojan(option TrojanOption) (*Trojan, error) { instance: trojan.New(tOption), }, nil } - -type trojanPacketConn struct { - net.PacketConn - conn net.Conn -} - -func (tpc *trojanPacketConn) WriteWithMetadata(p []byte, metadata *C.Metadata) (n int, err error) { - return trojan.WritePacket(tpc.conn, serializesSocksAddr(metadata), p) -} diff --git a/adapters/outbound/vmess.go b/adapters/outbound/vmess.go index 023b1cea..8eca97df 100644 --- a/adapters/outbound/vmess.go +++ b/adapters/outbound/vmess.go @@ -202,10 +202,6 @@ func (uc *vmessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) { return uc.Conn.Write(b) } -func (uc *vmessPacketConn) WriteWithMetadata(p []byte, metadata *C.Metadata) (n int, err error) { - return uc.Conn.Write(p) -} - func (uc *vmessPacketConn) ReadFrom(b []byte) (int, net.Addr, error) { n, err := uc.Conn.Read(b) return n, uc.rAddr, err diff --git a/constant/adapters.go b/constant/adapters.go index be2d0e70..ad80974a 100644 --- a/constant/adapters.go +++ b/constant/adapters.go @@ -57,7 +57,8 @@ type Conn interface { type PacketConn interface { net.PacketConn Connection - WriteWithMetadata(p []byte, metadata *Metadata) (n int, err error) + // Deprecate WriteWithMetadata because of remote resolve DNS cause TURN failed + // WriteWithMetadata(p []byte, metadata *Metadata) (n int, err error) } type ProxyAdapter interface { diff --git a/dns/util.go b/dns/util.go index b6adf8d6..23c5b12f 100644 --- a/dns/util.go +++ b/dns/util.go @@ -89,7 +89,7 @@ func putMsgToCache(c *cache.LruCache, key string, msg *D.Msg) { case len(msg.Extra) != 0: ttl = msg.Extra[0].Header().Ttl default: - log.Debugln("[DNS] response msg error: %#v", msg) + log.Debugln("[DNS] response msg empty: %#v", msg) return } @@ -111,10 +111,7 @@ func setMsgTTL(msg *D.Msg, ttl uint32) { } func isIPRequest(q D.Question) bool { - if q.Qclass == D.ClassINET && (q.Qtype == D.TypeA || q.Qtype == D.TypeAAAA) { - return true - } - return false + return q.Qclass == D.ClassINET && (q.Qtype == D.TypeA || q.Qtype == D.TypeAAAA) } func transform(servers []NameServer, resolver *Resolver) []dnsClient { diff --git a/tunnel/connection.go b/tunnel/connection.go index 0af760cc..bdba863a 100644 --- a/tunnel/connection.go +++ b/tunnel/connection.go @@ -2,6 +2,7 @@ package tunnel import ( "bufio" + "errors" "io" "net" "net/http" @@ -9,6 +10,7 @@ import ( "time" adapters "github.com/Dreamacro/clash/adapters/inbound" + "github.com/Dreamacro/clash/component/resolver" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/common/pool" @@ -81,12 +83,25 @@ func handleHTTP(request *adapters.HTTPAdapter, outbound net.Conn) { } } -func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) { +func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) error { defer packet.Drop() - if _, err := pc.WriteWithMetadata(packet.Data(), metadata); err != nil { - return + // local resolve UDP dns + if !metadata.Resolved() { + ip, err := resolver.ResolveIP(metadata.Host) + if err != nil { + return err + } + metadata.DstIP = ip } + + addr := metadata.UDPAddr() + if addr == nil { + return errors.New("udp addr invalid") + } + + _, err := pc.WriteTo(packet.Data(), addr) + return err } func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string, fAddr net.Addr) { diff --git a/tunnel/tracker.go b/tunnel/tracker.go index c8871697..142b7110 100644 --- a/tunnel/tracker.go +++ b/tunnel/tracker.go @@ -105,14 +105,6 @@ func (ut *udpTracker) WriteTo(b []byte, addr net.Addr) (int, error) { return n, err } -func (ut *udpTracker) WriteWithMetadata(p []byte, metadata *C.Metadata) (int, error) { - n, err := ut.PacketConn.WriteWithMetadata(p, metadata) - upload := int64(n) - ut.manager.Upload() <- upload - ut.UploadTotal += upload - return n, err -} - func (ut *udpTracker) Close() error { ut.manager.Leave(ut) return ut.PacketConn.Close()