mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-05-13 13:57:05 +00:00
Clean up DNS transports
This commit is contained in:
parent
a3fc14f35f
commit
3312b8da50
9 changed files with 736 additions and 1031 deletions
|
|
@ -49,6 +49,7 @@ type DNSTransport struct {
|
|||
dnsRouter adapter.DNSRouter
|
||||
endpointManager adapter.EndpointManager
|
||||
endpoint *Endpoint
|
||||
access sync.RWMutex
|
||||
routePrefixes []netip.Prefix
|
||||
routes map[string][]adapter.DNSTransport
|
||||
hosts map[string][]netip.Addr
|
||||
|
|
@ -91,6 +92,12 @@ func (t *DNSTransport) Start(stage adapter.StartStage) error {
|
|||
}
|
||||
|
||||
func (t *DNSTransport) Reset() {
|
||||
t.access.RLock()
|
||||
transports := t.collectResolversLocked()
|
||||
t.access.RUnlock()
|
||||
for _, transport := range transports {
|
||||
transport.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func (t *DNSTransport) onReconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCfg *nDNS.Config) {
|
||||
|
|
@ -101,7 +108,7 @@ func (t *DNSTransport) onReconfig(cfg *wgcfg.Config, routerCfg *router.Config, d
|
|||
}
|
||||
|
||||
func (t *DNSTransport) updateDNSServers(routeConfig *router.Config, dnsConfig *nDNS.Config) error {
|
||||
t.routePrefixes = buildRoutePrefixes(routeConfig)
|
||||
routePrefixes := buildRoutePrefixes(routeConfig)
|
||||
directDialerOnce := sync.OnceValue(func() N.Dialer {
|
||||
directDialer := common.Must1(dialer.NewDefault(t.ctx, option.DialerOptions{}))
|
||||
return &DNSDialer{transport: t, fallbackDialer: directDialer}
|
||||
|
|
@ -130,9 +137,19 @@ func (t *DNSTransport) updateDNSServers(routeConfig *router.Config, dnsConfig *n
|
|||
}
|
||||
defaultResolvers = append(defaultResolvers, myResolver)
|
||||
}
|
||||
|
||||
t.access.Lock()
|
||||
oldResolvers := t.collectResolversLocked()
|
||||
t.routePrefixes = routePrefixes
|
||||
t.routes = routes
|
||||
t.hosts = hosts
|
||||
t.defaultResolvers = defaultResolvers
|
||||
t.access.Unlock()
|
||||
|
||||
for _, transport := range oldResolvers {
|
||||
transport.Close()
|
||||
}
|
||||
|
||||
if len(defaultResolvers) > 0 {
|
||||
t.logger.Info("updated ", len(routes), " routes, ", len(hosts), " hosts, default resolvers: ",
|
||||
strings.Join(common.Map(dnsConfig.DefaultResolvers, func(it *dnstype.Resolver) string { return it.Addr }), " "))
|
||||
|
|
@ -207,7 +224,22 @@ func buildRoutePrefixes(routeConfig *router.Config) []netip.Prefix {
|
|||
}
|
||||
|
||||
func (t *DNSTransport) Close() error {
|
||||
return nil
|
||||
t.access.Lock()
|
||||
transports := t.collectResolversLocked()
|
||||
t.routePrefixes = nil
|
||||
t.routes = nil
|
||||
t.hosts = nil
|
||||
t.defaultResolvers = nil
|
||||
t.access.Unlock()
|
||||
|
||||
var err error
|
||||
for _, transport := range transports {
|
||||
name := "resolver/" + transport.Type() + "[" + transport.Tag() + "]"
|
||||
err = E.Append(err, transport.Close(), func(err error) error {
|
||||
return E.Cause(err, "close ", name)
|
||||
})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *DNSTransport) Raw() bool {
|
||||
|
|
@ -219,7 +251,15 @@ func (t *DNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M
|
|||
return nil, os.ErrInvalid
|
||||
}
|
||||
question := message.Question[0]
|
||||
addresses, hostsLoaded := t.hosts[question.Name]
|
||||
|
||||
t.access.RLock()
|
||||
hosts := t.hosts
|
||||
routes := t.routes
|
||||
defaultResolvers := t.defaultResolvers
|
||||
acceptDefaultResolvers := t.acceptDefaultResolvers
|
||||
t.access.RUnlock()
|
||||
|
||||
addresses, hostsLoaded := hosts[question.Name]
|
||||
if hostsLoaded {
|
||||
switch question.Qtype {
|
||||
case mDNS.TypeA:
|
||||
|
|
@ -238,7 +278,7 @@ func (t *DNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M
|
|||
}
|
||||
}
|
||||
}
|
||||
for domainSuffix, transports := range t.routes {
|
||||
for domainSuffix, transports := range routes {
|
||||
if strings.HasSuffix(question.Name, domainSuffix) {
|
||||
if len(transports) == 0 {
|
||||
return &mDNS.Msg{
|
||||
|
|
@ -262,10 +302,10 @@ func (t *DNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M
|
|||
return nil, lastErr
|
||||
}
|
||||
}
|
||||
if t.acceptDefaultResolvers {
|
||||
if len(t.defaultResolvers) > 0 {
|
||||
if acceptDefaultResolvers {
|
||||
if len(defaultResolvers) > 0 {
|
||||
var lastErr error
|
||||
for _, resolver := range t.defaultResolvers {
|
||||
for _, resolver := range defaultResolvers {
|
||||
response, err := resolver.Exchange(ctx, message)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
|
|
@ -281,6 +321,15 @@ func (t *DNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M
|
|||
return nil, dns.RcodeNameError
|
||||
}
|
||||
|
||||
func (t *DNSTransport) collectResolversLocked() []adapter.DNSTransport {
|
||||
var transports []adapter.DNSTransport
|
||||
for _, resolvers := range t.routes {
|
||||
transports = append(transports, resolvers...)
|
||||
}
|
||||
transports = append(transports, t.defaultResolvers...)
|
||||
return transports
|
||||
}
|
||||
|
||||
type DNSDialer struct {
|
||||
transport *DNSTransport
|
||||
fallbackDialer N.Dialer
|
||||
|
|
@ -290,7 +339,8 @@ func (d *DNSDialer) DialContext(ctx context.Context, network string, destination
|
|||
if destination.IsDomain() {
|
||||
panic("invalid request here")
|
||||
}
|
||||
for _, prefix := range d.transport.routePrefixes {
|
||||
routePrefixes := d.transport.routePrefixesSnapshot()
|
||||
for _, prefix := range routePrefixes {
|
||||
if prefix.Contains(destination.Addr) {
|
||||
return d.transport.endpoint.DialContext(ctx, network, destination)
|
||||
}
|
||||
|
|
@ -302,10 +352,17 @@ func (d *DNSDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (
|
|||
if destination.IsDomain() {
|
||||
panic("invalid request here")
|
||||
}
|
||||
for _, prefix := range d.transport.routePrefixes {
|
||||
routePrefixes := d.transport.routePrefixesSnapshot()
|
||||
for _, prefix := range routePrefixes {
|
||||
if prefix.Contains(destination.Addr) {
|
||||
return d.transport.endpoint.ListenPacket(ctx, destination)
|
||||
}
|
||||
}
|
||||
return d.fallbackDialer.ListenPacket(ctx, destination)
|
||||
}
|
||||
|
||||
func (t *DNSTransport) routePrefixesSnapshot() []netip.Prefix {
|
||||
t.access.RLock()
|
||||
defer t.access.RUnlock()
|
||||
return append([]netip.Prefix(nil), t.routePrefixes...)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue