Skip to content

Commit ebd31ca

Browse files
committed
Add optimistic DNS cache
1 parent 6ba7a6f commit ebd31ca

30 files changed

Lines changed: 1219 additions & 369 deletions

adapter/dns.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package adapter
33
import (
44
"context"
55
"net/netip"
6+
"time"
67

78
C "github.com/sagernet/sing-box/constant"
89
"github.com/sagernet/sing-box/log"
@@ -31,12 +32,13 @@ type DNSClient interface {
3132
}
3233

3334
type DNSQueryOptions struct {
34-
Transport DNSTransport
35-
Strategy C.DomainStrategy
36-
LookupStrategy C.DomainStrategy
37-
DisableCache bool
38-
RewriteTTL *uint32
39-
ClientSubnet netip.Prefix
35+
Transport DNSTransport
36+
Strategy C.DomainStrategy
37+
LookupStrategy C.DomainStrategy
38+
DisableCache bool
39+
DisableOptimisticCache bool
40+
RewriteTTL *uint32
41+
ClientSubnet netip.Prefix
4042
}
4143

4244
func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptions) (*DNSQueryOptions, error) {
@@ -49,11 +51,12 @@ func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptio
4951
return nil, E.New("domain resolver not found: " + options.Server)
5052
}
5153
return &DNSQueryOptions{
52-
Transport: transport,
53-
Strategy: C.DomainStrategy(options.Strategy),
54-
DisableCache: options.DisableCache,
55-
RewriteTTL: options.RewriteTTL,
56-
ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
54+
Transport: transport,
55+
Strategy: C.DomainStrategy(options.Strategy),
56+
DisableCache: options.DisableCache,
57+
DisableOptimisticCache: options.DisableOptimisticCache,
58+
RewriteTTL: options.RewriteTTL,
59+
ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
5760
}, nil
5861
}
5962

@@ -63,6 +66,13 @@ type RDRCStore interface {
6366
SaveRDRCAsync(transportName string, qName string, qType uint16, logger logger.Logger)
6467
}
6568

69+
type DNSCacheStore interface {
70+
LoadDNSCache(transportName string, qName string, qType uint16) (rawMessage []byte, expireAt time.Time, loaded bool)
71+
SaveDNSCache(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time) error
72+
SaveDNSCacheAsync(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time, logger logger.Logger)
73+
ClearDNSCache() error
74+
}
75+
6676
type DNSTransport interface {
6777
Lifecycle
6878
Type() string

adapter/experimental.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ type CacheFile interface {
4747
StoreRDRC() bool
4848
RDRCStore
4949

50+
StoreDNS() bool
51+
DNSCacheStore
52+
53+
SetDisableExpire(disableExpire bool)
54+
SetOptimisticTimeout(timeout time.Duration)
55+
5056
LoadMode() string
5157
StoreMode(mode string) error
5258
LoadSelected(group string) string

box.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,10 @@ func New(options Options) (*Box, error) {
196196
service.MustRegister[adapter.DNSTransportManager](ctx, dnsTransportManager)
197197
service.MustRegister[adapter.ServiceManager](ctx, serviceManager)
198198
service.MustRegister[adapter.CertificateProviderManager](ctx, certificateProviderManager)
199-
dnsRouter := dns.NewRouter(ctx, logFactory, dnsOptions)
199+
dnsRouter, err := dns.NewRouter(ctx, logFactory, dnsOptions)
200+
if err != nil {
201+
return nil, E.Cause(err, "initialize DNS router")
202+
}
200203
service.MustRegister[adapter.DNSRouter](ctx, dnsRouter)
201204
service.MustRegister[adapter.DNSRuleSetUpdateValidator](ctx, dnsRouter)
202205
networkManager, err := route.NewNetworkManager(ctx, logFactory.NewLogger("network"), routeOptions, dnsOptions)
@@ -372,7 +375,7 @@ func New(options Options) (*Box, error) {
372375
}
373376
}
374377
if needCacheFile {
375-
cacheFile := cachefile.New(ctx, common.PtrValueOrDefault(experimentalOptions.CacheFile))
378+
cacheFile := cachefile.New(ctx, logFactory.NewLogger("cache-file"), common.PtrValueOrDefault(experimentalOptions.CacheFile))
376379
service.MustRegister[adapter.CacheFile](ctx, cacheFile)
377380
internalServices = append(internalServices, cacheFile)
378381
}

common/dialer/dialer.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,12 @@ func NewWithOptions(options Options) (N.Dialer, error) {
8787
}
8888
server = dialOptions.DomainResolver.Server
8989
dnsQueryOptions = adapter.DNSQueryOptions{
90-
Transport: transport,
91-
Strategy: strategy,
92-
DisableCache: dialOptions.DomainResolver.DisableCache,
93-
RewriteTTL: dialOptions.DomainResolver.RewriteTTL,
94-
ClientSubnet: dialOptions.DomainResolver.ClientSubnet.Build(netip.Prefix{}),
90+
Transport: transport,
91+
Strategy: strategy,
92+
DisableCache: dialOptions.DomainResolver.DisableCache,
93+
DisableOptimisticCache: dialOptions.DomainResolver.DisableOptimisticCache,
94+
RewriteTTL: dialOptions.DomainResolver.RewriteTTL,
95+
ClientSubnet: dialOptions.DomainResolver.ClientSubnet.Build(netip.Prefix{}),
9596
}
9697
resolveFallbackDelay = time.Duration(dialOptions.FallbackDelay)
9798
} else if options.DirectResolver {

0 commit comments

Comments
 (0)