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  }