github.com/metacubex/mihomo@v1.18.5/listener/sing_tun/server.go (about) 1 package sing_tun 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "net/netip" 8 "runtime" 9 "strconv" 10 "strings" 11 12 "github.com/metacubex/mihomo/adapter/inbound" 13 "github.com/metacubex/mihomo/component/dialer" 14 "github.com/metacubex/mihomo/component/iface" 15 "github.com/metacubex/mihomo/component/resolver" 16 C "github.com/metacubex/mihomo/constant" 17 LC "github.com/metacubex/mihomo/listener/config" 18 "github.com/metacubex/mihomo/listener/sing" 19 "github.com/metacubex/mihomo/log" 20 21 tun "github.com/metacubex/sing-tun" 22 "github.com/sagernet/sing/common" 23 "github.com/sagernet/sing/common/control" 24 E "github.com/sagernet/sing/common/exceptions" 25 F "github.com/sagernet/sing/common/format" 26 "github.com/sagernet/sing/common/ranges" 27 ) 28 29 var InterfaceName = "Meta" 30 var EnforceBindInterface = false 31 32 type Listener struct { 33 closed bool 34 options LC.Tun 35 handler *ListenerHandler 36 tunName string 37 addrStr string 38 39 tunIf tun.Tun 40 tunStack tun.Stack 41 42 networkUpdateMonitor tun.NetworkUpdateMonitor 43 defaultInterfaceMonitor tun.DefaultInterfaceMonitor 44 packageManager tun.PackageManager 45 46 dnsServerIp []string 47 } 48 49 func CalculateInterfaceName(name string) (tunName string) { 50 if runtime.GOOS == "darwin" { 51 tunName = "utun" 52 } else if name != "" { 53 tunName = name 54 return 55 } else { 56 tunName = "tun" 57 } 58 interfaces, err := net.Interfaces() 59 if err != nil { 60 return 61 } 62 var tunIndex int 63 for _, netInterface := range interfaces { 64 if strings.HasPrefix(netInterface.Name, tunName) { 65 index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16) 66 if parseErr == nil { 67 tunIndex = int(index) + 1 68 } 69 } 70 } 71 tunName = F.ToString(tunName, tunIndex) 72 return 73 } 74 75 func checkTunName(tunName string) (ok bool) { 76 defer func() { 77 if !ok { 78 log.Warnln("[TUN] Unsupported tunName(%s) in %s, force regenerate by ourselves.", tunName, runtime.GOOS) 79 } 80 }() 81 if runtime.GOOS == "darwin" { 82 if len(tunName) <= 4 { 83 return false 84 } 85 if tunName[:4] != "utun" { 86 return false 87 } 88 if _, parseErr := strconv.ParseInt(tunName[4:], 10, 16); parseErr != nil { 89 return false 90 } 91 } 92 return true 93 } 94 95 func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Listener, err error) { 96 if len(additions) == 0 { 97 additions = []inbound.Addition{ 98 inbound.WithInName("DEFAULT-TUN"), 99 inbound.WithSpecialRules(""), 100 } 101 } 102 if options.GSOMaxSize == 0 { 103 options.GSOMaxSize = 65536 104 } 105 tunName := options.Device 106 if tunName == "" || !checkTunName(tunName) { 107 tunName = CalculateInterfaceName(InterfaceName) 108 options.Device = tunName 109 } 110 tunMTU := options.MTU 111 if tunMTU == 0 { 112 tunMTU = 9000 113 } 114 var udpTimeout int64 115 if options.UDPTimeout != 0 { 116 udpTimeout = options.UDPTimeout 117 } else { 118 udpTimeout = int64(sing.UDPTimeout.Seconds()) 119 } 120 tableIndex := options.TableIndex 121 if tableIndex == 0 { 122 tableIndex = 2022 123 } 124 includeUID := uidToRange(options.IncludeUID) 125 if len(options.IncludeUIDRange) > 0 { 126 var err error 127 includeUID, err = parseRange(includeUID, options.IncludeUIDRange) 128 if err != nil { 129 return nil, E.Cause(err, "parse include_uid_range") 130 } 131 } 132 excludeUID := uidToRange(options.ExcludeUID) 133 if len(options.ExcludeUIDRange) > 0 { 134 var err error 135 excludeUID, err = parseRange(excludeUID, options.ExcludeUIDRange) 136 if err != nil { 137 return nil, E.Cause(err, "parse exclude_uid_range") 138 } 139 } 140 141 var dnsAdds []netip.AddrPort 142 143 for _, d := range options.DNSHijack { 144 if _, after, ok := strings.Cut(d, "://"); ok { 145 d = after 146 } 147 d = strings.Replace(d, "any", "0.0.0.0", 1) 148 addrPort, err := netip.ParseAddrPort(d) 149 if err != nil { 150 return nil, fmt.Errorf("parse dns-hijack url error: %w", err) 151 } 152 153 dnsAdds = append(dnsAdds, addrPort) 154 } 155 156 var dnsServerIp []string 157 for _, a := range options.Inet4Address { 158 addrPort := netip.AddrPortFrom(a.Addr().Next(), 53) 159 dnsServerIp = append(dnsServerIp, a.Addr().Next().String()) 160 dnsAdds = append(dnsAdds, addrPort) 161 } 162 for _, a := range options.Inet6Address { 163 addrPort := netip.AddrPortFrom(a.Addr().Next(), 53) 164 dnsServerIp = append(dnsServerIp, a.Addr().Next().String()) 165 dnsAdds = append(dnsAdds, addrPort) 166 } 167 168 h, err := sing.NewListenerHandler(sing.ListenerConfig{ 169 Tunnel: tunnel, 170 Type: C.TUN, 171 Additions: additions, 172 }) 173 if err != nil { 174 return nil, err 175 } 176 177 handler := &ListenerHandler{ 178 ListenerHandler: h, 179 DnsAdds: dnsAdds, 180 } 181 l = &Listener{ 182 closed: false, 183 options: options, 184 handler: handler, 185 tunName: tunName, 186 } 187 defer func() { 188 if err != nil { 189 l.Close() 190 l = nil 191 } 192 }() 193 194 networkUpdateMonitor, err := tun.NewNetworkUpdateMonitor(log.SingLogger) 195 if err != nil { 196 err = E.Cause(err, "create NetworkUpdateMonitor") 197 return 198 } 199 l.networkUpdateMonitor = networkUpdateMonitor 200 err = networkUpdateMonitor.Start() 201 if err != nil { 202 err = E.Cause(err, "start NetworkUpdateMonitor") 203 return 204 } 205 206 defaultInterfaceMonitor, err := tun.NewDefaultInterfaceMonitor(networkUpdateMonitor, log.SingLogger, tun.DefaultInterfaceMonitorOptions{OverrideAndroidVPN: true}) 207 if err != nil { 208 err = E.Cause(err, "create DefaultInterfaceMonitor") 209 return 210 } 211 l.defaultInterfaceMonitor = defaultInterfaceMonitor 212 defaultInterfaceMonitor.RegisterCallback(func(event int) { 213 l.FlushDefaultInterface() 214 }) 215 err = defaultInterfaceMonitor.Start() 216 if err != nil { 217 err = E.Cause(err, "start DefaultInterfaceMonitor") 218 return 219 } 220 221 tunOptions := tun.Options{ 222 Name: tunName, 223 MTU: tunMTU, 224 GSO: options.GSO, 225 Inet4Address: options.Inet4Address, 226 Inet6Address: options.Inet6Address, 227 AutoRoute: options.AutoRoute, 228 StrictRoute: options.StrictRoute, 229 Inet4RouteAddress: options.Inet4RouteAddress, 230 Inet6RouteAddress: options.Inet6RouteAddress, 231 Inet4RouteExcludeAddress: options.Inet4RouteExcludeAddress, 232 Inet6RouteExcludeAddress: options.Inet6RouteExcludeAddress, 233 IncludeInterface: options.IncludeInterface, 234 ExcludeInterface: options.ExcludeInterface, 235 IncludeUID: includeUID, 236 ExcludeUID: excludeUID, 237 IncludeAndroidUser: options.IncludeAndroidUser, 238 IncludePackage: options.IncludePackage, 239 ExcludePackage: options.ExcludePackage, 240 FileDescriptor: options.FileDescriptor, 241 InterfaceMonitor: defaultInterfaceMonitor, 242 TableIndex: tableIndex, 243 } 244 245 err = l.buildAndroidRules(&tunOptions) 246 if err != nil { 247 err = E.Cause(err, "build android rules") 248 return 249 } 250 tunIf, err := tunNew(tunOptions) 251 if err != nil { 252 err = E.Cause(err, "configure tun interface") 253 return 254 } 255 256 l.dnsServerIp = dnsServerIp 257 // after tun.New sing-tun has set DNS to TUN interface 258 resolver.AddSystemDnsBlacklist(dnsServerIp...) 259 260 stackOptions := tun.StackOptions{ 261 Context: context.TODO(), 262 Tun: tunIf, 263 TunOptions: tunOptions, 264 EndpointIndependentNat: options.EndpointIndependentNat, 265 UDPTimeout: udpTimeout, 266 Handler: handler, 267 Logger: log.SingLogger, 268 InterfaceFinder: control.DefaultInterfaceFinder(), 269 EnforceBindInterface: EnforceBindInterface, 270 } 271 272 if options.FileDescriptor > 0 { 273 if tunName, err := getTunnelName(int32(options.FileDescriptor)); err != nil { 274 stackOptions.TunOptions.Name = tunName 275 stackOptions.ForwarderBindInterface = true 276 } 277 } 278 l.tunIf = tunIf 279 280 tunStack, err := tun.NewStack(strings.ToLower(options.Stack.String()), stackOptions) 281 if err != nil { 282 return 283 } 284 285 err = tunStack.Start() 286 if err != nil { 287 return 288 } 289 l.tunStack = tunStack 290 291 //l.openAndroidHotspot(tunOptions) 292 293 l.addrStr = fmt.Sprintf("%s(%s,%s), mtu: %d, auto route: %v, ip stack: %s", 294 tunName, tunOptions.Inet4Address, tunOptions.Inet6Address, tunMTU, options.AutoRoute, options.Stack) 295 return 296 } 297 298 func (l *Listener) FlushDefaultInterface() { 299 if l.options.AutoDetectInterface { 300 for _, destination := range []netip.Addr{netip.IPv4Unspecified(), netip.IPv6Unspecified(), netip.MustParseAddr("1.1.1.1")} { 301 autoDetectInterfaceName := l.defaultInterfaceMonitor.DefaultInterfaceName(destination) 302 if autoDetectInterfaceName == l.tunName { 303 log.Warnln("[TUN] Auto detect interface by %s get same name with tun", destination.String()) 304 } else if autoDetectInterfaceName == "" || autoDetectInterfaceName == "<nil>" { 305 log.Warnln("[TUN] Auto detect interface by %s get empty name.", destination.String()) 306 } else { 307 if old := dialer.DefaultInterface.Swap(autoDetectInterfaceName); old != autoDetectInterfaceName { 308 log.Warnln("[TUN] default interface changed by monitor, %s => %s", old, autoDetectInterfaceName) 309 iface.FlushCache() 310 } 311 return 312 } 313 } 314 if dialer.DefaultInterface.CompareAndSwap("", "<invalid>") { 315 log.Warnln("[TUN] Auto detect interface failed, set '<invalid>' to DefaultInterface to avoid lookback") 316 } 317 } 318 } 319 320 func uidToRange(uidList []uint32) []ranges.Range[uint32] { 321 return common.Map(uidList, func(uid uint32) ranges.Range[uint32] { 322 return ranges.NewSingle(uid) 323 }) 324 } 325 326 func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.Range[uint32], error) { 327 for _, uidRange := range rangeList { 328 if !strings.Contains(uidRange, ":") { 329 return nil, E.New("missing ':' in range: ", uidRange) 330 } 331 subIndex := strings.Index(uidRange, ":") 332 if subIndex == 0 { 333 return nil, E.New("missing range start: ", uidRange) 334 } else if subIndex == len(uidRange)-1 { 335 return nil, E.New("missing range end: ", uidRange) 336 } 337 var start, end uint64 338 var err error 339 start, err = strconv.ParseUint(uidRange[:subIndex], 10, 32) 340 if err != nil { 341 return nil, E.Cause(err, "parse range start") 342 } 343 end, err = strconv.ParseUint(uidRange[subIndex+1:], 10, 32) 344 if err != nil { 345 return nil, E.Cause(err, "parse range end") 346 } 347 uidRanges = append(uidRanges, ranges.New(uint32(start), uint32(end))) 348 } 349 return uidRanges, nil 350 } 351 352 func (l *Listener) Close() error { 353 l.closed = true 354 resolver.RemoveSystemDnsBlacklist(l.dnsServerIp...) 355 return common.Close( 356 l.tunStack, 357 l.tunIf, 358 l.defaultInterfaceMonitor, 359 l.networkUpdateMonitor, 360 l.packageManager, 361 ) 362 } 363 364 func (l *Listener) Config() LC.Tun { 365 return l.options 366 } 367 368 func (l *Listener) Address() string { 369 return l.addrStr 370 }