server_test.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. package dns_test
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/google/go-cmp/cmp"
  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. "github.com/miekg/dns"
  19. )
  20. type staticHandler struct {
  21. }
  22. func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
  23. ans := new(dns.Msg)
  24. ans.Id = r.Id
  25. var clientIP net.IP
  26. opt := r.IsEdns0()
  27. if opt != nil {
  28. for _, o := range opt.Option {
  29. if o.Option() == dns.EDNS0SUBNET {
  30. subnet := o.(*dns.EDNS0_SUBNET)
  31. clientIP = subnet.Address
  32. }
  33. }
  34. }
  35. for _, q := range r.Question {
  36. if q.Name == "google.com." && q.Qtype == dns.TypeA {
  37. if clientIP == nil {
  38. rr, _ := dns.NewRR("google.com. IN A 8.8.8.8")
  39. ans.Answer = append(ans.Answer, rr)
  40. } else {
  41. rr, _ := dns.NewRR("google.com. IN A 8.8.4.4")
  42. ans.Answer = append(ans.Answer, rr)
  43. }
  44. } else if q.Name == "facebook.com." && q.Qtype == dns.TypeA {
  45. rr, _ := dns.NewRR("facebook.com. IN A 9.9.9.9")
  46. ans.Answer = append(ans.Answer, rr)
  47. } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA {
  48. rr, err := dns.NewRR("ipv6.google.com. IN A 8.8.8.7")
  49. common.Must(err)
  50. ans.Answer = append(ans.Answer, rr)
  51. } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA {
  52. rr, err := dns.NewRR("ipv6.google.com. IN AAAA 2001:4860:4860::8888")
  53. common.Must(err)
  54. ans.Answer = append(ans.Answer, rr)
  55. }
  56. }
  57. w.WriteMsg(ans)
  58. }
  59. func TestUDPServerSubnet(t *testing.T) {
  60. port := udp.PickPort()
  61. dnsServer := dns.Server{
  62. Addr: "127.0.0.1:" + port.String(),
  63. Net: "udp",
  64. Handler: &staticHandler{},
  65. UDPSize: 1200,
  66. }
  67. go dnsServer.ListenAndServe()
  68. time.Sleep(time.Second)
  69. config := &core.Config{
  70. App: []*serial.TypedMessage{
  71. serial.ToTypedMessage(&Config{
  72. NameServers: []*net.Endpoint{
  73. {
  74. Network: net.Network_UDP,
  75. Address: &net.IPOrDomain{
  76. Address: &net.IPOrDomain_Ip{
  77. Ip: []byte{127, 0, 0, 1},
  78. },
  79. },
  80. Port: uint32(port),
  81. },
  82. },
  83. ClientIp: []byte{7, 8, 9, 10},
  84. }),
  85. serial.ToTypedMessage(&dispatcher.Config{}),
  86. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  87. serial.ToTypedMessage(&policy.Config{}),
  88. },
  89. Outbound: []*core.OutboundHandlerConfig{
  90. {
  91. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  92. },
  93. },
  94. }
  95. v, err := core.New(config)
  96. common.Must(err)
  97. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  98. ips, err := client.LookupIP("google.com")
  99. if err != nil {
  100. t.Fatal("unexpected error: ", err)
  101. }
  102. if r := cmp.Diff(ips, []net.IP{{8, 8, 4, 4}}); r != "" {
  103. t.Fatal(r)
  104. }
  105. }
  106. func TestUDPServer(t *testing.T) {
  107. port := udp.PickPort()
  108. dnsServer := dns.Server{
  109. Addr: "127.0.0.1:" + port.String(),
  110. Net: "udp",
  111. Handler: &staticHandler{},
  112. UDPSize: 1200,
  113. }
  114. go dnsServer.ListenAndServe()
  115. time.Sleep(time.Second)
  116. config := &core.Config{
  117. App: []*serial.TypedMessage{
  118. serial.ToTypedMessage(&Config{
  119. NameServers: []*net.Endpoint{
  120. {
  121. Network: net.Network_UDP,
  122. Address: &net.IPOrDomain{
  123. Address: &net.IPOrDomain_Ip{
  124. Ip: []byte{127, 0, 0, 1},
  125. },
  126. },
  127. Port: uint32(port),
  128. },
  129. },
  130. }),
  131. serial.ToTypedMessage(&dispatcher.Config{}),
  132. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  133. serial.ToTypedMessage(&policy.Config{}),
  134. },
  135. Outbound: []*core.OutboundHandlerConfig{
  136. {
  137. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  138. },
  139. },
  140. }
  141. v, err := core.New(config)
  142. common.Must(err)
  143. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  144. {
  145. ips, err := client.LookupIP("google.com")
  146. if err != nil {
  147. t.Fatal("unexpected error: ", err)
  148. }
  149. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  150. t.Fatal(r)
  151. }
  152. }
  153. {
  154. ips, err := client.LookupIP("facebook.com")
  155. if err != nil {
  156. t.Fatal("unexpected error: ", err)
  157. }
  158. if r := cmp.Diff(ips, []net.IP{{9, 9, 9, 9}}); r != "" {
  159. t.Fatal(r)
  160. }
  161. }
  162. dnsServer.Shutdown()
  163. {
  164. ips, err := client.LookupIP("google.com")
  165. if err != nil {
  166. t.Fatal("unexpected error: ", err)
  167. }
  168. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  169. t.Fatal(r)
  170. }
  171. }
  172. }
  173. func TestPrioritizedDomain(t *testing.T) {
  174. port := udp.PickPort()
  175. dnsServer := dns.Server{
  176. Addr: "127.0.0.1:" + port.String(),
  177. Net: "udp",
  178. Handler: &staticHandler{},
  179. UDPSize: 1200,
  180. }
  181. go dnsServer.ListenAndServe()
  182. time.Sleep(time.Second)
  183. config := &core.Config{
  184. App: []*serial.TypedMessage{
  185. serial.ToTypedMessage(&Config{
  186. NameServers: []*net.Endpoint{
  187. {
  188. Network: net.Network_UDP,
  189. Address: &net.IPOrDomain{
  190. Address: &net.IPOrDomain_Ip{
  191. Ip: []byte{127, 0, 0, 1},
  192. },
  193. },
  194. Port: 9999, /* unreachable */
  195. },
  196. },
  197. NameServer: []*NameServer{
  198. {
  199. Address: &net.Endpoint{
  200. Network: net.Network_UDP,
  201. Address: &net.IPOrDomain{
  202. Address: &net.IPOrDomain_Ip{
  203. Ip: []byte{127, 0, 0, 1},
  204. },
  205. },
  206. Port: uint32(port),
  207. },
  208. PrioritizedDomain: []*NameServer_PriorityDomain{
  209. {
  210. Type: DomainMatchingType_Full,
  211. Domain: "google.com",
  212. },
  213. },
  214. },
  215. },
  216. }),
  217. serial.ToTypedMessage(&dispatcher.Config{}),
  218. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  219. serial.ToTypedMessage(&policy.Config{}),
  220. },
  221. Outbound: []*core.OutboundHandlerConfig{
  222. {
  223. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  224. },
  225. },
  226. }
  227. v, err := core.New(config)
  228. common.Must(err)
  229. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  230. startTime := time.Now()
  231. {
  232. ips, err := client.LookupIP("google.com")
  233. if err != nil {
  234. t.Fatal("unexpected error: ", err)
  235. }
  236. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  237. t.Fatal(r)
  238. }
  239. }
  240. endTime := time.Now()
  241. if startTime.After(endTime.Add(time.Second * 2)) {
  242. t.Error("DNS query doesn't finish in 2 seconds.")
  243. }
  244. }
  245. func TestUDPServerIPv6(t *testing.T) {
  246. port := udp.PickPort()
  247. dnsServer := dns.Server{
  248. Addr: "127.0.0.1:" + port.String(),
  249. Net: "udp",
  250. Handler: &staticHandler{},
  251. UDPSize: 1200,
  252. }
  253. go dnsServer.ListenAndServe()
  254. time.Sleep(time.Second)
  255. config := &core.Config{
  256. App: []*serial.TypedMessage{
  257. serial.ToTypedMessage(&Config{
  258. NameServers: []*net.Endpoint{
  259. {
  260. Network: net.Network_UDP,
  261. Address: &net.IPOrDomain{
  262. Address: &net.IPOrDomain_Ip{
  263. Ip: []byte{127, 0, 0, 1},
  264. },
  265. },
  266. Port: uint32(port),
  267. },
  268. },
  269. }),
  270. serial.ToTypedMessage(&dispatcher.Config{}),
  271. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  272. serial.ToTypedMessage(&policy.Config{}),
  273. },
  274. Outbound: []*core.OutboundHandlerConfig{
  275. {
  276. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  277. },
  278. },
  279. }
  280. v, err := core.New(config)
  281. common.Must(err)
  282. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  283. client6 := client.(feature_dns.IPv6Lookup)
  284. {
  285. ips, err := client6.LookupIPv6("ipv6.google.com")
  286. if err != nil {
  287. t.Fatal("unexpected error: ", err)
  288. }
  289. if r := cmp.Diff(ips, []net.IP{{32, 1, 72, 96, 72, 96, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136}}); r != "" {
  290. t.Fatal(r)
  291. }
  292. }
  293. }
  294. func TestStaticHostDomain(t *testing.T) {
  295. port := udp.PickPort()
  296. dnsServer := dns.Server{
  297. Addr: "127.0.0.1:" + port.String(),
  298. Net: "udp",
  299. Handler: &staticHandler{},
  300. UDPSize: 1200,
  301. }
  302. go dnsServer.ListenAndServe()
  303. time.Sleep(time.Second)
  304. config := &core.Config{
  305. App: []*serial.TypedMessage{
  306. serial.ToTypedMessage(&Config{
  307. NameServers: []*net.Endpoint{
  308. {
  309. Network: net.Network_UDP,
  310. Address: &net.IPOrDomain{
  311. Address: &net.IPOrDomain_Ip{
  312. Ip: []byte{127, 0, 0, 1},
  313. },
  314. },
  315. Port: uint32(port),
  316. },
  317. },
  318. StaticHosts: []*Config_HostMapping{
  319. {
  320. Type: DomainMatchingType_Full,
  321. Domain: "example.com",
  322. ProxiedDomain: "google.com",
  323. },
  324. },
  325. }),
  326. serial.ToTypedMessage(&dispatcher.Config{}),
  327. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  328. serial.ToTypedMessage(&policy.Config{}),
  329. },
  330. Outbound: []*core.OutboundHandlerConfig{
  331. {
  332. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  333. },
  334. },
  335. }
  336. v, err := core.New(config)
  337. common.Must(err)
  338. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  339. {
  340. ips, err := client.LookupIP("example.com")
  341. if err != nil {
  342. t.Fatal("unexpected error: ", err)
  343. }
  344. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  345. t.Fatal(r)
  346. }
  347. }
  348. dnsServer.Shutdown()
  349. }