diff --git a/config/config.go b/config/config.go index bf2a8745..b4874175 100644 --- a/config/config.go +++ b/config/config.go @@ -110,11 +110,12 @@ type Profile struct { // Tun config type Tun struct { - Enable bool `yaml:"enable" json:"enable"` - Device string `yaml:"device" json:"device"` - Stack C.TUNStack `yaml:"stack" json:"stack"` - DNSHijack []netip.AddrPort `yaml:"dns-hijack" json:"dns-hijack"` - AutoRoute bool `yaml:"auto-route" json:"auto-route"` + Enable bool `yaml:"enable" json:"enable"` + Device string `yaml:"device" json:"device"` + Stack C.TUNStack `yaml:"stack" json:"stack"` + DNSHijack []netip.AddrPort `yaml:"dns-hijack" json:"dns-hijack"` + AutoRoute bool `yaml:"auto-route" json:"auto-route"` + AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"` } // IPTables config @@ -910,11 +911,12 @@ func parseTun(rawTun RawTun, general *General) (*Tun, error) { } return &Tun{ - Enable: rawTun.Enable, - Device: rawTun.Device, - Stack: rawTun.Stack, - DNSHijack: dnsHijack, - AutoRoute: rawTun.AutoRoute, + Enable: rawTun.Enable, + Device: rawTun.Device, + Stack: rawTun.Stack, + DNSHijack: dnsHijack, + AutoRoute: rawTun.AutoRoute, + AutoDetectInterface: rawTun.AutoDetectInterface, }, nil } diff --git a/listener/tun/ipstack/commons/router_darwin.go b/listener/tun/ipstack/commons/router_darwin.go index 9a5a18df..abead15a 100644 --- a/listener/tun/ipstack/commons/router_darwin.go +++ b/listener/tun/ipstack/commons/router_darwin.go @@ -12,7 +12,7 @@ func GetAutoDetectInterface() (string, error) { return cmd.ExecCmd("bash -c route -n get default | grep 'interface:' | awk -F ' ' 'NR==1{print $2}' | xargs echo -n") } -func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, autoRoute bool) error { +func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, autoRoute, autoDetectInterface bool) error { if !addr.Addr().Is4() { return fmt.Errorf("supported ipv4 only") } @@ -37,12 +37,12 @@ func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, } if autoRoute { - err = configInterfaceRouting(interfaceName, addr) + err = configInterfaceRouting(interfaceName, addr, autoDetectInterface) } return err } -func configInterfaceRouting(interfaceName string, addr netip.Prefix) error { +func configInterfaceRouting(interfaceName string, addr netip.Prefix, autoDetectInterface bool) error { var ( routes = append(defaultRoutes, addr.String()) gateway = addr.Masked().Addr().Next() @@ -54,7 +54,9 @@ func configInterfaceRouting(interfaceName string, addr netip.Prefix) error { } } - go DefaultInterfaceChangeMonitor() + if autoDetectInterface { + go DefaultInterfaceChangeMonitor() + } return execRouterCmd("add", "-inet6", "2000::/3", interfaceName) } diff --git a/listener/tun/ipstack/commons/router_linux.go b/listener/tun/ipstack/commons/router_linux.go index ff6f8ec7..60879eac 100644 --- a/listener/tun/ipstack/commons/router_linux.go +++ b/listener/tun/ipstack/commons/router_linux.go @@ -17,7 +17,7 @@ func GetAutoDetectInterface() (string, error) { return cmd.ExecCmd("bash -c ip route show | grep 'default via' | awk -F ' ' 'NR==1{print $5}' | xargs echo -n") } -func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, autoRoute bool) error { +func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, autoRoute, autoDetectInterface bool) error { var ( interfaceName = dev.Name() ip = addr.Masked().Addr().Next() @@ -34,12 +34,12 @@ func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, } if autoRoute { - err = configInterfaceRouting(interfaceName, addr) + err = configInterfaceRouting(interfaceName, addr, autoDetectInterface) } return err } -func configInterfaceRouting(interfaceName string, addr netip.Prefix) error { +func configInterfaceRouting(interfaceName string, addr netip.Prefix, autoDetectInterface bool) error { linkIP := addr.Masked().Addr().Next() if runtime.GOOS == "android" { const tableId = 1981801 @@ -61,7 +61,9 @@ func configInterfaceRouting(interfaceName string, addr netip.Prefix) error { } } - go DefaultInterfaceChangeMonitor() + if autoDetectInterface { + go DefaultInterfaceChangeMonitor() + } return nil } diff --git a/listener/tun/ipstack/commons/router_others.go b/listener/tun/ipstack/commons/router_others.go index 6c8ea341..cec981cc 100644 --- a/listener/tun/ipstack/commons/router_others.go +++ b/listener/tun/ipstack/commons/router_others.go @@ -14,6 +14,6 @@ func GetAutoDetectInterface() (string, error) { return "", fmt.Errorf("can not auto detect interface-name on this OS: %s, you must be detecting interface-name by manual", runtime.GOOS) } -func ConfigInterfaceAddress(device.Device, netip.Prefix, int, bool) error { +func ConfigInterfaceAddress(device.Device, netip.Prefix, int, bool, bool) error { return fmt.Errorf("unsupported on this OS: %s", runtime.GOOS) } diff --git a/listener/tun/ipstack/commons/router_windows.go b/listener/tun/ipstack/commons/router_windows.go index 50a1cbba..b9d1a68c 100644 --- a/listener/tun/ipstack/commons/router_windows.go +++ b/listener/tun/ipstack/commons/router_windows.go @@ -27,7 +27,7 @@ func GetAutoDetectInterface() (string, error) { return getAutoDetectInterfaceByFamily(winipcfg.AddressFamily(windows.AF_INET6)) } -func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, autoRoute bool) error { +func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, autoRoute, autoDetectInterface bool) error { retryOnFailure := services.StartedAtBoot() tryTimes := 0 var err error @@ -205,7 +205,9 @@ startOver: wintunInterfaceName = dev.Name() - go DefaultInterfaceChangeMonitor() + if autoDetectInterface { + go DefaultInterfaceChangeMonitor() + } return nil } diff --git a/listener/tun/tun_adapter.go b/listener/tun/tun_adapter.go index eed95333..39a8f245 100644 --- a/listener/tun/tun_adapter.go +++ b/listener/tun/tun_adapter.go @@ -90,7 +90,7 @@ func New(tunConf *config.Tun, dnsConf *config.DNS, tcpIn chan<- C.ConnContext, u } // setting address and routing - err = commons.ConfigInterfaceAddress(tunDevice, tunAddress, mtu, autoRoute) + err = commons.ConfigInterfaceAddress(tunDevice, tunAddress, mtu, autoRoute, tunConf.AutoDetectInterface) if err != nil { _ = tunDevice.Close() return nil, fmt.Errorf("setting interface address and routing failed: %w", err)