server_test.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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/net"
  13. "v2ray.com/core/common/serial"
  14. feature_dns "v2ray.com/core/features/dns"
  15. "v2ray.com/core/proxy/freedom"
  16. "v2ray.com/core/testing/servers/udp"
  17. . "v2ray.com/ext/assert"
  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. }
  48. }
  49. w.WriteMsg(ans)
  50. }
  51. func TestUDPServerSubnet(t *testing.T) {
  52. if runtime.GOOS == "windows" {
  53. t.Skip("doesn't work on Windows due to miekg/dns changes.")
  54. }
  55. assert := With(t)
  56. port := udp.PickPort()
  57. dnsServer := dns.Server{
  58. Addr: "127.0.0.1:" + port.String(),
  59. Net: "udp",
  60. Handler: &staticHandler{},
  61. UDPSize: 1200,
  62. }
  63. go dnsServer.ListenAndServe()
  64. time.Sleep(time.Second)
  65. config := &core.Config{
  66. App: []*serial.TypedMessage{
  67. serial.ToTypedMessage(&Config{
  68. NameServers: []*net.Endpoint{
  69. {
  70. Network: net.Network_UDP,
  71. Address: &net.IPOrDomain{
  72. Address: &net.IPOrDomain_Ip{
  73. Ip: []byte{127, 0, 0, 1},
  74. },
  75. },
  76. Port: uint32(port),
  77. },
  78. },
  79. ClientIp: []byte{7, 8, 9, 10},
  80. }),
  81. serial.ToTypedMessage(&dispatcher.Config{}),
  82. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  83. serial.ToTypedMessage(&policy.Config{}),
  84. },
  85. Outbound: []*core.OutboundHandlerConfig{
  86. {
  87. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  88. },
  89. },
  90. }
  91. v, err := core.New(config)
  92. assert(err, IsNil)
  93. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  94. ips, err := client.LookupIP("google.com")
  95. assert(err, IsNil)
  96. assert(len(ips), Equals, 1)
  97. assert([]byte(ips[0]), Equals, []byte{8, 8, 4, 4})
  98. }
  99. func TestUDPServer(t *testing.T) {
  100. if runtime.GOOS == "windows" {
  101. t.Skip("doesn't work on Windows due to miekg/dns changes.")
  102. }
  103. assert := With(t)
  104. port := udp.PickPort()
  105. dnsServer := dns.Server{
  106. Addr: "127.0.0.1:" + port.String(),
  107. Net: "udp",
  108. Handler: &staticHandler{},
  109. UDPSize: 1200,
  110. }
  111. go dnsServer.ListenAndServe()
  112. time.Sleep(time.Second)
  113. config := &core.Config{
  114. App: []*serial.TypedMessage{
  115. serial.ToTypedMessage(&Config{
  116. NameServers: []*net.Endpoint{
  117. {
  118. Network: net.Network_UDP,
  119. Address: &net.IPOrDomain{
  120. Address: &net.IPOrDomain_Ip{
  121. Ip: []byte{127, 0, 0, 1},
  122. },
  123. },
  124. Port: uint32(port),
  125. },
  126. },
  127. }),
  128. serial.ToTypedMessage(&dispatcher.Config{}),
  129. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  130. serial.ToTypedMessage(&policy.Config{}),
  131. },
  132. Outbound: []*core.OutboundHandlerConfig{
  133. {
  134. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  135. },
  136. },
  137. }
  138. v, err := core.New(config)
  139. assert(err, IsNil)
  140. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  141. ips, err := client.LookupIP("google.com")
  142. assert(err, IsNil)
  143. assert(len(ips), Equals, 1)
  144. assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
  145. ips, err = client.LookupIP("facebook.com")
  146. assert(err, IsNil)
  147. assert(len(ips), Equals, 1)
  148. assert([]byte(ips[0]), Equals, []byte{9, 9, 9, 9})
  149. dnsServer.Shutdown()
  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. }
  155. func TestPrioritizedDomain(t *testing.T) {
  156. if runtime.GOOS == "windows" {
  157. t.Skip("doesn't work on Windows due to miekg/dns changes.")
  158. }
  159. assert := With(t)
  160. port := udp.PickPort()
  161. dnsServer := dns.Server{
  162. Addr: "127.0.0.1:" + port.String(),
  163. Net: "udp",
  164. Handler: &staticHandler{},
  165. UDPSize: 1200,
  166. }
  167. go dnsServer.ListenAndServe()
  168. time.Sleep(time.Second)
  169. config := &core.Config{
  170. App: []*serial.TypedMessage{
  171. serial.ToTypedMessage(&Config{
  172. NameServers: []*net.Endpoint{
  173. {
  174. Network: net.Network_UDP,
  175. Address: &net.IPOrDomain{
  176. Address: &net.IPOrDomain_Ip{
  177. Ip: []byte{127, 0, 0, 1},
  178. },
  179. },
  180. Port: 9999, /* unreachable */
  181. },
  182. },
  183. NameServer: []*NameServer{
  184. {
  185. Address: &net.Endpoint{
  186. Network: net.Network_UDP,
  187. Address: &net.IPOrDomain{
  188. Address: &net.IPOrDomain_Ip{
  189. Ip: []byte{127, 0, 0, 1},
  190. },
  191. },
  192. Port: uint32(port),
  193. },
  194. PrioritizedDomain: []*NameServer_PriorityDomain{
  195. {
  196. Type: DomainMatchingType_Full,
  197. Domain: "google.com",
  198. },
  199. },
  200. },
  201. },
  202. }),
  203. serial.ToTypedMessage(&dispatcher.Config{}),
  204. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  205. serial.ToTypedMessage(&policy.Config{}),
  206. },
  207. Outbound: []*core.OutboundHandlerConfig{
  208. {
  209. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  210. },
  211. },
  212. }
  213. v, err := core.New(config)
  214. assert(err, IsNil)
  215. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  216. startTime := time.Now()
  217. ips, err := client.LookupIP("google.com")
  218. assert(err, IsNil)
  219. assert(len(ips), Equals, 1)
  220. assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
  221. endTime := time.Now()
  222. if startTime.After(endTime.Add(time.Second * 2)) {
  223. t.Error("DNS query doesn't finish in 2 seconds.")
  224. }
  225. }