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 }