diff --git a/config/config.go b/config/config.go index 50f7dd6c..c4834d58 100644 --- a/config/config.go +++ b/config/config.go @@ -274,35 +274,36 @@ type RawTun struct { GSO bool `yaml:"gso" json:"gso,omitempty"` GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"` //Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"` - Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"` - IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"` - IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"` - AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"` - AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"` - AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"` - LoopbackAddress []netip.Addr `yaml:"loopback-address" json:"loopback-address,omitempty"` - StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"` - RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"` - RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"` - RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"` - RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"` - IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"` - ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"` - IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"` - IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"` - ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"` - ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"` - ExcludeSrcPort []uint16 `yaml:"exclude-src-port" json:"exclude-src-port,omitempty"` - ExcludeSrcPortRange []string `yaml:"exclude-src-port-range" json:"exclude-src-port-range,omitempty"` - ExcludeDstPort []uint16 `yaml:"exclude-dst-port" json:"exclude-dst-port,omitempty"` - ExcludeDstPortRange []string `yaml:"exclude-dst-port-range" json:"exclude-dst-port-range,omitempty"` - IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"` - IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"` - ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"` - EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` - UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` - DisableICMPForwarding bool `yaml:"disable-icmp-forwarding" json:"disable-icmp-forwarding,omitempty"` - FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"` + Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"` + IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"` + IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"` + AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"` + AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"` + AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"` + AutoRedirectIPRoute2FallbackRuleIndex int `yaml:"auto-redirect-iproute2-fallback-rule-index" json:"auto-redirect-iproute2-fallback-rule-index,omitempty"` + LoopbackAddress []netip.Addr `yaml:"loopback-address" json:"loopback-address,omitempty"` + StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"` + RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"` + RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"` + RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"` + RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"` + IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"` + ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"` + IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"` + IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"` + ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"` + ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"` + ExcludeSrcPort []uint16 `yaml:"exclude-src-port" json:"exclude-src-port,omitempty"` + ExcludeSrcPortRange []string `yaml:"exclude-src-port-range" json:"exclude-src-port-range,omitempty"` + ExcludeDstPort []uint16 `yaml:"exclude-dst-port" json:"exclude-dst-port,omitempty"` + ExcludeDstPortRange []string `yaml:"exclude-dst-port-range" json:"exclude-dst-port-range,omitempty"` + IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"` + IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"` + ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"` + EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` + UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` + DisableICMPForwarding bool `yaml:"disable-icmp-forwarding" json:"disable-icmp-forwarding,omitempty"` + FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"` Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"` Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"` @@ -1639,39 +1640,40 @@ func parseTun(rawTun RawTun, dns *DNS, general *General) error { AutoRoute: rawTun.AutoRoute, AutoDetectInterface: rawTun.AutoDetectInterface, - MTU: rawTun.MTU, - GSO: rawTun.GSO, - GSOMaxSize: rawTun.GSOMaxSize, - Inet4Address: []netip.Prefix{tunAddressPrefix}, - Inet6Address: rawTun.Inet6Address, - IPRoute2TableIndex: rawTun.IPRoute2TableIndex, - IPRoute2RuleIndex: rawTun.IPRoute2RuleIndex, - AutoRedirect: rawTun.AutoRedirect, - AutoRedirectInputMark: rawTun.AutoRedirectInputMark, - AutoRedirectOutputMark: rawTun.AutoRedirectOutputMark, - LoopbackAddress: rawTun.LoopbackAddress, - StrictRoute: rawTun.StrictRoute, - RouteAddress: rawTun.RouteAddress, - RouteAddressSet: rawTun.RouteAddressSet, - RouteExcludeAddress: rawTun.RouteExcludeAddress, - RouteExcludeAddressSet: rawTun.RouteExcludeAddressSet, - IncludeInterface: rawTun.IncludeInterface, - ExcludeInterface: rawTun.ExcludeInterface, - IncludeUID: rawTun.IncludeUID, - IncludeUIDRange: rawTun.IncludeUIDRange, - ExcludeUID: rawTun.ExcludeUID, - ExcludeUIDRange: rawTun.ExcludeUIDRange, - ExcludeSrcPort: rawTun.ExcludeSrcPort, - ExcludeSrcPortRange: rawTun.ExcludeSrcPortRange, - ExcludeDstPort: rawTun.ExcludeDstPort, - ExcludeDstPortRange: rawTun.ExcludeDstPortRange, - IncludeAndroidUser: rawTun.IncludeAndroidUser, - IncludePackage: rawTun.IncludePackage, - ExcludePackage: rawTun.ExcludePackage, - EndpointIndependentNat: rawTun.EndpointIndependentNat, - UDPTimeout: rawTun.UDPTimeout, - DisableICMPForwarding: rawTun.DisableICMPForwarding, - FileDescriptor: rawTun.FileDescriptor, + MTU: rawTun.MTU, + GSO: rawTun.GSO, + GSOMaxSize: rawTun.GSOMaxSize, + Inet4Address: []netip.Prefix{tunAddressPrefix}, + Inet6Address: rawTun.Inet6Address, + IPRoute2TableIndex: rawTun.IPRoute2TableIndex, + IPRoute2RuleIndex: rawTun.IPRoute2RuleIndex, + AutoRedirect: rawTun.AutoRedirect, + AutoRedirectInputMark: rawTun.AutoRedirectInputMark, + AutoRedirectOutputMark: rawTun.AutoRedirectOutputMark, + AutoRedirectIPRoute2FallbackRuleIndex: rawTun.AutoRedirectIPRoute2FallbackRuleIndex, + LoopbackAddress: rawTun.LoopbackAddress, + StrictRoute: rawTun.StrictRoute, + RouteAddress: rawTun.RouteAddress, + RouteAddressSet: rawTun.RouteAddressSet, + RouteExcludeAddress: rawTun.RouteExcludeAddress, + RouteExcludeAddressSet: rawTun.RouteExcludeAddressSet, + IncludeInterface: rawTun.IncludeInterface, + ExcludeInterface: rawTun.ExcludeInterface, + IncludeUID: rawTun.IncludeUID, + IncludeUIDRange: rawTun.IncludeUIDRange, + ExcludeUID: rawTun.ExcludeUID, + ExcludeUIDRange: rawTun.ExcludeUIDRange, + ExcludeSrcPort: rawTun.ExcludeSrcPort, + ExcludeSrcPortRange: rawTun.ExcludeSrcPortRange, + ExcludeDstPort: rawTun.ExcludeDstPort, + ExcludeDstPortRange: rawTun.ExcludeDstPortRange, + IncludeAndroidUser: rawTun.IncludeAndroidUser, + IncludePackage: rawTun.IncludePackage, + ExcludePackage: rawTun.ExcludePackage, + EndpointIndependentNat: rawTun.EndpointIndependentNat, + UDPTimeout: rawTun.UDPTimeout, + DisableICMPForwarding: rawTun.DisableICMPForwarding, + FileDescriptor: rawTun.FileDescriptor, Inet4RouteAddress: rawTun.Inet4RouteAddress, Inet6RouteAddress: rawTun.Inet6RouteAddress, diff --git a/go.mod b/go.mod index 65972834..050a84ee 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/metacubex/sing-shadowsocks v0.2.12 github.com/metacubex/sing-shadowsocks2 v0.2.7 github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 - github.com/metacubex/sing-tun v0.4.12 + github.com/metacubex/sing-tun v0.4.15 github.com/metacubex/sing-vmess v0.2.5 github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f github.com/metacubex/smux v0.0.0-20260105030934-d0c8756d3141 diff --git a/go.sum b/go.sum index f39ac99a..11d1501a 100644 --- a/go.sum +++ b/go.sum @@ -131,8 +131,8 @@ github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6w github.com/metacubex/sing-shadowsocks2 v0.2.7/go.mod h1:vOEbfKC60txi0ca+yUlqEwOGc3Obl6cnSgx9Gf45KjE= github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI= github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E= -github.com/metacubex/sing-tun v0.4.12 h1:LCi+yB7y97X3cHQGdNXQBMQNHAzpP4AWg7YhSLk+LTM= -github.com/metacubex/sing-tun v0.4.12/go.mod h1:L/TjQY5JEGy8nvsuYmy/XgMFMCPiF0+AWSFCYfS6r9w= +github.com/metacubex/sing-tun v0.4.15 h1:0uOO8kCpodgs4Op8L7sn+C4J6a/lQagmeRTrzHxn+mo= +github.com/metacubex/sing-tun v0.4.15/go.mod h1:L/TjQY5JEGy8nvsuYmy/XgMFMCPiF0+AWSFCYfS6r9w= github.com/metacubex/sing-vmess v0.2.5 h1:m9Zt5I27lB9fmLMZfism9sH2LcnAfShZfwSkf6/KJoE= github.com/metacubex/sing-vmess v0.2.5/go.mod h1:AwtlzUgf8COe9tRYAKqWZ+leDH7p5U98a0ZUpYehl8Q= github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU= diff --git a/hub/route/configs.go b/hub/route/configs.go index af330743..7cf2c6cc 100644 --- a/hub/route/configs.go +++ b/hub/route/configs.go @@ -71,30 +71,31 @@ type tunSchema struct { GSO *bool `yaml:"gso" json:"gso,omitempty"` GSOMaxSize *uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"` //Inet4Address *[]netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"` - Inet6Address *[]netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"` - IPRoute2TableIndex *int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"` - IPRoute2RuleIndex *int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"` - AutoRedirect *bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"` - AutoRedirectInputMark *uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"` - AutoRedirectOutputMark *uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"` - LoopbackAddress *[]netip.Addr `yaml:"loopback-address" json:"loopback-address,omitempty"` - StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"` - RouteAddress *[]netip.Prefix `yaml:"route-address" json:"route-address,omitempty"` - RouteAddressSet *[]string `yaml:"route-address-set" json:"route-address-set,omitempty"` - RouteExcludeAddress *[]netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"` - RouteExcludeAddressSet *[]string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"` - IncludeInterface *[]string `yaml:"include-interface" json:"include-interface,omitempty"` - ExcludeInterface *[]string `yaml:"exclude-interface" json:"exclude-interface,omitempty"` - IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"` - IncludeUIDRange *[]string `yaml:"include-uid-range" json:"include-uid-range,omitempty"` - ExcludeUID *[]uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"` - ExcludeUIDRange *[]string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"` - IncludeAndroidUser *[]int `yaml:"include-android-user" json:"include-android-user,omitempty"` - IncludePackage *[]string `yaml:"include-package" json:"include-package,omitempty"` - ExcludePackage *[]string `yaml:"exclude-package" json:"exclude-package,omitempty"` - EndpointIndependentNat *bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` - UDPTimeout *int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` - FileDescriptor *int `yaml:"file-descriptor" json:"file-descriptor"` + Inet6Address *[]netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"` + IPRoute2TableIndex *int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"` + IPRoute2RuleIndex *int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"` + AutoRedirect *bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"` + AutoRedirectInputMark *uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"` + AutoRedirectOutputMark *uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"` + AutoRedirectIPRoute2FallbackRuleIndex *int `yaml:"auto-redirect-iproute2-fallback-rule-index" json:"auto-redirect-iproute2-fallback-rule-index,omitempty"` + LoopbackAddress *[]netip.Addr `yaml:"loopback-address" json:"loopback-address,omitempty"` + StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"` + RouteAddress *[]netip.Prefix `yaml:"route-address" json:"route-address,omitempty"` + RouteAddressSet *[]string `yaml:"route-address-set" json:"route-address-set,omitempty"` + RouteExcludeAddress *[]netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"` + RouteExcludeAddressSet *[]string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"` + IncludeInterface *[]string `yaml:"include-interface" json:"include-interface,omitempty"` + ExcludeInterface *[]string `yaml:"exclude-interface" json:"exclude-interface,omitempty"` + IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"` + IncludeUIDRange *[]string `yaml:"include-uid-range" json:"include-uid-range,omitempty"` + ExcludeUID *[]uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"` + ExcludeUIDRange *[]string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"` + IncludeAndroidUser *[]int `yaml:"include-android-user" json:"include-android-user,omitempty"` + IncludePackage *[]string `yaml:"include-package" json:"include-package,omitempty"` + ExcludePackage *[]string `yaml:"exclude-package" json:"exclude-package,omitempty"` + EndpointIndependentNat *bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` + UDPTimeout *int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` + FileDescriptor *int `yaml:"file-descriptor" json:"file-descriptor"` Inet4RouteAddress *[]netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"` Inet6RouteAddress *[]netip.Prefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"` @@ -181,6 +182,9 @@ func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun { if p.AutoRedirectOutputMark != nil { def.AutoRedirectOutputMark = *p.AutoRedirectOutputMark } + if p.AutoRedirectIPRoute2FallbackRuleIndex != nil { + def.AutoRedirectIPRoute2FallbackRuleIndex = *p.AutoRedirectIPRoute2FallbackRuleIndex + } if p.LoopbackAddress != nil { def.LoopbackAddress = *p.LoopbackAddress } diff --git a/listener/config/tun.go b/listener/config/tun.go index 0e262329..8c125b66 100644 --- a/listener/config/tun.go +++ b/listener/config/tun.go @@ -17,39 +17,40 @@ type Tun struct { AutoRoute bool `yaml:"auto-route" json:"auto-route"` AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"` - MTU uint32 `yaml:"mtu" json:"mtu,omitempty"` - GSO bool `yaml:"gso" json:"gso,omitempty"` - GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"` - Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"` - Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"` - IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"` - IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"` - AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"` - AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"` - AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"` - LoopbackAddress []netip.Addr `yaml:"loopback-address" json:"loopback-address,omitempty"` - StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"` - RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"` - RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"` - RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"` - RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"` - IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"` - ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"` - IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"` - IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"` - ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"` - ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"` - ExcludeSrcPort []uint16 `yaml:"exclude-src-port" json:"exclude-src-port,omitempty"` - ExcludeSrcPortRange []string `yaml:"exclude-src-port-range" json:"exclude-src-port-range,omitempty"` - ExcludeDstPort []uint16 `yaml:"exclude-dst-port" json:"exclude-dst-port,omitempty"` - ExcludeDstPortRange []string `yaml:"exclude-dst-port-range" json:"exclude-dst-port-range,omitempty"` - IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"` - IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"` - ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"` - EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` - UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` - DisableICMPForwarding bool `yaml:"disable-icmp-forwarding" json:"disable-icmp-forwarding,omitempty"` - FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"` + MTU uint32 `yaml:"mtu" json:"mtu,omitempty"` + GSO bool `yaml:"gso" json:"gso,omitempty"` + GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"` + Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"` + Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"` + IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"` + IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"` + AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"` + AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"` + AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"` + AutoRedirectIPRoute2FallbackRuleIndex int `yaml:"auto-redirect-iproute2-fallback-rule-index" json:"auto-redirect-iproute2-fallback-rule-index,omitempty"` + LoopbackAddress []netip.Addr `yaml:"loopback-address" json:"loopback-address,omitempty"` + StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"` + RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"` + RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"` + RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"` + RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"` + IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"` + ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"` + IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"` + IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"` + ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"` + ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"` + ExcludeSrcPort []uint16 `yaml:"exclude-src-port" json:"exclude-src-port,omitempty"` + ExcludeSrcPortRange []string `yaml:"exclude-src-port-range" json:"exclude-src-port-range,omitempty"` + ExcludeDstPort []uint16 `yaml:"exclude-dst-port" json:"exclude-dst-port,omitempty"` + ExcludeDstPortRange []string `yaml:"exclude-dst-port-range" json:"exclude-dst-port-range,omitempty"` + IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"` + IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"` + ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"` + EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` + UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` + DisableICMPForwarding bool `yaml:"disable-icmp-forwarding" json:"disable-icmp-forwarding,omitempty"` + FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"` Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"` Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"` @@ -136,6 +137,9 @@ func (t *Tun) Equal(other Tun) bool { if t.AutoRedirectOutputMark != other.AutoRedirectOutputMark { return false } + if t.AutoRedirectIPRoute2FallbackRuleIndex != other.AutoRedirectIPRoute2FallbackRuleIndex { + return false + } if !slices.Equal(t.RouteAddress, other.RouteAddress) { return false } diff --git a/listener/inbound/tun.go b/listener/inbound/tun.go index 79004023..9aa5c80b 100644 --- a/listener/inbound/tun.go +++ b/listener/inbound/tun.go @@ -18,39 +18,40 @@ type TunOption struct { AutoRoute bool `inbound:"auto-route,omitempty"` AutoDetectInterface bool `inbound:"auto-detect-interface,omitempty"` - MTU uint32 `inbound:"mtu,omitempty"` - GSO bool `inbound:"gso,omitempty"` - GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"` - Inet4Address []netip.Prefix `inbound:"inet4-address,omitempty"` - Inet6Address []netip.Prefix `inbound:"inet6-address,omitempty"` - IPRoute2TableIndex int `inbound:"iproute2-table-index,omitempty"` - IPRoute2RuleIndex int `inbound:"iproute2-rule-index,omitempty"` - AutoRedirect bool `inbound:"auto-redirect,omitempty"` - AutoRedirectInputMark uint32 `inbound:"auto-redirect-input-mark,omitempty"` - AutoRedirectOutputMark uint32 `inbound:"auto-redirect-output-mark,omitempty"` - LoopbackAddress []netip.Addr `inbound:"loopback-address,omitempty"` - StrictRoute bool `inbound:"strict-route,omitempty"` - RouteAddress []netip.Prefix `inbound:"route-address,omitempty"` - RouteAddressSet []string `inbound:"route-address-set,omitempty"` - RouteExcludeAddress []netip.Prefix `inbound:"route-exclude-address,omitempty"` - RouteExcludeAddressSet []string `inbound:"route-exclude-address-set,omitempty"` - IncludeInterface []string `inbound:"include-interface,omitempty"` - ExcludeInterface []string `inbound:"exclude-interface,omitempty"` - IncludeUID []uint32 `inbound:"include-uid,omitempty"` - IncludeUIDRange []string `inbound:"include-uid-range,omitempty"` - ExcludeUID []uint32 `inbound:"exclude-uid,omitempty"` - ExcludeUIDRange []string `inbound:"exclude-uid-range,omitempty"` - ExcludeSrcPort []uint16 `inbound:"exclude-src-port,omitempty"` - ExcludeSrcPortRange []string `inbound:"exclude-src-port-range,omitempty"` - ExcludeDstPort []uint16 `inbound:"exclude-dst-port,omitempty"` - ExcludeDstPortRange []string `inbound:"exclude-dst-port-range,omitempty"` - IncludeAndroidUser []int `inbound:"include-android-user,omitempty"` - IncludePackage []string `inbound:"include-package,omitempty"` - ExcludePackage []string `inbound:"exclude-package,omitempty"` - EndpointIndependentNat bool `inbound:"endpoint-independent-nat,omitempty"` - UDPTimeout int64 `inbound:"udp-timeout,omitempty"` - DisableICMPForwarding bool `inbound:"disable-icmp-forwarding,omitempty"` - FileDescriptor int `inbound:"file-descriptor,omitempty"` + MTU uint32 `inbound:"mtu,omitempty"` + GSO bool `inbound:"gso,omitempty"` + GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"` + Inet4Address []netip.Prefix `inbound:"inet4-address,omitempty"` + Inet6Address []netip.Prefix `inbound:"inet6-address,omitempty"` + IPRoute2TableIndex int `inbound:"iproute2-table-index,omitempty"` + IPRoute2RuleIndex int `inbound:"iproute2-rule-index,omitempty"` + AutoRedirect bool `inbound:"auto-redirect,omitempty"` + AutoRedirectInputMark uint32 `inbound:"auto-redirect-input-mark,omitempty"` + AutoRedirectOutputMark uint32 `inbound:"auto-redirect-output-mark,omitempty"` + AutoRedirectIPRoute2FallbackRuleIndex int `inbound:"auto-redirect-iproute2-fallback-rule-index,omitempty"` + LoopbackAddress []netip.Addr `inbound:"loopback-address,omitempty"` + StrictRoute bool `inbound:"strict-route,omitempty"` + RouteAddress []netip.Prefix `inbound:"route-address,omitempty"` + RouteAddressSet []string `inbound:"route-address-set,omitempty"` + RouteExcludeAddress []netip.Prefix `inbound:"route-exclude-address,omitempty"` + RouteExcludeAddressSet []string `inbound:"route-exclude-address-set,omitempty"` + IncludeInterface []string `inbound:"include-interface,omitempty"` + ExcludeInterface []string `inbound:"exclude-interface,omitempty"` + IncludeUID []uint32 `inbound:"include-uid,omitempty"` + IncludeUIDRange []string `inbound:"include-uid-range,omitempty"` + ExcludeUID []uint32 `inbound:"exclude-uid,omitempty"` + ExcludeUIDRange []string `inbound:"exclude-uid-range,omitempty"` + ExcludeSrcPort []uint16 `inbound:"exclude-src-port,omitempty"` + ExcludeSrcPortRange []string `inbound:"exclude-src-port-range,omitempty"` + ExcludeDstPort []uint16 `inbound:"exclude-dst-port,omitempty"` + ExcludeDstPortRange []string `inbound:"exclude-dst-port-range,omitempty"` + IncludeAndroidUser []int `inbound:"include-android-user,omitempty"` + IncludePackage []string `inbound:"include-package,omitempty"` + ExcludePackage []string `inbound:"exclude-package,omitempty"` + EndpointIndependentNat bool `inbound:"endpoint-independent-nat,omitempty"` + UDPTimeout int64 `inbound:"udp-timeout,omitempty"` + DisableICMPForwarding bool `inbound:"disable-icmp-forwarding,omitempty"` + FileDescriptor int `inbound:"file-descriptor,omitempty"` Inet4RouteAddress []netip.Prefix `inbound:"inet4-route-address,omitempty"` Inet6RouteAddress []netip.Prefix `inbound:"inet6-route-address,omitempty"` @@ -86,45 +87,46 @@ func NewTun(options *TunOption) (*Tun, error) { Base: base, config: options, tun: LC.Tun{ - Enable: true, - Device: options.Device, - Stack: options.Stack, - DNSHijack: options.DNSHijack, - AutoRoute: options.AutoRoute, - AutoDetectInterface: options.AutoDetectInterface, - MTU: options.MTU, - GSO: options.GSO, - GSOMaxSize: options.GSOMaxSize, - Inet4Address: options.Inet4Address, - Inet6Address: options.Inet6Address, - IPRoute2TableIndex: options.IPRoute2TableIndex, - IPRoute2RuleIndex: options.IPRoute2RuleIndex, - AutoRedirect: options.AutoRedirect, - AutoRedirectInputMark: options.AutoRedirectInputMark, - AutoRedirectOutputMark: options.AutoRedirectOutputMark, - LoopbackAddress: options.LoopbackAddress, - StrictRoute: options.StrictRoute, - RouteAddress: options.RouteAddress, - RouteAddressSet: options.RouteAddressSet, - RouteExcludeAddress: options.RouteExcludeAddress, - RouteExcludeAddressSet: options.RouteExcludeAddressSet, - IncludeInterface: options.IncludeInterface, - ExcludeInterface: options.ExcludeInterface, - IncludeUID: options.IncludeUID, - IncludeUIDRange: options.IncludeUIDRange, - ExcludeUID: options.ExcludeUID, - ExcludeUIDRange: options.ExcludeUIDRange, - ExcludeSrcPort: options.ExcludeSrcPort, - ExcludeSrcPortRange: options.ExcludeSrcPortRange, - ExcludeDstPort: options.ExcludeDstPort, - ExcludeDstPortRange: options.ExcludeDstPortRange, - IncludeAndroidUser: options.IncludeAndroidUser, - IncludePackage: options.IncludePackage, - ExcludePackage: options.ExcludePackage, - EndpointIndependentNat: options.EndpointIndependentNat, - UDPTimeout: options.UDPTimeout, - DisableICMPForwarding: options.DisableICMPForwarding, - FileDescriptor: options.FileDescriptor, + Enable: true, + Device: options.Device, + Stack: options.Stack, + DNSHijack: options.DNSHijack, + AutoRoute: options.AutoRoute, + AutoDetectInterface: options.AutoDetectInterface, + MTU: options.MTU, + GSO: options.GSO, + GSOMaxSize: options.GSOMaxSize, + Inet4Address: options.Inet4Address, + Inet6Address: options.Inet6Address, + IPRoute2TableIndex: options.IPRoute2TableIndex, + IPRoute2RuleIndex: options.IPRoute2RuleIndex, + AutoRedirect: options.AutoRedirect, + AutoRedirectInputMark: options.AutoRedirectInputMark, + AutoRedirectOutputMark: options.AutoRedirectOutputMark, + AutoRedirectIPRoute2FallbackRuleIndex: options.AutoRedirectIPRoute2FallbackRuleIndex, + LoopbackAddress: options.LoopbackAddress, + StrictRoute: options.StrictRoute, + RouteAddress: options.RouteAddress, + RouteAddressSet: options.RouteAddressSet, + RouteExcludeAddress: options.RouteExcludeAddress, + RouteExcludeAddressSet: options.RouteExcludeAddressSet, + IncludeInterface: options.IncludeInterface, + ExcludeInterface: options.ExcludeInterface, + IncludeUID: options.IncludeUID, + IncludeUIDRange: options.IncludeUIDRange, + ExcludeUID: options.ExcludeUID, + ExcludeUIDRange: options.ExcludeUIDRange, + ExcludeSrcPort: options.ExcludeSrcPort, + ExcludeSrcPortRange: options.ExcludeSrcPortRange, + ExcludeDstPort: options.ExcludeDstPort, + ExcludeDstPortRange: options.ExcludeDstPortRange, + IncludeAndroidUser: options.IncludeAndroidUser, + IncludePackage: options.IncludePackage, + ExcludePackage: options.ExcludePackage, + EndpointIndependentNat: options.EndpointIndependentNat, + UDPTimeout: options.UDPTimeout, + DisableICMPForwarding: options.DisableICMPForwarding, + FileDescriptor: options.FileDescriptor, Inet4RouteAddress: options.Inet4RouteAddress, Inet6RouteAddress: options.Inet6RouteAddress, diff --git a/listener/sing_tun/server.go b/listener/sing_tun/server.go index 41ba895b..e873bff8 100644 --- a/listener/sing_tun/server.go +++ b/listener/sing_tun/server.go @@ -153,6 +153,13 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis tunName = CalculateInterfaceName(InterfaceName) options.Device = tunName } + forwarderBindInterface := false + if options.FileDescriptor > 0 { + if tunnelName, err := getTunnelName(int32(options.FileDescriptor)); err != nil { + tunName = tunnelName // sing-tun must have the truth tun interface name even it from a fd + forwarderBindInterface = true + } + } routeAddress := options.RouteAddress if len(options.Inet4RouteAddress) > 0 { routeAddress = append(routeAddress, options.Inet4RouteAddress...) @@ -197,6 +204,10 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis if ruleIndex == 0 { ruleIndex = tun.DefaultIPRoute2RuleIndex } + autoRedirectFallbackRuleIndex := options.AutoRedirectIPRoute2FallbackRuleIndex + if autoRedirectFallbackRuleIndex == 0 { + autoRedirectFallbackRuleIndex = tun.DefaultIPRoute2AutoRedirectFallbackRuleIndex + } inputMark := options.AutoRedirectInputMark if inputMark == 0 { inputMark = tun.DefaultAutoRedirectInputMark @@ -349,36 +360,37 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis } tunOptions := tun.Options{ - Name: tunName, - MTU: tunMTU, - GSO: options.GSO, - Inet4Address: options.Inet4Address, - Inet6Address: options.Inet6Address, - AutoRoute: options.AutoRoute, - IPRoute2TableIndex: tableIndex, - IPRoute2RuleIndex: ruleIndex, - AutoRedirectInputMark: inputMark, - AutoRedirectOutputMark: outputMark, - Inet4LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is4), - Inet6LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is6), - StrictRoute: options.StrictRoute, - Inet4RouteAddress: inet4RouteAddress, - Inet6RouteAddress: inet6RouteAddress, - Inet4RouteExcludeAddress: inet4RouteExcludeAddress, - Inet6RouteExcludeAddress: inet6RouteExcludeAddress, - IncludeInterface: options.IncludeInterface, - ExcludeInterface: options.ExcludeInterface, - IncludeUID: includeUID, - ExcludeUID: excludeUID, - ExcludeSrcPort: excludeSrcPort, - ExcludeDstPort: excludeDstPort, - IncludeAndroidUser: options.IncludeAndroidUser, - IncludePackage: options.IncludePackage, - ExcludePackage: options.ExcludePackage, - FileDescriptor: options.FileDescriptor, - InterfaceMonitor: defaultInterfaceMonitor, - EXP_RecvMsgX: options.RecvMsgX, - EXP_SendMsgX: options.SendMsgX, + Name: tunName, + MTU: tunMTU, + GSO: options.GSO, + Inet4Address: options.Inet4Address, + Inet6Address: options.Inet6Address, + AutoRoute: options.AutoRoute, + IPRoute2TableIndex: tableIndex, + IPRoute2RuleIndex: ruleIndex, + IPRoute2AutoRedirectFallbackRuleIndex: autoRedirectFallbackRuleIndex, + AutoRedirectInputMark: inputMark, + AutoRedirectOutputMark: outputMark, + Inet4LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is4), + Inet6LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is6), + StrictRoute: options.StrictRoute, + Inet4RouteAddress: inet4RouteAddress, + Inet6RouteAddress: inet6RouteAddress, + Inet4RouteExcludeAddress: inet4RouteExcludeAddress, + Inet6RouteExcludeAddress: inet6RouteExcludeAddress, + IncludeInterface: options.IncludeInterface, + ExcludeInterface: options.ExcludeInterface, + IncludeUID: includeUID, + ExcludeUID: excludeUID, + ExcludeSrcPort: excludeSrcPort, + ExcludeDstPort: excludeDstPort, + IncludeAndroidUser: options.IncludeAndroidUser, + IncludePackage: options.IncludePackage, + ExcludePackage: options.ExcludePackage, + FileDescriptor: options.FileDescriptor, + InterfaceMonitor: defaultInterfaceMonitor, + EXP_RecvMsgX: options.RecvMsgX, + EXP_SendMsgX: options.SendMsgX, } if options.AutoRedirect { @@ -454,16 +466,10 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis UDPTimeout: udpTimeout, Handler: handler, Logger: log.SingLogger, + ForwarderBindInterface: forwarderBindInterface, InterfaceFinder: interfaceFinder, EnforceBindInterface: EnforceBindInterface, } - - if options.FileDescriptor > 0 { - if tunName, err := getTunnelName(int32(options.FileDescriptor)); err != nil { - stackOptions.TunOptions.Name = tunName - stackOptions.ForwarderBindInterface = true - } - } l.tunIf = tunIf tunStack, err := tun.NewStack(strings.ToLower(options.Stack.String()), stackOptions)