dnscommon_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package dns
  2. import (
  3. "math/rand"
  4. "testing"
  5. "time"
  6. "github.com/google/go-cmp/cmp"
  7. "github.com/miekg/dns"
  8. "github.com/xtls/xray-core/common"
  9. "github.com/xtls/xray-core/common/net"
  10. dns_feature "github.com/xtls/xray-core/features/dns"
  11. "golang.org/x/net/dns/dnsmessage"
  12. )
  13. func Test_parseResponse(t *testing.T) {
  14. var p [][]byte
  15. ans := new(dns.Msg)
  16. ans.Id = 0
  17. p = append(p, common.Must2(ans.Pack()).([]byte))
  18. p = append(p, []byte{})
  19. ans = new(dns.Msg)
  20. ans.Id = 1
  21. ans.Answer = append(ans.Answer,
  22. common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
  23. common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")).(dns.RR),
  24. common.Must2(dns.NewRR("google.com. IN A 8.8.8.8")).(dns.RR),
  25. common.Must2(dns.NewRR("google.com. IN A 8.8.4.4")).(dns.RR),
  26. )
  27. p = append(p, common.Must2(ans.Pack()).([]byte))
  28. ans = new(dns.Msg)
  29. ans.Id = 2
  30. ans.Answer = append(ans.Answer,
  31. common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
  32. common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")).(dns.RR),
  33. common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
  34. common.Must2(dns.NewRR("google.com. IN CNAME test.google.com")).(dns.RR),
  35. common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8888")).(dns.RR),
  36. common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8844")).(dns.RR),
  37. )
  38. p = append(p, common.Must2(ans.Pack()).([]byte))
  39. tests := []struct {
  40. name string
  41. want *IPRecord
  42. wantErr bool
  43. }{
  44. {
  45. "empty",
  46. &IPRecord{0, []net.Address(nil), time.Time{}, dnsmessage.RCodeSuccess},
  47. false,
  48. },
  49. {
  50. "error",
  51. nil,
  52. true,
  53. },
  54. {
  55. "a record",
  56. &IPRecord{
  57. 1,
  58. []net.Address{net.ParseAddress("8.8.8.8"), net.ParseAddress("8.8.4.4")},
  59. time.Time{},
  60. dnsmessage.RCodeSuccess,
  61. },
  62. false,
  63. },
  64. {
  65. "aaaa record",
  66. &IPRecord{2, []net.Address{net.ParseAddress("2001::123:8888"), net.ParseAddress("2001::123:8844")}, time.Time{}, dnsmessage.RCodeSuccess},
  67. false,
  68. },
  69. }
  70. for i, tt := range tests {
  71. t.Run(tt.name, func(t *testing.T) {
  72. got, err := parseResponse(p[i])
  73. if (err != nil) != tt.wantErr {
  74. t.Errorf("handleResponse() error = %v, wantErr %v", err, tt.wantErr)
  75. return
  76. }
  77. if got != nil {
  78. // reset the time
  79. got.Expire = time.Time{}
  80. }
  81. if cmp.Diff(got, tt.want) != "" {
  82. t.Error(cmp.Diff(got, tt.want))
  83. // t.Errorf("handleResponse() = %#v, want %#v", got, tt.want)
  84. }
  85. })
  86. }
  87. }
  88. func Test_buildReqMsgs(t *testing.T) {
  89. stubID := func() uint16 {
  90. return uint16(rand.Uint32())
  91. }
  92. type args struct {
  93. domain string
  94. option dns_feature.IPOption
  95. reqOpts *dnsmessage.Resource
  96. }
  97. tests := []struct {
  98. name string
  99. args args
  100. want int
  101. }{
  102. {"dual stack", args{"test.com", dns_feature.IPOption{
  103. IPv4Enable: true,
  104. IPv6Enable: true,
  105. FakeEnable: false,
  106. }, nil}, 2},
  107. {"ipv4 only", args{"test.com", dns_feature.IPOption{
  108. IPv4Enable: true,
  109. IPv6Enable: false,
  110. FakeEnable: false,
  111. }, nil}, 1},
  112. {"ipv6 only", args{"test.com", dns_feature.IPOption{
  113. IPv4Enable: false,
  114. IPv6Enable: true,
  115. FakeEnable: false,
  116. }, nil}, 1},
  117. {"none/error", args{"test.com", dns_feature.IPOption{
  118. IPv4Enable: false,
  119. IPv6Enable: false,
  120. FakeEnable: false,
  121. }, nil}, 0},
  122. }
  123. for _, tt := range tests {
  124. t.Run(tt.name, func(t *testing.T) {
  125. if got := buildReqMsgs(tt.args.domain, tt.args.option, stubID, tt.args.reqOpts); !(len(got) == tt.want) {
  126. t.Errorf("buildReqMsgs() = %v, want %v", got, tt.want)
  127. }
  128. })
  129. }
  130. }
  131. func Test_genEDNS0Options(t *testing.T) {
  132. type args struct {
  133. clientIP net.IP
  134. }
  135. tests := []struct {
  136. name string
  137. args args
  138. want *dnsmessage.Resource
  139. }{
  140. // TODO: Add test cases.
  141. {"ipv4", args{net.ParseIP("4.3.2.1")}, nil},
  142. {"ipv6", args{net.ParseIP("2001::4321")}, nil},
  143. }
  144. for _, tt := range tests {
  145. t.Run(tt.name, func(t *testing.T) {
  146. if got := genEDNS0Options(tt.args.clientIP); got == nil {
  147. t.Errorf("genEDNS0Options() = %v, want %v", got, tt.want)
  148. }
  149. })
  150. }
  151. }
  152. func TestFqdn(t *testing.T) {
  153. type args struct {
  154. domain string
  155. }
  156. tests := []struct {
  157. name string
  158. args args
  159. want string
  160. }{
  161. {"with fqdn", args{"www.example.com."}, "www.example.com."},
  162. {"without fqdn", args{"www.example.com"}, "www.example.com."},
  163. }
  164. for _, tt := range tests {
  165. t.Run(tt.name, func(t *testing.T) {
  166. if got := Fqdn(tt.args.domain); got != tt.want {
  167. t.Errorf("Fqdn() = %v, want %v", got, tt.want)
  168. }
  169. })
  170. }
  171. }