@@ -13,6 +13,7 @@ import (
1313 "sync"
1414 "time"
1515
16+ "github.com/database64128/shadowsocks-go/cache"
1617 "github.com/database64128/shadowsocks-go/conn"
1718 "github.com/database64128/shadowsocks-go/netio"
1819 "github.com/database64128/shadowsocks-go/zerocopy"
@@ -26,6 +27,8 @@ const (
2627 maxDNSPacketSize = 1232
2728
2829 lookupTimeout = 20 * time .Second
30+
31+ defaultCacheSize = 1024
2932)
3033
3134var (
@@ -42,9 +45,8 @@ type ResolverConfig struct {
4245
4346 // Type is the resolver type.
4447 //
45- // Available values:
46- // - "plain": Resolve names by sending cleartext DNS queries to the configured upstream server.
47- // - "system": Use the system resolver. This does not support custom server addresses or clients.
48+ // - "plain": Resolve names by sending cleartext DNS queries to the configured upstream server.
49+ // - "system": Use the system resolver. This does not support custom server addresses or clients.
4850 //
4951 // The default value is "plain".
5052 Type string `json:"type,omitzero"`
@@ -59,6 +61,12 @@ type ResolverConfig struct {
5961 // UDPClientName is the name of the UDPClient to use.
6062 // Leave empty to disable UDP.
6163 UDPClientName string `json:"udpClientName,omitzero"`
64+
65+ // CacheSize is the size of the DNS cache.
66+ //
67+ // If zero, the default cache size is 1024.
68+ // If negative, the cache will be unbounded.
69+ CacheSize int `json:"cacheSize,omitzero"`
6270}
6371
6472// NewSimpleResolver creates a new [NewSimpleResolver] from the config.
@@ -101,7 +109,12 @@ func (rc *ResolverConfig) NewSimpleResolver(tcpClientMap map[string]netio.Stream
101109 }
102110 }
103111
104- return NewResolver (rc .Name , rc .AddrPort , tcpClient , udpClient , logger ), nil
112+ cacheSize := rc .CacheSize
113+ if cacheSize == 0 {
114+ cacheSize = defaultCacheSize
115+ }
116+
117+ return NewResolver (rc .Name , cacheSize , rc .AddrPort , tcpClient , udpClient , logger ), nil
105118}
106119
107120// Result represents the result of name resolution.
@@ -120,11 +133,11 @@ type Resolver struct {
120133 // name stores the resolver's name to make its log messages more useful.
121134 name string
122135
123- // mu protects the DNS cache map .
124- mu sync.RWMutex
136+ // mu protects the DNS cache.
137+ mu sync.Mutex
125138
126- // cache is the DNS cache map .
127- cache map [string ] Result
139+ // cache is the DNS cache.
140+ cache cache. BoundedCache [string , Result ]
128141
129142 // serverAddr is the upstream server's address and port.
130143 serverAddr conn.Addr
@@ -142,10 +155,10 @@ type Resolver struct {
142155 logger * zap.Logger
143156}
144157
145- func NewResolver (name string , serverAddrPort netip.AddrPort , tcpClient netio.StreamClient , udpClient zerocopy.UDPClient , logger * zap.Logger ) * Resolver {
158+ func NewResolver (name string , cacheSize int , serverAddrPort netip.AddrPort , tcpClient netio.StreamClient , udpClient zerocopy.UDPClient , logger * zap.Logger ) * Resolver {
146159 return & Resolver {
147160 name : name ,
148- cache : make ( map [string ] Result ),
161+ cache : * cache. NewBoundedCache [string , Result ]( cacheSize ),
149162 serverAddr : conn .AddrFromIPPort (serverAddrPort ),
150163 serverAddrPort : serverAddrPort ,
151164 tcpClient : tcpClient ,
@@ -156,9 +169,9 @@ func NewResolver(name string, serverAddrPort netip.AddrPort, tcpClient netio.Str
156169
157170func (r * Resolver ) lookup (ctx context.Context , name string ) (Result , error ) {
158171 // Lookup cache first.
159- r .mu .RLock ()
160- result , ok := r .cache [ name ]
161- r .mu .RUnlock ()
172+ r .mu .Lock ()
173+ result , ok := r .cache . Get ( name )
174+ r .mu .Unlock ()
162175
163176 if ok && ! result .HasExpired () {
164177 if ce := r .logger .Check (zap .DebugLevel , "DNS lookup got result from cache" ); ce != nil {
@@ -294,7 +307,7 @@ func (r *Resolver) sendQueries(ctx context.Context, nameString string) (result R
294307 // Add result to cache if TTL hasn't expired.
295308 if ! result .HasExpired () {
296309 r .mu .Lock ()
297- r .cache [ nameString ] = result
310+ r .cache . Set ( nameString , result )
298311 r .mu .Unlock ()
299312 }
300313
0 commit comments