mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-07-10 05:38:52 +00:00
TUN inbound: Fix autoOutboundsInterface on Linux (#6413)
Fixes https://github.com/XTLS/Xray-core/issues/6412
This commit is contained in:
+42
-28
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user