[fix] auto-route for android

This commit is contained in:
gVisor bot 2022-04-20 22:00:05 +08:00
parent a2c8d8f9be
commit 113d84b438
6 changed files with 34 additions and 16 deletions

View file

@ -875,7 +875,7 @@ func parseAuthentication(rawRecords []string) []auth.AuthUser {
func parseTun(rawTun RawTun, general *General) (*Tun, error) {
if rawTun.Enable && rawTun.AutoDetectInterface {
autoDetectInterfaceName, err := commons.GetAutoDetectInterface()
if err != nil || autoDetectInterfaceName == "" {
if err != nil {
log.Warnln("Can not find auto detect interface.[%s]", err)
} else {
log.Warnln("Auto detect interface: %s", autoDetectInterfaceName)

View file

@ -2,9 +2,11 @@ package proxy
import (
"fmt"
"github.com/Dreamacro/clash/common/cmd"
"github.com/Dreamacro/clash/listener/inner"
"net"
"os"
"runtime"
"strconv"
"sync"
@ -395,5 +397,8 @@ func genAddr(host string, port int, allowLan bool) string {
func Cleanup() {
if tunStackListener != nil {
_ = tunStackListener.Close()
if runtime.GOOS == "android" {
_, _ = cmd.ExecCmd("ip rule del pref 5000")
}
}
}

View file

@ -3,7 +3,6 @@ package commons
import (
"fmt"
"net"
"sync"
"time"
"github.com/Dreamacro/clash/component/dialer"
@ -12,7 +11,6 @@ import (
var (
defaultRoutes = []string{"1.0.0.0/8", "2.0.0.0/7", "4.0.0.0/6", "8.0.0.0/5", "16.0.0.0/4", "32.0.0.0/3", "64.0.0.0/2", "128.0.0.0/1"}
mux sync.Mutex
defaultInterfaceMonitorDuration = 3 * time.Second
)
@ -25,7 +23,7 @@ func ipv4MaskString(bits int) string {
return fmt.Sprintf("%d.%d.%d.%d", m[0], m[1], m[2], m[3])
}
func DefaultInterfaceChangeMonitor(cb func(ifName string)) {
func DefaultInterfaceChangeMonitor() {
t := time.NewTicker(defaultInterfaceMonitorDuration)
defer t.Stop()
@ -44,9 +42,7 @@ func DefaultInterfaceChangeMonitor(cb func(ifName string)) {
}
dialer.DefaultInterface.Store(interfaceName)
if cb != nil {
cb(interfaceName)
}
log.Warnln("[TUN] default interface changed by monitor, %s => %s", old, interfaceName)
}
}

View file

@ -54,7 +54,7 @@ func configInterfaceRouting(interfaceName string, addr netip.Prefix) error {
}
}
go DefaultInterfaceChangeMonitor(nil)
go DefaultInterfaceChangeMonitor()
return execRouterCmd("add", "-inet6", "2000::/3", interfaceName)
}

View file

@ -2,13 +2,17 @@ package commons
import (
"fmt"
"net/netip"
"github.com/Dreamacro/clash/common/cmd"
"github.com/Dreamacro/clash/listener/tun/device"
"github.com/Dreamacro/clash/log"
"net/netip"
"runtime"
)
func GetAutoDetectInterface() (string, error) {
if runtime.GOOS == "android" {
return cmd.ExecCmd("sh -c ip route | awk 'NR==1{print $3}' | xargs echo -n")
}
return cmd.ExecCmd("bash -c ip route show | grep 'default via' | awk -F ' ' 'NR==1{print $5}' | xargs echo -n")
}
@ -35,14 +39,27 @@ func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int,
}
func configInterfaceRouting(interfaceName string, addr netip.Prefix) error {
linkIP := addr.Masked().Addr().Next()
for _, route := range defaultRoutes {
if err := execRouterCmd("add", route, interfaceName, linkIP.String()); err != nil {
return err
if runtime.GOOS == "android" {
tableId := 1981801
for _, route := range defaultRoutes {
if _, err := cmd.ExecCmd(fmt.Sprintf("ip route add %s dev %s scope link table %d", route, interfaceName, tableId)); err != nil {
return err
}
}
_, err := cmd.ExecCmd(fmt.Sprintf("ip rule add lookup %d suppress_prefixlength 0 pref 5000", tableId))
if err != nil {
log.Warnln("%s", err)
}
} else {
linkIP := addr.Masked().Addr().Next()
for _, route := range defaultRoutes {
if err := execRouterCmd("add", route, interfaceName, linkIP.String()); err != nil {
return err
}
}
}
go DefaultInterfaceChangeMonitor(nil)
go DefaultInterfaceChangeMonitor()
return nil
}

View file

@ -205,7 +205,7 @@ startOver:
wintunInterfaceName = dev.Name()
go DefaultInterfaceChangeMonitor(nil)
go DefaultInterfaceChangeMonitor()
return nil
}