github.com/metacubex/mihomo@v1.18.5/listener/inbound/tun.go (about) 1 package inbound 2 3 import ( 4 "errors" 5 "strings" 6 7 C "github.com/metacubex/mihomo/constant" 8 LC "github.com/metacubex/mihomo/listener/config" 9 "github.com/metacubex/mihomo/listener/sing_tun" 10 "github.com/metacubex/mihomo/log" 11 ) 12 13 type TunOption struct { 14 BaseOption 15 Device string `inbound:"device,omitempty"` 16 Stack string `inbound:"stack,omitempty"` 17 DNSHijack []string `inbound:"dns-hijack,omitempty"` 18 AutoRoute bool `inbound:"auto-route,omitempty"` 19 AutoDetectInterface bool `inbound:"auto-detect-interface,omitempty"` 20 21 MTU uint32 `inbound:"mtu,omitempty"` 22 GSO bool `inbound:"gso,omitempty"` 23 GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"` 24 Inet4Address []string `inbound:"inet4_address,omitempty"` 25 Inet6Address []string `inbound:"inet6_address,omitempty"` 26 StrictRoute bool `inbound:"strict_route,omitempty"` 27 Inet4RouteAddress []string `inbound:"inet4_route_address,omitempty"` 28 Inet6RouteAddress []string `inbound:"inet6_route_address,omitempty"` 29 Inet4RouteExcludeAddress []string `inbound:"inet4_route_exclude_address,omitempty"` 30 Inet6RouteExcludeAddress []string `inbound:"inet6_route_exclude_address,omitempty"` 31 IncludeInterface []string `inbound:"include-interface,omitempty"` 32 ExcludeInterface []string `inbound:"exclude-interface" json:"exclude-interface,omitempty"` 33 IncludeUID []uint32 `inbound:"include_uid,omitempty"` 34 IncludeUIDRange []string `inbound:"include_uid_range,omitempty"` 35 ExcludeUID []uint32 `inbound:"exclude_uid,omitempty"` 36 ExcludeUIDRange []string `inbound:"exclude_uid_range,omitempty"` 37 IncludeAndroidUser []int `inbound:"include_android_user,omitempty"` 38 IncludePackage []string `inbound:"include_package,omitempty"` 39 ExcludePackage []string `inbound:"exclude_package,omitempty"` 40 EndpointIndependentNat bool `inbound:"endpoint_independent_nat,omitempty"` 41 UDPTimeout int64 `inbound:"udp_timeout,omitempty"` 42 FileDescriptor int `inbound:"file-descriptor,omitempty"` 43 TableIndex int `inbound:"table-index,omitempty"` 44 } 45 46 func (o TunOption) Equal(config C.InboundConfig) bool { 47 return optionToString(o) == optionToString(config) 48 } 49 50 type Tun struct { 51 *Base 52 config *TunOption 53 l *sing_tun.Listener 54 tun LC.Tun 55 } 56 57 func NewTun(options *TunOption) (*Tun, error) { 58 base, err := NewBase(&options.BaseOption) 59 if err != nil { 60 return nil, err 61 } 62 stack, exist := C.StackTypeMapping[strings.ToLower(options.Stack)] 63 if !exist { 64 return nil, errors.New("invalid tun stack") 65 } 66 inet4Address, err := LC.StringSliceToNetipPrefixSlice(options.Inet4Address) 67 if err != nil { 68 return nil, err 69 } 70 inet6Address, err := LC.StringSliceToNetipPrefixSlice(options.Inet6Address) 71 if err != nil { 72 return nil, err 73 } 74 inet4RouteAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet4RouteAddress) 75 if err != nil { 76 return nil, err 77 } 78 inet6RouteAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet6RouteAddress) 79 if err != nil { 80 return nil, err 81 } 82 inet4RouteExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet4RouteExcludeAddress) 83 if err != nil { 84 return nil, err 85 } 86 inet6RouteExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet6RouteExcludeAddress) 87 if err != nil { 88 return nil, err 89 } 90 return &Tun{ 91 Base: base, 92 config: options, 93 tun: LC.Tun{ 94 Enable: true, 95 Device: options.Device, 96 Stack: stack, 97 DNSHijack: options.DNSHijack, 98 AutoRoute: options.AutoRoute, 99 AutoDetectInterface: options.AutoDetectInterface, 100 MTU: options.MTU, 101 GSO: options.GSO, 102 GSOMaxSize: options.GSOMaxSize, 103 Inet4Address: inet4Address, 104 Inet6Address: inet6Address, 105 StrictRoute: options.StrictRoute, 106 Inet4RouteAddress: inet4RouteAddress, 107 Inet6RouteAddress: inet6RouteAddress, 108 Inet4RouteExcludeAddress: inet4RouteExcludeAddress, 109 Inet6RouteExcludeAddress: inet6RouteExcludeAddress, 110 IncludeInterface: options.IncludeInterface, 111 ExcludeInterface: options.ExcludeInterface, 112 IncludeUID: options.IncludeUID, 113 IncludeUIDRange: options.IncludeUIDRange, 114 ExcludeUID: options.ExcludeUID, 115 ExcludeUIDRange: options.ExcludeUIDRange, 116 IncludeAndroidUser: options.IncludeAndroidUser, 117 IncludePackage: options.IncludePackage, 118 ExcludePackage: options.ExcludePackage, 119 EndpointIndependentNat: options.EndpointIndependentNat, 120 UDPTimeout: options.UDPTimeout, 121 FileDescriptor: options.FileDescriptor, 122 TableIndex: options.TableIndex, 123 }, 124 }, nil 125 } 126 127 // Config implements constant.InboundListener 128 func (t *Tun) Config() C.InboundConfig { 129 return t.config 130 } 131 132 // Address implements constant.InboundListener 133 func (t *Tun) Address() string { 134 return t.l.Address() 135 } 136 137 // Listen implements constant.InboundListener 138 func (t *Tun) Listen(tunnel C.Tunnel) error { 139 var err error 140 t.l, err = sing_tun.New(t.tun, tunnel, t.Additions()...) 141 if err != nil { 142 return err 143 } 144 log.Infoln("Tun[%s] proxy listening at: %s", t.Name(), t.Address()) 145 return nil 146 } 147 148 // Close implements constant.InboundListener 149 func (t *Tun) Close() error { 150 return t.l.Close() 151 } 152 153 var _ C.InboundListener = (*Tun)(nil)