github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/route/router.go (about) 1 package route 2 3 import ( 4 "context" 5 "errors" 6 "net" 7 "net/netip" 8 "net/url" 9 "os" 10 "os/user" 11 "strings" 12 "sync" 13 "time" 14 15 "github.com/inazumav/sing-box/adapter" 16 "github.com/inazumav/sing-box/common/dialer" 17 "github.com/inazumav/sing-box/common/dialer/conntrack" 18 "github.com/inazumav/sing-box/common/geoip" 19 "github.com/inazumav/sing-box/common/geosite" 20 "github.com/inazumav/sing-box/common/mux" 21 "github.com/inazumav/sing-box/common/process" 22 "github.com/inazumav/sing-box/common/sniff" 23 C "github.com/inazumav/sing-box/constant" 24 "github.com/inazumav/sing-box/experimental/libbox/platform" 25 "github.com/inazumav/sing-box/log" 26 "github.com/inazumav/sing-box/ntp" 27 "github.com/inazumav/sing-box/option" 28 "github.com/inazumav/sing-box/outbound" 29 "github.com/inazumav/sing-box/transport/fakeip" 30 "github.com/sagernet/sing-dns" 31 "github.com/sagernet/sing-tun" 32 "github.com/sagernet/sing-vmess" 33 "github.com/sagernet/sing/common" 34 "github.com/sagernet/sing/common/buf" 35 "github.com/sagernet/sing/common/bufio" 36 "github.com/sagernet/sing/common/bufio/deadline" 37 "github.com/sagernet/sing/common/control" 38 E "github.com/sagernet/sing/common/exceptions" 39 F "github.com/sagernet/sing/common/format" 40 M "github.com/sagernet/sing/common/metadata" 41 N "github.com/sagernet/sing/common/network" 42 serviceNTP "github.com/sagernet/sing/common/ntp" 43 "github.com/sagernet/sing/common/uot" 44 "github.com/sagernet/sing/service" 45 "github.com/sagernet/sing/service/pause" 46 ) 47 48 var _ adapter.Router = (*Router)(nil) 49 50 type Router struct { 51 ctx context.Context 52 logger log.ContextLogger 53 dnsLogger log.ContextLogger 54 inboundByTag map[string]adapter.Inbound 55 outbounds []adapter.Outbound 56 outboundByTag map[string]adapter.Outbound 57 rules []adapter.Rule 58 defaultDetour string 59 defaultOutboundForConnection adapter.Outbound 60 defaultOutboundForPacketConnection adapter.Outbound 61 needGeoIPDatabase bool 62 needGeositeDatabase bool 63 geoIPOptions option.GeoIPOptions 64 geositeOptions option.GeositeOptions 65 geoIPReader *geoip.Reader 66 geositeReader *geosite.Reader 67 geositeCache map[string]adapter.Rule 68 dnsClient *dns.Client 69 defaultDomainStrategy dns.DomainStrategy 70 dnsRules []adapter.DNSRule 71 defaultTransport dns.Transport 72 transports []dns.Transport 73 transportMap map[string]dns.Transport 74 transportDomainStrategy map[dns.Transport]dns.DomainStrategy 75 dnsReverseMapping *DNSReverseMapping 76 fakeIPStore adapter.FakeIPStore 77 interfaceFinder myInterfaceFinder 78 autoDetectInterface bool 79 defaultInterface string 80 defaultMark int 81 networkMonitor tun.NetworkUpdateMonitor 82 interfaceMonitor tun.DefaultInterfaceMonitor 83 packageManager tun.PackageManager 84 processSearcher process.Searcher 85 timeService *ntp.Service 86 pauseManager pause.Manager 87 clashServer adapter.ClashServer 88 v2rayServer adapter.V2RayServer 89 platformInterface platform.Interface 90 actionLock sync.RWMutex 91 } 92 93 func NewRouter( 94 ctx context.Context, 95 logFactory log.Factory, 96 options option.RouteOptions, 97 dnsOptions option.DNSOptions, 98 ntpOptions option.NTPOptions, 99 inbounds []option.Inbound, 100 platformInterface platform.Interface, 101 ) (*Router, error) { 102 router := &Router{ 103 ctx: ctx, 104 logger: logFactory.NewLogger("router"), 105 dnsLogger: logFactory.NewLogger("dns"), 106 outboundByTag: make(map[string]adapter.Outbound), 107 rules: make([]adapter.Rule, 0, len(options.Rules)), 108 dnsRules: make([]adapter.DNSRule, 0, len(dnsOptions.Rules)), 109 needGeoIPDatabase: hasRule(options.Rules, isGeoIPRule) || hasDNSRule(dnsOptions.Rules, isGeoIPDNSRule), 110 needGeositeDatabase: hasRule(options.Rules, isGeositeRule) || hasDNSRule(dnsOptions.Rules, isGeositeDNSRule), 111 geoIPOptions: common.PtrValueOrDefault(options.GeoIP), 112 geositeOptions: common.PtrValueOrDefault(options.Geosite), 113 geositeCache: make(map[string]adapter.Rule), 114 defaultDetour: options.Final, 115 defaultDomainStrategy: dns.DomainStrategy(dnsOptions.Strategy), 116 autoDetectInterface: options.AutoDetectInterface, 117 defaultInterface: options.DefaultInterface, 118 defaultMark: options.DefaultMark, 119 pauseManager: pause.ManagerFromContext(ctx), 120 platformInterface: platformInterface, 121 } 122 router.dnsClient = dns.NewClient(dns.ClientOptions{ 123 DisableCache: dnsOptions.DNSClientOptions.DisableCache, 124 DisableExpire: dnsOptions.DNSClientOptions.DisableExpire, 125 IndependentCache: dnsOptions.DNSClientOptions.IndependentCache, 126 Logger: router.dnsLogger, 127 }) 128 for i, ruleOptions := range options.Rules { 129 routeRule, err := NewRule(router, router.logger, ruleOptions) 130 if err != nil { 131 return nil, E.Cause(err, "parse rule[", i, "]") 132 } 133 router.rules = append(router.rules, routeRule) 134 } 135 for i, dnsRuleOptions := range dnsOptions.Rules { 136 dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions) 137 if err != nil { 138 return nil, E.Cause(err, "parse dns rule[", i, "]") 139 } 140 router.dnsRules = append(router.dnsRules, dnsRule) 141 } 142 143 transports := make([]dns.Transport, len(dnsOptions.Servers)) 144 dummyTransportMap := make(map[string]dns.Transport) 145 transportMap := make(map[string]dns.Transport) 146 transportTags := make([]string, len(dnsOptions.Servers)) 147 transportTagMap := make(map[string]bool) 148 transportDomainStrategy := make(map[dns.Transport]dns.DomainStrategy) 149 for i, server := range dnsOptions.Servers { 150 var tag string 151 if server.Tag != "" { 152 tag = server.Tag 153 } else { 154 tag = F.ToString(i) 155 } 156 if transportTagMap[tag] { 157 return nil, E.New("duplicate dns server tag: ", tag) 158 } 159 transportTags[i] = tag 160 transportTagMap[tag] = true 161 } 162 ctx = adapter.ContextWithRouter(ctx, router) 163 for { 164 lastLen := len(dummyTransportMap) 165 for i, server := range dnsOptions.Servers { 166 tag := transportTags[i] 167 if _, exists := dummyTransportMap[tag]; exists { 168 continue 169 } 170 var detour N.Dialer 171 if server.Detour == "" { 172 detour = dialer.NewRouter(router) 173 } else { 174 detour = dialer.NewDetour(router, server.Detour) 175 } 176 switch server.Address { 177 case "local": 178 default: 179 serverURL, _ := url.Parse(server.Address) 180 var serverAddress string 181 if serverURL != nil { 182 serverAddress = serverURL.Hostname() 183 } 184 if serverAddress == "" { 185 serverAddress = server.Address 186 } 187 _, notIpAddress := netip.ParseAddr(serverAddress) 188 if server.AddressResolver != "" { 189 if !transportTagMap[server.AddressResolver] { 190 return nil, E.New("parse dns server[", tag, "]: address resolver not found: ", server.AddressResolver) 191 } 192 if upstream, exists := dummyTransportMap[server.AddressResolver]; exists { 193 detour = dns.NewDialerWrapper(detour, router.dnsClient, upstream, dns.DomainStrategy(server.AddressStrategy), time.Duration(server.AddressFallbackDelay)) 194 } else { 195 continue 196 } 197 } else if notIpAddress != nil && strings.Contains(server.Address, ".") { 198 return nil, E.New("parse dns server[", tag, "]: missing address_resolver") 199 } 200 } 201 transport, err := dns.CreateTransport(tag, ctx, logFactory.NewLogger(F.ToString("dns/transport[", tag, "]")), detour, server.Address) 202 if err != nil { 203 return nil, E.Cause(err, "parse dns server[", tag, "]") 204 } 205 transports[i] = transport 206 dummyTransportMap[tag] = transport 207 if server.Tag != "" { 208 transportMap[server.Tag] = transport 209 } 210 strategy := dns.DomainStrategy(server.Strategy) 211 if strategy != dns.DomainStrategyAsIS { 212 transportDomainStrategy[transport] = strategy 213 } 214 } 215 if len(transports) == len(dummyTransportMap) { 216 break 217 } 218 if lastLen != len(dummyTransportMap) { 219 continue 220 } 221 unresolvedTags := common.MapIndexed(common.FilterIndexed(dnsOptions.Servers, func(index int, server option.DNSServerOptions) bool { 222 _, exists := dummyTransportMap[transportTags[index]] 223 return !exists 224 }), func(index int, server option.DNSServerOptions) string { 225 return transportTags[index] 226 }) 227 if len(unresolvedTags) == 0 { 228 panic(F.ToString("unexpected unresolved dns servers: ", len(transports), " ", len(dummyTransportMap), " ", len(transportMap))) 229 } 230 return nil, E.New("found circular reference in dns servers: ", strings.Join(unresolvedTags, " ")) 231 } 232 var defaultTransport dns.Transport 233 if dnsOptions.Final != "" { 234 defaultTransport = dummyTransportMap[dnsOptions.Final] 235 if defaultTransport == nil { 236 return nil, E.New("default dns server not found: ", dnsOptions.Final) 237 } 238 } 239 if defaultTransport == nil { 240 if len(transports) == 0 { 241 transports = append(transports, dns.NewLocalTransport("local", N.SystemDialer)) 242 } 243 defaultTransport = transports[0] 244 } 245 router.defaultTransport = defaultTransport 246 router.transports = transports 247 router.transportMap = transportMap 248 router.transportDomainStrategy = transportDomainStrategy 249 250 if dnsOptions.ReverseMapping { 251 router.dnsReverseMapping = NewDNSReverseMapping() 252 } 253 254 if fakeIPOptions := dnsOptions.FakeIP; fakeIPOptions != nil && dnsOptions.FakeIP.Enabled { 255 var inet4Range netip.Prefix 256 var inet6Range netip.Prefix 257 if fakeIPOptions.Inet4Range != nil { 258 inet4Range = fakeIPOptions.Inet4Range.Build() 259 } 260 if fakeIPOptions.Inet6Range != nil { 261 inet6Range = fakeIPOptions.Inet6Range.Build() 262 } 263 router.fakeIPStore = fakeip.NewStore(router, router.logger, inet4Range, inet6Range) 264 } 265 266 usePlatformDefaultInterfaceMonitor := platformInterface != nil && platformInterface.UsePlatformDefaultInterfaceMonitor() 267 needInterfaceMonitor := options.AutoDetectInterface || common.Any(inbounds, func(inbound option.Inbound) bool { 268 return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy || inbound.TunOptions.AutoRoute 269 }) 270 271 if !usePlatformDefaultInterfaceMonitor { 272 networkMonitor, err := tun.NewNetworkUpdateMonitor(router.logger) 273 if !((err != nil && !needInterfaceMonitor) || errors.Is(err, os.ErrInvalid)) { 274 if err != nil { 275 return nil, err 276 } 277 router.networkMonitor = networkMonitor 278 networkMonitor.RegisterCallback(func() { 279 _ = router.interfaceFinder.update() 280 }) 281 interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor, router.logger, tun.DefaultInterfaceMonitorOptions{ 282 OverrideAndroidVPN: options.OverrideAndroidVPN, 283 UnderNetworkExtension: platformInterface != nil && platformInterface.UnderNetworkExtension(), 284 }) 285 if err != nil { 286 return nil, E.New("auto_detect_interface unsupported on current platform") 287 } 288 interfaceMonitor.RegisterCallback(router.notifyNetworkUpdate) 289 router.interfaceMonitor = interfaceMonitor 290 } 291 } else { 292 interfaceMonitor := platformInterface.CreateDefaultInterfaceMonitor(router.logger) 293 interfaceMonitor.RegisterCallback(router.notifyNetworkUpdate) 294 router.interfaceMonitor = interfaceMonitor 295 } 296 297 needFindProcess := hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess 298 needPackageManager := C.IsAndroid && platformInterface == nil && (needFindProcess || common.Any(inbounds, func(inbound option.Inbound) bool { 299 return len(inbound.TunOptions.IncludePackage) > 0 || len(inbound.TunOptions.ExcludePackage) > 0 300 })) 301 if needPackageManager { 302 packageManager, err := tun.NewPackageManager(router) 303 if err != nil { 304 return nil, E.Cause(err, "create package manager") 305 } 306 router.packageManager = packageManager 307 } 308 if needFindProcess { 309 if platformInterface != nil { 310 router.processSearcher = platformInterface 311 } else { 312 searcher, err := process.NewSearcher(process.Config{ 313 Logger: logFactory.NewLogger("router/process"), 314 PackageManager: router.packageManager, 315 }) 316 if err != nil { 317 if err != os.ErrInvalid { 318 router.logger.Warn(E.Cause(err, "create process searcher")) 319 } 320 } else { 321 router.processSearcher = searcher 322 } 323 } 324 } 325 if ntpOptions.Enabled { 326 timeService, err := ntp.NewService(ctx, router, logFactory.NewLogger("ntp"), ntpOptions) 327 if err != nil { 328 return nil, err 329 } 330 service.ContextWith[serviceNTP.TimeService](ctx, timeService) 331 router.timeService = timeService 332 } 333 return router, nil 334 } 335 336 func (r *Router) Initialize(inbounds []adapter.Inbound, outbounds []adapter.Outbound, defaultOutbound func() adapter.Outbound) error { 337 inboundByTag := make(map[string]adapter.Inbound) 338 for _, inbound := range inbounds { 339 inboundByTag[inbound.Tag()] = inbound 340 } 341 outboundByTag := make(map[string]adapter.Outbound) 342 for _, detour := range outbounds { 343 outboundByTag[detour.Tag()] = detour 344 } 345 var defaultOutboundForConnection adapter.Outbound 346 var defaultOutboundForPacketConnection adapter.Outbound 347 if r.defaultDetour != "" { 348 detour, loaded := outboundByTag[r.defaultDetour] 349 if !loaded { 350 return E.New("default detour not found: ", r.defaultDetour) 351 } 352 if common.Contains(detour.Network(), N.NetworkTCP) { 353 defaultOutboundForConnection = detour 354 } 355 if common.Contains(detour.Network(), N.NetworkUDP) { 356 defaultOutboundForPacketConnection = detour 357 } 358 } 359 var index, packetIndex int 360 if defaultOutboundForConnection == nil { 361 for i, detour := range outbounds { 362 if common.Contains(detour.Network(), N.NetworkTCP) { 363 index = i 364 defaultOutboundForConnection = detour 365 break 366 } 367 } 368 } 369 if defaultOutboundForPacketConnection == nil { 370 for i, detour := range outbounds { 371 if common.Contains(detour.Network(), N.NetworkUDP) { 372 packetIndex = i 373 defaultOutboundForPacketConnection = detour 374 break 375 } 376 } 377 } 378 if defaultOutboundForConnection == nil || defaultOutboundForPacketConnection == nil { 379 detour := defaultOutbound() 380 if defaultOutboundForConnection == nil { 381 defaultOutboundForConnection = detour 382 } 383 if defaultOutboundForPacketConnection == nil { 384 defaultOutboundForPacketConnection = detour 385 } 386 outbounds = append(outbounds, detour) 387 outboundByTag[detour.Tag()] = detour 388 } 389 if defaultOutboundForConnection != defaultOutboundForPacketConnection { 390 var description string 391 if defaultOutboundForConnection.Tag() != "" { 392 description = defaultOutboundForConnection.Tag() 393 } else { 394 description = F.ToString(index) 395 } 396 var packetDescription string 397 if defaultOutboundForPacketConnection.Tag() != "" { 398 packetDescription = defaultOutboundForPacketConnection.Tag() 399 } else { 400 packetDescription = F.ToString(packetIndex) 401 } 402 r.logger.Info("using ", defaultOutboundForConnection.Type(), "[", description, "] as default outbound for connection") 403 r.logger.Info("using ", defaultOutboundForPacketConnection.Type(), "[", packetDescription, "] as default outbound for packet connection") 404 } 405 r.inboundByTag = inboundByTag 406 r.outbounds = outbounds 407 r.defaultOutboundForConnection = defaultOutboundForConnection 408 r.defaultOutboundForPacketConnection = defaultOutboundForPacketConnection 409 r.outboundByTag = outboundByTag 410 for i, rule := range r.rules { 411 if _, loaded := outboundByTag[rule.Outbound()]; !loaded { 412 return E.New("outbound not found for rule[", i, "]: ", rule.Outbound()) 413 } 414 } 415 return nil 416 } 417 418 func (r *Router) Outbounds() []adapter.Outbound { 419 return r.outbounds 420 } 421 422 func (r *Router) Start() error { 423 if r.needGeoIPDatabase { 424 err := r.prepareGeoIPDatabase() 425 if err != nil { 426 return err 427 } 428 } 429 if r.needGeositeDatabase { 430 err := r.prepareGeositeDatabase() 431 if err != nil { 432 return err 433 } 434 } 435 if r.interfaceMonitor != nil { 436 err := r.interfaceMonitor.Start() 437 if err != nil { 438 return err 439 } 440 } 441 if r.networkMonitor != nil { 442 err := r.networkMonitor.Start() 443 if err != nil { 444 return err 445 } 446 } 447 if r.packageManager != nil { 448 err := r.packageManager.Start() 449 if err != nil { 450 return err 451 } 452 } 453 if r.needGeositeDatabase { 454 for _, rule := range r.rules { 455 err := rule.UpdateGeosite() 456 if err != nil { 457 r.logger.Error("failed to initialize geosite: ", err) 458 } 459 } 460 for _, rule := range r.dnsRules { 461 err := rule.UpdateGeosite() 462 if err != nil { 463 r.logger.Error("failed to initialize geosite: ", err) 464 } 465 } 466 err := common.Close(r.geositeReader) 467 if err != nil { 468 return err 469 } 470 r.geositeCache = nil 471 r.geositeReader = nil 472 } 473 for i, rule := range r.rules { 474 err := rule.Start() 475 if err != nil { 476 return E.Cause(err, "initialize rule[", i, "]") 477 } 478 } 479 for i, rule := range r.dnsRules { 480 err := rule.Start() 481 if err != nil { 482 return E.Cause(err, "initialize DNS rule[", i, "]") 483 } 484 } 485 if r.fakeIPStore != nil { 486 err := r.fakeIPStore.Start() 487 if err != nil { 488 return err 489 } 490 } 491 for i, transport := range r.transports { 492 err := transport.Start() 493 if err != nil { 494 return E.Cause(err, "initialize DNS server[", i, "]") 495 } 496 } 497 if r.timeService != nil { 498 err := r.timeService.Start() 499 if err != nil { 500 return E.Cause(err, "initialize time service") 501 } 502 } 503 return nil 504 } 505 506 func (r *Router) Close() error { 507 var err error 508 for i, rule := range r.rules { 509 r.logger.Trace("closing rule[", i, "]") 510 err = E.Append(err, rule.Close(), func(err error) error { 511 return E.Cause(err, "close rule[", i, "]") 512 }) 513 } 514 for i, rule := range r.dnsRules { 515 r.logger.Trace("closing dns rule[", i, "]") 516 err = E.Append(err, rule.Close(), func(err error) error { 517 return E.Cause(err, "close dns rule[", i, "]") 518 }) 519 } 520 for i, transport := range r.transports { 521 r.logger.Trace("closing transport[", i, "] ") 522 err = E.Append(err, transport.Close(), func(err error) error { 523 return E.Cause(err, "close dns transport[", i, "]") 524 }) 525 } 526 if r.geoIPReader != nil { 527 r.logger.Trace("closing geoip reader") 528 err = E.Append(err, common.Close(r.geoIPReader), func(err error) error { 529 return E.Cause(err, "close geoip reader") 530 }) 531 } 532 if r.interfaceMonitor != nil { 533 r.logger.Trace("closing interface monitor") 534 err = E.Append(err, r.interfaceMonitor.Close(), func(err error) error { 535 return E.Cause(err, "close interface monitor") 536 }) 537 } 538 if r.networkMonitor != nil { 539 r.logger.Trace("closing network monitor") 540 err = E.Append(err, r.networkMonitor.Close(), func(err error) error { 541 return E.Cause(err, "close network monitor") 542 }) 543 } 544 if r.packageManager != nil { 545 r.logger.Trace("closing package manager") 546 err = E.Append(err, r.packageManager.Close(), func(err error) error { 547 return E.Cause(err, "close package manager") 548 }) 549 } 550 if r.timeService != nil { 551 r.logger.Trace("closing time service") 552 err = E.Append(err, r.timeService.Close(), func(err error) error { 553 return E.Cause(err, "close time service") 554 }) 555 } 556 if r.fakeIPStore != nil { 557 r.logger.Trace("closing fakeip store") 558 err = E.Append(err, r.fakeIPStore.Close(), func(err error) error { 559 return E.Cause(err, "close fakeip store") 560 }) 561 } 562 return err 563 } 564 565 func (r *Router) Outbound(tag string) (adapter.Outbound, bool) { 566 outbound, loaded := r.outboundByTag[tag] 567 return outbound, loaded 568 } 569 570 func (r *Router) DefaultOutbound(network string) adapter.Outbound { 571 if network == N.NetworkTCP { 572 return r.defaultOutboundForConnection 573 } else { 574 return r.defaultOutboundForPacketConnection 575 } 576 } 577 578 func (r *Router) FakeIPStore() adapter.FakeIPStore { 579 return r.fakeIPStore 580 } 581 582 func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 583 if metadata.InboundDetour != "" { 584 if metadata.LastInbound == metadata.InboundDetour { 585 return E.New("routing loop on detour: ", metadata.InboundDetour) 586 } 587 detour := r.inboundByTag[metadata.InboundDetour] 588 if detour == nil { 589 return E.New("inbound detour not found: ", metadata.InboundDetour) 590 } 591 injectable, isInjectable := detour.(adapter.InjectableInbound) 592 if !isInjectable { 593 return E.New("inbound detour is not injectable: ", metadata.InboundDetour) 594 } 595 if !common.Contains(injectable.Network(), N.NetworkTCP) { 596 return E.New("inject: TCP unsupported") 597 } 598 metadata.LastInbound = metadata.Inbound 599 metadata.Inbound = metadata.InboundDetour 600 metadata.InboundDetour = "" 601 err := injectable.NewConnection(ctx, conn, metadata) 602 if err != nil { 603 return E.Cause(err, "inject ", detour.Tag()) 604 } 605 return nil 606 } 607 metadata.Network = N.NetworkTCP 608 switch metadata.Destination.Fqdn { 609 case mux.Destination.Fqdn: 610 r.logger.InfoContext(ctx, "inbound multiplex connection") 611 handler := adapter.NewUpstreamHandler(metadata, r.RouteConnection, r.RoutePacketConnection, r) 612 return mux.HandleConnection(ctx, handler, r.logger, conn, adapter.UpstreamMetadata(metadata)) 613 case vmess.MuxDestination.Fqdn: 614 r.logger.InfoContext(ctx, "inbound legacy multiplex connection") 615 return vmess.HandleMuxConnection(ctx, conn, adapter.NewUpstreamHandler(metadata, r.RouteConnection, r.RoutePacketConnection, r)) 616 case uot.MagicAddress: 617 request, err := uot.ReadRequest(conn) 618 if err != nil { 619 return E.Cause(err, "read UoT request") 620 } 621 if request.IsConnect { 622 r.logger.InfoContext(ctx, "inbound UoT connect connection to ", request.Destination) 623 } else { 624 r.logger.InfoContext(ctx, "inbound UoT connection to ", request.Destination) 625 } 626 metadata.Domain = metadata.Destination.Fqdn 627 metadata.Destination = request.Destination 628 return r.RoutePacketConnection(ctx, uot.NewConn(conn, *request), metadata) 629 case uot.LegacyMagicAddress: 630 r.logger.InfoContext(ctx, "inbound legacy UoT connection") 631 metadata.Domain = metadata.Destination.Fqdn 632 metadata.Destination = M.Socksaddr{Addr: netip.IPv4Unspecified()} 633 return r.RoutePacketConnection(ctx, uot.NewConn(conn, uot.Request{}), metadata) 634 } 635 636 if r.fakeIPStore != nil && r.fakeIPStore.Contains(metadata.Destination.Addr) { 637 domain, loaded := r.fakeIPStore.Lookup(metadata.Destination.Addr) 638 if !loaded { 639 return E.New("missing fakeip context") 640 } 641 metadata.OriginDestination = metadata.Destination 642 metadata.Destination = M.Socksaddr{ 643 Fqdn: domain, 644 Port: metadata.Destination.Port, 645 } 646 metadata.FakeIP = true 647 r.logger.DebugContext(ctx, "found fakeip domain: ", domain) 648 } 649 650 if deadline.NeedAdditionalReadDeadline(conn) { 651 conn = deadline.NewConn(conn) 652 } 653 654 if metadata.InboundOptions.SniffEnabled { 655 buffer := buf.NewPacket() 656 buffer.FullReset() 657 sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost) 658 if sniffMetadata != nil { 659 metadata.Protocol = sniffMetadata.Protocol 660 metadata.Domain = sniffMetadata.Domain 661 if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) { 662 metadata.Destination = M.Socksaddr{ 663 Fqdn: metadata.Domain, 664 Port: metadata.Destination.Port, 665 } 666 } 667 if metadata.Domain != "" { 668 r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol, ", domain: ", metadata.Domain) 669 } else { 670 r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol) 671 } 672 } else if err != nil { 673 r.logger.TraceContext(ctx, "sniffed no protocol: ", err) 674 } 675 if !buffer.IsEmpty() { 676 conn = bufio.NewCachedConn(conn, buffer) 677 } else { 678 buffer.Release() 679 } 680 } 681 682 if r.dnsReverseMapping != nil && metadata.Domain == "" { 683 domain, loaded := r.dnsReverseMapping.Query(metadata.Destination.Addr) 684 if loaded { 685 metadata.Domain = domain 686 r.logger.DebugContext(ctx, "found reserve mapped domain: ", metadata.Domain) 687 } 688 } 689 690 if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS { 691 addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)) 692 if err != nil { 693 return err 694 } 695 metadata.DestinationAddresses = addresses 696 r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]") 697 } 698 ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForConnection) 699 if err != nil { 700 return err 701 } 702 if !common.Contains(detour.Network(), N.NetworkTCP) { 703 return E.New("missing supported outbound, closing connection") 704 } 705 if r.clashServer != nil { 706 trackerConn, tracker := r.clashServer.RoutedConnection(ctx, conn, metadata, matchedRule) 707 defer tracker.Leave() 708 conn = trackerConn 709 } 710 if r.v2rayServer != nil { 711 if statsService := r.v2rayServer.StatsService(); statsService != nil { 712 conn = statsService.RoutedConnection(metadata.Inbound, detour.Tag(), metadata.User, conn) 713 } 714 } 715 return detour.NewConnection(ctx, conn, metadata) 716 } 717 718 func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 719 if metadata.InboundDetour != "" { 720 if metadata.LastInbound == metadata.InboundDetour { 721 return E.New("routing loop on detour: ", metadata.InboundDetour) 722 } 723 detour := r.inboundByTag[metadata.InboundDetour] 724 if detour == nil { 725 return E.New("inbound detour not found: ", metadata.InboundDetour) 726 } 727 injectable, isInjectable := detour.(adapter.InjectableInbound) 728 if !isInjectable { 729 return E.New("inbound detour is not injectable: ", metadata.InboundDetour) 730 } 731 if !common.Contains(injectable.Network(), N.NetworkUDP) { 732 return E.New("inject: UDP unsupported") 733 } 734 metadata.LastInbound = metadata.Inbound 735 metadata.Inbound = metadata.InboundDetour 736 metadata.InboundDetour = "" 737 err := injectable.NewPacketConnection(ctx, conn, metadata) 738 if err != nil { 739 return E.Cause(err, "inject ", detour.Tag()) 740 } 741 return nil 742 } 743 metadata.Network = N.NetworkUDP 744 745 if r.fakeIPStore != nil && r.fakeIPStore.Contains(metadata.Destination.Addr) { 746 domain, loaded := r.fakeIPStore.Lookup(metadata.Destination.Addr) 747 if !loaded { 748 return E.New("missing fakeip context") 749 } 750 metadata.OriginDestination = metadata.Destination 751 metadata.Destination = M.Socksaddr{ 752 Fqdn: domain, 753 Port: metadata.Destination.Port, 754 } 755 metadata.FakeIP = true 756 r.logger.DebugContext(ctx, "found fakeip domain: ", domain) 757 } 758 759 // Currently we don't have deadline usages for UDP connections 760 /*if deadline.NeedAdditionalReadDeadline(conn) { 761 conn = deadline.NewPacketConn(bufio.NewNetPacketConn(conn)) 762 }*/ 763 764 if metadata.InboundOptions.SniffEnabled || metadata.Destination.Addr.IsUnspecified() { 765 buffer := buf.NewPacket() 766 buffer.FullReset() 767 destination, err := conn.ReadPacket(buffer) 768 if err != nil { 769 buffer.Release() 770 return err 771 } 772 if metadata.Destination.Addr.IsUnspecified() { 773 metadata.Destination = destination 774 } 775 if metadata.InboundOptions.SniffEnabled { 776 sniffMetadata, _ := sniff.PeekPacket(ctx, buffer.Bytes(), sniff.DomainNameQuery, sniff.QUICClientHello, sniff.STUNMessage) 777 if sniffMetadata != nil { 778 metadata.Protocol = sniffMetadata.Protocol 779 metadata.Domain = sniffMetadata.Domain 780 if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) { 781 metadata.Destination = M.Socksaddr{ 782 Fqdn: metadata.Domain, 783 Port: metadata.Destination.Port, 784 } 785 } 786 if metadata.Domain != "" { 787 r.logger.DebugContext(ctx, "sniffed packet protocol: ", metadata.Protocol, ", domain: ", metadata.Domain) 788 } else { 789 r.logger.DebugContext(ctx, "sniffed packet protocol: ", metadata.Protocol) 790 } 791 } 792 } 793 conn = bufio.NewCachedPacketConn(conn, buffer, destination) 794 } 795 if r.dnsReverseMapping != nil && metadata.Domain == "" { 796 domain, loaded := r.dnsReverseMapping.Query(metadata.Destination.Addr) 797 if loaded { 798 metadata.Domain = domain 799 r.logger.DebugContext(ctx, "found reserve mapped domain: ", metadata.Domain) 800 } 801 } 802 if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS { 803 addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)) 804 if err != nil { 805 return err 806 } 807 metadata.DestinationAddresses = addresses 808 r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]") 809 } 810 ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForPacketConnection) 811 if err != nil { 812 return err 813 } 814 if !common.Contains(detour.Network(), N.NetworkUDP) { 815 return E.New("missing supported outbound, closing packet connection") 816 } 817 if r.clashServer != nil { 818 trackerConn, tracker := r.clashServer.RoutedPacketConnection(ctx, conn, metadata, matchedRule) 819 defer tracker.Leave() 820 conn = trackerConn 821 } 822 if r.v2rayServer != nil { 823 if statsService := r.v2rayServer.StatsService(); statsService != nil { 824 conn = statsService.RoutedPacketConnection(metadata.Inbound, detour.Tag(), metadata.User, conn) 825 } 826 } 827 if metadata.FakeIP { 828 conn = fakeip.NewNATPacketConn(conn, metadata.OriginDestination, metadata.Destination) 829 } 830 return detour.NewPacketConnection(ctx, conn, metadata) 831 } 832 833 func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, defaultOutbound adapter.Outbound) (context.Context, adapter.Rule, adapter.Outbound, error) { 834 matchRule, matchOutbound := r.match0(ctx, metadata, defaultOutbound) 835 if contextOutbound, loaded := outbound.TagFromContext(ctx); loaded { 836 if contextOutbound == matchOutbound.Tag() { 837 return nil, nil, nil, E.New("connection loopback in outbound/", matchOutbound.Type(), "[", matchOutbound.Tag(), "]") 838 } 839 } 840 ctx = outbound.ContextWithTag(ctx, matchOutbound.Tag()) 841 return ctx, matchRule, matchOutbound, nil 842 } 843 844 func (r *Router) match0(ctx context.Context, metadata *adapter.InboundContext, defaultOutbound adapter.Outbound) (adapter.Rule, adapter.Outbound) { 845 if r.processSearcher != nil { 846 var originDestination netip.AddrPort 847 if metadata.OriginDestination.IsValid() { 848 originDestination = metadata.OriginDestination.AddrPort() 849 } else if metadata.Destination.IsIP() { 850 originDestination = metadata.Destination.AddrPort() 851 } 852 processInfo, err := process.FindProcessInfo(r.processSearcher, ctx, metadata.Network, metadata.Source.AddrPort(), originDestination) 853 if err != nil { 854 r.logger.InfoContext(ctx, "failed to search process: ", err) 855 } else { 856 if processInfo.ProcessPath != "" { 857 r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath) 858 } else if processInfo.PackageName != "" { 859 r.logger.InfoContext(ctx, "found package name: ", processInfo.PackageName) 860 } else if processInfo.UserId != -1 { 861 if /*needUserName &&*/ true { 862 osUser, _ := user.LookupId(F.ToString(processInfo.UserId)) 863 if osUser != nil { 864 processInfo.User = osUser.Username 865 } 866 } 867 if processInfo.User != "" { 868 r.logger.InfoContext(ctx, "found user: ", processInfo.User) 869 } else { 870 r.logger.InfoContext(ctx, "found user id: ", processInfo.UserId) 871 } 872 } 873 metadata.ProcessInfo = processInfo 874 } 875 } 876 for i, rule := range r.rules { 877 if rule.Match(metadata) { 878 detour := rule.Outbound() 879 r.logger.DebugContext(ctx, "match[", i, "] ", rule.String(), " => ", detour) 880 if outbound, loaded := r.Outbound(detour); loaded { 881 return rule, outbound 882 } 883 r.logger.ErrorContext(ctx, "outbound not found: ", detour) 884 } 885 } 886 return nil, defaultOutbound 887 } 888 889 func (r *Router) InterfaceFinder() control.InterfaceFinder { 890 return &r.interfaceFinder 891 } 892 893 func (r *Router) UpdateInterfaces() error { 894 if r.platformInterface == nil || !r.platformInterface.UsePlatformInterfaceGetter() { 895 return r.interfaceFinder.update() 896 } else { 897 interfaces, err := r.platformInterface.Interfaces() 898 if err != nil { 899 return err 900 } 901 r.interfaceFinder.updateInterfaces(common.Map(interfaces, func(it platform.NetworkInterface) net.Interface { 902 return net.Interface{ 903 Name: it.Name, 904 Index: it.Index, 905 MTU: it.MTU, 906 } 907 })) 908 return nil 909 } 910 } 911 912 func (r *Router) AutoDetectInterface() bool { 913 return r.autoDetectInterface 914 } 915 916 func (r *Router) AutoDetectInterfaceFunc() control.Func { 917 if r.platformInterface != nil && r.platformInterface.UsePlatformAutoDetectInterfaceControl() { 918 return r.platformInterface.AutoDetectInterfaceControl() 919 } else { 920 return control.BindToInterfaceFunc(r.InterfaceFinder(), func(network string, address string) (interfaceName string, interfaceIndex int) { 921 remoteAddr := M.ParseSocksaddr(address).Addr 922 if C.IsLinux { 923 return r.InterfaceMonitor().DefaultInterfaceName(remoteAddr), -1 924 } else { 925 return "", r.InterfaceMonitor().DefaultInterfaceIndex(remoteAddr) 926 } 927 }) 928 } 929 } 930 931 func (r *Router) DefaultInterface() string { 932 return r.defaultInterface 933 } 934 935 func (r *Router) DefaultMark() int { 936 return r.defaultMark 937 } 938 939 func (r *Router) Rules() []adapter.Rule { 940 return r.rules 941 } 942 943 func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor { 944 return r.networkMonitor 945 } 946 947 func (r *Router) InterfaceMonitor() tun.DefaultInterfaceMonitor { 948 return r.interfaceMonitor 949 } 950 951 func (r *Router) PackageManager() tun.PackageManager { 952 return r.packageManager 953 } 954 955 func (r *Router) ClashServer() adapter.ClashServer { 956 return r.clashServer 957 } 958 959 func (r *Router) SetClashServer(server adapter.ClashServer) { 960 r.clashServer = server 961 } 962 963 func (r *Router) V2RayServer() adapter.V2RayServer { 964 return r.v2rayServer 965 } 966 967 func (r *Router) SetV2RayServer(server adapter.V2RayServer) { 968 r.v2rayServer = server 969 } 970 971 func (r *Router) OnPackagesUpdated(packages int, sharedUsers int) { 972 r.logger.Info("updated packages list: ", packages, " packages, ", sharedUsers, " shared users") 973 } 974 975 func (r *Router) NewError(ctx context.Context, err error) { 976 common.Close(err) 977 if E.IsClosedOrCanceled(err) { 978 r.logger.DebugContext(ctx, "connection closed: ", err) 979 return 980 } 981 r.logger.ErrorContext(ctx, err) 982 } 983 984 func (r *Router) notifyNetworkUpdate(event int) { 985 if event == tun.EventNoRoute { 986 r.pauseManager.NetworkPause() 987 r.logger.Error("missing default interface") 988 } else { 989 r.pauseManager.NetworkWake() 990 if C.IsAndroid && r.platformInterface == nil { 991 var vpnStatus string 992 if r.interfaceMonitor.AndroidVPNEnabled() { 993 vpnStatus = "enabled" 994 } else { 995 vpnStatus = "disabled" 996 } 997 r.logger.Info("updated default interface ", r.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", r.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()), ", vpn ", vpnStatus) 998 } else { 999 r.logger.Info("updated default interface ", r.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", r.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified())) 1000 } 1001 } 1002 1003 r.ResetNetwork() 1004 return 1005 } 1006 1007 func (r *Router) ResetNetwork() error { 1008 conntrack.Close() 1009 1010 for _, outbound := range r.outbounds { 1011 listener, isListener := outbound.(adapter.InterfaceUpdateListener) 1012 if isListener { 1013 listener.InterfaceUpdated() 1014 } 1015 } 1016 1017 for _, transport := range r.transports { 1018 transport.Reset() 1019 } 1020 return nil 1021 }