dialer.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package dialer
  2. import (
  3. "context"
  4. "net"
  5. "net/netip"
  6. "time"
  7. "github.com/sagernet/sing-box/adapter"
  8. C "github.com/sagernet/sing-box/constant"
  9. "github.com/sagernet/sing-box/experimental/deprecated"
  10. "github.com/sagernet/sing-box/option"
  11. E "github.com/sagernet/sing/common/exceptions"
  12. M "github.com/sagernet/sing/common/metadata"
  13. N "github.com/sagernet/sing/common/network"
  14. "github.com/sagernet/sing/service"
  15. )
  16. func New(ctx context.Context, options option.DialerOptions, remoteIsDomain bool) (N.Dialer, error) {
  17. if options.IsWireGuardListener {
  18. return NewDefault(ctx, options)
  19. }
  20. var (
  21. dialer N.Dialer
  22. err error
  23. )
  24. if options.Detour != "" {
  25. outboundManager := service.FromContext[adapter.OutboundManager](ctx)
  26. if outboundManager == nil {
  27. return nil, E.New("missing outbound manager")
  28. }
  29. dialer = NewDetour(outboundManager, options.Detour)
  30. } else {
  31. dialer, err = NewDefault(ctx, options)
  32. if err != nil {
  33. return nil, err
  34. }
  35. }
  36. if remoteIsDomain && options.Detour == "" {
  37. networkManager := service.FromContext[adapter.NetworkManager](ctx)
  38. dnsTransport := service.FromContext[adapter.DNSTransportManager](ctx)
  39. var defaultOptions adapter.NetworkOptions
  40. if networkManager != nil {
  41. defaultOptions = networkManager.DefaultOptions()
  42. }
  43. var (
  44. dnsQueryOptions adapter.DNSQueryOptions
  45. resolveFallbackDelay time.Duration
  46. )
  47. if options.DomainResolver != nil && options.DomainResolver.Server != "" {
  48. transport, loaded := dnsTransport.Transport(options.DomainResolver.Server)
  49. if !loaded {
  50. return nil, E.New("domain resolver not found: " + options.DomainResolver.Server)
  51. }
  52. var strategy C.DomainStrategy
  53. if options.DomainResolver.Strategy != option.DomainStrategy(C.DomainStrategyAsIS) {
  54. strategy = C.DomainStrategy(options.DomainResolver.Strategy)
  55. } else if
  56. //nolint:staticcheck
  57. options.DomainStrategy != option.DomainStrategy(C.DomainStrategyAsIS) {
  58. //nolint:staticcheck
  59. strategy = C.DomainStrategy(options.DomainStrategy)
  60. }
  61. dnsQueryOptions = adapter.DNSQueryOptions{
  62. Transport: transport,
  63. Strategy: strategy,
  64. DisableCache: options.DomainResolver.DisableCache,
  65. RewriteTTL: options.DomainResolver.RewriteTTL,
  66. ClientSubnet: options.DomainResolver.ClientSubnet.Build(netip.Prefix{}),
  67. }
  68. resolveFallbackDelay = time.Duration(options.FallbackDelay)
  69. } else if defaultOptions.DomainResolver != "" {
  70. dnsQueryOptions = defaultOptions.DomainResolveOptions
  71. transport, loaded := dnsTransport.Transport(defaultOptions.DomainResolver)
  72. if !loaded {
  73. return nil, E.New("default domain resolver not found: " + defaultOptions.DomainResolver)
  74. }
  75. dnsQueryOptions.Transport = transport
  76. resolveFallbackDelay = time.Duration(options.FallbackDelay)
  77. } else {
  78. deprecated.Report(ctx, deprecated.OptionMissingDomainResolver)
  79. }
  80. dialer = NewResolveDialer(
  81. ctx,
  82. dialer,
  83. options.Detour == "" && !options.TCPFastOpen,
  84. dnsQueryOptions,
  85. resolveFallbackDelay,
  86. )
  87. }
  88. return dialer, nil
  89. }
  90. type ParallelInterfaceDialer interface {
  91. N.Dialer
  92. DialParallelInterface(ctx context.Context, network string, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error)
  93. ListenSerialInterfacePacket(ctx context.Context, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, error)
  94. }
  95. type ParallelNetworkDialer interface {
  96. DialParallelNetwork(ctx context.Context, network string, destination M.Socksaddr, destinationAddresses []netip.Addr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error)
  97. ListenSerialNetworkPacket(ctx context.Context, destination M.Socksaddr, destinationAddresses []netip.Addr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, netip.Addr, error)
  98. }