transport_dialer.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package dns
  2. import (
  3. "context"
  4. "net"
  5. "time"
  6. "github.com/sagernet/sing-box/adapter"
  7. "github.com/sagernet/sing-box/common/dialer"
  8. C "github.com/sagernet/sing-box/constant"
  9. "github.com/sagernet/sing-box/option"
  10. E "github.com/sagernet/sing/common/exceptions"
  11. M "github.com/sagernet/sing/common/metadata"
  12. N "github.com/sagernet/sing/common/network"
  13. "github.com/sagernet/sing/service"
  14. )
  15. func NewLocalDialer(ctx context.Context, options option.LocalDNSServerOptions) (N.Dialer, error) {
  16. if options.LegacyDefaultDialer {
  17. return dialer.NewDefaultOutbound(ctx), nil
  18. } else {
  19. return dialer.New(ctx, options.DialerOptions, false)
  20. }
  21. }
  22. func NewRemoteDialer(ctx context.Context, options option.RemoteDNSServerOptions) (N.Dialer, error) {
  23. var (
  24. transportDialer N.Dialer
  25. err error
  26. )
  27. if options.LegacyDefaultDialer {
  28. transportDialer = dialer.NewDefaultOutbound(ctx)
  29. } else {
  30. transportDialer, err = dialer.New(ctx, options.DialerOptions, options.ServerIsDomain())
  31. }
  32. if err != nil {
  33. return nil, err
  34. }
  35. if options.AddressResolver != "" {
  36. transport := service.FromContext[adapter.DNSTransportManager](ctx)
  37. resolverTransport, loaded := transport.Transport(options.AddressResolver)
  38. if !loaded {
  39. return nil, E.New("address resolver not found: ", options.AddressResolver)
  40. }
  41. transportDialer = NewTransportDialer(transportDialer, service.FromContext[adapter.DNSRouter](ctx), resolverTransport, C.DomainStrategy(options.AddressStrategy), time.Duration(options.AddressFallbackDelay))
  42. } else if options.ServerIsDomain() {
  43. return nil, E.New("missing address resolver for server: ", options.Server)
  44. }
  45. return transportDialer, nil
  46. }
  47. type TransportDialer struct {
  48. dialer N.Dialer
  49. dnsRouter adapter.DNSRouter
  50. transport adapter.DNSTransport
  51. strategy C.DomainStrategy
  52. fallbackDelay time.Duration
  53. }
  54. func NewTransportDialer(dialer N.Dialer, dnsRouter adapter.DNSRouter, transport adapter.DNSTransport, strategy C.DomainStrategy, fallbackDelay time.Duration) *TransportDialer {
  55. return &TransportDialer{
  56. dialer,
  57. dnsRouter,
  58. transport,
  59. strategy,
  60. fallbackDelay,
  61. }
  62. }
  63. func (d *TransportDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  64. if destination.IsIP() {
  65. return d.dialer.DialContext(ctx, network, destination)
  66. }
  67. addresses, err := d.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{
  68. Transport: d.transport,
  69. Strategy: d.strategy,
  70. })
  71. if err != nil {
  72. return nil, err
  73. }
  74. return N.DialParallel(ctx, d.dialer, network, destination, addresses, d.strategy == C.DomainStrategyPreferIPv6, d.fallbackDelay)
  75. }
  76. func (d *TransportDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  77. if destination.IsIP() {
  78. return d.dialer.ListenPacket(ctx, destination)
  79. }
  80. addresses, err := d.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{
  81. Transport: d.transport,
  82. Strategy: d.strategy,
  83. })
  84. if err != nil {
  85. return nil, err
  86. }
  87. conn, _, err := N.ListenSerial(ctx, d.dialer, destination, addresses)
  88. return conn, err
  89. }
  90. func (d *TransportDialer) Upstream() any {
  91. return d.dialer
  92. }