dialer.go 3.8 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. dialer, err = NewDefault(ctx, options)
  26. if err != nil {
  27. return nil, err
  28. }
  29. } else {
  30. outboundManager := service.FromContext[adapter.OutboundManager](ctx)
  31. if outboundManager == nil {
  32. return nil, E.New("missing outbound manager")
  33. }
  34. dialer = NewDetour(outboundManager, options.Detour)
  35. }
  36. if remoteIsDomain && options.Detour == "" && options.DomainResolver == "" {
  37. deprecated.Report(ctx, deprecated.OptionMissingDomainResolverInDialOptions)
  38. }
  39. if (options.Detour == "" && remoteIsDomain) || options.DomainResolver != "" {
  40. router := service.FromContext[adapter.DNSRouter](ctx)
  41. if router != nil {
  42. var resolveTransport adapter.DNSTransport
  43. if options.DomainResolver != "" {
  44. transport, loaded := service.FromContext[adapter.DNSTransportManager](ctx).Transport(options.DomainResolver)
  45. if !loaded {
  46. return nil, E.New("DNS server not found: " + options.DomainResolver)
  47. }
  48. resolveTransport = transport
  49. }
  50. dialer = NewResolveDialer(
  51. router,
  52. dialer,
  53. options.Detour == "" && !options.TCPFastOpen,
  54. resolveTransport,
  55. C.DomainStrategy(options.DomainStrategy),
  56. time.Duration(options.FallbackDelay))
  57. }
  58. }
  59. return dialer, nil
  60. }
  61. func NewDirect(ctx context.Context, options option.DialerOptions) (ParallelInterfaceDialer, error) {
  62. if options.Detour != "" {
  63. return nil, E.New("`detour` is not supported in direct context")
  64. }
  65. if options.IsWireGuardListener {
  66. return NewDefault(ctx, options)
  67. }
  68. dialer, err := NewDefault(ctx, options)
  69. if err != nil {
  70. return nil, err
  71. }
  72. var resolveTransport adapter.DNSTransport
  73. if options.DomainResolver != "" {
  74. transport, loaded := service.FromContext[adapter.DNSTransportManager](ctx).Transport(options.DomainResolver)
  75. if !loaded {
  76. return nil, E.New("DNS server not found: " + options.DomainResolver)
  77. }
  78. resolveTransport = transport
  79. }
  80. return NewResolveParallelInterfaceDialer(
  81. service.FromContext[adapter.DNSRouter](ctx),
  82. dialer,
  83. true,
  84. resolveTransport,
  85. C.DomainStrategy(options.DomainStrategy),
  86. time.Duration(options.FallbackDelay),
  87. ), nil
  88. }
  89. type ParallelInterfaceDialer interface {
  90. N.Dialer
  91. DialParallelInterface(ctx context.Context, network string, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error)
  92. ListenSerialInterfacePacket(ctx context.Context, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, error)
  93. }
  94. type ParallelNetworkDialer interface {
  95. 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)
  96. 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)
  97. }