dialer.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. "",
  85. dnsQueryOptions,
  86. resolveFallbackDelay,
  87. )
  88. }
  89. return dialer, nil
  90. }
  91. func NewDNS(ctx context.Context, options option.DialerOptions, remoteIsDomain bool) (N.Dialer, error) {
  92. var (
  93. dialer N.Dialer
  94. err error
  95. )
  96. if options.Detour != "" {
  97. outboundManager := service.FromContext[adapter.OutboundManager](ctx)
  98. if outboundManager == nil {
  99. return nil, E.New("missing outbound manager")
  100. }
  101. dialer = NewDetour(outboundManager, options.Detour)
  102. } else {
  103. dialer, err = NewDefault(ctx, options)
  104. if err != nil {
  105. return nil, err
  106. }
  107. }
  108. if remoteIsDomain {
  109. var (
  110. dnsQueryOptions adapter.DNSQueryOptions
  111. resolveFallbackDelay time.Duration
  112. )
  113. if options.DomainResolver == nil || options.DomainResolver.Server == "" {
  114. return nil, E.New("missing domain resolver for domain server address")
  115. }
  116. var strategy C.DomainStrategy
  117. if options.DomainResolver.Strategy != option.DomainStrategy(C.DomainStrategyAsIS) {
  118. strategy = C.DomainStrategy(options.DomainResolver.Strategy)
  119. } else if
  120. //nolint:staticcheck
  121. options.DomainStrategy != option.DomainStrategy(C.DomainStrategyAsIS) {
  122. //nolint:staticcheck
  123. strategy = C.DomainStrategy(options.DomainStrategy)
  124. }
  125. dnsQueryOptions = adapter.DNSQueryOptions{
  126. Strategy: strategy,
  127. DisableCache: options.DomainResolver.DisableCache,
  128. RewriteTTL: options.DomainResolver.RewriteTTL,
  129. ClientSubnet: options.DomainResolver.ClientSubnet.Build(netip.Prefix{}),
  130. }
  131. resolveFallbackDelay = time.Duration(options.FallbackDelay)
  132. dialer = NewResolveDialer(
  133. ctx,
  134. dialer,
  135. options.Detour == "" && !options.TCPFastOpen,
  136. options.DomainResolver.Server,
  137. dnsQueryOptions,
  138. resolveFallbackDelay,
  139. )
  140. }
  141. return dialer, nil
  142. }
  143. type ParallelInterfaceDialer interface {
  144. N.Dialer
  145. DialParallelInterface(ctx context.Context, network string, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error)
  146. ListenSerialInterfacePacket(ctx context.Context, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, error)
  147. }
  148. type ParallelNetworkDialer interface {
  149. 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)
  150. 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)
  151. }