TUN inbound: Fix autoOutboundsInterface on Linux (#6413)

Fixes https://github.com/XTLS/Xray-core/issues/6412
This commit is contained in:
Jasper344612
2026-07-04 09:38:25 +08:00
committed by GitHub
parent 3dc8bf3d8b
commit 3263ae9255
+42 -28
View File
@@ -308,36 +308,37 @@ func findOutboundInterface(tunIndex int, fixedName string) (*net.Interface, erro
return iface, nil return iface, nil
} }
probeIPs := []net.IP{ for _, family := range []int{
net.ParseIP("8.8.8.8"), netlink.FAMILY_V4,
net.ParseIP("2001:4860:4860::8888"), netlink.FAMILY_V6,
} {
iface, err := findDefaultInterface(family, tunIndex)
if err == nil {
return iface, nil
}
} }
for _, ip := range probeIPs { return nil, errors.New("no usable outbound interface found")
routes, err := netlink.RouteGet(ip) }
if err != nil || len(routes) == 0 {
continue func findDefaultInterface(family int, tunIndex int) (*net.Interface, error) {
} routes, err := netlink.RouteList(nil, family)
route := routes[0] if err != nil {
if route.LinkIndex == tunIndex { return nil, err
continue }
var selected *net.Interface
selectedMetric := -1
for _, route := range routes {
if route.Dst != nil {
ones, _ := route.Dst.Mask.Size()
if ones != 0 {
continue
}
} }
link, err := netlink.LinkByIndex(route.LinkIndex) if route.LinkIndex == 0 || route.LinkIndex == tunIndex {
if err != nil {
continue
}
attrs := link.Attrs()
if attrs.Flags&net.FlagUp == 0 {
continue
}
operState := attrs.OperState
if operState != netlink.OperUp && operState != netlink.OperUnknown {
continue
}
if route.Src == nil || route.Src.IsLoopback() || route.Src.IsLinkLocalUnicast() {
continue continue
} }
@@ -345,8 +346,21 @@ func findOutboundInterface(tunIndex int, fixedName string) (*net.Interface, erro
if err != nil { if err != nil {
continue continue
} }
return iface, nil
if iface.Flags&net.FlagUp == 0 ||
iface.Flags&net.FlagLoopback != 0 {
continue
}
if selected == nil || route.Priority < selectedMetric {
selected = iface
selectedMetric = route.Priority
}
} }
return nil, errors.New("no usable outbound interface found") if selected == nil {
return nil, errors.New("physical default route not found")
}
return selected, nil
} }