github.com/sagernet/sing-box@v1.9.0-rc.20/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 "runtime" 12 "strings" 13 "time" 14 15 "github.com/sagernet/sing-box/adapter" 16 "github.com/sagernet/sing-box/common/conntrack" 17 "github.com/sagernet/sing-box/common/dialer" 18 "github.com/sagernet/sing-box/common/geoip" 19 "github.com/sagernet/sing-box/common/geosite" 20 "github.com/sagernet/sing-box/common/process" 21 "github.com/sagernet/sing-box/common/sniff" 22 "github.com/sagernet/sing-box/common/taskmonitor" 23 C "github.com/sagernet/sing-box/constant" 24 "github.com/sagernet/sing-box/experimental/libbox/platform" 25 "github.com/sagernet/sing-box/log" 26 "github.com/sagernet/sing-box/option" 27 "github.com/sagernet/sing-box/outbound" 28 "github.com/sagernet/sing-box/transport/fakeip" 29 "github.com/sagernet/sing-dns" 30 "github.com/sagernet/sing-mux" 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 "github.com/sagernet/sing/common/ntp" 43 "github.com/sagernet/sing/common/task" 44 "github.com/sagernet/sing/common/uot" 45 "github.com/sagernet/sing/common/winpowrprof" 46 "github.com/sagernet/sing/service" 47 "github.com/sagernet/sing/service/pause" 48 ) 49 50 var _ adapter.Router = (*Router)(nil) 51 52 type Router struct { 53 ctx context.Context 54 logger log.ContextLogger 55 dnsLogger log.ContextLogger 56 inboundByTag map[string]adapter.Inbound 57 outbounds []adapter.Outbound 58 outboundByTag map[string]adapter.Outbound 59 rules []adapter.Rule 60 defaultDetour string 61 defaultOutboundForConnection adapter.Outbound 62 defaultOutboundForPacketConnection adapter.Outbound 63 needGeoIPDatabase bool 64 needGeositeDatabase bool 65 geoIPOptions option.GeoIPOptions 66 geositeOptions option.GeositeOptions 67 geoIPReader *geoip.Reader 68 geositeReader *geosite.Reader 69 geositeCache map[string]adapter.Rule 70 needFindProcess bool 71 dnsClient *dns.Client 72 defaultDomainStrategy dns.DomainStrategy 73 dnsRules []adapter.DNSRule 74 ruleSets []adapter.RuleSet 75 ruleSetMap map[string]adapter.RuleSet 76 defaultTransport dns.Transport 77 transports []dns.Transport 78 transportMap map[string]dns.Transport 79 transportDomainStrategy map[dns.Transport]dns.DomainStrategy 80 dnsReverseMapping *DNSReverseMapping 81 fakeIPStore adapter.FakeIPStore 82 interfaceFinder *control.DefaultInterfaceFinder 83 autoDetectInterface bool 84 defaultInterface string 85 defaultMark int 86 networkMonitor tun.NetworkUpdateMonitor 87 interfaceMonitor tun.DefaultInterfaceMonitor 88 packageManager tun.PackageManager 89 powerListener winpowrprof.EventListener 90 processSearcher process.Searcher 91 timeService *ntp.Service 92 pauseManager pause.Manager 93 clashServer adapter.ClashServer 94 v2rayServer adapter.V2RayServer 95 platformInterface platform.Interface 96 needWIFIState bool 97 needPackageManager bool 98 wifiState adapter.WIFIState 99 started bool 100 } 101 102 func NewRouter( 103 ctx context.Context, 104 logFactory log.Factory, 105 options option.RouteOptions, 106 dnsOptions option.DNSOptions, 107 ntpOptions option.NTPOptions, 108 inbounds []option.Inbound, 109 platformInterface platform.Interface, 110 ) (*Router, error) { 111 router := &Router{ 112 ctx: ctx, 113 logger: logFactory.NewLogger("router"), 114 dnsLogger: logFactory.NewLogger("dns"), 115 outboundByTag: make(map[string]adapter.Outbound), 116 rules: make([]adapter.Rule, 0, len(options.Rules)), 117 dnsRules: make([]adapter.DNSRule, 0, len(dnsOptions.Rules)), 118 ruleSetMap: make(map[string]adapter.RuleSet), 119 needGeoIPDatabase: hasRule(options.Rules, isGeoIPRule) || hasDNSRule(dnsOptions.Rules, isGeoIPDNSRule), 120 needGeositeDatabase: hasRule(options.Rules, isGeositeRule) || hasDNSRule(dnsOptions.Rules, isGeositeDNSRule), 121 geoIPOptions: common.PtrValueOrDefault(options.GeoIP), 122 geositeOptions: common.PtrValueOrDefault(options.Geosite), 123 geositeCache: make(map[string]adapter.Rule), 124 needFindProcess: hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess, 125 defaultDetour: options.Final, 126 defaultDomainStrategy: dns.DomainStrategy(dnsOptions.Strategy), 127 interfaceFinder: control.NewDefaultInterfaceFinder(), 128 autoDetectInterface: options.AutoDetectInterface, 129 defaultInterface: options.DefaultInterface, 130 defaultMark: options.DefaultMark, 131 pauseManager: service.FromContext[pause.Manager](ctx), 132 platformInterface: platformInterface, 133 needWIFIState: hasRule(options.Rules, isWIFIRule) || hasDNSRule(dnsOptions.Rules, isWIFIDNSRule), 134 needPackageManager: C.IsAndroid && platformInterface == nil && common.Any(inbounds, func(inbound option.Inbound) bool { 135 return len(inbound.TunOptions.IncludePackage) > 0 || len(inbound.TunOptions.ExcludePackage) > 0 136 }), 137 } 138 router.dnsClient = dns.NewClient(dns.ClientOptions{ 139 DisableCache: dnsOptions.DNSClientOptions.DisableCache, 140 DisableExpire: dnsOptions.DNSClientOptions.DisableExpire, 141 IndependentCache: dnsOptions.DNSClientOptions.IndependentCache, 142 RDRC: func() dns.RDRCStore { 143 cacheFile := service.FromContext[adapter.CacheFile](ctx) 144 if cacheFile == nil { 145 return nil 146 } 147 if !cacheFile.StoreRDRC() { 148 return nil 149 } 150 return cacheFile 151 }, 152 Logger: router.dnsLogger, 153 }) 154 for i, ruleOptions := range options.Rules { 155 routeRule, err := NewRule(router, router.logger, ruleOptions, true) 156 if err != nil { 157 return nil, E.Cause(err, "parse rule[", i, "]") 158 } 159 router.rules = append(router.rules, routeRule) 160 } 161 for i, dnsRuleOptions := range dnsOptions.Rules { 162 dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions, true) 163 if err != nil { 164 return nil, E.Cause(err, "parse dns rule[", i, "]") 165 } 166 router.dnsRules = append(router.dnsRules, dnsRule) 167 } 168 for i, ruleSetOptions := range options.RuleSet { 169 if _, exists := router.ruleSetMap[ruleSetOptions.Tag]; exists { 170 return nil, E.New("duplicate rule-set tag: ", ruleSetOptions.Tag) 171 } 172 ruleSet, err := NewRuleSet(ctx, router, router.logger, ruleSetOptions) 173 if err != nil { 174 return nil, E.Cause(err, "parse rule-set[", i, "]") 175 } 176 router.ruleSets = append(router.ruleSets, ruleSet) 177 router.ruleSetMap[ruleSetOptions.Tag] = ruleSet 178 } 179 180 transports := make([]dns.Transport, len(dnsOptions.Servers)) 181 dummyTransportMap := make(map[string]dns.Transport) 182 transportMap := make(map[string]dns.Transport) 183 transportTags := make([]string, len(dnsOptions.Servers)) 184 transportTagMap := make(map[string]bool) 185 transportDomainStrategy := make(map[dns.Transport]dns.DomainStrategy) 186 for i, server := range dnsOptions.Servers { 187 var tag string 188 if server.Tag != "" { 189 tag = server.Tag 190 } else { 191 tag = F.ToString(i) 192 } 193 if transportTagMap[tag] { 194 return nil, E.New("duplicate dns server tag: ", tag) 195 } 196 transportTags[i] = tag 197 transportTagMap[tag] = true 198 } 199 ctx = adapter.ContextWithRouter(ctx, router) 200 for { 201 lastLen := len(dummyTransportMap) 202 for i, server := range dnsOptions.Servers { 203 tag := transportTags[i] 204 if _, exists := dummyTransportMap[tag]; exists { 205 continue 206 } 207 var detour N.Dialer 208 if server.Detour == "" { 209 detour = dialer.NewRouter(router) 210 } else { 211 detour = dialer.NewDetour(router, server.Detour) 212 } 213 switch server.Address { 214 case "local": 215 default: 216 serverURL, _ := url.Parse(server.Address) 217 var serverAddress string 218 if serverURL != nil { 219 serverAddress = serverURL.Hostname() 220 } 221 if serverAddress == "" { 222 serverAddress = server.Address 223 } 224 _, notIpAddress := netip.ParseAddr(serverAddress) 225 if server.AddressResolver != "" { 226 if !transportTagMap[server.AddressResolver] { 227 return nil, E.New("parse dns server[", tag, "]: address resolver not found: ", server.AddressResolver) 228 } 229 if upstream, exists := dummyTransportMap[server.AddressResolver]; exists { 230 detour = dns.NewDialerWrapper(detour, router.dnsClient, upstream, dns.DomainStrategy(server.AddressStrategy), time.Duration(server.AddressFallbackDelay)) 231 } else { 232 continue 233 } 234 } else if notIpAddress != nil && strings.Contains(server.Address, ".") { 235 return nil, E.New("parse dns server[", tag, "]: missing address_resolver") 236 } 237 } 238 var clientSubnet netip.Prefix 239 if server.ClientSubnet != nil { 240 clientSubnet = server.ClientSubnet.Build() 241 } else if dnsOptions.ClientSubnet != nil { 242 clientSubnet = dnsOptions.ClientSubnet.Build() 243 } 244 transport, err := dns.CreateTransport(dns.TransportOptions{ 245 Context: ctx, 246 Logger: logFactory.NewLogger(F.ToString("dns/transport[", tag, "]")), 247 Name: tag, 248 Dialer: detour, 249 Address: server.Address, 250 ClientSubnet: clientSubnet, 251 }) 252 if err != nil { 253 return nil, E.Cause(err, "parse dns server[", tag, "]") 254 } 255 transports[i] = transport 256 dummyTransportMap[tag] = transport 257 if server.Tag != "" { 258 transportMap[server.Tag] = transport 259 } 260 strategy := dns.DomainStrategy(server.Strategy) 261 if strategy != dns.DomainStrategyAsIS { 262 transportDomainStrategy[transport] = strategy 263 } 264 } 265 if len(transports) == len(dummyTransportMap) { 266 break 267 } 268 if lastLen != len(dummyTransportMap) { 269 continue 270 } 271 unresolvedTags := common.MapIndexed(common.FilterIndexed(dnsOptions.Servers, func(index int, server option.DNSServerOptions) bool { 272 _, exists := dummyTransportMap[transportTags[index]] 273 return !exists 274 }), func(index int, server option.DNSServerOptions) string { 275 return transportTags[index] 276 }) 277 if len(unresolvedTags) == 0 { 278 panic(F.ToString("unexpected unresolved dns servers: ", len(transports), " ", len(dummyTransportMap), " ", len(transportMap))) 279 } 280 return nil, E.New("found circular reference in dns servers: ", strings.Join(unresolvedTags, " ")) 281 } 282 var defaultTransport dns.Transport 283 if dnsOptions.Final != "" { 284 defaultTransport = dummyTransportMap[dnsOptions.Final] 285 if defaultTransport == nil { 286 return nil, E.New("default dns server not found: ", dnsOptions.Final) 287 } 288 } 289 if defaultTransport == nil { 290 if len(transports) == 0 { 291 transports = append(transports, common.Must1(dns.CreateTransport(dns.TransportOptions{ 292 Context: ctx, 293 Name: "local", 294 Address: "local", 295 Dialer: common.Must1(dialer.NewDefault(router, option.DialerOptions{})), 296 }))) 297 } 298 defaultTransport = transports[0] 299 } 300 if _, isFakeIP := defaultTransport.(adapter.FakeIPTransport); isFakeIP { 301 return nil, E.New("default DNS server cannot be fakeip") 302 } 303 router.defaultTransport = defaultTransport 304 router.transports = transports 305 router.transportMap = transportMap 306 router.transportDomainStrategy = transportDomainStrategy 307 308 if dnsOptions.ReverseMapping { 309 router.dnsReverseMapping = NewDNSReverseMapping() 310 } 311 312 if fakeIPOptions := dnsOptions.FakeIP; fakeIPOptions != nil && dnsOptions.FakeIP.Enabled { 313 var inet4Range netip.Prefix 314 var inet6Range netip.Prefix 315 if fakeIPOptions.Inet4Range != nil { 316 inet4Range = *fakeIPOptions.Inet4Range 317 } 318 if fakeIPOptions.Inet6Range != nil { 319 inet6Range = *fakeIPOptions.Inet6Range 320 } 321 router.fakeIPStore = fakeip.NewStore(ctx, router.logger, inet4Range, inet6Range) 322 } 323 324 usePlatformDefaultInterfaceMonitor := platformInterface != nil && platformInterface.UsePlatformDefaultInterfaceMonitor() 325 needInterfaceMonitor := options.AutoDetectInterface || common.Any(inbounds, func(inbound option.Inbound) bool { 326 return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy || inbound.TunOptions.AutoRoute 327 }) 328 329 if !usePlatformDefaultInterfaceMonitor { 330 networkMonitor, err := tun.NewNetworkUpdateMonitor(router.logger) 331 if !((err != nil && !needInterfaceMonitor) || errors.Is(err, os.ErrInvalid)) { 332 if err != nil { 333 return nil, err 334 } 335 router.networkMonitor = networkMonitor 336 networkMonitor.RegisterCallback(func() { 337 _ = router.interfaceFinder.Update() 338 }) 339 interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor, router.logger, tun.DefaultInterfaceMonitorOptions{ 340 OverrideAndroidVPN: options.OverrideAndroidVPN, 341 UnderNetworkExtension: platformInterface != nil && platformInterface.UnderNetworkExtension(), 342 }) 343 if err != nil { 344 return nil, E.New("auto_detect_interface unsupported on current platform") 345 } 346 interfaceMonitor.RegisterCallback(router.notifyNetworkUpdate) 347 router.interfaceMonitor = interfaceMonitor 348 } 349 } else { 350 interfaceMonitor := platformInterface.CreateDefaultInterfaceMonitor(router.logger) 351 interfaceMonitor.RegisterCallback(router.notifyNetworkUpdate) 352 router.interfaceMonitor = interfaceMonitor 353 } 354 355 if runtime.GOOS == "windows" { 356 powerListener, err := winpowrprof.NewEventListener(router.notifyWindowsPowerEvent) 357 if err != nil { 358 return nil, E.Cause(err, "initialize power listener") 359 } 360 router.powerListener = powerListener 361 } 362 363 if ntpOptions.Enabled { 364 ntpDialer, err := dialer.New(router, ntpOptions.DialerOptions) 365 if err != nil { 366 return nil, E.Cause(err, "create NTP service") 367 } 368 timeService := ntp.NewService(ntp.Options{ 369 Context: ctx, 370 Dialer: ntpDialer, 371 Logger: logFactory.NewLogger("ntp"), 372 Server: ntpOptions.ServerOptions.Build(), 373 Interval: time.Duration(ntpOptions.Interval), 374 WriteToSystem: ntpOptions.WriteToSystem, 375 }) 376 service.MustRegister[ntp.TimeService](ctx, timeService) 377 router.timeService = timeService 378 } 379 return router, nil 380 } 381 382 func (r *Router) Initialize(inbounds []adapter.Inbound, outbounds []adapter.Outbound, defaultOutbound func() adapter.Outbound) error { 383 inboundByTag := make(map[string]adapter.Inbound) 384 for _, inbound := range inbounds { 385 inboundByTag[inbound.Tag()] = inbound 386 } 387 outboundByTag := make(map[string]adapter.Outbound) 388 for _, detour := range outbounds { 389 outboundByTag[detour.Tag()] = detour 390 } 391 var defaultOutboundForConnection adapter.Outbound 392 var defaultOutboundForPacketConnection adapter.Outbound 393 if r.defaultDetour != "" { 394 detour, loaded := outboundByTag[r.defaultDetour] 395 if !loaded { 396 return E.New("default detour not found: ", r.defaultDetour) 397 } 398 if common.Contains(detour.Network(), N.NetworkTCP) { 399 defaultOutboundForConnection = detour 400 } 401 if common.Contains(detour.Network(), N.NetworkUDP) { 402 defaultOutboundForPacketConnection = detour 403 } 404 } 405 var index, packetIndex int 406 if defaultOutboundForConnection == nil { 407 for i, detour := range outbounds { 408 if common.Contains(detour.Network(), N.NetworkTCP) { 409 index = i 410 defaultOutboundForConnection = detour 411 break 412 } 413 } 414 } 415 if defaultOutboundForPacketConnection == nil { 416 for i, detour := range outbounds { 417 if common.Contains(detour.Network(), N.NetworkUDP) { 418 packetIndex = i 419 defaultOutboundForPacketConnection = detour 420 break 421 } 422 } 423 } 424 if defaultOutboundForConnection == nil || defaultOutboundForPacketConnection == nil { 425 detour := defaultOutbound() 426 if defaultOutboundForConnection == nil { 427 defaultOutboundForConnection = detour 428 } 429 if defaultOutboundForPacketConnection == nil { 430 defaultOutboundForPacketConnection = detour 431 } 432 outbounds = append(outbounds, detour) 433 outboundByTag[detour.Tag()] = detour 434 } 435 if defaultOutboundForConnection != defaultOutboundForPacketConnection { 436 var description string 437 if defaultOutboundForConnection.Tag() != "" { 438 description = defaultOutboundForConnection.Tag() 439 } else { 440 description = F.ToString(index) 441 } 442 var packetDescription string 443 if defaultOutboundForPacketConnection.Tag() != "" { 444 packetDescription = defaultOutboundForPacketConnection.Tag() 445 } else { 446 packetDescription = F.ToString(packetIndex) 447 } 448 r.logger.Info("using ", defaultOutboundForConnection.Type(), "[", description, "] as default outbound for connection") 449 r.logger.Info("using ", defaultOutboundForPacketConnection.Type(), "[", packetDescription, "] as default outbound for packet connection") 450 } 451 r.inboundByTag = inboundByTag 452 r.outbounds = outbounds 453 r.defaultOutboundForConnection = defaultOutboundForConnection 454 r.defaultOutboundForPacketConnection = defaultOutboundForPacketConnection 455 r.outboundByTag = outboundByTag 456 for i, rule := range r.rules { 457 if _, loaded := outboundByTag[rule.Outbound()]; !loaded { 458 return E.New("outbound not found for rule[", i, "]: ", rule.Outbound()) 459 } 460 } 461 return nil 462 } 463 464 func (r *Router) Outbounds() []adapter.Outbound { 465 if !r.started { 466 return nil 467 } 468 return r.outbounds 469 } 470 471 func (r *Router) PreStart() error { 472 monitor := taskmonitor.New(r.logger, C.StartTimeout) 473 if r.interfaceMonitor != nil { 474 monitor.Start("initialize interface monitor") 475 err := r.interfaceMonitor.Start() 476 monitor.Finish() 477 if err != nil { 478 return err 479 } 480 } 481 if r.networkMonitor != nil { 482 monitor.Start("initialize network monitor") 483 err := r.networkMonitor.Start() 484 monitor.Finish() 485 if err != nil { 486 return err 487 } 488 } 489 if r.fakeIPStore != nil { 490 monitor.Start("initialize fakeip store") 491 err := r.fakeIPStore.Start() 492 monitor.Finish() 493 if err != nil { 494 return err 495 } 496 } 497 return nil 498 } 499 500 func (r *Router) Start() error { 501 monitor := taskmonitor.New(r.logger, C.StartTimeout) 502 if r.needGeoIPDatabase { 503 monitor.Start("initialize geoip database") 504 err := r.prepareGeoIPDatabase() 505 monitor.Finish() 506 if err != nil { 507 return err 508 } 509 } 510 if r.needGeositeDatabase { 511 monitor.Start("initialize geosite database") 512 err := r.prepareGeositeDatabase() 513 monitor.Finish() 514 if err != nil { 515 return err 516 } 517 } 518 if r.needGeositeDatabase { 519 for _, rule := range r.rules { 520 err := rule.UpdateGeosite() 521 if err != nil { 522 r.logger.Error("failed to initialize geosite: ", err) 523 } 524 } 525 for _, rule := range r.dnsRules { 526 err := rule.UpdateGeosite() 527 if err != nil { 528 r.logger.Error("failed to initialize geosite: ", err) 529 } 530 } 531 err := common.Close(r.geositeReader) 532 if err != nil { 533 return err 534 } 535 r.geositeCache = nil 536 r.geositeReader = nil 537 } 538 539 if len(r.ruleSets) > 0 { 540 monitor.Start("initialize rule-set") 541 ruleSetStartContext := NewRuleSetStartContext() 542 var ruleSetStartGroup task.Group 543 for i, ruleSet := range r.ruleSets { 544 ruleSetInPlace := ruleSet 545 ruleSetStartGroup.Append0(func(ctx context.Context) error { 546 err := ruleSetInPlace.StartContext(ctx, ruleSetStartContext) 547 if err != nil { 548 return E.Cause(err, "initialize rule-set[", i, "]") 549 } 550 return nil 551 }) 552 } 553 ruleSetStartGroup.Concurrency(5) 554 ruleSetStartGroup.FastFail() 555 err := ruleSetStartGroup.Run(r.ctx) 556 monitor.Finish() 557 if err != nil { 558 return err 559 } 560 ruleSetStartContext.Close() 561 } 562 var ( 563 needProcessFromRuleSet bool 564 needWIFIStateFromRuleSet bool 565 ) 566 for _, ruleSet := range r.ruleSets { 567 metadata := ruleSet.Metadata() 568 if metadata.ContainsProcessRule { 569 needProcessFromRuleSet = true 570 } 571 if metadata.ContainsWIFIRule { 572 needWIFIStateFromRuleSet = true 573 } 574 } 575 if needProcessFromRuleSet || r.needFindProcess || r.needPackageManager { 576 if C.IsAndroid && r.platformInterface == nil { 577 monitor.Start("initialize package manager") 578 packageManager, err := tun.NewPackageManager(r) 579 monitor.Finish() 580 if err != nil { 581 return E.Cause(err, "create package manager") 582 } 583 monitor.Start("start package manager") 584 err = packageManager.Start() 585 monitor.Finish() 586 if err != nil { 587 return E.Cause(err, "start package manager") 588 } 589 r.packageManager = packageManager 590 } 591 592 if r.platformInterface != nil { 593 r.processSearcher = r.platformInterface 594 } else { 595 monitor.Start("initialize process searcher") 596 searcher, err := process.NewSearcher(process.Config{ 597 Logger: r.logger, 598 PackageManager: r.packageManager, 599 }) 600 monitor.Finish() 601 if err != nil { 602 if err != os.ErrInvalid { 603 r.logger.Warn(E.Cause(err, "create process searcher")) 604 } 605 } else { 606 r.processSearcher = searcher 607 } 608 } 609 } 610 611 if r.powerListener != nil { 612 monitor.Start("start power listener") 613 err := r.powerListener.Start() 614 monitor.Finish() 615 if err != nil { 616 return E.Cause(err, "start power listener") 617 } 618 } 619 620 if (needWIFIStateFromRuleSet || r.needWIFIState) && r.platformInterface != nil { 621 monitor.Start("initialize WIFI state") 622 r.needWIFIState = true 623 r.interfaceMonitor.RegisterCallback(func(_ int) { 624 r.updateWIFIState() 625 }) 626 r.updateWIFIState() 627 monitor.Finish() 628 } 629 630 for i, rule := range r.rules { 631 monitor.Start("initialize rule[", i, "]") 632 err := rule.Start() 633 monitor.Finish() 634 if err != nil { 635 return E.Cause(err, "initialize rule[", i, "]") 636 } 637 } 638 639 monitor.Start("initialize DNS client") 640 r.dnsClient.Start() 641 monitor.Finish() 642 643 for i, rule := range r.dnsRules { 644 monitor.Start("initialize DNS rule[", i, "]") 645 err := rule.Start() 646 monitor.Finish() 647 if err != nil { 648 return E.Cause(err, "initialize DNS rule[", i, "]") 649 } 650 } 651 for i, transport := range r.transports { 652 monitor.Start("initialize DNS transport[", i, "]") 653 err := transport.Start() 654 monitor.Finish() 655 if err != nil { 656 return E.Cause(err, "initialize DNS server[", i, "]") 657 } 658 } 659 if r.timeService != nil { 660 monitor.Start("initialize time service") 661 err := r.timeService.Start() 662 monitor.Finish() 663 if err != nil { 664 return E.Cause(err, "initialize time service") 665 } 666 } 667 return nil 668 } 669 670 func (r *Router) Close() error { 671 monitor := taskmonitor.New(r.logger, C.StopTimeout) 672 var err error 673 for i, rule := range r.rules { 674 monitor.Start("close rule[", i, "]") 675 err = E.Append(err, rule.Close(), func(err error) error { 676 return E.Cause(err, "close rule[", i, "]") 677 }) 678 monitor.Finish() 679 } 680 for i, rule := range r.dnsRules { 681 monitor.Start("close dns rule[", i, "]") 682 err = E.Append(err, rule.Close(), func(err error) error { 683 return E.Cause(err, "close dns rule[", i, "]") 684 }) 685 monitor.Finish() 686 } 687 for i, transport := range r.transports { 688 monitor.Start("close dns transport[", i, "]") 689 err = E.Append(err, transport.Close(), func(err error) error { 690 return E.Cause(err, "close dns transport[", i, "]") 691 }) 692 monitor.Finish() 693 } 694 if r.geoIPReader != nil { 695 monitor.Start("close geoip reader") 696 err = E.Append(err, r.geoIPReader.Close(), func(err error) error { 697 return E.Cause(err, "close geoip reader") 698 }) 699 monitor.Finish() 700 } 701 if r.interfaceMonitor != nil { 702 monitor.Start("close interface monitor") 703 err = E.Append(err, r.interfaceMonitor.Close(), func(err error) error { 704 return E.Cause(err, "close interface monitor") 705 }) 706 monitor.Finish() 707 } 708 if r.networkMonitor != nil { 709 monitor.Start("close network monitor") 710 err = E.Append(err, r.networkMonitor.Close(), func(err error) error { 711 return E.Cause(err, "close network monitor") 712 }) 713 monitor.Finish() 714 } 715 if r.packageManager != nil { 716 monitor.Start("close package manager") 717 err = E.Append(err, r.packageManager.Close(), func(err error) error { 718 return E.Cause(err, "close package manager") 719 }) 720 monitor.Finish() 721 } 722 if r.powerListener != nil { 723 monitor.Start("close power listener") 724 err = E.Append(err, r.powerListener.Close(), func(err error) error { 725 return E.Cause(err, "close power listener") 726 }) 727 monitor.Finish() 728 } 729 if r.timeService != nil { 730 monitor.Start("close time service") 731 err = E.Append(err, r.timeService.Close(), func(err error) error { 732 return E.Cause(err, "close time service") 733 }) 734 monitor.Finish() 735 } 736 if r.fakeIPStore != nil { 737 monitor.Start("close fakeip store") 738 err = E.Append(err, r.fakeIPStore.Close(), func(err error) error { 739 return E.Cause(err, "close fakeip store") 740 }) 741 monitor.Finish() 742 } 743 return err 744 } 745 746 func (r *Router) PostStart() error { 747 if len(r.ruleSets) > 0 { 748 for i, ruleSet := range r.ruleSets { 749 err := ruleSet.PostStart() 750 if err != nil { 751 return E.Cause(err, "post start rule-set[", i, "]") 752 } 753 } 754 } 755 r.started = true 756 return nil 757 } 758 759 func (r *Router) Outbound(tag string) (adapter.Outbound, bool) { 760 outbound, loaded := r.outboundByTag[tag] 761 return outbound, loaded 762 } 763 764 func (r *Router) DefaultOutbound(network string) (adapter.Outbound, error) { 765 if network == N.NetworkTCP { 766 if r.defaultOutboundForConnection == nil { 767 return nil, E.New("missing default outbound for TCP connections") 768 } 769 return r.defaultOutboundForConnection, nil 770 } else { 771 if r.defaultOutboundForPacketConnection == nil { 772 return nil, E.New("missing default outbound for UDP connections") 773 } 774 return r.defaultOutboundForPacketConnection, nil 775 } 776 } 777 778 func (r *Router) FakeIPStore() adapter.FakeIPStore { 779 return r.fakeIPStore 780 } 781 782 func (r *Router) RuleSet(tag string) (adapter.RuleSet, bool) { 783 ruleSet, loaded := r.ruleSetMap[tag] 784 return ruleSet, loaded 785 } 786 787 func (r *Router) NeedWIFIState() bool { 788 return r.needWIFIState 789 } 790 791 func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 792 if r.pauseManager.IsDevicePaused() { 793 return E.New("reject connection to ", metadata.Destination, " while device paused") 794 } 795 796 if metadata.InboundDetour != "" { 797 if metadata.LastInbound == metadata.InboundDetour { 798 return E.New("routing loop on detour: ", metadata.InboundDetour) 799 } 800 detour := r.inboundByTag[metadata.InboundDetour] 801 if detour == nil { 802 return E.New("inbound detour not found: ", metadata.InboundDetour) 803 } 804 injectable, isInjectable := detour.(adapter.InjectableInbound) 805 if !isInjectable { 806 return E.New("inbound detour is not injectable: ", metadata.InboundDetour) 807 } 808 if !common.Contains(injectable.Network(), N.NetworkTCP) { 809 return E.New("inject: TCP unsupported") 810 } 811 metadata.LastInbound = metadata.Inbound 812 metadata.Inbound = metadata.InboundDetour 813 metadata.InboundDetour = "" 814 err := injectable.NewConnection(ctx, conn, metadata) 815 if err != nil { 816 return E.Cause(err, "inject ", detour.Tag()) 817 } 818 return nil 819 } 820 conntrack.KillerCheck() 821 metadata.Network = N.NetworkTCP 822 switch metadata.Destination.Fqdn { 823 case mux.Destination.Fqdn: 824 return E.New("global multiplex is deprecated since sing-box v1.7.0, enable multiplex in inbound options instead.") 825 case vmess.MuxDestination.Fqdn: 826 return E.New("global multiplex (v2ray legacy) not supported since sing-box v1.7.0.") 827 case uot.MagicAddress: 828 return E.New("global UoT not supported since sing-box v1.7.0.") 829 case uot.LegacyMagicAddress: 830 return E.New("global UoT (legacy) not supported since sing-box v1.7.0.") 831 } 832 833 if r.fakeIPStore != nil && r.fakeIPStore.Contains(metadata.Destination.Addr) { 834 domain, loaded := r.fakeIPStore.Lookup(metadata.Destination.Addr) 835 if !loaded { 836 return E.New("missing fakeip context") 837 } 838 metadata.OriginDestination = metadata.Destination 839 metadata.Destination = M.Socksaddr{ 840 Fqdn: domain, 841 Port: metadata.Destination.Port, 842 } 843 metadata.FakeIP = true 844 r.logger.DebugContext(ctx, "found fakeip domain: ", domain) 845 } 846 847 if deadline.NeedAdditionalReadDeadline(conn) { 848 conn = deadline.NewConn(conn) 849 } 850 851 if metadata.InboundOptions.SniffEnabled { 852 buffer := buf.NewPacket() 853 sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost) 854 if sniffMetadata != nil { 855 metadata.Protocol = sniffMetadata.Protocol 856 metadata.Domain = sniffMetadata.Domain 857 if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) { 858 metadata.Destination = M.Socksaddr{ 859 Fqdn: metadata.Domain, 860 Port: metadata.Destination.Port, 861 } 862 } 863 if metadata.Domain != "" { 864 r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol, ", domain: ", metadata.Domain) 865 } else { 866 r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol) 867 } 868 } else if err != nil { 869 r.logger.TraceContext(ctx, "sniffed no protocol: ", err) 870 } 871 if !buffer.IsEmpty() { 872 conn = bufio.NewCachedConn(conn, buffer) 873 } else { 874 buffer.Release() 875 } 876 } 877 878 if r.dnsReverseMapping != nil && metadata.Domain == "" { 879 domain, loaded := r.dnsReverseMapping.Query(metadata.Destination.Addr) 880 if loaded { 881 metadata.Domain = domain 882 r.logger.DebugContext(ctx, "found reserve mapped domain: ", metadata.Domain) 883 } 884 } 885 886 if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS { 887 addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)) 888 if err != nil { 889 return err 890 } 891 metadata.DestinationAddresses = addresses 892 r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]") 893 } 894 if metadata.Destination.IsIPv4() { 895 metadata.IPVersion = 4 896 } else if metadata.Destination.IsIPv6() { 897 metadata.IPVersion = 6 898 } 899 ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForConnection) 900 if err != nil { 901 return err 902 } 903 if !common.Contains(detour.Network(), N.NetworkTCP) { 904 return E.New("missing supported outbound, closing connection") 905 } 906 if r.clashServer != nil { 907 trackerConn, tracker := r.clashServer.RoutedConnection(ctx, conn, metadata, matchedRule) 908 defer tracker.Leave() 909 conn = trackerConn 910 } 911 if r.v2rayServer != nil { 912 if statsService := r.v2rayServer.StatsService(); statsService != nil { 913 conn = statsService.RoutedConnection(metadata.Inbound, detour.Tag(), metadata.User, conn) 914 } 915 } 916 return detour.NewConnection(ctx, conn, metadata) 917 } 918 919 func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 920 if r.pauseManager.IsDevicePaused() { 921 return E.New("reject packet connection to ", metadata.Destination, " while device paused") 922 } 923 if metadata.InboundDetour != "" { 924 if metadata.LastInbound == metadata.InboundDetour { 925 return E.New("routing loop on detour: ", metadata.InboundDetour) 926 } 927 detour := r.inboundByTag[metadata.InboundDetour] 928 if detour == nil { 929 return E.New("inbound detour not found: ", metadata.InboundDetour) 930 } 931 injectable, isInjectable := detour.(adapter.InjectableInbound) 932 if !isInjectable { 933 return E.New("inbound detour is not injectable: ", metadata.InboundDetour) 934 } 935 if !common.Contains(injectable.Network(), N.NetworkUDP) { 936 return E.New("inject: UDP unsupported") 937 } 938 metadata.LastInbound = metadata.Inbound 939 metadata.Inbound = metadata.InboundDetour 940 metadata.InboundDetour = "" 941 err := injectable.NewPacketConnection(ctx, conn, metadata) 942 if err != nil { 943 return E.Cause(err, "inject ", detour.Tag()) 944 } 945 return nil 946 } 947 conntrack.KillerCheck() 948 metadata.Network = N.NetworkUDP 949 950 if r.fakeIPStore != nil && r.fakeIPStore.Contains(metadata.Destination.Addr) { 951 domain, loaded := r.fakeIPStore.Lookup(metadata.Destination.Addr) 952 if !loaded { 953 return E.New("missing fakeip context") 954 } 955 metadata.OriginDestination = metadata.Destination 956 metadata.Destination = M.Socksaddr{ 957 Fqdn: domain, 958 Port: metadata.Destination.Port, 959 } 960 metadata.FakeIP = true 961 r.logger.DebugContext(ctx, "found fakeip domain: ", domain) 962 } 963 964 // Currently we don't have deadline usages for UDP connections 965 /*if deadline.NeedAdditionalReadDeadline(conn) { 966 conn = deadline.NewPacketConn(bufio.NewNetPacketConn(conn)) 967 }*/ 968 969 if metadata.InboundOptions.SniffEnabled || metadata.Destination.Addr.IsUnspecified() { 970 buffer := buf.NewPacket() 971 destination, err := conn.ReadPacket(buffer) 972 if err != nil { 973 buffer.Release() 974 return err 975 } 976 if metadata.Destination.Addr.IsUnspecified() { 977 metadata.Destination = destination 978 } 979 if metadata.InboundOptions.SniffEnabled { 980 sniffMetadata, _ := sniff.PeekPacket(ctx, buffer.Bytes(), sniff.DomainNameQuery, sniff.QUICClientHello, sniff.STUNMessage) 981 if sniffMetadata != nil { 982 metadata.Protocol = sniffMetadata.Protocol 983 metadata.Domain = sniffMetadata.Domain 984 if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) { 985 metadata.Destination = M.Socksaddr{ 986 Fqdn: metadata.Domain, 987 Port: metadata.Destination.Port, 988 } 989 } 990 if metadata.Domain != "" { 991 r.logger.DebugContext(ctx, "sniffed packet protocol: ", metadata.Protocol, ", domain: ", metadata.Domain) 992 } else { 993 r.logger.DebugContext(ctx, "sniffed packet protocol: ", metadata.Protocol) 994 } 995 } 996 } 997 conn = bufio.NewCachedPacketConn(conn, buffer, destination) 998 } 999 if r.dnsReverseMapping != nil && metadata.Domain == "" { 1000 domain, loaded := r.dnsReverseMapping.Query(metadata.Destination.Addr) 1001 if loaded { 1002 metadata.Domain = domain 1003 r.logger.DebugContext(ctx, "found reserve mapped domain: ", metadata.Domain) 1004 } 1005 } 1006 if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS { 1007 addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)) 1008 if err != nil { 1009 return err 1010 } 1011 metadata.DestinationAddresses = addresses 1012 r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]") 1013 } 1014 if metadata.Destination.IsIPv4() { 1015 metadata.IPVersion = 4 1016 } else if metadata.Destination.IsIPv6() { 1017 metadata.IPVersion = 6 1018 } 1019 ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForPacketConnection) 1020 if err != nil { 1021 return err 1022 } 1023 if !common.Contains(detour.Network(), N.NetworkUDP) { 1024 return E.New("missing supported outbound, closing packet connection") 1025 } 1026 if r.clashServer != nil { 1027 trackerConn, tracker := r.clashServer.RoutedPacketConnection(ctx, conn, metadata, matchedRule) 1028 defer tracker.Leave() 1029 conn = trackerConn 1030 } 1031 if r.v2rayServer != nil { 1032 if statsService := r.v2rayServer.StatsService(); statsService != nil { 1033 conn = statsService.RoutedPacketConnection(metadata.Inbound, detour.Tag(), metadata.User, conn) 1034 } 1035 } 1036 if metadata.FakeIP { 1037 conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), metadata.OriginDestination, metadata.Destination) 1038 } 1039 return detour.NewPacketConnection(ctx, conn, metadata) 1040 } 1041 1042 func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, defaultOutbound adapter.Outbound) (context.Context, adapter.Rule, adapter.Outbound, error) { 1043 matchRule, matchOutbound := r.match0(ctx, metadata, defaultOutbound) 1044 if contextOutbound, loaded := outbound.TagFromContext(ctx); loaded { 1045 if contextOutbound == matchOutbound.Tag() { 1046 return nil, nil, nil, E.New("connection loopback in outbound/", matchOutbound.Type(), "[", matchOutbound.Tag(), "]") 1047 } 1048 } 1049 ctx = outbound.ContextWithTag(ctx, matchOutbound.Tag()) 1050 return ctx, matchRule, matchOutbound, nil 1051 } 1052 1053 func (r *Router) match0(ctx context.Context, metadata *adapter.InboundContext, defaultOutbound adapter.Outbound) (adapter.Rule, adapter.Outbound) { 1054 if r.processSearcher != nil { 1055 var originDestination netip.AddrPort 1056 if metadata.OriginDestination.IsValid() { 1057 originDestination = metadata.OriginDestination.AddrPort() 1058 } else if metadata.Destination.IsIP() { 1059 originDestination = metadata.Destination.AddrPort() 1060 } 1061 processInfo, err := process.FindProcessInfo(r.processSearcher, ctx, metadata.Network, metadata.Source.AddrPort(), originDestination) 1062 if err != nil { 1063 r.logger.InfoContext(ctx, "failed to search process: ", err) 1064 } else { 1065 if processInfo.ProcessPath != "" { 1066 r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath) 1067 } else if processInfo.PackageName != "" { 1068 r.logger.InfoContext(ctx, "found package name: ", processInfo.PackageName) 1069 } else if processInfo.UserId != -1 { 1070 if /*needUserName &&*/ true { 1071 osUser, _ := user.LookupId(F.ToString(processInfo.UserId)) 1072 if osUser != nil { 1073 processInfo.User = osUser.Username 1074 } 1075 } 1076 if processInfo.User != "" { 1077 r.logger.InfoContext(ctx, "found user: ", processInfo.User) 1078 } else { 1079 r.logger.InfoContext(ctx, "found user id: ", processInfo.UserId) 1080 } 1081 } 1082 metadata.ProcessInfo = processInfo 1083 } 1084 } 1085 for i, rule := range r.rules { 1086 metadata.ResetRuleCache() 1087 if rule.Match(metadata) { 1088 detour := rule.Outbound() 1089 r.logger.DebugContext(ctx, "match[", i, "] ", rule.String(), " => ", detour) 1090 if outbound, loaded := r.Outbound(detour); loaded { 1091 return rule, outbound 1092 } 1093 r.logger.ErrorContext(ctx, "outbound not found: ", detour) 1094 } 1095 } 1096 return nil, defaultOutbound 1097 } 1098 1099 func (r *Router) InterfaceFinder() control.InterfaceFinder { 1100 return r.interfaceFinder 1101 } 1102 1103 func (r *Router) UpdateInterfaces() error { 1104 if r.platformInterface == nil || !r.platformInterface.UsePlatformInterfaceGetter() { 1105 return r.interfaceFinder.Update() 1106 } else { 1107 interfaces, err := r.platformInterface.Interfaces() 1108 if err != nil { 1109 return err 1110 } 1111 r.interfaceFinder.UpdateInterfaces(interfaces) 1112 return nil 1113 } 1114 } 1115 1116 func (r *Router) AutoDetectInterface() bool { 1117 return r.autoDetectInterface 1118 } 1119 1120 func (r *Router) AutoDetectInterfaceFunc() control.Func { 1121 if r.platformInterface != nil && r.platformInterface.UsePlatformAutoDetectInterfaceControl() { 1122 return r.platformInterface.AutoDetectInterfaceControl() 1123 } else { 1124 return control.BindToInterfaceFunc(r.InterfaceFinder(), func(network string, address string) (interfaceName string, interfaceIndex int, err error) { 1125 remoteAddr := M.ParseSocksaddr(address).Addr 1126 if C.IsLinux { 1127 interfaceName, interfaceIndex = r.InterfaceMonitor().DefaultInterface(remoteAddr) 1128 if interfaceIndex == -1 { 1129 err = tun.ErrNoRoute 1130 } 1131 } else { 1132 interfaceIndex = r.InterfaceMonitor().DefaultInterfaceIndex(remoteAddr) 1133 if interfaceIndex == -1 { 1134 err = tun.ErrNoRoute 1135 } 1136 } 1137 return 1138 }) 1139 } 1140 } 1141 1142 func (r *Router) DefaultInterface() string { 1143 return r.defaultInterface 1144 } 1145 1146 func (r *Router) DefaultMark() int { 1147 return r.defaultMark 1148 } 1149 1150 func (r *Router) Rules() []adapter.Rule { 1151 return r.rules 1152 } 1153 1154 func (r *Router) WIFIState() adapter.WIFIState { 1155 return r.wifiState 1156 } 1157 1158 func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor { 1159 return r.networkMonitor 1160 } 1161 1162 func (r *Router) InterfaceMonitor() tun.DefaultInterfaceMonitor { 1163 return r.interfaceMonitor 1164 } 1165 1166 func (r *Router) PackageManager() tun.PackageManager { 1167 return r.packageManager 1168 } 1169 1170 func (r *Router) ClashServer() adapter.ClashServer { 1171 return r.clashServer 1172 } 1173 1174 func (r *Router) SetClashServer(server adapter.ClashServer) { 1175 r.clashServer = server 1176 } 1177 1178 func (r *Router) V2RayServer() adapter.V2RayServer { 1179 return r.v2rayServer 1180 } 1181 1182 func (r *Router) SetV2RayServer(server adapter.V2RayServer) { 1183 r.v2rayServer = server 1184 } 1185 1186 func (r *Router) OnPackagesUpdated(packages int, sharedUsers int) { 1187 r.logger.Info("updated packages list: ", packages, " packages, ", sharedUsers, " shared users") 1188 } 1189 1190 func (r *Router) NewError(ctx context.Context, err error) { 1191 common.Close(err) 1192 if E.IsClosedOrCanceled(err) { 1193 r.logger.DebugContext(ctx, "connection closed: ", err) 1194 return 1195 } 1196 r.logger.ErrorContext(ctx, err) 1197 } 1198 1199 func (r *Router) notifyNetworkUpdate(event int) { 1200 if event == tun.EventNoRoute { 1201 r.pauseManager.NetworkPause() 1202 r.logger.Error("missing default interface") 1203 } else { 1204 r.pauseManager.NetworkWake() 1205 if C.IsAndroid && r.platformInterface == nil { 1206 var vpnStatus string 1207 if r.interfaceMonitor.AndroidVPNEnabled() { 1208 vpnStatus = "enabled" 1209 } else { 1210 vpnStatus = "disabled" 1211 } 1212 r.logger.Info("updated default interface ", r.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", r.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()), ", vpn ", vpnStatus) 1213 } else { 1214 r.logger.Info("updated default interface ", r.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", r.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified())) 1215 } 1216 } 1217 1218 if !r.started { 1219 return 1220 } 1221 1222 _ = r.ResetNetwork() 1223 } 1224 1225 func (r *Router) ResetNetwork() error { 1226 conntrack.Close() 1227 1228 for _, outbound := range r.outbounds { 1229 listener, isListener := outbound.(adapter.InterfaceUpdateListener) 1230 if isListener { 1231 listener.InterfaceUpdated() 1232 } 1233 } 1234 1235 for _, transport := range r.transports { 1236 transport.Reset() 1237 } 1238 return nil 1239 } 1240 1241 func (r *Router) updateWIFIState() { 1242 if r.platformInterface == nil { 1243 return 1244 } 1245 state := r.platformInterface.ReadWIFIState() 1246 if state != r.wifiState { 1247 r.wifiState = state 1248 if state.SSID == "" && state.BSSID == "" { 1249 r.logger.Info("updated WIFI state: disconnected") 1250 } else { 1251 r.logger.Info("updated WIFI state: SSID=", state.SSID, ", BSSID=", state.BSSID) 1252 } 1253 } 1254 } 1255 1256 func (r *Router) notifyWindowsPowerEvent(event int) { 1257 switch event { 1258 case winpowrprof.EVENT_SUSPEND: 1259 r.pauseManager.DevicePause() 1260 _ = r.ResetNetwork() 1261 case winpowrprof.EVENT_RESUME: 1262 if !r.pauseManager.IsDevicePaused() { 1263 return 1264 } 1265 fallthrough 1266 case winpowrprof.EVENT_RESUME_AUTOMATIC: 1267 r.pauseManager.DeviceWake() 1268 _ = r.ResetNetwork() 1269 } 1270 }