Skip to content

Commit a04ceff

Browse files
committed
2025-03-03 12:12:30
1 parent 1f3543f commit a04ceff

File tree

2 files changed

+50
-36
lines changed

2 files changed

+50
-36
lines changed

daze.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ import (
4949
var Conf = struct {
5050
DialerTimeout time.Duration
5151
RouterLruSize int
52+
Socks5LruSize int
5253
}{
5354
DialerTimeout: time.Second * 8,
5455
// A single cache entry represents a single host or DNS name lookup. Make the cache as large as the maximum number
5556
// of clients that access your web site concurrently. Note that setting the cache size too high is a waste of
5657
// memory and degrades performance.
5758
RouterLruSize: 64,
59+
Socks5LruSize: 8,
5860
}
5961

6062
// ResolverDns returns a DNS resolver.
@@ -441,7 +443,7 @@ func (l *Locale) ServeSocks5UDP(ctx *Context, cli io.ReadWriteCloser) error {
441443
bndPort uint16
442444
bnd *net.UDPConn
443445
buf = make([]byte, 2048)
444-
cpl = map[string]io.ReadWriteCloser{}
446+
cpl = lru.New[string, io.ReadWriteCloser](Conf.Socks5LruSize)
445447
dstHost string
446448
dstPort uint16
447449
dst string
@@ -458,6 +460,9 @@ func (l *Locale) ServeSocks5UDP(ctx *Context, cli io.ReadWriteCloser) error {
458460
if err != nil {
459461
return err
460462
}
463+
cpl.Drop = func(k string, v io.ReadWriteCloser) {
464+
v.Close()
465+
}
461466

462467
// https://datatracker.ietf.org/doc/html/rfc1928, Page 7, UDP ASSOCIATE:
463468
// A UDP association terminates when the TCP connection that the UDP ASSOCIATE request arrived on terminates.
@@ -513,27 +518,26 @@ func (l *Locale) ServeSocks5UDP(ctx *Context, cli io.ReadWriteCloser) error {
513518
dstPort = binary.BigEndian.Uint16(appHead[20:22])
514519
}
515520
dst = dstHost + ":" + strconv.Itoa(int(dstPort))
516-
srv = cpl[dst]
517-
if srv == nil {
521+
if !cpl.Has(dst) {
518522
log.Printf("conn: %08x proto format=socks5", ctx.Cid)
519523
srv, err = l.Dialer.Dial(ctx, "udp", dst)
520524
if err != nil {
521525
log.Printf("conn: %08x error %s", ctx.Cid, err)
522526
continue
523527
}
524-
cpl[dst] = srv
528+
cpl.Set(dst, srv)
525529
go l.ServeSocks5UDPRead(srv, bnd, appAddr, appHead)
526530
}
531+
srv = cpl.Get(dst)
527532
_, err = srv.Write(buf[appHeadSize:appSize])
528533
if err != nil {
529534
log.Printf("conn: %08x error %s", ctx.Cid, err)
530-
srv.Close()
531-
delete(cpl, dst)
535+
cpl.Del(dst)
532536
continue
533537
}
534538
}
535-
for _, e := range cpl {
536-
e.Close()
539+
for k := range cpl.C {
540+
cpl.Del(k)
537541
}
538542
return nil
539543
}

lib/lru/lru.go

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ func (l *List[K, V]) Insert(e *Elem[K, V]) *Elem[K, V] {
3838
return e
3939
}
4040

41+
// Remove removes e from its list, decrements l's size.
42+
func (l *List[K, V]) Remove(e *Elem[K, V]) {
43+
e.Prev.Next = e.Next
44+
e.Next.Prev = e.Prev
45+
e.Prev = nil // Avoid memory leaks
46+
e.Next = nil // Avoid memory leaks
47+
l.Size--
48+
}
49+
4150
// Update e to next to root.
4251
func (l *List[K, V]) Update(e *Elem[K, V]) {
4352
if l.Root.Next == e {
@@ -51,42 +60,17 @@ func (l *List[K, V]) Update(e *Elem[K, V]) {
5160
e.Next.Prev = e
5261
}
5362

54-
// Remove removes e from its list, decrements l's size.
55-
func (l *List[K, V]) Remove(e *Elem[K, V]) {
56-
e.Prev.Next = e.Next
57-
e.Next.Prev = e.Prev
58-
e.Prev = nil // Avoid memory leaks
59-
e.Next = nil // Avoid memory leaks
60-
l.Size--
61-
}
62-
6363
// Lru cache. It is safe for concurrent access.
6464
type Lru[K comparable, V any] struct {
65-
// Size is the maximum number of cache entries before
66-
// an item is evicted. Zero means no limit.
65+
// Drop is called automatically when an elem is deleted.
66+
Drop func(k K, v V)
67+
// Size is the maximum number of cache entries before an item is evicted. Zero means no limit.
6768
Size int
6869
List *List[K, V]
6970
C map[K]*Elem[K, V]
7071
M *sync.Mutex
7172
}
7273

73-
// Set adds a value to the cache.
74-
func (l *Lru[K, V]) Set(k K, v V) {
75-
l.M.Lock()
76-
defer l.M.Unlock()
77-
if e, ok := l.C[k]; ok {
78-
l.List.Update(e)
79-
e.K = k
80-
e.V = v
81-
return
82-
}
83-
if l.List.Size == l.Size {
84-
delete(l.C, l.List.Root.Prev.K)
85-
l.List.Remove(l.List.Root.Prev)
86-
}
87-
l.C[k] = l.List.Insert(&Elem[K, V]{K: k, V: v})
88-
}
89-
9074
// Get looks up a key's value from the cache.
9175
func (l *Lru[K, V]) GetExists(k K) (v V, ok bool) {
9276
l.M.Lock()
@@ -111,21 +95,47 @@ func (l *Lru[K, V]) Del(k K) {
11195
l.M.Lock()
11296
defer l.M.Unlock()
11397
if e, ok := l.C[k]; ok {
98+
l.Drop(k, e.V)
11499
delete(l.C, k)
115100
l.List.Remove(e)
116101
}
117102
}
118103

104+
// Has returns true if a key exists.
105+
func (l *Lru[K, V]) Has(k K) bool {
106+
_, b := l.C[k]
107+
return b
108+
}
109+
119110
// Len returns the number of items in the cache.
120111
func (l *Lru[K, V]) Len() int {
121112
l.M.Lock()
122113
defer l.M.Unlock()
123114
return l.List.Size
124115
}
125116

117+
// Set adds a value to the cache.
118+
func (l *Lru[K, V]) Set(k K, v V) {
119+
l.M.Lock()
120+
defer l.M.Unlock()
121+
if e, ok := l.C[k]; ok {
122+
l.List.Update(e)
123+
e.K = k
124+
e.V = v
125+
return
126+
}
127+
if l.List.Size == l.Size {
128+
l.Drop(l.List.Root.Prev.K, l.List.Root.Prev.V)
129+
delete(l.C, l.List.Root.Prev.K)
130+
l.List.Remove(l.List.Root.Prev)
131+
}
132+
l.C[k] = l.List.Insert(&Elem[K, V]{K: k, V: v})
133+
}
134+
126135
// New returns a new LRU cache. If size is zero, the cache has no limit.
127136
func New[K comparable, V any](size int) *Lru[K, V] {
128137
return &Lru[K, V]{
138+
Drop: func(k K, v V) {},
129139
Size: size,
130140
List: new(List[K, V]).Init(),
131141
C: map[K]*Elem[K, V]{},

0 commit comments

Comments
 (0)