Skip to content

Commit ebf0933

Browse files
committed
🫜 socks5: use bounded cache for domain cache
1 parent 6e59794 commit ebf0933

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

socks5/addr.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"unique"
1111
"unsafe"
1212

13+
"github.com/database64128/shadowsocks-go/cache"
1314
"github.com/database64128/shadowsocks-go/conn"
1415
)
1516

@@ -321,8 +322,7 @@ func ConnAddrFromSlice(b []byte) (conn.Addr, int, error) {
321322
//
322323
// The zero value is ready for use.
323324
type DomainCache struct {
324-
domain string
325-
handle unique.Handle[string]
325+
handleByDomain *cache.BoundedCache[string, unique.Handle[string]]
326326
}
327327

328328
// ConnAddrFromSlice is like [ConnAddrFromSlice] but uses the domain cache to minimize string allocations.
@@ -339,14 +339,25 @@ func (c *DomainCache) ConnAddrFromSlice(b []byte) (conn.Addr, int, error) {
339339
if len(b) < portEnd {
340340
return conn.Addr{}, 0, fmt.Errorf("addr length %d is too short for ATYP %#x", len(b), b[0])
341341
}
342-
if domainBytes := b[2:domainEnd]; string(domainBytes) != c.domain {
342+
if c.handleByDomain == nil {
343+
// Initialize the cache with a reasonable size.
344+
const domainCacheSize = 32
345+
c.handleByDomain = cache.NewBoundedCache[string, unique.Handle[string]](domainCacheSize)
346+
}
347+
var domain string
348+
domainBytes := b[2:domainEnd]
349+
entry, ok := c.handleByDomain.GetEntry(string(domainBytes))
350+
if !ok {
343351
// Unsafe is required for Go 1.24 and earlier to avoid allocating on lookup.
344352
// Drop unsafe when we upgrade to Go 1.25.
345-
c.handle = unique.Make(unsafe.String(unsafe.SliceData(domainBytes), len(domainBytes)))
346-
c.domain = c.handle.Value()
353+
handle := unique.Make(unsafe.String(unsafe.SliceData(domainBytes), len(domainBytes)))
354+
domain = handle.Value()
355+
c.handleByDomain.InsertUnchecked(domain, handle)
356+
} else {
357+
domain = entry.Key
347358
}
348359
port := binary.BigEndian.Uint16(b[domainEnd:])
349-
addr, err := conn.AddrFromDomainPort(c.domain, port)
360+
addr, err := conn.AddrFromDomainPort(domain, port)
350361
return addr, portEnd, err
351362

352363
case AtypIPv4:

0 commit comments

Comments
 (0)