repro_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package dns
  2. import (
  3. "context"
  4. "net/netip"
  5. "testing"
  6. "github.com/sagernet/sing-box/adapter"
  7. C "github.com/sagernet/sing-box/constant"
  8. "github.com/sagernet/sing-box/option"
  9. E "github.com/sagernet/sing/common/exceptions"
  10. "github.com/sagernet/sing/common/json/badoption"
  11. mDNS "github.com/miekg/dns"
  12. "github.com/stretchr/testify/require"
  13. )
  14. func TestReproLookupWithRulesUsesRequestStrategy(t *testing.T) {
  15. t.Parallel()
  16. defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
  17. var qTypes []uint16
  18. router := newTestRouter(t, nil, &fakeDNSTransportManager{
  19. defaultTransport: defaultTransport,
  20. transports: map[string]adapter.DNSTransport{
  21. "default": defaultTransport,
  22. },
  23. }, &fakeDNSClient{
  24. exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
  25. qTypes = append(qTypes, message.Question[0].Qtype)
  26. if message.Question[0].Qtype == mDNS.TypeA {
  27. return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("2.2.2.2")}, 60), nil
  28. }
  29. return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("2001:db8::1")}, 60), nil
  30. },
  31. })
  32. addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{
  33. Strategy: C.DomainStrategyIPv4Only,
  34. })
  35. require.NoError(t, err)
  36. require.Equal(t, []uint16{mDNS.TypeA}, qTypes)
  37. require.Equal(t, []netip.Addr{netip.MustParseAddr("2.2.2.2")}, addresses)
  38. }
  39. func TestReproLogicalMatchResponseIPCIDR(t *testing.T) {
  40. t.Parallel()
  41. transportManager := &fakeDNSTransportManager{
  42. defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
  43. transports: map[string]adapter.DNSTransport{
  44. "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
  45. "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
  46. "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
  47. },
  48. }
  49. client := &fakeDNSClient{
  50. exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
  51. switch transport.Tag() {
  52. case "upstream":
  53. return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
  54. case "selected":
  55. return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
  56. default:
  57. return nil, E.New("unexpected transport")
  58. }
  59. },
  60. }
  61. rules := []option.DNSRule{
  62. {
  63. Type: C.RuleTypeDefault,
  64. DefaultOptions: option.DefaultDNSRule{
  65. RawDefaultDNSRule: option.RawDefaultDNSRule{
  66. Domain: badoption.Listable[string]{"example.com"},
  67. },
  68. DNSRuleAction: option.DNSRuleAction{
  69. Action: C.RuleActionTypeEvaluate,
  70. RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
  71. },
  72. },
  73. },
  74. {
  75. Type: C.RuleTypeLogical,
  76. LogicalOptions: option.LogicalDNSRule{
  77. RawLogicalDNSRule: option.RawLogicalDNSRule{
  78. Mode: C.LogicalTypeOr,
  79. Rules: []option.DNSRule{{
  80. Type: C.RuleTypeDefault,
  81. DefaultOptions: option.DefaultDNSRule{
  82. RawDefaultDNSRule: option.RawDefaultDNSRule{
  83. MatchResponse: true,
  84. IPCIDR: badoption.Listable[string]{"1.1.1.0/24"},
  85. },
  86. },
  87. }},
  88. },
  89. DNSRuleAction: option.DNSRuleAction{
  90. Action: C.RuleActionTypeRoute,
  91. RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
  92. },
  93. },
  94. },
  95. }
  96. router := newTestRouter(t, rules, transportManager, client)
  97. response, err := router.Exchange(context.Background(), &mDNS.Msg{
  98. Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
  99. }, adapter.DNSQueryOptions{})
  100. require.NoError(t, err)
  101. require.Equal(t, []netip.Addr{netip.MustParseAddr("8.8.8.8")}, MessageToAddresses(response))
  102. }