TUN inbound: Warn about forwarding on the outbound interface instead of refusing to start

Mobile Hotspot may well be on before the TUN starts, and having it share
the TUN instead of the physical interface then moves forwarding off it, but
the TUN can only be picked to share while it runs. So the TUN starts, with a
warning that says so, and Xray's own connections recover once forwarding
goes off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
patterniha
2026-10-05 16:12:47 +03:30
co-authored by Claude Opus 5.5
parent b71975abed
commit 46d49adc5c
3 changed files with 6 additions and 8 deletions
+1 -1
View File
@@ -213,7 +213,7 @@ If the filters cannot be added, Xray does not start. They are removed when Xray
`autoSystemWfpBlockLeak` (Windows only) is empty by default, as the filters break some setups: with `"dns"`, a local DNS resolver other programs use (e.g. on `127.0.0.1:53`), the DNS of another VPN on its own interface, virtual machines whose NAT resolves names on the host, or signing in to a captive portal; with `"misconfigtun"`, IPv4 or IPv6 on the local network while no route of that version leads to the TUN. Without the filters, DNS may leak as described above. To keep an IP version out of the TUN on purpose while still blocking DNS leaks, use only `["dns"]`.
`autoOutboundsInterface` (the default with `autoSystemRoutingTable`) keeps Xray's own connections out of the TUN by binding them to another interface, which Windows only honors while that interface has weak host send and forwarding off for the IP versions routed to the TUN. Otherwise, Windows sends them into the TUN, from that interface's address, and they stall. While the TUN runs, Xray therefore turns weak host send off on that interface, and on again when it stops or another interface takes over. Forwarding cannot be turned off this way, as Mobile Hotspot and Internet Connection Sharing need it: the TUN does not start while it is on, and an error is logged when it comes on later.
`autoOutboundsInterface` (the default with `autoSystemRoutingTable`) keeps Xray's own connections out of the TUN by binding them to another interface, which Windows only honors while that interface has weak host send and forwarding off for the IP versions routed to the TUN. Otherwise, Windows sends them into the TUN, from that interface's address, and they stall. While the TUN runs, Xray therefore turns weak host send off on that interface, and on again when it stops or another interface takes over. Forwarding cannot be turned off this way, as Mobile Hotspot and Internet Connection Sharing need it, so a warning is logged while it is on. Having the hotspot share the TUN instead of that interface (Settings, Mobile hotspot, Share my internet connection from) moves forwarding to the TUN, where it does no harm, and sends the hotspot's devices through Xray as well.
You can give the adapter ip address manually, you can live Windows to give it autogenerated ip address (which take few seconds), it doesn't matter, the traffic going _through_ the interface will be forwarded into the app for proxying. \
Minimal configuration that will work for local machine is routing passing the traffic on-link through the interface.
+1 -3
View File
@@ -307,9 +307,7 @@ startOver:
if route6 {
t.guard.families = append(t.guard.families, windows.AF_INET6)
}
if problem := t.guard.check(); problem != "" {
return errors.New(problem)
}
t.guard.recheck()
// 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) {
+4 -4
View File
@@ -75,13 +75,13 @@ func (g *outboundGuard) check() string {
}
}
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"
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 is check for a running TUN, which logs a forwarding problem when it
// comes up. (Windows may turn forwarding on and off a few times meanwhile.)
// 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()
@@ -89,7 +89,7 @@ func (g *outboundGuard) recheck() {
g.reported = problem
g.Unlock()
if cameUp {
errors.LogError(context.Background(), "[tun] ", problem)
errors.LogWarning(context.Background(), "[tun] ", problem)
}
}