diff --git a/app/dns/dnscommon.go b/app/dns/dnscommon.go index de0d794c..fa3ac406 100644 --- a/app/dns/dnscommon.go +++ b/app/dns/dnscommon.go @@ -1,13 +1,17 @@ package dns import ( + "context" "encoding/binary" "strings" "time" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/common/session" + "github.com/xtls/xray-core/core" dns_feature "github.com/xtls/xray-core/features/dns" "golang.org/x/net/dns/dnsmessage" ) @@ -225,3 +229,19 @@ L: return ipRecord, nil } + +// toDnsContext create a new background context with parent inbound, session and dns log +func toDnsContext(ctx context.Context, addr string) context.Context { + dnsCtx := core.ToBackgroundDetachedContext(ctx) + if inbound := session.InboundFromContext(ctx); inbound != nil { + dnsCtx = session.ContextWithInbound(dnsCtx, inbound) + } + dnsCtx = session.ContextWithContent(dnsCtx, session.ContentFromContext(ctx)) + dnsCtx = log.ContextWithAccessMessage(dnsCtx, &log.AccessMessage{ + From: "DNS", + To: addr, + Status: log.AccessAccepted, + Reason: "", + }) + return dnsCtx +} diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index 86161a85..fecc5efb 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -52,23 +52,11 @@ func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher) (*DoHNameServ TLSHandshakeTimeout: 30 * time.Second, ForceAttemptHTTP2: true, DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - dispatcherCtx := context.Background() - dest, err := net.ParseDestination(network + ":" + addr) if err != nil { return nil, err } - - dispatcherCtx = session.ContextWithContent(dispatcherCtx, session.ContentFromContext(ctx)) - dispatcherCtx = session.ContextWithInbound(dispatcherCtx, session.InboundFromContext(ctx)) - dispatcherCtx = log.ContextWithAccessMessage(dispatcherCtx, &log.AccessMessage{ - From: "DoH", - To: s.dohURL, - Status: log.AccessAccepted, - Reason: "", - }) - - link, err := s.dispatcher.Dispatch(dispatcherCtx, dest) + link, err := s.dispatcher.Dispatch(toDnsContext(ctx, s.dohURL), dest) select { case <-ctx.Done(): return nil, ctx.Err() @@ -115,7 +103,7 @@ func NewDoHLocalNameServer(url *url.URL) *DoHNameServer { } conn, err := internet.DialSystem(ctx, dest, nil) log.Record(&log.AccessMessage{ - From: "DoH", + From: "DNS", To: s.dohURL, Status: log.AccessAccepted, Detour: "local", diff --git a/app/dns/nameserver_local.go b/app/dns/nameserver_local.go index 0748732d..bf741c23 100644 --- a/app/dns/nameserver_local.go +++ b/app/dns/nameserver_local.go @@ -3,7 +3,9 @@ package dns import ( "context" "strings" + "time" + "github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/dns/localdns" @@ -18,6 +20,7 @@ const errEmptyResponse = "No address associated with hostname" // QueryIP implements Server. func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) (ips []net.IP, err error) { + start := time.Now() ips, err = s.client.LookupIP(domain, option) if err != nil && strings.HasSuffix(err.Error(), errEmptyResponse) { @@ -26,6 +29,7 @@ func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, op if len(ips) > 0 { newError("Localhost got answer: ", domain, " -> ", ips).AtInfo().WriteToLog() + log.Record(&log.DNSLog{Server: s.Name(), Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err}) } return diff --git a/app/dns/nameserver_quic.go b/app/dns/nameserver_quic.go index 63be44ba..e1c005ea 100644 --- a/app/dns/nameserver_quic.go +++ b/app/dns/nameserver_quic.go @@ -10,6 +10,7 @@ import ( "github.com/lucas-clemente/quic-go" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" + "github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol/dns" "github.com/xtls/xray-core/common/session" @@ -275,6 +276,7 @@ func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP ne ips, err := s.findIPsForDomain(fqdn, option) if err != errRecordNotFound { newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog() + log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err}) return ips, err } } @@ -306,10 +308,12 @@ func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP ne close(done) }() s.sendQuery(ctx, fqdn, clientIP, option) + start := time.Now() for { ips, err := s.findIPsForDomain(fqdn, option) if err != errRecordNotFound { + log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err}) return ips, err } @@ -371,6 +375,12 @@ func (s *QUICNameServer) openConnection() (quic.Connection, error) { } conn, err := quic.DialAddrContext(context.Background(), s.destination.NetAddr(), tlsConfig.GetTLSConfig(tls.WithNextProto("http/1.1", http2.NextProtoTLS, NextProtoDQ)), quicConfig) + log.Record(&log.AccessMessage{ + From: "DNS", + To: s.destination, + Status: log.AccessAccepted, + Detour: "local", + }) if err != nil { return nil, err } diff --git a/app/dns/nameserver_tcp.go b/app/dns/nameserver_tcp.go index 99206bfc..cf63ac21 100644 --- a/app/dns/nameserver_tcp.go +++ b/app/dns/nameserver_tcp.go @@ -11,6 +11,7 @@ import ( "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" + "github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net/cnc" "github.com/xtls/xray-core/common/protocol/dns" @@ -43,7 +44,7 @@ func NewTCPNameServer(url *url.URL, dispatcher routing.Dispatcher) (*TCPNameServ } s.dial = func(ctx context.Context) (net.Conn, error) { - link, err := dispatcher.Dispatch(ctx, *s.destination) + link, err := dispatcher.Dispatch(toDnsContext(ctx, s.destination.String()), *s.destination) if err != nil { return nil, err } @@ -314,6 +315,7 @@ func (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net ips, err := s.findIPsForDomain(fqdn, option) if err != errRecordNotFound { newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog() + log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err}) return ips, err } } @@ -345,10 +347,12 @@ func (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net close(done) }() s.sendQuery(ctx, fqdn, clientIP, option) + start := time.Now() for { ips, err := s.findIPsForDomain(fqdn, option) if err != errRecordNotFound { + log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err}) return ips, err } diff --git a/app/dns/nameserver_udp.go b/app/dns/nameserver_udp.go index fc8e5d68..d511df5b 100644 --- a/app/dns/nameserver_udp.go +++ b/app/dns/nameserver_udp.go @@ -15,7 +15,6 @@ import ( "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/signal/pubsub" "github.com/xtls/xray-core/common/task" - "github.com/xtls/xray-core/core" dns_feature "github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/transport/internet/udp" @@ -195,21 +194,7 @@ func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, client for _, req := range reqs { s.addPendingRequest(req) b, _ := dns.PackMessage(req.msg) - udpCtx := core.ToBackgroundDetachedContext(ctx) - if inbound := session.InboundFromContext(ctx); inbound != nil { - udpCtx = session.ContextWithInbound(udpCtx, inbound) - } - - udpCtx = session.ContextWithContent(udpCtx, &session.Content{ - Protocol: "dns", - }) - udpCtx = log.ContextWithAccessMessage(udpCtx, &log.AccessMessage{ - From: "DNS", - To: s.address, - Status: log.AccessAccepted, - Reason: "", - }) - s.udpServer.Dispatch(udpCtx, *s.address, b) + s.udpServer.Dispatch(toDnsContext(ctx, s.address.String()), *s.address, b) } }