resolve.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package dialer
  2. import (
  3. "context"
  4. "net"
  5. "time"
  6. "github.com/sagernet/sing-box/adapter"
  7. C "github.com/sagernet/sing-box/constant"
  8. "github.com/sagernet/sing-box/log"
  9. "github.com/sagernet/sing/common/bufio"
  10. M "github.com/sagernet/sing/common/metadata"
  11. N "github.com/sagernet/sing/common/network"
  12. "github.com/sagernet/sing/service"
  13. )
  14. var (
  15. _ N.Dialer = (*resolveDialer)(nil)
  16. _ ParallelInterfaceDialer = (*resolveParallelNetworkDialer)(nil)
  17. )
  18. type ResolveDialer interface {
  19. N.Dialer
  20. QueryOptions() adapter.DNSQueryOptions
  21. }
  22. type ParallelInterfaceResolveDialer interface {
  23. ParallelInterfaceDialer
  24. QueryOptions() adapter.DNSQueryOptions
  25. }
  26. type resolveDialer struct {
  27. router adapter.DNSRouter
  28. dialer N.Dialer
  29. parallel bool
  30. queryOptions adapter.DNSQueryOptions
  31. fallbackDelay time.Duration
  32. }
  33. func NewResolveDialer(ctx context.Context, dialer N.Dialer, parallel bool, queryOptions adapter.DNSQueryOptions, fallbackDelay time.Duration) ResolveDialer {
  34. return &resolveDialer{
  35. service.FromContext[adapter.DNSRouter](ctx),
  36. dialer,
  37. parallel,
  38. queryOptions,
  39. fallbackDelay,
  40. }
  41. }
  42. type resolveParallelNetworkDialer struct {
  43. resolveDialer
  44. dialer ParallelInterfaceDialer
  45. }
  46. func NewResolveParallelInterfaceDialer(ctx context.Context, dialer ParallelInterfaceDialer, parallel bool, queryOptions adapter.DNSQueryOptions, fallbackDelay time.Duration) ParallelInterfaceResolveDialer {
  47. return &resolveParallelNetworkDialer{
  48. resolveDialer{
  49. service.FromContext[adapter.DNSRouter](ctx),
  50. dialer,
  51. parallel,
  52. queryOptions,
  53. fallbackDelay,
  54. },
  55. dialer,
  56. }
  57. }
  58. func (d *resolveDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  59. if !destination.IsFqdn() {
  60. return d.dialer.DialContext(ctx, network, destination)
  61. }
  62. ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
  63. addresses, err := d.router.Lookup(ctx, destination.Fqdn, d.queryOptions)
  64. if err != nil {
  65. return nil, err
  66. }
  67. if d.parallel {
  68. return N.DialParallel(ctx, d.dialer, network, destination, addresses, d.queryOptions.Strategy == C.DomainStrategyPreferIPv6, d.fallbackDelay)
  69. } else {
  70. return N.DialSerial(ctx, d.dialer, network, destination, addresses)
  71. }
  72. }
  73. func (d *resolveDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  74. if !destination.IsFqdn() {
  75. return d.dialer.ListenPacket(ctx, destination)
  76. }
  77. ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
  78. addresses, err := d.router.Lookup(ctx, destination.Fqdn, d.queryOptions)
  79. if err != nil {
  80. return nil, err
  81. }
  82. conn, destinationAddress, err := N.ListenSerial(ctx, d.dialer, destination, addresses)
  83. if err != nil {
  84. return nil, err
  85. }
  86. return bufio.NewNATPacketConn(bufio.NewPacketConn(conn), M.SocksaddrFrom(destinationAddress, destination.Port), destination), nil
  87. }
  88. func (d *resolveDialer) QueryOptions() adapter.DNSQueryOptions {
  89. return d.queryOptions
  90. }
  91. func (d *resolveDialer) Upstream() any {
  92. return d.dialer
  93. }
  94. func (d *resolveParallelNetworkDialer) DialParallelInterface(ctx context.Context, network string, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error) {
  95. if !destination.IsFqdn() {
  96. return d.dialer.DialContext(ctx, network, destination)
  97. }
  98. ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
  99. addresses, err := d.router.Lookup(ctx, destination.Fqdn, d.queryOptions)
  100. if err != nil {
  101. return nil, err
  102. }
  103. if fallbackDelay == 0 {
  104. fallbackDelay = d.fallbackDelay
  105. }
  106. if d.parallel {
  107. return DialParallelNetwork(ctx, d.dialer, network, destination, addresses, d.queryOptions.Strategy == C.DomainStrategyPreferIPv6, strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
  108. } else {
  109. return DialSerialNetwork(ctx, d.dialer, network, destination, addresses, strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
  110. }
  111. }
  112. func (d *resolveParallelNetworkDialer) ListenSerialInterfacePacket(ctx context.Context, destination M.Socksaddr, strategy *C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, error) {
  113. if !destination.IsFqdn() {
  114. return d.dialer.ListenPacket(ctx, destination)
  115. }
  116. ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
  117. addresses, err := d.router.Lookup(ctx, destination.Fqdn, d.queryOptions)
  118. if err != nil {
  119. return nil, err
  120. }
  121. if fallbackDelay == 0 {
  122. fallbackDelay = d.fallbackDelay
  123. }
  124. conn, destinationAddress, err := ListenSerialNetworkPacket(ctx, d.dialer, destination, addresses, strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
  125. if err != nil {
  126. return nil, err
  127. }
  128. return bufio.NewNATPacketConn(bufio.NewPacketConn(conn), M.SocksaddrFrom(destinationAddress, destination.Port), destination), nil
  129. }
  130. func (d *resolveParallelNetworkDialer) QueryOptions() adapter.DNSQueryOptions {
  131. return d.queryOptions
  132. }
  133. func (d *resolveParallelNetworkDialer) Upstream() any {
  134. return d.dialer
  135. }