mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
feat: add loopback-address support for tun
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
This commit is contained in:
parent
ae7967f662
commit
9283cb0f5f
@ -239,13 +239,15 @@ func (n *num) UnmarshalText(text []byte) (err error) {
|
|||||||
|
|
||||||
func TestStructure_TextUnmarshaller(t *testing.T) {
|
func TestStructure_TextUnmarshaller(t *testing.T) {
|
||||||
rawMap := map[string]any{
|
rawMap := map[string]any{
|
||||||
"num": "255",
|
"num": "255",
|
||||||
"num_p": "127",
|
"num_p": "127",
|
||||||
|
"num_arr": []string{"1", "2", "3"},
|
||||||
}
|
}
|
||||||
|
|
||||||
s := &struct {
|
s := &struct {
|
||||||
Num num `test:"num"`
|
Num num `test:"num"`
|
||||||
NumP *num `test:"num_p"`
|
NumP *num `test:"num_p"`
|
||||||
|
NumArr []num `test:"num_arr"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
err := decoder.Decode(rawMap, s)
|
err := decoder.Decode(rawMap, s)
|
||||||
@ -253,6 +255,7 @@ func TestStructure_TextUnmarshaller(t *testing.T) {
|
|||||||
assert.Equal(t, 255, s.Num.a)
|
assert.Equal(t, 255, s.Num.a)
|
||||||
assert.NotNil(t, s.NumP)
|
assert.NotNil(t, s.NumP)
|
||||||
assert.Equal(t, s.NumP.a, 127)
|
assert.Equal(t, s.NumP.a, 127)
|
||||||
|
assert.Equal(t, s.NumArr, []num{{1}, {2}, {3}})
|
||||||
|
|
||||||
// test WeaklyTypedInput
|
// test WeaklyTypedInput
|
||||||
rawMap["num"] = 256
|
rawMap["num"] = 256
|
||||||
|
|||||||
@ -270,6 +270,7 @@ type RawTun struct {
|
|||||||
AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
|
AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
|
||||||
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,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"`
|
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"`
|
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
|
||||||
RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
|
RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
|
||||||
RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"`
|
RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"`
|
||||||
@ -1559,6 +1560,7 @@ func parseTun(rawTun RawTun, general *General) error {
|
|||||||
AutoRedirect: rawTun.AutoRedirect,
|
AutoRedirect: rawTun.AutoRedirect,
|
||||||
AutoRedirectInputMark: rawTun.AutoRedirectInputMark,
|
AutoRedirectInputMark: rawTun.AutoRedirectInputMark,
|
||||||
AutoRedirectOutputMark: rawTun.AutoRedirectOutputMark,
|
AutoRedirectOutputMark: rawTun.AutoRedirectOutputMark,
|
||||||
|
LoopbackAddress: rawTun.LoopbackAddress,
|
||||||
StrictRoute: rawTun.StrictRoute,
|
StrictRoute: rawTun.StrictRoute,
|
||||||
RouteAddress: rawTun.RouteAddress,
|
RouteAddress: rawTun.RouteAddress,
|
||||||
RouteAddressSet: rawTun.RouteAddressSet,
|
RouteAddressSet: rawTun.RouteAddressSet,
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -31,7 +31,7 @@ require (
|
|||||||
github.com/metacubex/sing-shadowsocks v0.2.11-0.20250531133822-e545de386d4c
|
github.com/metacubex/sing-shadowsocks v0.2.11-0.20250531133822-e545de386d4c
|
||||||
github.com/metacubex/sing-shadowsocks2 v0.2.5-0.20250531133559-f4d53bd59335
|
github.com/metacubex/sing-shadowsocks2 v0.2.5-0.20250531133559-f4d53bd59335
|
||||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2
|
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2
|
||||||
github.com/metacubex/sing-tun v0.4.6-0.20250524142129-9d110c0af70c
|
github.com/metacubex/sing-tun v0.4.7-0.20250611091011-60774779fdd8
|
||||||
github.com/metacubex/sing-vmess v0.2.2
|
github.com/metacubex/sing-vmess v0.2.2
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
|
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
|
||||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
|
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
|
||||||
|
|||||||
4
go.sum
4
go.sum
@ -128,8 +128,8 @@ github.com/metacubex/sing-shadowsocks2 v0.2.5-0.20250531133559-f4d53bd59335 h1:n
|
|||||||
github.com/metacubex/sing-shadowsocks2 v0.2.5-0.20250531133559-f4d53bd59335/go.mod h1:WP8+S0kqtnSbX1vlIpo5i8Irm/ijZITEPBcZ26B5unY=
|
github.com/metacubex/sing-shadowsocks2 v0.2.5-0.20250531133559-f4d53bd59335/go.mod h1:WP8+S0kqtnSbX1vlIpo5i8Irm/ijZITEPBcZ26B5unY=
|
||||||
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 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-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
|
||||||
github.com/metacubex/sing-tun v0.4.6-0.20250524142129-9d110c0af70c h1:Y6jk7AH5BEg9Dsvczrf/KokYsvxeKSZZlCLHg+hC4ro=
|
github.com/metacubex/sing-tun v0.4.7-0.20250611091011-60774779fdd8 h1:4zWKqxTx75TbfW2EmlQ3hxM6RTRg2PYOAVMCnU4I61I=
|
||||||
github.com/metacubex/sing-tun v0.4.6-0.20250524142129-9d110c0af70c/go.mod h1:HDaHDL6onAX2ZGbAGUXKp++PohRdNb7Nzt6zxzhox+U=
|
github.com/metacubex/sing-tun v0.4.7-0.20250611091011-60774779fdd8/go.mod h1:2YywXPWW8Z97kTH7RffOeykKzU+l0aiKlglWV1PAS64=
|
||||||
github.com/metacubex/sing-vmess v0.2.2 h1:nG6GIKF1UOGmlzs+BIetdGHkFZ20YqFVIYp5Htqzp+4=
|
github.com/metacubex/sing-vmess v0.2.2 h1:nG6GIKF1UOGmlzs+BIetdGHkFZ20YqFVIYp5Htqzp+4=
|
||||||
github.com/metacubex/sing-vmess v0.2.2/go.mod h1:CVDNcdSLVYFgTHQlubr88d8CdqupAUDqLjROos+H9xk=
|
github.com/metacubex/sing-vmess v0.2.2/go.mod h1:CVDNcdSLVYFgTHQlubr88d8CdqupAUDqLjROos+H9xk=
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
|
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
|
||||||
|
|||||||
@ -75,6 +75,7 @@ type tunSchema struct {
|
|||||||
AutoRedirect *bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
|
AutoRedirect *bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
|
||||||
AutoRedirectInputMark *uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,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"`
|
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"`
|
StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"`
|
||||||
RouteAddress *[]netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
|
RouteAddress *[]netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
|
||||||
RouteAddressSet *[]string `yaml:"route-address-set" json:"route-address-set,omitempty"`
|
RouteAddressSet *[]string `yaml:"route-address-set" json:"route-address-set,omitempty"`
|
||||||
@ -174,6 +175,9 @@ func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun {
|
|||||||
if p.AutoRedirectOutputMark != nil {
|
if p.AutoRedirectOutputMark != nil {
|
||||||
def.AutoRedirectOutputMark = *p.AutoRedirectOutputMark
|
def.AutoRedirectOutputMark = *p.AutoRedirectOutputMark
|
||||||
}
|
}
|
||||||
|
if p.LoopbackAddress != nil {
|
||||||
|
def.LoopbackAddress = *p.LoopbackAddress
|
||||||
|
}
|
||||||
if p.StrictRoute != nil {
|
if p.StrictRoute != nil {
|
||||||
def.StrictRoute = *p.StrictRoute
|
def.StrictRoute = *p.StrictRoute
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,18 +9,6 @@ import (
|
|||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StringSliceToNetipPrefixSlice(ss []string) ([]netip.Prefix, error) {
|
|
||||||
lps := make([]netip.Prefix, 0, len(ss))
|
|
||||||
for _, s := range ss {
|
|
||||||
prefix, err := netip.ParsePrefix(s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
lps = append(lps, prefix)
|
|
||||||
}
|
|
||||||
return lps, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Tun struct {
|
type Tun struct {
|
||||||
Enable bool `yaml:"enable" json:"enable"`
|
Enable bool `yaml:"enable" json:"enable"`
|
||||||
Device string `yaml:"device" json:"device"`
|
Device string `yaml:"device" json:"device"`
|
||||||
@ -39,6 +27,7 @@ type Tun struct {
|
|||||||
AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
|
AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
|
||||||
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,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"`
|
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"`
|
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
|
||||||
RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
|
RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
|
||||||
RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"`
|
RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"`
|
||||||
@ -142,6 +131,9 @@ func (t *Tun) Equal(other Tun) bool {
|
|||||||
if t.AutoRedirectOutputMark != other.AutoRedirectOutputMark {
|
if t.AutoRedirectOutputMark != other.AutoRedirectOutputMark {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if !slices.Equal(t.RouteAddress, other.RouteAddress) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if t.StrictRoute != other.StrictRoute {
|
if t.StrictRoute != other.StrictRoute {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
package inbound
|
package inbound
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"encoding"
|
||||||
"strings"
|
"net/netip"
|
||||||
|
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
LC "github.com/metacubex/mihomo/listener/config"
|
LC "github.com/metacubex/mihomo/listener/config"
|
||||||
@ -12,50 +12,55 @@ import (
|
|||||||
|
|
||||||
type TunOption struct {
|
type TunOption struct {
|
||||||
BaseOption
|
BaseOption
|
||||||
Device string `inbound:"device,omitempty"`
|
Device string `inbound:"device,omitempty"`
|
||||||
Stack string `inbound:"stack,omitempty"`
|
Stack C.TUNStack `inbound:"stack,omitempty"`
|
||||||
DNSHijack []string `inbound:"dns-hijack,omitempty"`
|
DNSHijack []string `inbound:"dns-hijack,omitempty"`
|
||||||
AutoRoute bool `inbound:"auto-route,omitempty"`
|
AutoRoute bool `inbound:"auto-route,omitempty"`
|
||||||
AutoDetectInterface bool `inbound:"auto-detect-interface,omitempty"`
|
AutoDetectInterface bool `inbound:"auto-detect-interface,omitempty"`
|
||||||
|
|
||||||
MTU uint32 `inbound:"mtu,omitempty"`
|
MTU uint32 `inbound:"mtu,omitempty"`
|
||||||
GSO bool `inbound:"gso,omitempty"`
|
GSO bool `inbound:"gso,omitempty"`
|
||||||
GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"`
|
GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"`
|
||||||
Inet4Address []string `inbound:"inet4-address,omitempty"`
|
Inet4Address []netip.Prefix `inbound:"inet4-address,omitempty"`
|
||||||
Inet6Address []string `inbound:"inet6-address,omitempty"`
|
Inet6Address []netip.Prefix `inbound:"inet6-address,omitempty"`
|
||||||
IPRoute2TableIndex int `inbound:"iproute2-table-index,omitempty"`
|
IPRoute2TableIndex int `inbound:"iproute2-table-index,omitempty"`
|
||||||
IPRoute2RuleIndex int `inbound:"iproute2-rule-index,omitempty"`
|
IPRoute2RuleIndex int `inbound:"iproute2-rule-index,omitempty"`
|
||||||
AutoRedirect bool `inbound:"auto-redirect,omitempty"`
|
AutoRedirect bool `inbound:"auto-redirect,omitempty"`
|
||||||
AutoRedirectInputMark uint32 `inbound:"auto-redirect-input-mark,omitempty"`
|
AutoRedirectInputMark uint32 `inbound:"auto-redirect-input-mark,omitempty"`
|
||||||
AutoRedirectOutputMark uint32 `inbound:"auto-redirect-output-mark,omitempty"`
|
AutoRedirectOutputMark uint32 `inbound:"auto-redirect-output-mark,omitempty"`
|
||||||
StrictRoute bool `inbound:"strict-route,omitempty"`
|
LoopbackAddress []netip.Addr `inbound:"loopback-address,omitempty"`
|
||||||
RouteAddress []string `inbound:"route-address,omitempty"`
|
StrictRoute bool `inbound:"strict-route,omitempty"`
|
||||||
RouteAddressSet []string `inbound:"route-address-set,omitempty"`
|
RouteAddress []netip.Prefix `inbound:"route-address,omitempty"`
|
||||||
RouteExcludeAddress []string `inbound:"route-exclude-address,omitempty"`
|
RouteAddressSet []string `inbound:"route-address-set,omitempty"`
|
||||||
RouteExcludeAddressSet []string `inbound:"route-exclude-address-set,omitempty"`
|
RouteExcludeAddress []netip.Prefix `inbound:"route-exclude-address,omitempty"`
|
||||||
IncludeInterface []string `inbound:"include-interface,omitempty"`
|
RouteExcludeAddressSet []string `inbound:"route-exclude-address-set,omitempty"`
|
||||||
ExcludeInterface []string `inbound:"exclude-interface,omitempty"`
|
IncludeInterface []string `inbound:"include-interface,omitempty"`
|
||||||
IncludeUID []uint32 `inbound:"include-uid,omitempty"`
|
ExcludeInterface []string `inbound:"exclude-interface,omitempty"`
|
||||||
IncludeUIDRange []string `inbound:"include-uid-range,omitempty"`
|
IncludeUID []uint32 `inbound:"include-uid,omitempty"`
|
||||||
ExcludeUID []uint32 `inbound:"exclude-uid,omitempty"`
|
IncludeUIDRange []string `inbound:"include-uid-range,omitempty"`
|
||||||
ExcludeUIDRange []string `inbound:"exclude-uid-range,omitempty"`
|
ExcludeUID []uint32 `inbound:"exclude-uid,omitempty"`
|
||||||
ExcludeSrcPort []uint16 `inbound:"exclude-src-port,omitempty"`
|
ExcludeUIDRange []string `inbound:"exclude-uid-range,omitempty"`
|
||||||
ExcludeSrcPortRange []string `inbound:"exclude-src-port-range,omitempty"`
|
ExcludeSrcPort []uint16 `inbound:"exclude-src-port,omitempty"`
|
||||||
ExcludeDstPort []uint16 `inbound:"exclude-dst-port,omitempty"`
|
ExcludeSrcPortRange []string `inbound:"exclude-src-port-range,omitempty"`
|
||||||
ExcludeDstPortRange []string `inbound:"exclude-dst-port-range,omitempty"`
|
ExcludeDstPort []uint16 `inbound:"exclude-dst-port,omitempty"`
|
||||||
IncludeAndroidUser []int `inbound:"include-android-user,omitempty"`
|
ExcludeDstPortRange []string `inbound:"exclude-dst-port-range,omitempty"`
|
||||||
IncludePackage []string `inbound:"include-package,omitempty"`
|
IncludeAndroidUser []int `inbound:"include-android-user,omitempty"`
|
||||||
ExcludePackage []string `inbound:"exclude-package,omitempty"`
|
IncludePackage []string `inbound:"include-package,omitempty"`
|
||||||
EndpointIndependentNat bool `inbound:"endpoint-independent-nat,omitempty"`
|
ExcludePackage []string `inbound:"exclude-package,omitempty"`
|
||||||
UDPTimeout int64 `inbound:"udp-timeout,omitempty"`
|
EndpointIndependentNat bool `inbound:"endpoint-independent-nat,omitempty"`
|
||||||
FileDescriptor int `inbound:"file-descriptor,omitempty"`
|
UDPTimeout int64 `inbound:"udp-timeout,omitempty"`
|
||||||
|
FileDescriptor int `inbound:"file-descriptor,omitempty"`
|
||||||
|
|
||||||
Inet4RouteAddress []string `inbound:"inet4-route-address,omitempty"`
|
Inet4RouteAddress []netip.Prefix `inbound:"inet4-route-address,omitempty"`
|
||||||
Inet6RouteAddress []string `inbound:"inet6-route-address,omitempty"`
|
Inet6RouteAddress []netip.Prefix `inbound:"inet6-route-address,omitempty"`
|
||||||
Inet4RouteExcludeAddress []string `inbound:"inet4-route-exclude-address,omitempty"`
|
Inet4RouteExcludeAddress []netip.Prefix `inbound:"inet4-route-exclude-address,omitempty"`
|
||||||
Inet6RouteExcludeAddress []string `inbound:"inet6-route-exclude-address,omitempty"`
|
Inet6RouteExcludeAddress []netip.Prefix `inbound:"inet6-route-exclude-address,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ encoding.TextUnmarshaler = (*netip.Addr)(nil) // ensure netip.Addr can decode direct by structure package
|
||||||
|
var _ encoding.TextUnmarshaler = (*netip.Prefix)(nil) // ensure netip.Prefix can decode direct by structure package
|
||||||
|
var _ encoding.TextUnmarshaler = (*C.TUNStack)(nil) // ensure C.TUNStack can decode direct by structure package
|
||||||
|
|
||||||
func (o TunOption) Equal(config C.InboundConfig) bool {
|
func (o TunOption) Equal(config C.InboundConfig) bool {
|
||||||
return optionToString(o) == optionToString(config)
|
return optionToString(o) == optionToString(config)
|
||||||
}
|
}
|
||||||
@ -72,68 +77,31 @@ func NewTun(options *TunOption) (*Tun, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
stack, exist := C.StackTypeMapping[strings.ToLower(options.Stack)]
|
|
||||||
if !exist {
|
|
||||||
return nil, errors.New("invalid tun stack")
|
|
||||||
}
|
|
||||||
|
|
||||||
routeAddress, err := LC.StringSliceToNetipPrefixSlice(options.RouteAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
routeExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.RouteExcludeAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
inet4Address, err := LC.StringSliceToNetipPrefixSlice(options.Inet4Address)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
inet6Address, err := LC.StringSliceToNetipPrefixSlice(options.Inet6Address)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
inet4RouteAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet4RouteAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
inet6RouteAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet6RouteAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
inet4RouteExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet4RouteExcludeAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
inet6RouteExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet6RouteExcludeAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Tun{
|
return &Tun{
|
||||||
Base: base,
|
Base: base,
|
||||||
config: options,
|
config: options,
|
||||||
tun: LC.Tun{
|
tun: LC.Tun{
|
||||||
Enable: true,
|
Enable: true,
|
||||||
Device: options.Device,
|
Device: options.Device,
|
||||||
Stack: stack,
|
Stack: options.Stack,
|
||||||
DNSHijack: options.DNSHijack,
|
DNSHijack: options.DNSHijack,
|
||||||
AutoRoute: options.AutoRoute,
|
AutoRoute: options.AutoRoute,
|
||||||
AutoDetectInterface: options.AutoDetectInterface,
|
AutoDetectInterface: options.AutoDetectInterface,
|
||||||
MTU: options.MTU,
|
MTU: options.MTU,
|
||||||
GSO: options.GSO,
|
GSO: options.GSO,
|
||||||
GSOMaxSize: options.GSOMaxSize,
|
GSOMaxSize: options.GSOMaxSize,
|
||||||
Inet4Address: inet4Address,
|
Inet4Address: options.Inet4Address,
|
||||||
Inet6Address: inet6Address,
|
Inet6Address: options.Inet6Address,
|
||||||
IPRoute2TableIndex: options.IPRoute2TableIndex,
|
IPRoute2TableIndex: options.IPRoute2TableIndex,
|
||||||
IPRoute2RuleIndex: options.IPRoute2RuleIndex,
|
IPRoute2RuleIndex: options.IPRoute2RuleIndex,
|
||||||
AutoRedirect: options.AutoRedirect,
|
AutoRedirect: options.AutoRedirect,
|
||||||
AutoRedirectInputMark: options.AutoRedirectInputMark,
|
AutoRedirectInputMark: options.AutoRedirectInputMark,
|
||||||
AutoRedirectOutputMark: options.AutoRedirectOutputMark,
|
AutoRedirectOutputMark: options.AutoRedirectOutputMark,
|
||||||
|
LoopbackAddress: options.LoopbackAddress,
|
||||||
StrictRoute: options.StrictRoute,
|
StrictRoute: options.StrictRoute,
|
||||||
RouteAddress: routeAddress,
|
RouteAddress: options.RouteAddress,
|
||||||
RouteAddressSet: options.RouteAddressSet,
|
RouteAddressSet: options.RouteAddressSet,
|
||||||
RouteExcludeAddress: routeExcludeAddress,
|
RouteExcludeAddress: options.RouteExcludeAddress,
|
||||||
RouteExcludeAddressSet: options.RouteExcludeAddressSet,
|
RouteExcludeAddressSet: options.RouteExcludeAddressSet,
|
||||||
IncludeInterface: options.IncludeInterface,
|
IncludeInterface: options.IncludeInterface,
|
||||||
ExcludeInterface: options.ExcludeInterface,
|
ExcludeInterface: options.ExcludeInterface,
|
||||||
@ -152,10 +120,10 @@ func NewTun(options *TunOption) (*Tun, error) {
|
|||||||
UDPTimeout: options.UDPTimeout,
|
UDPTimeout: options.UDPTimeout,
|
||||||
FileDescriptor: options.FileDescriptor,
|
FileDescriptor: options.FileDescriptor,
|
||||||
|
|
||||||
Inet4RouteAddress: inet4RouteAddress,
|
Inet4RouteAddress: options.Inet4RouteAddress,
|
||||||
Inet6RouteAddress: inet6RouteAddress,
|
Inet6RouteAddress: options.Inet6RouteAddress,
|
||||||
Inet4RouteExcludeAddress: inet4RouteExcludeAddress,
|
Inet4RouteExcludeAddress: options.Inet4RouteExcludeAddress,
|
||||||
Inet6RouteExcludeAddress: inet6RouteExcludeAddress,
|
Inet6RouteExcludeAddress: options.Inet6RouteExcludeAddress,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,7 +64,7 @@ func ParseListener(mapping map[string]any) (C.InboundListener, error) {
|
|||||||
listener, err = IN.NewTunnel(tunnelOption)
|
listener, err = IN.NewTunnel(tunnelOption)
|
||||||
case "tun":
|
case "tun":
|
||||||
tunOption := &IN.TunOption{
|
tunOption := &IN.TunOption{
|
||||||
Stack: C.TunGvisor.String(),
|
Stack: C.TunGvisor,
|
||||||
DNSHijack: []string{"0.0.0.0:53"}, // default hijack all dns query
|
DNSHijack: []string{"0.0.0.0:53"}, // default hijack all dns query
|
||||||
}
|
}
|
||||||
err = decoder.Decode(mapping, tunOption)
|
err = decoder.Decode(mapping, tunOption)
|
||||||
|
|||||||
@ -347,6 +347,8 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
|||||||
IPRoute2RuleIndex: ruleIndex,
|
IPRoute2RuleIndex: ruleIndex,
|
||||||
AutoRedirectInputMark: inputMark,
|
AutoRedirectInputMark: inputMark,
|
||||||
AutoRedirectOutputMark: outputMark,
|
AutoRedirectOutputMark: outputMark,
|
||||||
|
Inet4LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is4),
|
||||||
|
Inet6LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is6),
|
||||||
StrictRoute: options.StrictRoute,
|
StrictRoute: options.StrictRoute,
|
||||||
Inet4RouteAddress: inet4RouteAddress,
|
Inet4RouteAddress: inet4RouteAddress,
|
||||||
Inet6RouteAddress: inet6RouteAddress,
|
Inet6RouteAddress: inet6RouteAddress,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user