Add Stack.ResetNetwork

This commit is contained in:
世界 2026-07-19 17:41:50 +08:00
parent 79084fa798
commit b59636919c
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
7 changed files with 64 additions and 5 deletions

View file

@ -114,11 +114,12 @@ type ForwardDispatcher struct {
udpTimeout time.Duration
icmpTimeout time.Duration
table map[flowKey]*flowEntry
lastSweep int64
ports map[Port]*portNAT
natList atomic.Pointer[[]*portNAT]
revNAT atomic.Pointer[map[netip.Addr]*portNAT]
table map[flowKey]*flowEntry
lastSweep int64
resetPending atomic.Bool
ports map[Port]*portNAT
natList atomic.Pointer[[]*portNAT]
revNAT atomic.Pointer[map[netip.Addr]*portNAT]
activeNATs []*portNAT
writebackBatch [][]byte
@ -544,10 +545,22 @@ func (d *ForwardDispatcher) stageReject(packet *forwardPacket) {
}
}
func (d *ForwardDispatcher) ResetNetwork() {
if d == nil {
return
}
d.resetPending.Store(true)
}
func (d *ForwardDispatcher) Flush() {
if d == nil {
return
}
if d.resetPending.Swap(false) {
for key, entry := range d.table {
d.removeEntry(key, entry, FlowCloseReset)
}
}
for _, nat := range d.activeNATs {
d.flushPort(nat)
}

View file

@ -14,6 +14,7 @@ import (
type Stack interface {
Start() error
ResetNetwork()
Close() error
}

View file

@ -134,6 +134,16 @@ func (t *GVisor) Start() error {
return nil
}
func (t *GVisor) ResetNetwork() {
if t.udpForwarder != nil {
t.udpForwarder.udpNat.Purge()
}
if t.icmpForwarder != nil {
t.icmpForwarder.Purge()
}
t.dispatcher.ResetNetwork()
}
func (t *GVisor) Close() error {
t.dispatcher.Close()
if t.icmpForwarder != nil {

View file

@ -72,6 +72,15 @@ func NewICMPForwarder(stack *stack.Stack, handler Handler, logger logger.Logger)
return forwarder
}
func (f *ICMPForwarder) Purge() {
f.flowAccess.Lock()
for key, flow := range f.flows {
flow.close(FlowCloseReset)
delete(f.flows, key)
}
f.flowAccess.Unlock()
}
func (f *ICMPForwarder) Close() error {
f.returnPath.closed.Store(true)
f.flowAccess.Lock()

View file

@ -62,6 +62,13 @@ func (m *Mixed) Start() error {
return nil
}
func (m *Mixed) ResetNetwork() {
m.System.ResetNetwork()
if m.udpForwarder != nil {
m.udpForwarder.udpNat.Purge()
}
}
func (m *Mixed) Close() error {
if m.stack == nil {
return nil

View file

@ -113,6 +113,16 @@ func NewSystem(options StackOptions) (Stack, error) {
return stack, nil
}
func (s *System) ResetNetwork() {
if s.tcpNat != nil {
s.tcpNat.Purge()
}
if s.udpNat != nil {
s.udpNat.Purge()
}
s.dispatcher.ResetNetwork()
}
func (s *System) Close() error {
s.dispatcher.Close()
if s.udpNat != nil {

View file

@ -86,6 +86,15 @@ func (n *TCPNat) checkTimeout() {
n.addrAccess.Unlock()
}
func (n *TCPNat) Purge() {
n.addrAccess.Lock()
n.portAccess.Lock()
clear(n.addrMap)
clear(n.portMap)
n.portAccess.Unlock()
n.addrAccess.Unlock()
}
func (n *TCPNat) LookupBack(port uint16) *TCPSession {
n.portAccess.RLock()
session := n.portMap[port]