mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 16:41:30 +00:00
Improve dns log
This commit is contained in:
parent
f6f3390490
commit
8e4de29409
|
@ -7,6 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-dns"
|
"github.com/sagernet/sing-dns"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
@ -33,6 +34,7 @@ func (d *ResolveDialer) DialContext(ctx context.Context, network string, destina
|
||||||
return d.dialer.DialContext(ctx, network, destination)
|
return d.dialer.DialContext(ctx, network, destination)
|
||||||
}
|
}
|
||||||
ctx, metadata := adapter.AppendContext(ctx)
|
ctx, metadata := adapter.AppendContext(ctx)
|
||||||
|
ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
|
||||||
metadata.Destination = destination
|
metadata.Destination = destination
|
||||||
metadata.Domain = ""
|
metadata.Domain = ""
|
||||||
var addresses []netip.Addr
|
var addresses []netip.Addr
|
||||||
|
@ -53,6 +55,7 @@ func (d *ResolveDialer) ListenPacket(ctx context.Context, destination M.Socksadd
|
||||||
return d.dialer.ListenPacket(ctx, destination)
|
return d.dialer.ListenPacket(ctx, destination)
|
||||||
}
|
}
|
||||||
ctx, metadata := adapter.AppendContext(ctx)
|
ctx, metadata := adapter.AppendContext(ctx)
|
||||||
|
ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
|
||||||
metadata.Destination = destination
|
metadata.Destination = destination
|
||||||
metadata.Domain = ""
|
metadata.Domain = ""
|
||||||
var addresses []netip.Addr
|
var addresses []netip.Addr
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -14,15 +14,15 @@ require (
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||||
github.com/oschwald/maxminddb-golang v1.9.0
|
github.com/oschwald/maxminddb-golang v1.9.0
|
||||||
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a
|
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220801112436-b9e99d83271e
|
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220803073114-9fad6b0cf330
|
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9
|
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9
|
||||||
github.com/spf13/cobra v1.5.0
|
github.com/spf13/cobra v1.5.0
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
go.uber.org/atomic v1.9.0
|
go.uber.org/atomic v1.9.0
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
||||||
golang.org/x/net v0.0.0-20220728211354-c7608f3a8462
|
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b
|
||||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d
|
golang.org/x/sys v0.0.0-20220731174439-a90be440212d
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -151,12 +151,12 @@ github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 h1:hE+vtsjBCCPmxk
|
||||||
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||||
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a h1:CHxuamnZEAxXoep7ycGSuMOiKzsRYuYa0ucnOCdUT9U=
|
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a h1:CHxuamnZEAxXoep7ycGSuMOiKzsRYuYa0ucnOCdUT9U=
|
||||||
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220801112436-b9e99d83271e h1:bkAQ07NmD2vvEg1r/VrKr63BeJXQqZP29waU1Lr1XBM=
|
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 h1:jxt2PYixIkK2i7nUGW3f+PzJagEZcbNyQddBWGuqNnw=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220801112436-b9e99d83271e/go.mod h1:4pEktidzm9Aq9QaN0TuwhOTYD2nFSPsoXckG4svKz/Q=
|
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1 h1:RYvOc69eSNMN0dwVugrDts41Nn7Ar/C/n/fvytvFcp4=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1 h1:RYvOc69eSNMN0dwVugrDts41Nn7Ar/C/n/fvytvFcp4=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1/go.mod h1:NqZjiXszgVCMQ4gVDa2V+drhS8NMfGqUqDF86EacEFc=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1/go.mod h1:NqZjiXszgVCMQ4gVDa2V+drhS8NMfGqUqDF86EacEFc=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220803073114-9fad6b0cf330 h1:CtucdvCCxX57pibRy1Cucy104XR0XuVJqWoTIg42O0Q=
|
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed h1:28qeqeuHLZEkzdcZjYwcCn8y4ckyKimaP+L4P25dqUo=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220803073114-9fad6b0cf330/go.mod h1:jNlPidQzZYkpmpQJ+sDN2YGrPsL4QImoqBpuauId9po=
|
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed/go.mod h1:jNlPidQzZYkpmpQJ+sDN2YGrPsL4QImoqBpuauId9po=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9 h1:x+r8P5MKyQWGN3tcI5dmOM1Aei1mlWua2ciMBGz0/oM=
|
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9 h1:x+r8P5MKyQWGN3tcI5dmOM1Aei1mlWua2ciMBGz0/oM=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9/go.mod h1:ETvczg3TQzGa8zg0lYXj8cYTJr4+OFUmtQer9/c/cLU=
|
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9/go.mod h1:ETvczg3TQzGa8zg0lYXj8cYTJr4+OFUmtQer9/c/cLU=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
@ -241,8 +241,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220728211354-c7608f3a8462 h1:UreQrH7DbFXSi9ZFox6FNT3WBooWmdANpU+IfkT1T4I=
|
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0=
|
||||||
golang.org/x/net v0.0.0-20220728211354-c7608f3a8462/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
|
|
@ -54,6 +54,7 @@ type simpleLogger struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *simpleLogger) Log(ctx context.Context, level Level, args []any) {
|
func (l *simpleLogger) Log(ctx context.Context, level Level, args []any) {
|
||||||
|
level = OverrideLevelFromContext(level, ctx)
|
||||||
if level > l.level {
|
if level > l.level {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ type observableLogger struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *observableLogger) Log(ctx context.Context, level Level, args []any) {
|
func (l *observableLogger) Log(ctx context.Context, level Level, args []any) {
|
||||||
|
level = OverrideLevelFromContext(level, ctx)
|
||||||
if level > l.level {
|
if level > l.level {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
19
log/override.go
Normal file
19
log/override.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type overrideLevelKey struct{}
|
||||||
|
|
||||||
|
func ContextWithOverrideLevel(ctx context.Context, level Level) context.Context {
|
||||||
|
return context.WithValue(ctx, (*overrideLevelKey)(nil), level)
|
||||||
|
}
|
||||||
|
|
||||||
|
func OverrideLevelFromContext(origin Level, ctx context.Context) Level {
|
||||||
|
level, loaded := ctx.Value((*overrideLevelKey)(nil)).(Level)
|
||||||
|
if !loaded || origin < level {
|
||||||
|
return origin
|
||||||
|
}
|
||||||
|
return level
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, o
|
||||||
case C.TypeBlock:
|
case C.TypeBlock:
|
||||||
return NewBlock(logger, options.Tag), nil
|
return NewBlock(logger, options.Tag), nil
|
||||||
case C.TypeDNS:
|
case C.TypeDNS:
|
||||||
return NewDNS(router, logger, options.Tag), nil
|
return NewDNS(router, options.Tag), nil
|
||||||
case C.TypeSocks:
|
case C.TypeSocks:
|
||||||
return NewSocks(router, logger, options.Tag, options.SocksOptions)
|
return NewSocks(router, logger, options.Tag, options.SocksOptions)
|
||||||
case C.TypeHTTP:
|
case C.TypeHTTP:
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/common/canceler"
|
"github.com/sagernet/sing-box/common/canceler"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/log"
|
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
"github.com/sagernet/sing/common/buf"
|
"github.com/sagernet/sing/common/buf"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
|
@ -26,13 +25,12 @@ type DNS struct {
|
||||||
myOutboundAdapter
|
myOutboundAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDNS(router adapter.Router, logger log.ContextLogger, tag string) *DNS {
|
func NewDNS(router adapter.Router, tag string) *DNS {
|
||||||
return &DNS{
|
return &DNS{
|
||||||
myOutboundAdapter{
|
myOutboundAdapter{
|
||||||
protocol: C.TypeDNS,
|
protocol: C.TypeDNS,
|
||||||
network: []string{N.NetworkTCP, N.NetworkUDP},
|
network: []string{N.NetworkTCP, N.NetworkUDP},
|
||||||
router: router,
|
router: router,
|
||||||
logger: logger,
|
|
||||||
tag: tag,
|
tag: tag,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -75,7 +73,6 @@ func (d *DNS) NewConnection(ctx context.Context, conn net.Conn, metadata adapter
|
||||||
if len(message.Questions) > 0 {
|
if len(message.Questions) > 0 {
|
||||||
question := message.Questions[0]
|
question := message.Questions[0]
|
||||||
metadata.Domain = string(question.Name.Data[:question.Name.Length-1])
|
metadata.Domain = string(question.Name.Data[:question.Name.Length-1])
|
||||||
d.logger.DebugContext(ctx, "inbound dns query ", formatDNSQuestion(question), " from ", metadata.Source)
|
|
||||||
}
|
}
|
||||||
go func() error {
|
go func() error {
|
||||||
response, err := d.router.Exchange(ctx, &message)
|
response, err := d.router.Exchange(ctx, &message)
|
||||||
|
@ -124,7 +121,6 @@ func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metada
|
||||||
if len(message.Questions) > 0 {
|
if len(message.Questions) > 0 {
|
||||||
question := message.Questions[0]
|
question := message.Questions[0]
|
||||||
metadata.Domain = string(question.Name.Data[:question.Name.Length-1])
|
metadata.Domain = string(question.Name.Data[:question.Name.Length-1])
|
||||||
d.logger.DebugContext(ctx, "inbound dns query ", formatDNSQuestion(question), " from ", metadata.Source)
|
|
||||||
}
|
}
|
||||||
timeout.Update()
|
timeout.Update()
|
||||||
go func() error {
|
go func() error {
|
||||||
|
@ -150,17 +146,3 @@ func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metada
|
||||||
})
|
})
|
||||||
return group.Run(ctx)
|
return group.Run(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,8 +10,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
|
||||||
"runtime/debug"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -36,8 +34,6 @@ import (
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
"github.com/sagernet/sing/common/rw"
|
"github.com/sagernet/sing/common/rw"
|
||||||
|
|
||||||
"golang.org/x/net/dns/dnsmessage"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var warnDefaultInterfaceOnUnsupportedPlatform = warning.New(
|
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)
|
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) {
|
func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, defaultOutbound adapter.Outbound) (adapter.Rule, adapter.Outbound) {
|
||||||
if r.processSearcher != nil {
|
if r.processSearcher != nil {
|
||||||
processInfo, err := process.FindProcessInfo(r.processSearcher, ctx, metadata.Network, metadata.Source.Addr, int(metadata.Source.Port))
|
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) {
|
func (r *Router) matchDNS(ctx context.Context) (context.Context, dns.Transport) {
|
||||||
metadata := adapter.ContextFrom(ctx)
|
metadata := adapter.ContextFrom(ctx)
|
||||||
if metadata == nil {
|
if metadata == nil {
|
||||||
r.dnsLogger.WarnContext(ctx, "no context: ", reflect.TypeOf(ctx))
|
panic("no context")
|
||||||
debug.PrintStack()
|
|
||||||
return ctx, r.defaultTransport
|
|
||||||
}
|
}
|
||||||
for i, rule := range r.dnsRules {
|
for i, rule := range r.dnsRules {
|
||||||
if rule.Match(metadata) {
|
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, ")")
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ require (
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1
|
||||||
github.com/spyzhov/ajson v0.7.1
|
github.com/spyzhov/ajson v0.7.1
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
golang.org/x/net v0.0.0-20220728211354-c7608f3a8462
|
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
@ -53,8 +53,8 @@ require (
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 // indirect
|
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 // indirect
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220801112436-b9e99d83271e // indirect
|
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 // indirect
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220803073114-9fad6b0cf330 // indirect
|
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed // indirect
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9 // indirect
|
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9 // indirect
|
||||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||||
|
|
12
test/go.sum
12
test/go.sum
|
@ -176,12 +176,12 @@ github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 h1:hE+vtsjBCCPmxk
|
||||||
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||||
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a h1:CHxuamnZEAxXoep7ycGSuMOiKzsRYuYa0ucnOCdUT9U=
|
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a h1:CHxuamnZEAxXoep7ycGSuMOiKzsRYuYa0ucnOCdUT9U=
|
||||||
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
github.com/sagernet/sing v0.0.0-20220803094243-d9ca259bec6a/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220801112436-b9e99d83271e h1:bkAQ07NmD2vvEg1r/VrKr63BeJXQqZP29waU1Lr1XBM=
|
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 h1:jxt2PYixIkK2i7nUGW3f+PzJagEZcbNyQddBWGuqNnw=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220801112436-b9e99d83271e/go.mod h1:4pEktidzm9Aq9QaN0TuwhOTYD2nFSPsoXckG4svKz/Q=
|
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1 h1:RYvOc69eSNMN0dwVugrDts41Nn7Ar/C/n/fvytvFcp4=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1 h1:RYvOc69eSNMN0dwVugrDts41Nn7Ar/C/n/fvytvFcp4=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1/go.mod h1:NqZjiXszgVCMQ4gVDa2V+drhS8NMfGqUqDF86EacEFc=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1/go.mod h1:NqZjiXszgVCMQ4gVDa2V+drhS8NMfGqUqDF86EacEFc=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220803073114-9fad6b0cf330 h1:CtucdvCCxX57pibRy1Cucy104XR0XuVJqWoTIg42O0Q=
|
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed h1:28qeqeuHLZEkzdcZjYwcCn8y4ckyKimaP+L4P25dqUo=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220803073114-9fad6b0cf330/go.mod h1:jNlPidQzZYkpmpQJ+sDN2YGrPsL4QImoqBpuauId9po=
|
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed/go.mod h1:jNlPidQzZYkpmpQJ+sDN2YGrPsL4QImoqBpuauId9po=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9 h1:x+r8P5MKyQWGN3tcI5dmOM1Aei1mlWua2ciMBGz0/oM=
|
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9 h1:x+r8P5MKyQWGN3tcI5dmOM1Aei1mlWua2ciMBGz0/oM=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9/go.mod h1:ETvczg3TQzGa8zg0lYXj8cYTJr4+OFUmtQer9/c/cLU=
|
github.com/sagernet/sing-vmess v0.0.0-20220802053753-a38d3b22e6b9/go.mod h1:ETvczg3TQzGa8zg0lYXj8cYTJr4+OFUmtQer9/c/cLU=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
@ -271,8 +271,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220728211354-c7608f3a8462 h1:UreQrH7DbFXSi9ZFox6FNT3WBooWmdANpU+IfkT1T4I=
|
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0=
|
||||||
golang.org/x/net v0.0.0-20220728211354-c7608f3a8462/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
|
Loading…
Reference in a new issue