Explorar o código

Fix DNS lookup

世界 hai 5 meses
pai
achega
349db7baec
Modificáronse 4 ficheiros con 42 adicións e 10 borrados
  1. 1 1
      dns/client.go
  2. 7 4
      dns/router.go
  3. 4 2
      dns/transport/local/local.go
  4. 30 3
      route/conn.go

+ 1 - 1
dns/client.go

@@ -483,7 +483,7 @@ func (c *Client) loadResponse(question dns.Question, transport adapter.DNSTransp
 }
 
 func MessageToAddresses(response *dns.Msg) ([]netip.Addr, error) {
-	if response.Rcode != dns.RcodeSuccess && response.Rcode != dns.RcodeNameError {
+	if response.Rcode != dns.RcodeSuccess {
 		return nil, RcodeError(response.Rcode)
 	}
 	addresses := make([]netip.Addr, 0, len(response.Answer))

+ 7 - 4
dns/router.go

@@ -330,6 +330,9 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
 		err           error
 	)
 	printResult := func() {
+		if err == nil && len(responseAddrs) == 0 {
+			err = E.New("empty result")
+		}
 		if err != nil {
 			if errors.Is(err, ErrResponseRejectedCached) {
 				r.logger.DebugContext(ctx, "response rejected for ", domain, " (cached)")
@@ -338,15 +341,15 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
 			} else {
 				r.logger.ErrorContext(ctx, E.Cause(err, "lookup failed for ", domain))
 			}
-		} else if len(responseAddrs) == 0 {
-			r.logger.ErrorContext(ctx, "lookup failed for ", domain, ": empty result")
-			err = RcodeNameError
+		}
+		if err != nil {
+			err = E.Cause(err, "lookup ", domain)
 		}
 	}
 	responseAddrs, cached = r.client.LookupCache(domain, options.Strategy)
 	if cached {
 		if len(responseAddrs) == 0 {
-			return nil, RcodeNameError
+			return nil, E.New("lookup ", domain, ": empty result (cached)")
 		}
 		return responseAddrs, nil
 	}

+ 4 - 2
dns/transport/local/local.go

@@ -3,6 +3,7 @@ package local
 import (
 	"context"
 	"math/rand"
+	"net/netip"
 	"time"
 
 	"github.com/sagernet/sing-box/adapter"
@@ -90,8 +91,9 @@ func (t *Transport) exchangeParallel(ctx context.Context, systemConfig *dnsConfi
 	startRacer := func(ctx context.Context, fqdn string) {
 		response, err := t.tryOneName(ctx, systemConfig, fqdn, message)
 		if err == nil {
-			addresses, _ := dns.MessageToAddresses(response)
-			if len(addresses) == 0 {
+			var addresses []netip.Addr
+			addresses, err = dns.MessageToAddresses(response)
+			if err == nil && len(addresses) == 0 {
 				err = E.New(fqdn, ": empty result")
 			}
 		}

+ 30 - 3
route/conn.go

@@ -7,6 +7,7 @@ import (
 	"net"
 	"net/netip"
 	"os"
+	"strings"
 	"sync"
 	"sync/atomic"
 	"time"
@@ -66,7 +67,17 @@ func (m *ConnectionManager) NewConnection(ctx context.Context, this N.Dialer, co
 		remoteConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
 	}
 	if err != nil {
-		err = E.Cause(err, "open outbound connection")
+		var remoteString string
+		if len(metadata.DestinationAddresses) > 0 {
+			remoteString = "[" + strings.Join(common.Map(metadata.DestinationAddresses, netip.Addr.String), ",") + "]"
+		} else {
+			remoteString = metadata.Destination.String()
+		}
+		var dialerString string
+		if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
+			dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
+		}
+		err = E.Cause(err, "open connection to ", remoteString, dialerString)
 		N.CloseOnHandshakeFailure(conn, onClose, err)
 		m.logger.ErrorContext(ctx, err)
 		return
@@ -133,8 +144,19 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
 			remoteConn, err = this.DialContext(ctx, N.NetworkUDP, metadata.Destination)
 		}
 		if err != nil {
+			var remoteString string
+			if len(metadata.DestinationAddresses) > 0 {
+				remoteString = "[" + strings.Join(common.Map(metadata.DestinationAddresses, netip.Addr.String), ",") + "]"
+			} else {
+				remoteString = metadata.Destination.String()
+			}
+			var dialerString string
+			if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
+				dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
+			}
+			err = E.Cause(err, "open packet connection to ", remoteString, dialerString)
 			N.CloseOnHandshakeFailure(conn, onClose, err)
-			m.logger.ErrorContext(ctx, "open outbound packet connection: ", err)
+			m.logger.ErrorContext(ctx, err)
 			return
 		}
 		remotePacketConn = bufio.NewUnbindPacketConn(remoteConn)
@@ -149,8 +171,13 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
 			remotePacketConn, err = this.ListenPacket(ctx, metadata.Destination)
 		}
 		if err != nil {
+			var dialerString string
+			if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
+				dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
+			}
+			err = E.Cause(err, "listen packet connection using ", dialerString)
 			N.CloseOnHandshakeFailure(conn, onClose, err)
-			m.logger.ErrorContext(ctx, "listen outbound packet connection: ", err)
+			m.logger.ErrorContext(ctx, err)
 			return
 		}
 	}