mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-06-21 18:29:13 +03:00
Improve dns log
This commit is contained in:
@@ -10,8 +10,6 @@ import (
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -36,8 +34,6 @@ import (
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
)
|
||||
|
||||
var warnDefaultInterfaceOnUnsupportedPlatform = warning.New(
|
||||
@@ -580,27 +576,6 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
|
||||
return detour.NewPacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (r *Router) Exchange(ctx context.Context, message *dnsmessage.Message) (*dnsmessage.Message, error) {
|
||||
ctx, transport := r.matchDNS(ctx)
|
||||
ctx, cancel := context.WithTimeout(ctx, C.DNSTimeout)
|
||||
defer cancel()
|
||||
return r.dnsClient.Exchange(ctx, transport, message)
|
||||
}
|
||||
|
||||
func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) {
|
||||
ctx, transport := r.matchDNS(ctx)
|
||||
ctx, cancel := context.WithTimeout(ctx, C.DNSTimeout)
|
||||
defer cancel()
|
||||
return r.dnsClient.Lookup(ctx, transport, domain, strategy)
|
||||
}
|
||||
|
||||
func (r *Router) LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error) {
|
||||
ctx, transport := r.matchDNS(ctx)
|
||||
ctx, cancel := context.WithTimeout(ctx, C.DNSTimeout)
|
||||
defer cancel()
|
||||
return r.dnsClient.Lookup(ctx, transport, domain, r.defaultDomainStrategy)
|
||||
}
|
||||
|
||||
func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, defaultOutbound adapter.Outbound) (adapter.Rule, adapter.Outbound) {
|
||||
if r.processSearcher != nil {
|
||||
processInfo, err := process.FindProcessInfo(r.processSearcher, ctx, metadata.Network, metadata.Source.Addr, int(metadata.Source.Port))
|
||||
@@ -643,9 +618,7 @@ func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, de
|
||||
func (r *Router) matchDNS(ctx context.Context) (context.Context, dns.Transport) {
|
||||
metadata := adapter.ContextFrom(ctx)
|
||||
if metadata == nil {
|
||||
r.dnsLogger.WarnContext(ctx, "no context: ", reflect.TypeOf(ctx))
|
||||
debug.PrintStack()
|
||||
return ctx, r.defaultTransport
|
||||
panic("no context")
|
||||
}
|
||||
for i, rule := range r.dnsRules {
|
||||
if rule.Match(metadata) {
|
||||
|
||||
109
route/router_dns.go
Normal file
109
route/router_dns.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-dns"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
)
|
||||
|
||||
func (r *Router) Exchange(ctx context.Context, message *dnsmessage.Message) (*dnsmessage.Message, error) {
|
||||
if len(message.Questions) > 0 {
|
||||
r.dnsLogger.DebugContext(ctx, "exchange ", formatDNSQuestion(message.Questions[0]))
|
||||
}
|
||||
ctx, transport := r.matchDNS(ctx)
|
||||
ctx, cancel := context.WithTimeout(ctx, C.DNSTimeout)
|
||||
defer cancel()
|
||||
response, err := r.dnsClient.Exchange(ctx, transport, message)
|
||||
if err != nil && len(message.Questions) > 0 {
|
||||
r.dnsLogger.ErrorContext(ctx, E.Cause(err, "exchange failed for ", message.Questions[0].Name.String()))
|
||||
}
|
||||
if response != nil {
|
||||
LogDNSAnswers(r.dnsLogger, ctx, message.Questions[0].Name.String(), response.Answers)
|
||||
}
|
||||
return response, err
|
||||
}
|
||||
|
||||
func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) {
|
||||
r.dnsLogger.Debug(ctx, "lookup domain ", domain)
|
||||
ctx, transport := r.matchDNS(ctx)
|
||||
ctx, cancel := context.WithTimeout(ctx, C.DNSTimeout)
|
||||
defer cancel()
|
||||
addrs, err := r.dnsClient.Lookup(ctx, transport, domain, strategy)
|
||||
if len(addrs) > 0 {
|
||||
r.logger.InfoContext(ctx, "lookup succeed for ", domain, ": ", F.MapToString(addrs))
|
||||
} else {
|
||||
r.logger.ErrorContext(ctx, E.Cause(err, "lookup failed for ", domain))
|
||||
}
|
||||
return addrs, err
|
||||
}
|
||||
|
||||
func (r *Router) LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error) {
|
||||
return r.Lookup(ctx, domain, r.defaultDomainStrategy)
|
||||
}
|
||||
|
||||
func LogDNSAnswers(logger log.ContextLogger, ctx context.Context, domain string, answers []dnsmessage.Resource) {
|
||||
for _, rawAnswer := range answers {
|
||||
var content string
|
||||
switch answer := rawAnswer.Body.(type) {
|
||||
case *dnsmessage.AResource:
|
||||
content = netip.AddrFrom4(answer.A).String()
|
||||
case *dnsmessage.NSResource:
|
||||
content = answer.NS.String()
|
||||
case *dnsmessage.CNAMEResource:
|
||||
content = answer.CNAME.String()
|
||||
case *dnsmessage.SOAResource:
|
||||
content = answer.MBox.String()
|
||||
case *dnsmessage.PTRResource:
|
||||
content = answer.PTR.String()
|
||||
case *dnsmessage.MXResource:
|
||||
content = answer.MX.String()
|
||||
case *dnsmessage.TXTResource:
|
||||
content = strings.Join(answer.TXT, " ")
|
||||
case *dnsmessage.AAAAResource:
|
||||
content = netip.AddrFrom16(answer.AAAA).String()
|
||||
case *dnsmessage.SRVResource:
|
||||
content = answer.Target.String()
|
||||
case *dnsmessage.UnknownResource:
|
||||
content = answer.Type.String()
|
||||
default:
|
||||
continue
|
||||
}
|
||||
rType := formatDNSType(rawAnswer.Header.Type)
|
||||
if rType == "" {
|
||||
logger.InfoContext(ctx, "exchanged ", domain, " ", rType)
|
||||
} else {
|
||||
logger.InfoContext(ctx, "exchanged ", domain, " ", rType, " ", content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func formatDNSQuestion(question dnsmessage.Question) string {
|
||||
var qType string
|
||||
qType = question.Type.String()
|
||||
if len(qType) > 4 {
|
||||
qType = qType[4:]
|
||||
}
|
||||
var qClass string
|
||||
qClass = question.Class.String()
|
||||
if len(qClass) > 5 {
|
||||
qClass = qClass[5:]
|
||||
}
|
||||
return string(question.Name.Data[:question.Name.Length-1]) + " " + qType + " " + qClass
|
||||
}
|
||||
|
||||
func formatDNSType(qType dnsmessage.Type) string {
|
||||
qTypeName := qType.String()
|
||||
if len(qTypeName) > 4 {
|
||||
return qTypeName[4:]
|
||||
} else {
|
||||
return F.ToString("unknown (type ", qTypeName, ")")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user