Chore: increase nattable capacity

This commit is contained in:
yaling888 2022-04-24 02:19:23 +08:00 committed by adlyq
parent 4fd7d0f707
commit 16a35527b7
2 changed files with 42 additions and 13 deletions

View file

@ -1,13 +1,15 @@
package nat package nat
import ( import (
"container/list"
"net/netip" "net/netip"
"sync"
"github.com/Dreamacro/clash/common/generics/list"
) )
const ( const (
portBegin = 30000 portBegin = 30000
portLength = 4096 portLength = 10240
) )
var zeroTuple = tuple{} var zeroTuple = tuple{}
@ -23,9 +25,10 @@ type binding struct {
} }
type table struct { type table struct {
tuples map[tuple]*list.Element mu sync.Mutex
ports [portLength]*list.Element tuples map[tuple]*list.Element[*binding]
available *list.List ports [portLength]*list.Element[*binding]
available *list.List[*binding]
} }
func (t *table) tupleOf(port uint16) tuple { func (t *table) tupleOf(port uint16) tuple {
@ -36,28 +39,31 @@ func (t *table) tupleOf(port uint16) tuple {
elm := t.ports[offset] elm := t.ports[offset]
t.available.MoveToFront(elm) return elm.Value.tuple
return elm.Value.(*binding).tuple
} }
func (t *table) portOf(tuple tuple) uint16 { func (t *table) portOf(tuple tuple) uint16 {
t.mu.Lock()
elm := t.tuples[tuple] elm := t.tuples[tuple]
t.mu.Unlock()
if elm == nil { if elm == nil {
return 0 return 0
} }
t.available.MoveToFront(elm) t.available.MoveToFront(elm)
return portBegin + elm.Value.(*binding).offset return portBegin + elm.Value.offset
} }
func (t *table) newConn(tuple tuple) uint16 { func (t *table) newConn(tuple tuple) uint16 {
elm := t.available.Back() elm := t.available.Back()
b := elm.Value.(*binding) b := elm.Value
t.mu.Lock()
delete(t.tuples, b.tuple) delete(t.tuples, b.tuple)
t.tuples[tuple] = elm t.tuples[tuple] = elm
t.mu.Unlock()
b.tuple = tuple b.tuple = tuple
t.available.MoveToFront(elm) t.available.MoveToFront(elm)
@ -65,11 +71,24 @@ func (t *table) newConn(tuple tuple) uint16 {
return portBegin + b.offset return portBegin + b.offset
} }
func (t *table) delete(tup tuple) {
t.mu.Lock()
elm := t.tuples[tup]
if elm == nil {
t.mu.Unlock()
return
}
delete(t.tuples, tup)
t.mu.Unlock()
t.available.MoveToBack(elm)
}
func newTable() *table { func newTable() *table {
result := &table{ result := &table{
tuples: make(map[tuple]*list.Element, portLength), tuples: make(map[tuple]*list.Element[*binding], portLength),
ports: [portLength]*list.Element{}, ports: [portLength]*list.Element[*binding]{},
available: list.New(), available: list.New[*binding](),
} }
for idx := range result.ports { for idx := range result.ports {

View file

@ -16,6 +16,8 @@ type conn struct {
net.Conn net.Conn
tuple tuple tuple tuple
close func(tuple tuple)
} }
func (t *TCP) Accept() (net.Conn, error) { func (t *TCP) Accept() (net.Conn, error) {
@ -37,6 +39,9 @@ func (t *TCP) Accept() (net.Conn, error) {
return &conn{ return &conn{
Conn: c, Conn: c,
tuple: tup, tuple: tup,
close: func(tuple tuple) {
t.table.delete(tuple)
},
}, nil }, nil
} }
@ -52,6 +57,11 @@ func (t *TCP) SetDeadline(time time.Time) error {
return t.listener.SetDeadline(time) return t.listener.SetDeadline(time)
} }
func (c *conn) Close() error {
c.close(c.tuple)
return c.Conn.Close()
}
func (c *conn) LocalAddr() net.Addr { func (c *conn) LocalAddr() net.Addr {
return &net.TCPAddr{ return &net.TCPAddr{
IP: c.tuple.SourceAddr.Addr().AsSlice(), IP: c.tuple.SourceAddr.Addr().AsSlice(),