dns_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. }
  59. }
  60. w.WriteMsg(ans)
  61. }
  62. func TestUDPDNSTunnel(t *testing.T) {
  63. port := udp.PickPort()
  64. dnsServer := dns.Server{
  65. Addr: "127.0.0.1:" + port.String(),
  66. Net: "udp",
  67. Handler: &staticHandler{},
  68. UDPSize: 1200,
  69. }
  70. defer dnsServer.Shutdown()
  71. go dnsServer.ListenAndServe()
  72. time.Sleep(time.Second)
  73. serverPort := udp.PickPort()
  74. config := &core.Config{
  75. App: []*serial.TypedMessage{
  76. serial.ToTypedMessage(&dnsapp.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. }),
  89. serial.ToTypedMessage(&dispatcher.Config{}),
  90. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  91. serial.ToTypedMessage(&proxyman.InboundConfig{}),
  92. serial.ToTypedMessage(&policy.Config{}),
  93. },
  94. Inbound: []*core.InboundHandlerConfig{
  95. {
  96. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  97. Address: net.NewIPOrDomain(net.LocalHostIP),
  98. Port: uint32(port),
  99. Networks: []net.Network{net.Network_UDP},
  100. }),
  101. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  102. PortRange: net.SinglePortRange(serverPort),
  103. Listen: net.NewIPOrDomain(net.LocalHostIP),
  104. }),
  105. },
  106. },
  107. Outbound: []*core.OutboundHandlerConfig{
  108. {
  109. ProxySettings: serial.ToTypedMessage(&dns_proxy.Config{}),
  110. },
  111. },
  112. }
  113. v, err := core.New(config)
  114. common.Must(err)
  115. common.Must(v.Start())
  116. defer v.Close()
  117. m1 := new(dns.Msg)
  118. m1.Id = dns.Id()
  119. m1.RecursionDesired = true
  120. m1.Question = make([]dns.Question, 1)
  121. m1.Question[0] = dns.Question{"google.com.", dns.TypeA, dns.ClassINET}
  122. c := new(dns.Client)
  123. in, _, err := c.Exchange(m1, "127.0.0.1:"+strconv.Itoa(int(serverPort)))
  124. common.Must(err)
  125. if len(in.Answer) != 1 {
  126. t.Fatal("len(answer): ", len(in.Answer))
  127. }
  128. rr, ok := in.Answer[0].(*dns.A)
  129. if !ok {
  130. t.Fatal("not A record")
  131. }
  132. if r := cmp.Diff(rr.A[:], net.IP{8, 8, 8, 8}); r != "" {
  133. t.Error(r)
  134. }
  135. }
  136. func TestTCPDNSTunnel(t *testing.T) {
  137. port := udp.PickPort()
  138. dnsServer := dns.Server{
  139. Addr: "127.0.0.1:" + port.String(),
  140. Net: "udp",
  141. Handler: &staticHandler{},
  142. }
  143. defer dnsServer.Shutdown()
  144. go dnsServer.ListenAndServe()
  145. time.Sleep(time.Second)
  146. serverPort := tcp.PickPort()
  147. config := &core.Config{
  148. App: []*serial.TypedMessage{
  149. serial.ToTypedMessage(&dnsapp.Config{
  150. NameServer: []*dnsapp.NameServer{
  151. {
  152. Address: &net.Endpoint{
  153. Network: net.Network_UDP,
  154. Address: &net.IPOrDomain{
  155. Address: &net.IPOrDomain_Ip{
  156. Ip: []byte{127, 0, 0, 1},
  157. },
  158. },
  159. Port: uint32(port),
  160. },
  161. },
  162. },
  163. }),
  164. serial.ToTypedMessage(&dispatcher.Config{}),
  165. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  166. serial.ToTypedMessage(&proxyman.InboundConfig{}),
  167. serial.ToTypedMessage(&policy.Config{}),
  168. },
  169. Inbound: []*core.InboundHandlerConfig{
  170. {
  171. ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
  172. Address: net.NewIPOrDomain(net.LocalHostIP),
  173. Port: uint32(port),
  174. Networks: []net.Network{net.Network_TCP},
  175. }),
  176. ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
  177. PortRange: net.SinglePortRange(serverPort),
  178. Listen: net.NewIPOrDomain(net.LocalHostIP),
  179. }),
  180. },
  181. },
  182. Outbound: []*core.OutboundHandlerConfig{
  183. {
  184. ProxySettings: serial.ToTypedMessage(&dns_proxy.Config{}),
  185. },
  186. },
  187. }
  188. v, err := core.New(config)
  189. common.Must(err)
  190. common.Must(v.Start())
  191. defer v.Close()
  192. m1 := new(dns.Msg)
  193. m1.Id = dns.Id()
  194. m1.RecursionDesired = true
  195. m1.Question = make([]dns.Question, 1)
  196. m1.Question[0] = dns.Question{"google.com.", dns.TypeA, dns.ClassINET}
  197. c := &dns.Client{
  198. Net: "tcp",
  199. }
  200. in, _, err := c.Exchange(m1, "127.0.0.1:"+serverPort.String())
  201. common.Must(err)
  202. if len(in.Answer) != 1 {
  203. t.Fatal("len(answer): ", len(in.Answer))
  204. }
  205. rr, ok := in.Answer[0].(*dns.A)
  206. if !ok {
  207. t.Fatal("not A record")
  208. }
  209. if r := cmp.Diff(rr.A[:], net.IP{8, 8, 8, 8}); r != "" {
  210. t.Error(r)
  211. }
  212. }