github.com/sagernet/sing-box@v1.2.7/route/router.go (about)

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