Fix system stack TCP NAT collision
This commit is contained in:
parent
3b51857024
commit
8caaa93f8d
1 changed files with 11 additions and 5 deletions
|
|
@ -15,10 +15,15 @@ type TCPNat struct {
|
||||||
portIndex uint16
|
portIndex uint16
|
||||||
portAccess sync.RWMutex
|
portAccess sync.RWMutex
|
||||||
addrAccess sync.RWMutex
|
addrAccess sync.RWMutex
|
||||||
addrMap map[netip.AddrPort]uint16
|
addrMap map[tcpNatKey]uint16
|
||||||
portMap map[uint16]*TCPSession
|
portMap map[uint16]*TCPSession
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tcpNatKey struct {
|
||||||
|
Source netip.AddrPort
|
||||||
|
Destination netip.AddrPort
|
||||||
|
}
|
||||||
|
|
||||||
type TCPSession struct {
|
type TCPSession struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
Source netip.AddrPort
|
Source netip.AddrPort
|
||||||
|
|
@ -30,7 +35,7 @@ func NewNat(ctx context.Context, timeout time.Duration) *TCPNat {
|
||||||
natMap := &TCPNat{
|
natMap := &TCPNat{
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
portIndex: 10000,
|
portIndex: 10000,
|
||||||
addrMap: make(map[netip.AddrPort]uint16),
|
addrMap: make(map[tcpNatKey]uint16),
|
||||||
portMap: make(map[uint16]*TCPSession),
|
portMap: make(map[uint16]*TCPSession),
|
||||||
}
|
}
|
||||||
go natMap.loopCheckTimeout(ctx)
|
go natMap.loopCheckTimeout(ctx)
|
||||||
|
|
@ -59,7 +64,7 @@ func (n *TCPNat) checkTimeout() {
|
||||||
for natPort, session := range n.portMap {
|
for natPort, session := range n.portMap {
|
||||||
session.Lock()
|
session.Lock()
|
||||||
if now.Sub(session.LastActive) > n.timeout {
|
if now.Sub(session.LastActive) > n.timeout {
|
||||||
delete(n.addrMap, session.Source)
|
delete(n.addrMap, tcpNatKey{Source: session.Source, Destination: session.Destination})
|
||||||
delete(n.portMap, natPort)
|
delete(n.portMap, natPort)
|
||||||
}
|
}
|
||||||
session.Unlock()
|
session.Unlock()
|
||||||
|
|
@ -81,8 +86,9 @@ func (n *TCPNat) LookupBack(port uint16) *TCPSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *TCPNat) Lookup(source netip.AddrPort, destination netip.AddrPort, handler Handler) (uint16, error) {
|
func (n *TCPNat) Lookup(source netip.AddrPort, destination netip.AddrPort, handler Handler) (uint16, error) {
|
||||||
|
key := tcpNatKey{Source: source, Destination: destination}
|
||||||
n.addrAccess.RLock()
|
n.addrAccess.RLock()
|
||||||
port, loaded := n.addrMap[source]
|
port, loaded := n.addrMap[key]
|
||||||
n.addrAccess.RUnlock()
|
n.addrAccess.RUnlock()
|
||||||
if loaded {
|
if loaded {
|
||||||
return port, nil
|
return port, nil
|
||||||
|
|
@ -99,7 +105,7 @@ func (n *TCPNat) Lookup(source netip.AddrPort, destination netip.AddrPort, handl
|
||||||
} else {
|
} else {
|
||||||
n.portIndex++
|
n.portIndex++
|
||||||
}
|
}
|
||||||
n.addrMap[source] = nextPort
|
n.addrMap[key] = nextPort
|
||||||
n.addrAccess.Unlock()
|
n.addrAccess.Unlock()
|
||||||
n.portAccess.Lock()
|
n.portAccess.Lock()
|
||||||
n.portMap[nextPort] = &TCPSession{
|
n.portMap[nextPort] = &TCPSession{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue