server_test.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. package dns_test
  2. import (
  3. "runtime"
  4. "testing"
  5. "time"
  6. "v2ray.com/core"
  7. "v2ray.com/core/app/dispatcher"
  8. . "v2ray.com/core/app/dns"
  9. "v2ray.com/core/app/policy"
  10. "v2ray.com/core/app/proxyman"
  11. _ "v2ray.com/core/app/proxyman/outbound"
  12. "v2ray.com/core/common"
  13. "v2ray.com/core/common/net"
  14. "v2ray.com/core/common/serial"
  15. feature_dns "v2ray.com/core/features/dns"
  16. "v2ray.com/core/proxy/freedom"
  17. "v2ray.com/core/testing/servers/udp"
  18. . "v2ray.com/ext/assert"
  19. "github.com/miekg/dns"
  20. )
  21. type staticHandler struct {
  22. }
  23. func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
  24. ans := new(dns.Msg)
  25. ans.Id = r.Id
  26. var clientIP net.IP
  27. opt := r.IsEdns0()
  28. if opt != nil {
  29. for _, o := range opt.Option {
  30. if o.Option() == dns.EDNS0SUBNET {
  31. subnet := o.(*dns.EDNS0_SUBNET)
  32. clientIP = subnet.Address
  33. }
  34. }
  35. }
  36. for _, q := range r.Question {
  37. if q.Name == "google.com." && q.Qtype == dns.TypeA {
  38. if clientIP == nil {
  39. rr, _ := dns.NewRR("google.com. IN A 8.8.8.8")
  40. ans.Answer = append(ans.Answer, rr)
  41. } else {
  42. rr, _ := dns.NewRR("google.com. IN A 8.8.4.4")
  43. ans.Answer = append(ans.Answer, rr)
  44. }
  45. } else if q.Name == "facebook.com." && q.Qtype == dns.TypeA {
  46. rr, _ := dns.NewRR("facebook.com. IN A 9.9.9.9")
  47. ans.Answer = append(ans.Answer, rr)
  48. } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA {
  49. rr, err := dns.NewRR("ipv6.google.com. IN A 8.8.8.7")
  50. common.Must(err)
  51. ans.Answer = append(ans.Answer, rr)
  52. } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA {
  53. rr, err := dns.NewRR("ipv6.google.com. IN AAAA 2001:4860:4860::8888")
  54. common.Must(err)
  55. ans.Answer = append(ans.Answer, rr)
  56. }
  57. }
  58. w.WriteMsg(ans)
  59. }
  60. func TestUDPServerSubnet(t *testing.T) {
  61. if runtime.GOOS == "windows" {
  62. t.Skip("doesn't work on Windows due to miekg/dns changes.")
  63. }
  64. assert := With(t)
  65. port := udp.PickPort()
  66. dnsServer := dns.Server{
  67. Addr: "127.0.0.1:" + port.String(),
  68. Net: "udp",
  69. Handler: &staticHandler{},
  70. UDPSize: 1200,
  71. }
  72. go dnsServer.ListenAndServe()
  73. time.Sleep(time.Second)
  74. config := &core.Config{
  75. App: []*serial.TypedMessage{
  76. serial.ToTypedMessage(&Config{
  77. NameServers: []*net.Endpoint{
  78. {
  79. Network: net.Network_UDP,
  80. Address: &net.IPOrDomain{
  81. Address: &net.IPOrDomain_Ip{
  82. Ip: []byte{127, 0, 0, 1},
  83. },
  84. },
  85. Port: uint32(port),
  86. },
  87. },
  88. ClientIp: []byte{7, 8, 9, 10},
  89. }),
  90. serial.ToTypedMessage(&dispatcher.Config{}),
  91. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  92. serial.ToTypedMessage(&policy.Config{}),
  93. },
  94. Outbound: []*core.OutboundHandlerConfig{
  95. {
  96. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  97. },
  98. },
  99. }
  100. v, err := core.New(config)
  101. assert(err, IsNil)
  102. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  103. ips, err := client.LookupIP("google.com")
  104. assert(err, IsNil)
  105. assert(len(ips), Equals, 1)
  106. assert([]byte(ips[0]), Equals, []byte{8, 8, 4, 4})
  107. }
  108. func TestUDPServer(t *testing.T) {
  109. if runtime.GOOS == "windows" {
  110. t.Skip("doesn't work on Windows due to miekg/dns changes.")
  111. }
  112. assert := With(t)
  113. port := udp.PickPort()
  114. dnsServer := dns.Server{
  115. Addr: "127.0.0.1:" + port.String(),
  116. Net: "udp",
  117. Handler: &staticHandler{},
  118. UDPSize: 1200,
  119. }
  120. go dnsServer.ListenAndServe()
  121. time.Sleep(time.Second)
  122. config := &core.Config{
  123. App: []*serial.TypedMessage{
  124. serial.ToTypedMessage(&Config{
  125. NameServers: []*net.Endpoint{
  126. {
  127. Network: net.Network_UDP,
  128. Address: &net.IPOrDomain{
  129. Address: &net.IPOrDomain_Ip{
  130. Ip: []byte{127, 0, 0, 1},
  131. },
  132. },
  133. Port: uint32(port),
  134. },
  135. },
  136. }),
  137. serial.ToTypedMessage(&dispatcher.Config{}),
  138. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  139. serial.ToTypedMessage(&policy.Config{}),
  140. },
  141. Outbound: []*core.OutboundHandlerConfig{
  142. {
  143. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  144. },
  145. },
  146. }
  147. v, err := core.New(config)
  148. assert(err, IsNil)
  149. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  150. ips, err := client.LookupIP("google.com")
  151. assert(err, IsNil)
  152. assert(len(ips), Equals, 1)
  153. assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
  154. ips, err = client.LookupIP("facebook.com")
  155. assert(err, IsNil)
  156. assert(len(ips), Equals, 1)
  157. assert([]byte(ips[0]), Equals, []byte{9, 9, 9, 9})
  158. dnsServer.Shutdown()
  159. ips, err = client.LookupIP("google.com")
  160. assert(err, IsNil)
  161. assert(len(ips), Equals, 1)
  162. assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
  163. }
  164. func TestPrioritizedDomain(t *testing.T) {
  165. if runtime.GOOS == "windows" {
  166. t.Skip("doesn't work on Windows due to miekg/dns changes.")
  167. }
  168. assert := With(t)
  169. port := udp.PickPort()
  170. dnsServer := dns.Server{
  171. Addr: "127.0.0.1:" + port.String(),
  172. Net: "udp",
  173. Handler: &staticHandler{},
  174. UDPSize: 1200,
  175. }
  176. go dnsServer.ListenAndServe()
  177. time.Sleep(time.Second)
  178. config := &core.Config{
  179. App: []*serial.TypedMessage{
  180. serial.ToTypedMessage(&Config{
  181. NameServers: []*net.Endpoint{
  182. {
  183. Network: net.Network_UDP,
  184. Address: &net.IPOrDomain{
  185. Address: &net.IPOrDomain_Ip{
  186. Ip: []byte{127, 0, 0, 1},
  187. },
  188. },
  189. Port: 9999, /* unreachable */
  190. },
  191. },
  192. NameServer: []*NameServer{
  193. {
  194. Address: &net.Endpoint{
  195. Network: net.Network_UDP,
  196. Address: &net.IPOrDomain{
  197. Address: &net.IPOrDomain_Ip{
  198. Ip: []byte{127, 0, 0, 1},
  199. },
  200. },
  201. Port: uint32(port),
  202. },
  203. PrioritizedDomain: []*NameServer_PriorityDomain{
  204. {
  205. Type: DomainMatchingType_Full,
  206. Domain: "google.com",
  207. },
  208. },
  209. },
  210. },
  211. }),
  212. serial.ToTypedMessage(&dispatcher.Config{}),
  213. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  214. serial.ToTypedMessage(&policy.Config{}),
  215. },
  216. Outbound: []*core.OutboundHandlerConfig{
  217. {
  218. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  219. },
  220. },
  221. }
  222. v, err := core.New(config)
  223. assert(err, IsNil)
  224. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  225. startTime := time.Now()
  226. ips, err := client.LookupIP("google.com")
  227. assert(err, IsNil)
  228. assert(len(ips), Equals, 1)
  229. assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
  230. endTime := time.Now()
  231. if startTime.After(endTime.Add(time.Second * 2)) {
  232. t.Error("DNS query doesn't finish in 2 seconds.")
  233. }
  234. }
  235. func TestUDPServerIPv6(t *testing.T) {
  236. if runtime.GOOS == "windows" {
  237. t.Skip("doesn't work on Windows due to miekg/dns changes.")
  238. }
  239. assert := With(t)
  240. port := udp.PickPort()
  241. dnsServer := dns.Server{
  242. Addr: "127.0.0.1:" + port.String(),
  243. Net: "udp",
  244. Handler: &staticHandler{},
  245. UDPSize: 1200,
  246. }
  247. go dnsServer.ListenAndServe()
  248. time.Sleep(time.Second)
  249. config := &core.Config{
  250. App: []*serial.TypedMessage{
  251. serial.ToTypedMessage(&Config{
  252. NameServers: []*net.Endpoint{
  253. {
  254. Network: net.Network_UDP,
  255. Address: &net.IPOrDomain{
  256. Address: &net.IPOrDomain_Ip{
  257. Ip: []byte{127, 0, 0, 1},
  258. },
  259. },
  260. Port: uint32(port),
  261. },
  262. },
  263. }),
  264. serial.ToTypedMessage(&dispatcher.Config{}),
  265. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  266. serial.ToTypedMessage(&policy.Config{}),
  267. },
  268. Outbound: []*core.OutboundHandlerConfig{
  269. {
  270. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  271. },
  272. },
  273. }
  274. v, err := core.New(config)
  275. assert(err, IsNil)
  276. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  277. client6 := client.(feature_dns.IPv6Lookup)
  278. ips, err := client6.LookupIPv6("ipv6.google.com")
  279. assert(err, IsNil)
  280. assert(len(ips), Equals, 1)
  281. assert([]byte(ips[0]), Equals, []byte{32, 1, 72, 96, 72, 96, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136})
  282. }