dns_test.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. package dns_test
  2. import (
  3. "strconv"
  4. "testing"
  5. "time"
  6. "github.com/google/go-cmp/cmp"
  7. "github.com/miekg/dns"
  8. "v2ray.com/core"
  9. "v2ray.com/core/app/dispatcher"
  10. dnsapp "v2ray.com/core/app/dns"
  11. "v2ray.com/core/app/policy"
  12. "v2ray.com/core/app/proxyman"
  13. _ "v2ray.com/core/app/proxyman/inbound"
  14. _ "v2ray.com/core/app/proxyman/outbound"
  15. "v2ray.com/core/common"
  16. "v2ray.com/core/common/net"
  17. "v2ray.com/core/common/serial"
  18. dns_proxy "v2ray.com/core/proxy/dns"
  19. "v2ray.com/core/proxy/dokodemo"
  20. "v2ray.com/core/testing/servers/tcp"
  21. "v2ray.com/core/testing/servers/udp"
  22. )
  23. type staticHandler struct {
  24. }
  25. func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
  26. ans := new(dns.Msg)
  27. ans.Id = r.Id
  28. var clientIP net.IP
  29. opt := r.IsEdns0()
  30. if opt != nil {
  31. for _, o := range opt.Option {
  32. if o.Option() == dns.EDNS0SUBNET {
  33. subnet := o.(*dns.EDNS0_SUBNET)
  34. clientIP = subnet.Address
  35. }
  36. }
  37. }
  38. for _, q := range r.Question {
  39. if q.Name == "google.com." && q.Qtype == dns.TypeA {
  40. if clientIP == nil {
  41. rr, _ := dns.NewRR("google.com. IN A 8.8.8.8")
  42. ans.Answer = append(ans.Answer, rr)
  43. } else {
  44. rr, _ := dns.NewRR("google.com. IN A 8.8.4.4")
  45. ans.Answer = append(ans.Answer, rr)
  46. }
  47. } else if q.Name == "facebook.com." && q.Qtype == dns.TypeA {
  48. rr, _ := dns.NewRR("facebook.com. IN A 9.9.9.9")
  49. ans.Answer = append(ans.Answer, rr)
  50. } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA {
  51. rr, err := dns.NewRR("ipv6.google.com. IN A 8.8.8.7")
  52. common.Must(err)
  53. ans.Answer = append(ans.Answer, rr)
  54. } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA {
  55. rr, err := dns.NewRR("ipv6.google.com. IN AAAA 2001:4860:4860::8888")
  56. common.Must(err)
  57. ans.Answer = append(ans.Answer, rr)
  58. } else if q.Name == "notexist.google.com." && q.Qtype == dns.TypeAAAA {
  59. ans.MsgHdr.Rcode = dns.RcodeNameError
  60. }
  61. }
  62. w.WriteMsg(ans)
  63. }
  64. func TestUDPDNSTunnel(t *testing.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. defer dnsServer.Shutdown()
  73. go dnsServer.ListenAndServe()
  74. time.Sleep(time.Second)
  75. serverPort := udp.PickPort()
  76. config := &core.Config{
  77. App: []*serial.TypedMessage{
  78. serial.ToTypedMessage(&dnsapp.Config{
  79. NameServers: []*net.Endpoint{
  80. {
  81. Network: net.Network_UDP,
  82. Address: &net.IPOrDomain{
  83. Address: &net.IPOrDomain_Ip{
  84. Ip: []byte{127, 0, 0, 1},
  85. },
  86. },
  87. Port: uint32(port),
  88. },
  89. },
  90. }),
  91. serial.ToTypedMessage(&dispatcher.Config{}),
  92. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  93. serial.ToTypedMessage(&proxyman.InboundConfig{}),
  94. serial.ToTypedMessage(&policy.Config{}),
  95. },
  96. Inbound: []*core.InboundHandlerConfig{
  97. {
  98. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  99. Address: net.NewIPOrDomain(net.LocalHostIP),
  100. Port: uint32(port),
  101. Networks: []net.Network{net.Network_UDP},
  102. }),
  103. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  104. PortRange: net.SinglePortRange(serverPort),
  105. Listen: net.NewIPOrDomain(net.LocalHostIP),
  106. }),
  107. },
  108. },
  109. Outbound: []*core.OutboundHandlerConfig{
  110. {
  111. ProxySettings: serial.ToTypedMessage(&dns_proxy.Config{}),
  112. },
  113. },
  114. }
  115. v, err := core.New(config)
  116. common.Must(err)
  117. common.Must(v.Start())
  118. defer v.Close()
  119. {
  120. m1 := new(dns.Msg)
  121. m1.Id = dns.Id()
  122. m1.RecursionDesired = true
  123. m1.Question = make([]dns.Question, 1)
  124. m1.Question[0] = dns.Question{"google.com.", dns.TypeA, dns.ClassINET}
  125. c := new(dns.Client)
  126. in, _, err := c.Exchange(m1, "127.0.0.1:"+strconv.Itoa(int(serverPort)))
  127. common.Must(err)
  128. if len(in.Answer) != 1 {
  129. t.Fatal("len(answer): ", len(in.Answer))
  130. }
  131. rr, ok := in.Answer[0].(*dns.A)
  132. if !ok {
  133. t.Fatal("not A record")
  134. }
  135. if r := cmp.Diff(rr.A[:], net.IP{8, 8, 8, 8}); r != "" {
  136. t.Error(r)
  137. }
  138. }
  139. {
  140. m1 := new(dns.Msg)
  141. m1.Id = dns.Id()
  142. m1.RecursionDesired = true
  143. m1.Question = make([]dns.Question, 1)
  144. m1.Question[0] = dns.Question{"ipv4only.google.com.", dns.TypeAAAA, dns.ClassINET}
  145. c := new(dns.Client)
  146. in, _, err := c.Exchange(m1, "127.0.0.1:"+strconv.Itoa(int(serverPort)))
  147. common.Must(err)
  148. if len(in.Answer) != 0 {
  149. t.Fatal("len(answer): ", len(in.Answer))
  150. }
  151. }
  152. {
  153. m1 := new(dns.Msg)
  154. m1.Id = dns.Id()
  155. m1.RecursionDesired = true
  156. m1.Question = make([]dns.Question, 1)
  157. m1.Question[0] = dns.Question{"notexist.google.com.", dns.TypeAAAA, dns.ClassINET}
  158. c := new(dns.Client)
  159. in, _, err := c.Exchange(m1, "127.0.0.1:"+strconv.Itoa(int(serverPort)))
  160. common.Must(err)
  161. if in.Rcode != dns.RcodeNameError {
  162. t.Error("expected NameError, but got ", in.Rcode)
  163. }
  164. }
  165. }
  166. func TestTCPDNSTunnel(t *testing.T) {
  167. port := udp.PickPort()
  168. dnsServer := dns.Server{
  169. Addr: "127.0.0.1:" + port.String(),
  170. Net: "udp",
  171. Handler: &staticHandler{},
  172. }
  173. defer dnsServer.Shutdown()
  174. go dnsServer.ListenAndServe()
  175. time.Sleep(time.Second)
  176. serverPort := tcp.PickPort()
  177. config := &core.Config{
  178. App: []*serial.TypedMessage{
  179. serial.ToTypedMessage(&dnsapp.Config{
  180. NameServer: []*dnsapp.NameServer{
  181. {
  182. Address: &net.Endpoint{
  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: uint32(port),
  190. },
  191. },
  192. },
  193. }),
  194. serial.ToTypedMessage(&dispatcher.Config{}),
  195. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  196. serial.ToTypedMessage(&proxyman.InboundConfig{}),
  197. serial.ToTypedMessage(&policy.Config{}),
  198. },
  199. Inbound: []*core.InboundHandlerConfig{
  200. {
  201. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  202. Address: net.NewIPOrDomain(net.LocalHostIP),
  203. Port: uint32(port),
  204. Networks: []net.Network{net.Network_TCP},
  205. }),
  206. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  207. PortRange: net.SinglePortRange(serverPort),
  208. Listen: net.NewIPOrDomain(net.LocalHostIP),
  209. }),
  210. },
  211. },
  212. Outbound: []*core.OutboundHandlerConfig{
  213. {
  214. ProxySettings: serial.ToTypedMessage(&dns_proxy.Config{}),
  215. },
  216. },
  217. }
  218. v, err := core.New(config)
  219. common.Must(err)
  220. common.Must(v.Start())
  221. defer v.Close()
  222. m1 := new(dns.Msg)
  223. m1.Id = dns.Id()
  224. m1.RecursionDesired = true
  225. m1.Question = make([]dns.Question, 1)
  226. m1.Question[0] = dns.Question{"google.com.", dns.TypeA, dns.ClassINET}
  227. c := &dns.Client{
  228. Net: "tcp",
  229. }
  230. in, _, err := c.Exchange(m1, "127.0.0.1:"+serverPort.String())
  231. common.Must(err)
  232. if len(in.Answer) != 1 {
  233. t.Fatal("len(answer): ", len(in.Answer))
  234. }
  235. rr, ok := in.Answer[0].(*dns.A)
  236. if !ok {
  237. t.Fatal("not A record")
  238. }
  239. if r := cmp.Diff(rr.A[:], net.IP{8, 8, 8, 8}); r != "" {
  240. t.Error(r)
  241. }
  242. }
  243. func TestUDP2TCPDNSTunnel(t *testing.T) {
  244. port := tcp.PickPort()
  245. dnsServer := dns.Server{
  246. Addr: "127.0.0.1:" + port.String(),
  247. Net: "tcp",
  248. Handler: &staticHandler{},
  249. }
  250. defer dnsServer.Shutdown()
  251. go dnsServer.ListenAndServe()
  252. time.Sleep(time.Second)
  253. serverPort := tcp.PickPort()
  254. config := &core.Config{
  255. App: []*serial.TypedMessage{
  256. serial.ToTypedMessage(&dnsapp.Config{
  257. NameServer: []*dnsapp.NameServer{
  258. {
  259. Address: &net.Endpoint{
  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. }),
  271. serial.ToTypedMessage(&dispatcher.Config{}),
  272. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  273. serial.ToTypedMessage(&proxyman.InboundConfig{}),
  274. serial.ToTypedMessage(&policy.Config{}),
  275. },
  276. Inbound: []*core.InboundHandlerConfig{
  277. {
  278. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  279. Address: net.NewIPOrDomain(net.LocalHostIP),
  280. Port: uint32(port),
  281. Networks: []net.Network{net.Network_TCP},
  282. }),
  283. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  284. PortRange: net.SinglePortRange(serverPort),
  285. Listen: net.NewIPOrDomain(net.LocalHostIP),
  286. }),
  287. },
  288. },
  289. Outbound: []*core.OutboundHandlerConfig{
  290. {
  291. ProxySettings: serial.ToTypedMessage(&dns_proxy.Config{
  292. Server: &net.Endpoint{
  293. Network: net.Network_TCP,
  294. },
  295. }),
  296. },
  297. },
  298. }
  299. v, err := core.New(config)
  300. common.Must(err)
  301. common.Must(v.Start())
  302. defer v.Close()
  303. m1 := new(dns.Msg)
  304. m1.Id = dns.Id()
  305. m1.RecursionDesired = true
  306. m1.Question = make([]dns.Question, 1)
  307. m1.Question[0] = dns.Question{"google.com.", dns.TypeA, dns.ClassINET}
  308. c := &dns.Client{
  309. Net: "tcp",
  310. }
  311. in, _, err := c.Exchange(m1, "127.0.0.1:"+serverPort.String())
  312. common.Must(err)
  313. if len(in.Answer) != 1 {
  314. t.Fatal("len(answer): ", len(in.Answer))
  315. }
  316. rr, ok := in.Answer[0].(*dns.A)
  317. if !ok {
  318. t.Fatal("not A record")
  319. }
  320. if r := cmp.Diff(rr.A[:], net.IP{8, 8, 8, 8}); r != "" {
  321. t.Error(r)
  322. }
  323. }