dnscommon_test.go 4.4 KB

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