From 30a78f1563667ed31a19bd3f19249467548d1f88 Mon Sep 17 00:00:00 2001 From: patterniha <71074308+patterniha@users.noreply.github.com> Date: Mon, 5 Oct 2026 17:49:40 +0330 Subject: [PATCH] TUN inbound: Merge the outbound guard's check and recheck Since the TUN starts with forwarding on the outbound interface too, check is only called through recheck, so they are one function now. Co-Authored-By: Claude Opus 5.5 --- proxy/tun/tun_windows.go | 6 ++--- proxy/tun/tun_windows_outbound.go | 41 +++++++++++-------------------- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/proxy/tun/tun_windows.go b/proxy/tun/tun_windows.go index 2c57dbfb0..2045efa7b 100644 --- a/proxy/tun/tun_windows.go +++ b/proxy/tun/tun_windows.go @@ -307,12 +307,12 @@ startOver: if route6 { t.guard.families = append(t.guard.families, windows.AF_INET6) } - t.guard.recheck() + t.guard.check() // Only a registered callback goes into the fields: a nil pointer in // them would not compare equal to nil in Close. cbr, err := winipcfg.RegisterRouteChangeCallback(func(notificationType winipcfg.MibNotificationType, route *winipcfg.MibIPforwardRow2) { updater.Update() - t.guard.recheck() + t.guard.check() }) if err != nil { return err @@ -320,7 +320,7 @@ startOver: t.cbr = cbr cbi, err := winipcfg.RegisterInterfaceChangeCallback(func(notificationType winipcfg.MibNotificationType, iface *winipcfg.MibIPInterfaceRow) { updater.Update() - t.guard.recheck() + t.guard.check() }) if err != nil { return err diff --git a/proxy/tun/tun_windows_outbound.go b/proxy/tun/tun_windows_outbound.go index b6737d5c7..3bc347da9 100644 --- a/proxy/tun/tun_windows_outbound.go +++ b/proxy/tun/tun_windows_outbound.go @@ -25,20 +25,20 @@ import ( // Internet Connection Sharing need, so it is only reported. type outboundGuard struct { sync.Mutex - families []winipcfg.AddressFamily - luid winipcfg.LUID // of the interface last checked - turnedOff []winipcfg.AddressFamily // where weak host send was turned off on it - reported string // the forwarding problem last seen - stopped bool + families []winipcfg.AddressFamily + luid winipcfg.LUID // of the interface last checked + turnedOff []winipcfg.AddressFamily // where weak host send was turned off on it + forwarding bool // whether forwarding was on there + stopped bool } -// check turns weak host send off on the bound interface, and returns what is -// wrong if forwarding is on there. -func (g *outboundGuard) check() string { +// check turns weak host send off on the bound interface, and warns when +// forwarding comes on there, but not again while it stays on. +func (g *outboundGuard) check() { g.Lock() defer g.Unlock() if g.stopped { - return "" + return } var luid winipcfg.LUID var name string @@ -51,7 +51,8 @@ func (g *outboundGuard) check() string { g.luid = luid } if luid == 0 { - return "" + g.forwarding = false + return } var forwarding []string for _, family := range g.families { @@ -74,22 +75,10 @@ func (g *outboundGuard) check() string { errors.LogInfo(context.Background(), "[tun] weak host send turned off for ", familyName(family), " on ", name, " while the TUN runs, as Windows would ignore autoOutboundsInterface") } } - if len(forwarding) > 0 { - return "forwarding is on for " + strings.Join(forwarding, " and ") + " on " + name + " (Mobile Hotspot and Internet Connection Sharing turn it on), so Windows ignores autoOutboundsInterface there, and Xray's own connections go into the TUN and stall: turn the hotspot off, or have it share the TUN instead of " + name - } - return "" -} - -// recheck runs check, and warns about forwarding when it comes up. (Windows -// may turn forwarding on and off a few times meanwhile.) -func (g *outboundGuard) recheck() { - problem := g.check() - g.Lock() - cameUp := problem != "" && g.reported == "" - g.reported = problem - g.Unlock() - if cameUp { - errors.LogWarning(context.Background(), "[tun] ", problem) + wasOn := g.forwarding + g.forwarding = len(forwarding) > 0 + if g.forwarding && !wasOn { + errors.LogWarning(context.Background(), "[tun] forwarding is on for ", strings.Join(forwarding, " and "), " on ", name, " (Mobile Hotspot and Internet Connection Sharing turn it on), so Windows ignores autoOutboundsInterface there, and Xray's own connections go into the TUN and stall: turn the hotspot off, or have it share the TUN instead of ", name) } }