dnscommon_test.go 4.4 KB

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