resolve.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. )
  13. var (
  14. _ N.Dialer = (*resolveDialer)(nil)
  15. _ ParallelInterfaceDialer = (*resolveParallelNetworkDialer)(nil)
  16. )
  17. type resolveDialer struct {
  18. dialer N.Dialer
  19. parallel bool
  20. router adapter.DNSRouter
  21. strategy C.DomainStrategy
  22. fallbackDelay time.Duration
  23. }
  24. func NewResolveDialer(router adapter.DNSRouter, dialer N.Dialer, parallel bool, strategy C.DomainStrategy, fallbackDelay time.Duration) N.Dialer {
  25. return &resolveDialer{
  26. dialer,
  27. parallel,
  28. router,
  29. strategy,
  30. fallbackDelay,
  31. }
  32. }
  33. type resolveParallelNetworkDialer struct {
  34. resolveDialer
  35. dialer ParallelInterfaceDialer
  36. }
  37. func NewResolveParallelInterfaceDialer(router adapter.DNSRouter, dialer ParallelInterfaceDialer, parallel bool, strategy C.DomainStrategy, fallbackDelay time.Duration) ParallelInterfaceDialer {
  38. return &resolveParallelNetworkDialer{
  39. resolveDialer{
  40. dialer,
  41. parallel,
  42. router,
  43. strategy,
  44. fallbackDelay,
  45. },
  46. dialer,
  47. }
  48. }
  49. func (d *resolveDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  50. if !destination.IsFqdn() {
  51. return d.dialer.DialContext(ctx, network, destination)
  52. }
  53. ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
  54. addresses, err := d.router.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{Strategy: d.strategy})
  55. if err != nil {
  56. return nil, err
  57. }
  58. if d.parallel {
  59. return N.DialParallel(ctx, d.dialer, network, destination, addresses, d.strategy == C.DomainStrategyPreferIPv6, d.fallbackDelay)
  60. } else {
  61. return N.DialSerial(ctx, d.dialer, network, destination, addresses)
  62. }
  63. }
  64. func (d *resolveDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  65. if !destination.IsFqdn() {
  66. return d.dialer.ListenPacket(ctx, destination)
  67. }
  68. ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
  69. addresses, err := d.router.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{Strategy: d.strategy})
  70. if err != nil {
  71. return nil, err
  72. }
  73. conn, destinationAddress, err := N.ListenSerial(ctx, d.dialer, destination, addresses)
  74. if err != nil {
  75. return nil, err
  76. }
  77. return bufio.NewNATPacketConn(bufio.NewPacketConn(conn), M.SocksaddrFrom(destinationAddress, destination.Port), destination), nil
  78. }
  79. 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) {
  80. if !destination.IsFqdn() {
  81. return d.dialer.DialContext(ctx, network, destination)
  82. }
  83. ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
  84. addresses, err := d.router.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{
  85. Strategy: d.strategy,
  86. })
  87. if err != nil {
  88. return nil, err
  89. }
  90. if fallbackDelay == 0 {
  91. fallbackDelay = d.fallbackDelay
  92. }
  93. if d.parallel {
  94. return DialParallelNetwork(ctx, d.dialer, network, destination, addresses, d.strategy == C.DomainStrategyPreferIPv6, strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
  95. } else {
  96. return DialSerialNetwork(ctx, d.dialer, network, destination, addresses, strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
  97. }
  98. }
  99. 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) {
  100. if !destination.IsFqdn() {
  101. return d.dialer.ListenPacket(ctx, destination)
  102. }
  103. ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
  104. addresses, err := d.router.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{Strategy: d.strategy})
  105. if err != nil {
  106. return nil, err
  107. }
  108. conn, destinationAddress, err := ListenSerialNetworkPacket(ctx, d.dialer, destination, addresses, strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
  109. if err != nil {
  110. return nil, err
  111. }
  112. return bufio.NewNATPacketConn(bufio.NewPacketConn(conn), M.SocksaddrFrom(destinationAddress, destination.Port), destination), nil
  113. }
  114. func (d *resolveDialer) Upstream() any {
  115. return d.dialer
  116. }