Improve network reset

This commit is contained in:
世界
2026-07-19 17:50:02 +08:00
parent 552994b6ca
commit d2e030bdca
26 changed files with 256 additions and 68 deletions
+1
View File
@@ -14,6 +14,7 @@ import (
type Searcher interface {
FindProcessInfo(ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*adapter.ConnectionOwner, error)
ResetCache()
Close() error
}
+3
View File
@@ -23,6 +23,9 @@ func NewSearcher(config Config) (Searcher, error) {
return &androidSearcher{config.PackageManager}, nil
}
func (s *androidSearcher) ResetCache() {
}
func (s *androidSearcher) Close() error {
return nil
}
+4
View File
@@ -20,6 +20,10 @@ func NewSearcher(_ Config) (Searcher, error) {
return &darwinSearcher{}, nil
}
func (d *darwinSearcher) ResetCache() {
sharedDarwinConnectionFinder.resetCache()
}
func (d *darwinSearcher) Close() error {
return nil
}
+6
View File
@@ -119,6 +119,12 @@ func (f *darwinConnectionFinder) find(network string, source netip.AddrPort, des
return nil, ErrNotFound
}
func (f *darwinConnectionFinder) resetCache() {
f.access.Lock()
defer f.access.Unlock()
clear(f.snapshots)
}
func (f *darwinConnectionFinder) loadSnapshot(network string, forceRefresh bool) (darwinSnapshot, bool, error) {
f.access.Lock()
defer f.access.Unlock()
+4
View File
@@ -35,6 +35,10 @@ func NewSearcher(config Config) (Searcher, error) {
return searcher, nil
}
func (s *linuxSearcher) ResetCache() {
s.processPathCache.cache.Purge()
}
func (s *linuxSearcher) Close() error {
var errs []error
for _, conn := range s.diagConns {
+3
View File
@@ -28,6 +28,9 @@ func initWin32API() error {
return winiphlpapi.LoadExtendedTable()
}
func (s *windowsSearcher) ResetCache() {
}
func (s *windowsSearcher) Close() error {
return nil
}
+20 -6
View File
@@ -10,6 +10,7 @@ import (
"net/url"
"strconv"
"sync"
"sync/atomic"
"time"
"github.com/sagernet/sing-box/adapter"
@@ -45,6 +46,8 @@ type HTTPSTransport struct {
dialer N.Dialer
destination *url.URL
headers http.Header
serverAddr M.Socksaddr
fallback *atomic.Bool
transportAccess sync.Mutex
transport *HTTPSTransportWrapper
transportResetAt time.Time
@@ -123,13 +126,20 @@ func NewHTTPSRaw(
if tlsConfig != nil {
dialer = tls.NewDialer(dialer, tlsConfig)
}
fallback := new(atomic.Bool)
if destination.Scheme == "http" {
// plain HTTP DoH used by Tailscale
fallback.Store(true)
}
return &HTTPSTransport{
TransportAdapter: adapter,
logger: logger,
dialer: dialer,
destination: destination,
headers: headers,
transport: NewHTTPSTransportWrapper(dialer, serverAddr, destination),
serverAddr: serverAddr,
fallback: fallback,
transport: NewHTTPSTransportWrapper(dialer, serverAddr, fallback),
}
}
@@ -148,8 +158,14 @@ func (t *HTTPSTransport) Close() error {
func (t *HTTPSTransport) Reset() {
t.transportAccess.Lock()
defer t.transportAccess.Unlock()
t.transport.CloseIdleConnections()
t.transport = t.transport.Clone()
t.resetTransportLocked()
}
func (t *HTTPSTransport) resetTransportLocked() {
oldTransport := t.transport
t.transport = NewHTTPSTransportWrapper(t.dialer, t.serverAddr, t.fallback)
t.transportResetAt = time.Now()
oldTransport.Close()
}
func (t *HTTPSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
@@ -162,9 +178,7 @@ func (t *HTTPSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS
if t.transportResetAt.After(startAt) {
return nil, err
}
t.transport.CloseIdleConnections()
t.transport = t.transport.Clone()
t.transportResetAt = time.Now()
t.resetTransportLocked()
}
return nil, err
}
+78 -40
View File
@@ -5,7 +5,7 @@ import (
"errors"
"net"
"net/http"
"net/url"
"sync"
"sync/atomic"
"github.com/sagernet/sing-box/common/tls"
@@ -22,42 +22,50 @@ type HTTPSTransportWrapper struct {
http2Transport *http2.Transport
httpTransport *http.Transport
fallback *atomic.Bool
connAccess sync.Mutex
connections map[*httpsTrackedConn]struct{}
closed bool
}
func NewHTTPSTransportWrapper(dialer N.Dialer, serverAddr M.Socksaddr, destination *url.URL) *HTTPSTransportWrapper {
var fallback atomic.Bool
if destination.Scheme == "http" {
// plain HTTP DoH used by Tailscale
fallback.Store(true)
func NewHTTPSTransportWrapper(dialer N.Dialer, serverAddr M.Socksaddr, fallback *atomic.Bool) *HTTPSTransportWrapper {
wrapper := &HTTPSTransportWrapper{
fallback: fallback,
connections: make(map[*httpsTrackedConn]struct{}),
}
return &HTTPSTransportWrapper{
http2Transport: &http2.Transport{
DialTLSContext: func(ctx context.Context, _, _ string, _ *tls.STDConfig) (net.Conn, error) {
resultConn, err := dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
if err != nil {
return nil, err
wrapper.http2Transport = &http2.Transport{
DialTLSContext: func(ctx context.Context, _, _ string, _ *tls.STDConfig) (net.Conn, error) {
resultConn, err := dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
if err != nil {
return nil, err
}
if tlsConn, isTLSConn := resultConn.(tls.Conn); isTLSConn {
state := tlsConn.ConnectionState()
if state.NegotiatedProtocol != http2.NextProtoTLS {
tlsConn.Close()
fallback.Store(true)
return nil, errFallback
}
if tlsConn, isTLSConn := resultConn.(tls.Conn); isTLSConn {
state := tlsConn.ConnectionState()
if state.NegotiatedProtocol != http2.NextProtoTLS {
tlsConn.Close()
fallback.Store(true)
return nil, errFallback
}
}
return resultConn, nil
},
}
return wrapper.trackConn(resultConn)
},
httpTransport: &http.Transport{
DialContext: func(ctx context.Context, _, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
},
DialTLSContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
return dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
},
},
fallback: &fallback,
}
wrapper.httpTransport = &http.Transport{
DialContext: func(ctx context.Context, _, addr string) (net.Conn, error) {
resultConn, err := dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
if err != nil {
return nil, err
}
return wrapper.trackConn(resultConn)
},
DialTLSContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
resultConn, err := dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
if err != nil {
return nil, err
}
return wrapper.trackConn(resultConn)
},
}
return wrapper
}
func (h *HTTPSTransportWrapper) RoundTrip(request *http.Request) (*http.Response, error) {
@@ -74,17 +82,47 @@ func (h *HTTPSTransportWrapper) RoundTrip(request *http.Request) (*http.Response
return response, nil
}
func (h *HTTPSTransportWrapper) CloseIdleConnections() {
func (h *HTTPSTransportWrapper) trackConn(conn net.Conn) (net.Conn, error) {
trackedConn := &httpsTrackedConn{Conn: conn, wrapper: h}
h.connAccess.Lock()
if h.closed {
h.connAccess.Unlock()
conn.Close()
return nil, net.ErrClosed
}
h.connections[trackedConn] = struct{}{}
h.connAccess.Unlock()
return trackedConn, nil
}
func (h *HTTPSTransportWrapper) Close() {
h.connAccess.Lock()
if h.closed {
h.connAccess.Unlock()
return
}
h.closed = true
connections := make([]*httpsTrackedConn, 0, len(h.connections))
for trackedConn := range h.connections {
connections = append(connections, trackedConn)
}
h.connections = nil
h.connAccess.Unlock()
for _, trackedConn := range connections {
trackedConn.Conn.Close()
}
h.http2Transport.CloseIdleConnections()
h.httpTransport.CloseIdleConnections()
}
func (h *HTTPSTransportWrapper) Clone() *HTTPSTransportWrapper {
return &HTTPSTransportWrapper{
httpTransport: h.httpTransport,
http2Transport: &http2.Transport{
DialTLSContext: h.http2Transport.DialTLSContext,
},
fallback: h.fallback,
}
type httpsTrackedConn struct {
net.Conn
wrapper *HTTPSTransportWrapper
}
func (c *httpsTrackedConn) Close() error {
c.wrapper.connAccess.Lock()
delete(c.wrapper.connections, c)
c.wrapper.connAccess.Unlock()
return c.Conn.Close()
}
+3
View File
@@ -148,6 +148,9 @@ func (t *Transport) Reset() {
}
}
t.system.reset()
if t.resolved != nil {
t.resolved.Reset()
}
if t.dhcpTransport != nil {
t.dhcpTransport.Reset()
}
+1
View File
@@ -9,6 +9,7 @@ import (
type ResolvedResolver interface {
Start() error
Close() error
Reset()
Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error)
ExchangeAsync(ctx context.Context, message *mDNS.Msg, callback func(response *mDNS.Msg, err error))
}
@@ -134,6 +134,19 @@ func (t *DBusResolvedResolver) Close() error {
return closeErr
}
func (t *DBusResolvedResolver) Reset() {
serverSet := t.savedServerSet.Load()
if serverSet == nil {
return
}
for _, server := range serverSet.servers {
server.primaryTransport.Reset()
if server.fallbackTransport != nil {
server.fallbackTransport.Reset()
}
}
}
func (t *DBusResolvedResolver) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
serverSet := t.savedServerSet.Load()
if serverSet == nil {
+4 -4
View File
@@ -46,14 +46,14 @@ require (
github.com/sagernet/sing v0.8.12-0.20260717153536-4f1ed45a99a5
github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3
github.com/sagernet/sing-mux v0.3.5
github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04
github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c
github.com/sagernet/sing-openconnect v0.0.0-20260719094202-dc28b269c7ce
github.com/sagernet/sing-openvpn v0.0.0-20260719094204-c57d60b5c5a4
github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc
github.com/sagernet/sing-shadowsocks v0.2.8
github.com/sagernet/sing-shadowsocks2 v0.2.1
github.com/sagernet/sing-shadowtls v0.2.1
github.com/sagernet/sing-snell v0.0.0-20260710094516-a4e97ee24beb
github.com/sagernet/sing-tun v0.8.12-0.20260719050255-7e7bd198288c
github.com/sagernet/sing-snell v0.0.0-20260719094200-c43fbee0e839
github.com/sagernet/sing-tun v0.8.12-0.20260719094150-557ca930fccd
github.com/sagernet/sing-usbip v0.0.0-20260616101517-efb91521eddb
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1
github.com/sagernet/smux v1.5.50-sing-box-mod.1
+8 -8
View File
@@ -285,10 +285,10 @@ github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3 h1:3y6
github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3/go.mod h1:XEqEDYRCAYLaoPjZ1ifVWJg5iWAJHL2gOAXe/PM28Cg=
github.com/sagernet/sing-mux v0.3.5 h1:RHnhVEc+SFqkrK4xMygYjDwwLhzp2Bj3lztSukONfhI=
github.com/sagernet/sing-mux v0.3.5/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk=
github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04 h1:HIb3Tu19qqH5fD5xnyyHb6zJaETIsnXamb/hWTtxil8=
github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04/go.mod h1:EIzh5HtImfQJxPKXFwS9lyMnmMy4aCQCx7ntQ4u41Gs=
github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c h1:EhwLZF3IUyDj4uZ7vkUZAI7GymXCeOCwiseuOTsFjp8=
github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c/go.mod h1:CmTGnS5ijVSqFQV1dTq4WvFLUoz7bk9xasBPsX8NcYo=
github.com/sagernet/sing-openconnect v0.0.0-20260719094202-dc28b269c7ce h1:uPyEKbqEyGaJoKxQtiS+T9ZTrioL0Vl5Ko3i6iTpV2Y=
github.com/sagernet/sing-openconnect v0.0.0-20260719094202-dc28b269c7ce/go.mod h1:EIzh5HtImfQJxPKXFwS9lyMnmMy4aCQCx7ntQ4u41Gs=
github.com/sagernet/sing-openvpn v0.0.0-20260719094204-c57d60b5c5a4 h1:3H1pOsE5IRzr2U+oUTabPrvryj7xg1CEmOnMMwsQSQA=
github.com/sagernet/sing-openvpn v0.0.0-20260719094204-c57d60b5c5a4/go.mod h1:CmTGnS5ijVSqFQV1dTq4WvFLUoz7bk9xasBPsX8NcYo=
github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc h1:zdc0fj4JdAdgAmQIoh7ZF+B/wPTEF2X75lYDqTmvlaw=
github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc/go.mod h1:9k+dzGsWMttUGldBzq3dU792YHXzW6NgfbOGltnXq+0=
github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE=
@@ -297,10 +297,10 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq
github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.2.1 h1:ZiHZdnEnP+YS73NMsxiZmIFCwNd0M4k7PkGCKNXhbaM=
github.com/sagernet/sing-shadowtls v0.2.1/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
github.com/sagernet/sing-snell v0.0.0-20260710094516-a4e97ee24beb h1:VvU2/PZqP5tbKTDq0BxkhRO8ZnKI4UJzziakgBiP2Qg=
github.com/sagernet/sing-snell v0.0.0-20260710094516-a4e97ee24beb/go.mod h1:PcwzX/Xvqky0EP3kGt8OCjYb3R1pydenPHNQZcPZmXY=
github.com/sagernet/sing-tun v0.8.12-0.20260719050255-7e7bd198288c h1:jS5eWD9PyXhHY89DueRDgenfcrfpyPOuuZIoNfnBmOs=
github.com/sagernet/sing-tun v0.8.12-0.20260719050255-7e7bd198288c/go.mod h1:F/gRq5VX1WN/OZtsvbN2JjXXuNl2ATJglHMSk1/iN9U=
github.com/sagernet/sing-snell v0.0.0-20260719094200-c43fbee0e839 h1:YL0oCb55moImUGvjhhVEYODGMo5i9dAf+RpmMFPCq9w=
github.com/sagernet/sing-snell v0.0.0-20260719094200-c43fbee0e839/go.mod h1:PcwzX/Xvqky0EP3kGt8OCjYb3R1pydenPHNQZcPZmXY=
github.com/sagernet/sing-tun v0.8.12-0.20260719094150-557ca930fccd h1:tH79/IieRjLx5DiVu3NpXc1hir0xL6Avmmist0aFHks=
github.com/sagernet/sing-tun v0.8.12-0.20260719094150-557ca930fccd/go.mod h1:F/gRq5VX1WN/OZtsvbN2JjXXuNl2ATJglHMSk1/iN9U=
github.com/sagernet/sing-usbip v0.0.0-20260616101517-efb91521eddb h1:KEMbfexD4DvrQGYWwx6r+AwH9Veh8z6cnBZmtCS2G+0=
github.com/sagernet/sing-usbip v0.0.0-20260616101517-efb91521eddb/go.mod h1:D4CnJX3MNAAANhbQUxfIRgBdnvlTEaV7h6ojedcs+pw=
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkVyVvdmBSufR8/nRFonwJeKSIROxHcm5br9o=
+4
View File
@@ -77,6 +77,10 @@ func (i *Inbound) Start(stage adapter.StartStage) error {
return i.listener.Start()
}
func (i *Inbound) InterfaceUpdated() {
i.udpNat.Purge()
}
func (i *Inbound) Close() error {
return i.listener.Close()
}
+23 -9
View File
@@ -29,10 +29,11 @@ func RegisterOutbound(registry *outbound.Registry) {
}
var (
_ N.ParallelDialer = (*Outbound)(nil)
_ dialer.ParallelNetworkDialer = (*Outbound)(nil)
_ dialer.DirectDialer = (*Outbound)(nil)
_ adapter.FlowOutbound = (*Outbound)(nil)
_ N.ParallelDialer = (*Outbound)(nil)
_ dialer.ParallelNetworkDialer = (*Outbound)(nil)
_ dialer.DirectDialer = (*Outbound)(nil)
_ adapter.FlowOutbound = (*Outbound)(nil)
_ adapter.InterfaceUpdateListener = (*Outbound)(nil)
)
type Outbound struct {
@@ -88,30 +89,43 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
func (h *Outbound) Start(stage adapter.StartStage) error {
switch stage {
case adapter.StartStatePostStart, adapter.StartStateStarted:
h.fetchMyAddresses()
if len(h.myAddresses.Load()) == 0 {
h.fetchMyAddresses()
}
}
return nil
}
func (h *Outbound) fetchMyAddresses() {
if len(h.myAddresses.Load()) > 0 {
return
}
myInterfaceNames := h.network.InterfaceMonitor().MyInterfaces()
if len(myInterfaceNames) == 0 {
return
}
var myAddresses []netip.Prefix
var (
myAddresses []netip.Prefix
found bool
)
for _, myInterfaceName := range myInterfaceNames {
myInterface, err := h.network.InterfaceFinder().ByName(myInterfaceName)
if err != nil {
continue
}
found = true
myAddresses = append(myAddresses, myInterface.Addresses...)
}
if !found {
return
}
h.myAddresses.Store(myAddresses)
}
func (h *Outbound) InterfaceUpdated() {
h.fetchMyAddresses()
if h.icmpPort != nil {
h.icmpPort.Close()
}
}
func (h *Outbound) isMyLoopbackAddress(addresses ...netip.Addr) bool {
for _, prefix := range h.myAddresses.Load() {
for _, address := range addresses {
+15 -1
View File
@@ -28,7 +28,10 @@ func RegisterURLTest(registry *outbound.Registry) {
outbound.Register[option.URLTestOutboundOptions](registry, C.TypeURLTest, NewURLTest)
}
var _ adapter.OutboundGroup = (*URLTest)(nil)
var (
_ adapter.OutboundGroup = (*URLTest)(nil)
_ adapter.InterfaceUpdateListener = (*URLTest)(nil)
)
type URLTest struct {
outbound.Adapter
@@ -114,6 +117,17 @@ func (s *URLTest) CheckOutbounds() {
s.group.CheckOutbounds(true)
}
func (s *URLTest) InterfaceUpdated() {
group := s.group
if group == nil {
return
}
if group.pause.IsDevicePaused() || group.pause.IsNetworkPaused() {
return
}
go group.CheckOutbounds(true)
}
func (s *URLTest) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
s.group.Touch()
var outbound adapter.Outbound
+5
View File
@@ -34,6 +34,7 @@ import (
var (
_ adapter.OutboundWithPreferredRoutes = (*Endpoint)(nil)
_ adapter.FlowOutbound = (*Endpoint)(nil)
_ adapter.InterfaceUpdateListener = (*Endpoint)(nil)
_ dialer.PacketDialerWithDestination = (*Endpoint)(nil)
_ tun.Port = (*Endpoint)(nil)
)
@@ -396,6 +397,10 @@ func (e *Endpoint) Close() error {
return err
}
func (e *Endpoint) InterfaceUpdated() {
e.client.RestartSession()
}
func (e *Endpoint) PreMatchFlow(network string, destination netip.Addr) adapter.PreMatchAction {
return adapter.PreMatchFlow
}
+5
View File
@@ -32,6 +32,7 @@ import (
var (
_ adapter.OutboundWithPreferredRoutes = (*ClientEndpoint)(nil)
_ adapter.FlowOutbound = (*ClientEndpoint)(nil)
_ adapter.InterfaceUpdateListener = (*ClientEndpoint)(nil)
_ dialer.PacketDialerWithDestination = (*ClientEndpoint)(nil)
_ tun.Port = (*ClientEndpoint)(nil)
)
@@ -453,6 +454,10 @@ func (c *ClientEndpoint) Close() error {
return err
}
func (c *ClientEndpoint) InterfaceUpdated() {
c.client.RestartSession()
}
func (c *ClientEndpoint) PreMatchFlow(network string, destination netip.Addr) adapter.PreMatchAction {
return adapter.PreMatchFlow
}
+4
View File
@@ -85,6 +85,10 @@ func (t *TProxy) Start(stage adapter.StartStage) error {
return err
}
func (t *TProxy) InterfaceUpdated() {
t.udpNat.Purge()
}
func (t *TProxy) Close() error {
_ = t.udpNat.Close()
return t.listener.Close()
+7
View File
@@ -32,9 +32,12 @@ type Outbound struct {
serverAddr M.Socksaddr
}
var _ adapter.InterfaceUpdateListener = (*Outbound)(nil)
type snellClient interface {
snellprotocol.Method
DialContext(ctx context.Context, destination M.Socksaddr) (net.Conn, error)
Reset()
Close() error
}
@@ -136,6 +139,10 @@ func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
return packetConn, nil
}
func (h *Outbound) InterfaceUpdated() {
h.client.Reset()
}
func (h *Outbound) Close() error {
return h.client.Close()
}
+11
View File
@@ -68,6 +68,7 @@ import (
var (
_ adapter.OutboundWithPreferredRoutes = (*Endpoint)(nil)
_ adapter.InterfaceUpdateListener = (*Endpoint)(nil)
_ dialer.PacketDialerWithDestination = (*Endpoint)(nil)
_ tun.Port = (*Endpoint)(nil)
)
@@ -696,6 +697,16 @@ func (t *Endpoint) Close() error {
return err
}
func (t *Endpoint) InterfaceUpdated() {
if !t.started.Load() {
return
}
netMon, loaded := t.server.Sys().NetMon.GetOK()
if loaded && netMon != nil {
netMon.InjectEvent()
}
}
func (t *Endpoint) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
switch network {
case N.NetworkTCP:
+7
View File
@@ -507,6 +507,13 @@ func (t *Inbound) updateRouteAddressSet(it adapter.RuleSet) {
t.routeExcludeAddressSet = nil
}
func (t *Inbound) InterfaceUpdated() {
tunStack := t.tunStack
if tunStack != nil {
tunStack.ResetNetwork()
}
}
func (t *Inbound) Close() error {
return common.Close(
t.tunStack,
+11
View File
@@ -26,6 +26,7 @@ import (
var (
_ adapter.OutboundWithPreferredRoutes = (*Endpoint)(nil)
_ adapter.InterfaceUpdateListener = (*Endpoint)(nil)
_ dialer.PacketDialerWithDestination = (*Endpoint)(nil)
)
@@ -159,6 +160,16 @@ func (w *Endpoint) Close() error {
return w.endpoint.Close()
}
func (w *Endpoint) InterfaceUpdated() {
if !w.started.Load() {
return
}
err := w.endpoint.BindUpdate()
if err != nil {
w.logger.Error(E.Cause(err, "update bind"))
}
}
func (w *Endpoint) PreMatchFlow(network string, destination netip.Addr) adapter.PreMatchAction {
return adapter.PreMatchFlow
}
+3
View File
@@ -44,6 +44,9 @@ func (s *platformSearcher) FindProcessInfo(ctx context.Context, network string,
return s.platform.FindConnectionOwner(request)
}
func (s *platformSearcher) ResetCache() {
}
func (s *platformSearcher) Close() error {
return nil
}
+6
View File
@@ -288,4 +288,10 @@ func (r *Router) NeighborResolver() adapter.NeighborResolver {
func (r *Router) ResetNetwork() {
r.httpClientManager.ResetNetwork()
r.dns.ResetNetwork()
if r.processCache != nil {
r.processCache.Purge()
}
if r.processSearcher != nil {
r.processSearcher.ResetCache()
}
}
+7
View File
@@ -254,6 +254,13 @@ func (e *Endpoint) Lookup(address netip.Addr) *device.Peer {
return e.allowedIPs.Lookup(address.AsSlice())
}
func (e *Endpoint) BindUpdate() error {
if e.device == nil {
return nil
}
return e.device.BindUpdate()
}
func (e *Endpoint) onPauseUpdated(event int) {
switch event {
case pause.EventDevicePaused, pause.EventNetworkPause: