server_test.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. package dns_test
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/google/go-cmp/cmp"
  6. "github.com/miekg/dns"
  7. "v2ray.com/core"
  8. "v2ray.com/core/app/dispatcher"
  9. . "v2ray.com/core/app/dns"
  10. "v2ray.com/core/app/policy"
  11. "v2ray.com/core/app/proxyman"
  12. _ "v2ray.com/core/app/proxyman/outbound"
  13. "v2ray.com/core/app/router"
  14. "v2ray.com/core/common"
  15. "v2ray.com/core/common/net"
  16. "v2ray.com/core/common/serial"
  17. feature_dns "v2ray.com/core/features/dns"
  18. "v2ray.com/core/proxy/freedom"
  19. "v2ray.com/core/testing/servers/udp"
  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 == "api.google.com." && q.Qtype == dns.TypeA {
  46. rr, _ := dns.NewRR("api.google.com. IN A 8.8.7.7")
  47. ans.Answer = append(ans.Answer, rr)
  48. } else if q.Name == "v2.api.google.com." && q.Qtype == dns.TypeA {
  49. rr, _ := dns.NewRR("v2.api.google.com. IN A 8.8.7.8")
  50. ans.Answer = append(ans.Answer, rr)
  51. } else if q.Name == "facebook.com." && q.Qtype == dns.TypeA {
  52. rr, _ := dns.NewRR("facebook.com. IN A 9.9.9.9")
  53. ans.Answer = append(ans.Answer, rr)
  54. } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA {
  55. rr, err := dns.NewRR("ipv6.google.com. IN A 8.8.8.7")
  56. common.Must(err)
  57. ans.Answer = append(ans.Answer, rr)
  58. } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA {
  59. rr, err := dns.NewRR("ipv6.google.com. IN AAAA 2001:4860:4860::8888")
  60. common.Must(err)
  61. ans.Answer = append(ans.Answer, rr)
  62. } else if q.Name == "notexist.google.com." && q.Qtype == dns.TypeAAAA {
  63. ans.MsgHdr.Rcode = dns.RcodeNameError
  64. } else if q.Name == "hostname." && q.Qtype == dns.TypeA {
  65. rr, _ := dns.NewRR("hostname. IN A 127.0.0.1")
  66. ans.Answer = append(ans.Answer, rr)
  67. } else if q.Name == "hostname.local." && q.Qtype == dns.TypeA {
  68. rr, _ := dns.NewRR("hostname.local. IN A 127.0.0.1")
  69. ans.Answer = append(ans.Answer, rr)
  70. } else if q.Name == "hostname.localdomain." && q.Qtype == dns.TypeA {
  71. rr, _ := dns.NewRR("hostname.localdomain. IN A 127.0.0.1")
  72. ans.Answer = append(ans.Answer, rr)
  73. } else if q.Name == "localhost." && q.Qtype == dns.TypeA {
  74. rr, _ := dns.NewRR("localhost. IN A 127.0.0.2")
  75. ans.Answer = append(ans.Answer, rr)
  76. } else if q.Name == "localhost-a." && q.Qtype == dns.TypeA {
  77. rr, _ := dns.NewRR("localhost-a. IN A 127.0.0.3")
  78. ans.Answer = append(ans.Answer, rr)
  79. } else if q.Name == "localhost-b." && q.Qtype == dns.TypeA {
  80. rr, _ := dns.NewRR("localhost-b. IN A 127.0.0.4")
  81. ans.Answer = append(ans.Answer, rr)
  82. } else if q.Name == "Mijia\\ Cloud." && q.Qtype == dns.TypeA {
  83. rr, _ := dns.NewRR("Mijia\\ Cloud. IN A 127.0.0.1")
  84. ans.Answer = append(ans.Answer, rr)
  85. }
  86. }
  87. w.WriteMsg(ans)
  88. }
  89. func TestUDPServerSubnet(t *testing.T) {
  90. port := udp.PickPort()
  91. dnsServer := dns.Server{
  92. Addr: "127.0.0.1:" + port.String(),
  93. Net: "udp",
  94. Handler: &staticHandler{},
  95. UDPSize: 1200,
  96. }
  97. go dnsServer.ListenAndServe()
  98. time.Sleep(time.Second)
  99. config := &core.Config{
  100. App: []*serial.TypedMessage{
  101. serial.ToTypedMessage(&Config{
  102. NameServers: []*net.Endpoint{
  103. {
  104. Network: net.Network_UDP,
  105. Address: &net.IPOrDomain{
  106. Address: &net.IPOrDomain_Ip{
  107. Ip: []byte{127, 0, 0, 1},
  108. },
  109. },
  110. Port: uint32(port),
  111. },
  112. },
  113. ClientIp: []byte{7, 8, 9, 10},
  114. }),
  115. serial.ToTypedMessage(&dispatcher.Config{}),
  116. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  117. serial.ToTypedMessage(&policy.Config{}),
  118. },
  119. Outbound: []*core.OutboundHandlerConfig{
  120. {
  121. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  122. },
  123. },
  124. }
  125. v, err := core.New(config)
  126. common.Must(err)
  127. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  128. ips, err := client.LookupIP("google.com")
  129. if err != nil {
  130. t.Fatal("unexpected error: ", err)
  131. }
  132. if r := cmp.Diff(ips, []net.IP{{8, 8, 4, 4}}); r != "" {
  133. t.Fatal(r)
  134. }
  135. }
  136. func TestUDPServer(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. UDPSize: 1200,
  143. }
  144. go dnsServer.ListenAndServe()
  145. time.Sleep(time.Second)
  146. config := &core.Config{
  147. App: []*serial.TypedMessage{
  148. serial.ToTypedMessage(&Config{
  149. NameServers: []*net.Endpoint{
  150. {
  151. Network: net.Network_UDP,
  152. Address: &net.IPOrDomain{
  153. Address: &net.IPOrDomain_Ip{
  154. Ip: []byte{127, 0, 0, 1},
  155. },
  156. },
  157. Port: uint32(port),
  158. },
  159. },
  160. }),
  161. serial.ToTypedMessage(&dispatcher.Config{}),
  162. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  163. serial.ToTypedMessage(&policy.Config{}),
  164. },
  165. Outbound: []*core.OutboundHandlerConfig{
  166. {
  167. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  168. },
  169. },
  170. }
  171. v, err := core.New(config)
  172. common.Must(err)
  173. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  174. {
  175. ips, err := client.LookupIP("google.com")
  176. if err != nil {
  177. t.Fatal("unexpected error: ", err)
  178. }
  179. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  180. t.Fatal(r)
  181. }
  182. }
  183. {
  184. ips, err := client.LookupIP("facebook.com")
  185. if err != nil {
  186. t.Fatal("unexpected error: ", err)
  187. }
  188. if r := cmp.Diff(ips, []net.IP{{9, 9, 9, 9}}); r != "" {
  189. t.Fatal(r)
  190. }
  191. }
  192. {
  193. _, err := client.LookupIP("notexist.google.com")
  194. if err == nil {
  195. t.Fatal("nil error")
  196. }
  197. if r := feature_dns.RCodeFromError(err); r != uint16(dns.RcodeNameError) {
  198. t.Fatal("expected NameError, but got ", r)
  199. }
  200. }
  201. {
  202. clientv6 := client.(feature_dns.IPv6Lookup)
  203. ips, err := clientv6.LookupIPv6("ipv4only.google.com")
  204. if err != feature_dns.ErrEmptyResponse {
  205. t.Fatal("error: ", err)
  206. }
  207. if len(ips) != 0 {
  208. t.Fatal("ips: ", ips)
  209. }
  210. }
  211. dnsServer.Shutdown()
  212. {
  213. ips, err := client.LookupIP("google.com")
  214. if err != nil {
  215. t.Fatal("unexpected error: ", err)
  216. }
  217. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  218. t.Fatal(r)
  219. }
  220. }
  221. }
  222. func TestPrioritizedDomain(t *testing.T) {
  223. port := udp.PickPort()
  224. dnsServer := dns.Server{
  225. Addr: "127.0.0.1:" + port.String(),
  226. Net: "udp",
  227. Handler: &staticHandler{},
  228. UDPSize: 1200,
  229. }
  230. go dnsServer.ListenAndServe()
  231. time.Sleep(time.Second)
  232. config := &core.Config{
  233. App: []*serial.TypedMessage{
  234. serial.ToTypedMessage(&Config{
  235. NameServers: []*net.Endpoint{
  236. {
  237. Network: net.Network_UDP,
  238. Address: &net.IPOrDomain{
  239. Address: &net.IPOrDomain_Ip{
  240. Ip: []byte{127, 0, 0, 1},
  241. },
  242. },
  243. Port: 9999, /* unreachable */
  244. },
  245. },
  246. NameServer: []*NameServer{
  247. {
  248. Address: &net.Endpoint{
  249. Network: net.Network_UDP,
  250. Address: &net.IPOrDomain{
  251. Address: &net.IPOrDomain_Ip{
  252. Ip: []byte{127, 0, 0, 1},
  253. },
  254. },
  255. Port: uint32(port),
  256. },
  257. PrioritizedDomain: []*NameServer_PriorityDomain{
  258. {
  259. Type: DomainMatchingType_Full,
  260. Domain: "google.com",
  261. },
  262. },
  263. },
  264. },
  265. }),
  266. serial.ToTypedMessage(&dispatcher.Config{}),
  267. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  268. serial.ToTypedMessage(&policy.Config{}),
  269. },
  270. Outbound: []*core.OutboundHandlerConfig{
  271. {
  272. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  273. },
  274. },
  275. }
  276. v, err := core.New(config)
  277. common.Must(err)
  278. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  279. startTime := time.Now()
  280. {
  281. ips, err := client.LookupIP("google.com")
  282. if err != nil {
  283. t.Fatal("unexpected error: ", err)
  284. }
  285. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  286. t.Fatal(r)
  287. }
  288. }
  289. endTime := time.Now()
  290. if startTime.After(endTime.Add(time.Second * 2)) {
  291. t.Error("DNS query doesn't finish in 2 seconds.")
  292. }
  293. }
  294. func TestUDPServerIPv6(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. }),
  319. serial.ToTypedMessage(&dispatcher.Config{}),
  320. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  321. serial.ToTypedMessage(&policy.Config{}),
  322. },
  323. Outbound: []*core.OutboundHandlerConfig{
  324. {
  325. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  326. },
  327. },
  328. }
  329. v, err := core.New(config)
  330. common.Must(err)
  331. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  332. client6 := client.(feature_dns.IPv6Lookup)
  333. {
  334. ips, err := client6.LookupIPv6("ipv6.google.com")
  335. if err != nil {
  336. t.Fatal("unexpected error: ", err)
  337. }
  338. if r := cmp.Diff(ips, []net.IP{{32, 1, 72, 96, 72, 96, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136}}); r != "" {
  339. t.Fatal(r)
  340. }
  341. }
  342. }
  343. func TestStaticHostDomain(t *testing.T) {
  344. port := udp.PickPort()
  345. dnsServer := dns.Server{
  346. Addr: "127.0.0.1:" + port.String(),
  347. Net: "udp",
  348. Handler: &staticHandler{},
  349. UDPSize: 1200,
  350. }
  351. go dnsServer.ListenAndServe()
  352. time.Sleep(time.Second)
  353. config := &core.Config{
  354. App: []*serial.TypedMessage{
  355. serial.ToTypedMessage(&Config{
  356. NameServers: []*net.Endpoint{
  357. {
  358. Network: net.Network_UDP,
  359. Address: &net.IPOrDomain{
  360. Address: &net.IPOrDomain_Ip{
  361. Ip: []byte{127, 0, 0, 1},
  362. },
  363. },
  364. Port: uint32(port),
  365. },
  366. },
  367. StaticHosts: []*Config_HostMapping{
  368. {
  369. Type: DomainMatchingType_Full,
  370. Domain: "example.com",
  371. ProxiedDomain: "google.com",
  372. },
  373. },
  374. }),
  375. serial.ToTypedMessage(&dispatcher.Config{}),
  376. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  377. serial.ToTypedMessage(&policy.Config{}),
  378. },
  379. Outbound: []*core.OutboundHandlerConfig{
  380. {
  381. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  382. },
  383. },
  384. }
  385. v, err := core.New(config)
  386. common.Must(err)
  387. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  388. {
  389. ips, err := client.LookupIP("example.com")
  390. if err != nil {
  391. t.Fatal("unexpected error: ", err)
  392. }
  393. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  394. t.Fatal(r)
  395. }
  396. }
  397. dnsServer.Shutdown()
  398. }
  399. func TestIPMatch(t *testing.T) {
  400. port := udp.PickPort()
  401. dnsServer := dns.Server{
  402. Addr: "127.0.0.1:" + port.String(),
  403. Net: "udp",
  404. Handler: &staticHandler{},
  405. UDPSize: 1200,
  406. }
  407. go dnsServer.ListenAndServe()
  408. time.Sleep(time.Second)
  409. config := &core.Config{
  410. App: []*serial.TypedMessage{
  411. serial.ToTypedMessage(&Config{
  412. NameServer: []*NameServer{
  413. // private dns, not match
  414. {
  415. Address: &net.Endpoint{
  416. Network: net.Network_UDP,
  417. Address: &net.IPOrDomain{
  418. Address: &net.IPOrDomain_Ip{
  419. Ip: []byte{127, 0, 0, 1},
  420. },
  421. },
  422. Port: uint32(port),
  423. },
  424. Geoip: []*router.GeoIP{
  425. {
  426. CountryCode: "local",
  427. Cidr: []*router.CIDR{
  428. {
  429. // inner ip, will not match
  430. Ip: []byte{192, 168, 11, 1},
  431. Prefix: 32,
  432. },
  433. },
  434. },
  435. },
  436. },
  437. // second dns, match ip
  438. {
  439. Address: &net.Endpoint{
  440. Network: net.Network_UDP,
  441. Address: &net.IPOrDomain{
  442. Address: &net.IPOrDomain_Ip{
  443. Ip: []byte{127, 0, 0, 1},
  444. },
  445. },
  446. Port: uint32(port),
  447. },
  448. Geoip: []*router.GeoIP{
  449. {
  450. CountryCode: "test",
  451. Cidr: []*router.CIDR{
  452. {
  453. Ip: []byte{8, 8, 8, 8},
  454. Prefix: 32,
  455. },
  456. },
  457. },
  458. {
  459. CountryCode: "test",
  460. Cidr: []*router.CIDR{
  461. {
  462. Ip: []byte{8, 8, 8, 4},
  463. Prefix: 32,
  464. },
  465. },
  466. },
  467. },
  468. },
  469. },
  470. }),
  471. serial.ToTypedMessage(&dispatcher.Config{}),
  472. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  473. serial.ToTypedMessage(&policy.Config{}),
  474. },
  475. Outbound: []*core.OutboundHandlerConfig{
  476. {
  477. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  478. },
  479. },
  480. }
  481. v, err := core.New(config)
  482. common.Must(err)
  483. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  484. startTime := time.Now()
  485. {
  486. ips, err := client.LookupIP("google.com")
  487. if err != nil {
  488. t.Fatal("unexpected error: ", err)
  489. }
  490. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  491. t.Fatal(r)
  492. }
  493. }
  494. endTime := time.Now()
  495. if startTime.After(endTime.Add(time.Second * 2)) {
  496. t.Error("DNS query doesn't finish in 2 seconds.")
  497. }
  498. }
  499. func TestLocalDomain(t *testing.T) {
  500. port := udp.PickPort()
  501. dnsServer := dns.Server{
  502. Addr: "127.0.0.1:" + port.String(),
  503. Net: "udp",
  504. Handler: &staticHandler{},
  505. UDPSize: 1200,
  506. }
  507. go dnsServer.ListenAndServe()
  508. time.Sleep(time.Second)
  509. config := &core.Config{
  510. App: []*serial.TypedMessage{
  511. serial.ToTypedMessage(&Config{
  512. NameServers: []*net.Endpoint{
  513. {
  514. Network: net.Network_UDP,
  515. Address: &net.IPOrDomain{
  516. Address: &net.IPOrDomain_Ip{
  517. Ip: []byte{127, 0, 0, 1},
  518. },
  519. },
  520. Port: 9999, /* unreachable */
  521. },
  522. },
  523. NameServer: []*NameServer{
  524. {
  525. Address: &net.Endpoint{
  526. Network: net.Network_UDP,
  527. Address: &net.IPOrDomain{
  528. Address: &net.IPOrDomain_Ip{
  529. Ip: []byte{127, 0, 0, 1},
  530. },
  531. },
  532. Port: uint32(port),
  533. },
  534. PrioritizedDomain: []*NameServer_PriorityDomain{
  535. // Equivalent of dotless:localhost
  536. {Type: DomainMatchingType_Regex, Domain: "^[^.]*localhost[^.]*$"},
  537. },
  538. Geoip: []*router.GeoIP{
  539. { // Will match localhost, localhost-a and localhost-b,
  540. CountryCode: "local",
  541. Cidr: []*router.CIDR{
  542. {Ip: []byte{127, 0, 0, 2}, Prefix: 32},
  543. {Ip: []byte{127, 0, 0, 3}, Prefix: 32},
  544. {Ip: []byte{127, 0, 0, 4}, Prefix: 32},
  545. },
  546. },
  547. },
  548. },
  549. {
  550. Address: &net.Endpoint{
  551. Network: net.Network_UDP,
  552. Address: &net.IPOrDomain{
  553. Address: &net.IPOrDomain_Ip{
  554. Ip: []byte{127, 0, 0, 1},
  555. },
  556. },
  557. Port: uint32(port),
  558. },
  559. PrioritizedDomain: []*NameServer_PriorityDomain{
  560. // Equivalent of dotless: and domain:local
  561. {Type: DomainMatchingType_Regex, Domain: "^[^.]*$"},
  562. {Type: DomainMatchingType_Subdomain, Domain: "local"},
  563. {Type: DomainMatchingType_Subdomain, Domain: "localdomain"},
  564. },
  565. },
  566. },
  567. StaticHosts: []*Config_HostMapping{
  568. {
  569. Type: DomainMatchingType_Full,
  570. Domain: "hostnamestatic",
  571. Ip: [][]byte{{127, 0, 0, 53}},
  572. },
  573. {
  574. Type: DomainMatchingType_Full,
  575. Domain: "hostnamealias",
  576. ProxiedDomain: "hostname.localdomain",
  577. },
  578. },
  579. }),
  580. serial.ToTypedMessage(&dispatcher.Config{}),
  581. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  582. serial.ToTypedMessage(&policy.Config{}),
  583. },
  584. Outbound: []*core.OutboundHandlerConfig{
  585. {
  586. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  587. },
  588. },
  589. }
  590. v, err := core.New(config)
  591. common.Must(err)
  592. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  593. startTime := time.Now()
  594. { // Will match dotless:
  595. ips, err := client.LookupIP("hostname")
  596. if err != nil {
  597. t.Fatal("unexpected error: ", err)
  598. }
  599. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
  600. t.Fatal(r)
  601. }
  602. }
  603. { // Will match domain:local
  604. ips, err := client.LookupIP("hostname.local")
  605. if err != nil {
  606. t.Fatal("unexpected error: ", err)
  607. }
  608. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
  609. t.Fatal(r)
  610. }
  611. }
  612. { // Will match static ip
  613. ips, err := client.LookupIP("hostnamestatic")
  614. if err != nil {
  615. t.Fatal("unexpected error: ", err)
  616. }
  617. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 53}}); r != "" {
  618. t.Fatal(r)
  619. }
  620. }
  621. { // Will match domain replacing
  622. ips, err := client.LookupIP("hostnamealias")
  623. if err != nil {
  624. t.Fatal("unexpected error: ", err)
  625. }
  626. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
  627. t.Fatal(r)
  628. }
  629. }
  630. { // Will match dotless:localhost, but not expectIPs: 127.0.0.2, 127.0.0.3, then matches at dotless:
  631. ips, err := client.LookupIP("localhost")
  632. if err != nil {
  633. t.Fatal("unexpected error: ", err)
  634. }
  635. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 2}}); r != "" {
  636. t.Fatal(r)
  637. }
  638. }
  639. { // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
  640. ips, err := client.LookupIP("localhost-a")
  641. if err != nil {
  642. t.Fatal("unexpected error: ", err)
  643. }
  644. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 3}}); r != "" {
  645. t.Fatal(r)
  646. }
  647. }
  648. { // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
  649. ips, err := client.LookupIP("localhost-b")
  650. if err != nil {
  651. t.Fatal("unexpected error: ", err)
  652. }
  653. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 4}}); r != "" {
  654. t.Fatal(r)
  655. }
  656. }
  657. { // Will match dotless:
  658. ips, err := client.LookupIP("Mijia Cloud")
  659. if err != nil {
  660. t.Fatal("unexpected error: ", err)
  661. }
  662. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
  663. t.Fatal(r)
  664. }
  665. }
  666. endTime := time.Now()
  667. if startTime.After(endTime.Add(time.Second * 2)) {
  668. t.Error("DNS query doesn't finish in 2 seconds.")
  669. }
  670. }
  671. func TestMultiMatchPrioritizedDomain(t *testing.T) {
  672. port := udp.PickPort()
  673. dnsServer := dns.Server{
  674. Addr: "127.0.0.1:" + port.String(),
  675. Net: "udp",
  676. Handler: &staticHandler{},
  677. UDPSize: 1200,
  678. }
  679. go dnsServer.ListenAndServe()
  680. time.Sleep(time.Second)
  681. config := &core.Config{
  682. App: []*serial.TypedMessage{
  683. serial.ToTypedMessage(&Config{
  684. NameServers: []*net.Endpoint{
  685. {
  686. Network: net.Network_UDP,
  687. Address: &net.IPOrDomain{
  688. Address: &net.IPOrDomain_Ip{
  689. Ip: []byte{127, 0, 0, 1},
  690. },
  691. },
  692. Port: 9999, /* unreachable */
  693. },
  694. },
  695. NameServer: []*NameServer{
  696. {
  697. Address: &net.Endpoint{
  698. Network: net.Network_UDP,
  699. Address: &net.IPOrDomain{
  700. Address: &net.IPOrDomain_Ip{
  701. Ip: []byte{127, 0, 0, 1},
  702. },
  703. },
  704. Port: uint32(port),
  705. },
  706. PrioritizedDomain: []*NameServer_PriorityDomain{
  707. {
  708. Type: DomainMatchingType_Subdomain,
  709. Domain: "google.com",
  710. },
  711. },
  712. Geoip: []*router.GeoIP{
  713. { // Will only match 8.8.8.8 and 8.8.4.4
  714. Cidr: []*router.CIDR{
  715. {Ip: []byte{8, 8, 8, 8}, Prefix: 32},
  716. {Ip: []byte{8, 8, 4, 4}, Prefix: 32},
  717. },
  718. },
  719. },
  720. },
  721. {
  722. Address: &net.Endpoint{
  723. Network: net.Network_UDP,
  724. Address: &net.IPOrDomain{
  725. Address: &net.IPOrDomain_Ip{
  726. Ip: []byte{127, 0, 0, 1},
  727. },
  728. },
  729. Port: uint32(port),
  730. },
  731. PrioritizedDomain: []*NameServer_PriorityDomain{
  732. {
  733. Type: DomainMatchingType_Subdomain,
  734. Domain: "google.com",
  735. },
  736. },
  737. Geoip: []*router.GeoIP{
  738. { // Will match 8.8.8.8 and 8.8.8.7, etc
  739. Cidr: []*router.CIDR{
  740. {Ip: []byte{8, 8, 8, 7}, Prefix: 24},
  741. },
  742. },
  743. },
  744. },
  745. {
  746. Address: &net.Endpoint{
  747. Network: net.Network_UDP,
  748. Address: &net.IPOrDomain{
  749. Address: &net.IPOrDomain_Ip{
  750. Ip: []byte{127, 0, 0, 1},
  751. },
  752. },
  753. Port: uint32(port),
  754. },
  755. PrioritizedDomain: []*NameServer_PriorityDomain{
  756. {
  757. Type: DomainMatchingType_Subdomain,
  758. Domain: "api.google.com",
  759. },
  760. },
  761. Geoip: []*router.GeoIP{
  762. { // Will only match 8.8.7.7 (api.google.com)
  763. Cidr: []*router.CIDR{
  764. {Ip: []byte{8, 8, 7, 7}, Prefix: 32},
  765. },
  766. },
  767. },
  768. },
  769. {
  770. Address: &net.Endpoint{
  771. Network: net.Network_UDP,
  772. Address: &net.IPOrDomain{
  773. Address: &net.IPOrDomain_Ip{
  774. Ip: []byte{127, 0, 0, 1},
  775. },
  776. },
  777. Port: uint32(port),
  778. },
  779. PrioritizedDomain: []*NameServer_PriorityDomain{
  780. {
  781. Type: DomainMatchingType_Full,
  782. Domain: "v2.api.google.com",
  783. },
  784. },
  785. Geoip: []*router.GeoIP{
  786. { // Will only match 8.8.7.8 (v2.api.google.com)
  787. Cidr: []*router.CIDR{
  788. {Ip: []byte{8, 8, 7, 8}, Prefix: 32},
  789. },
  790. },
  791. },
  792. },
  793. },
  794. }),
  795. serial.ToTypedMessage(&dispatcher.Config{}),
  796. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  797. serial.ToTypedMessage(&policy.Config{}),
  798. },
  799. Outbound: []*core.OutboundHandlerConfig{
  800. {
  801. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  802. },
  803. },
  804. }
  805. v, err := core.New(config)
  806. common.Must(err)
  807. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  808. startTime := time.Now()
  809. { // Will match server 1,2 and server 1 returns expected ip
  810. ips, err := client.LookupIP("google.com")
  811. if err != nil {
  812. t.Fatal("unexpected error: ", err)
  813. }
  814. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  815. t.Fatal(r)
  816. }
  817. }
  818. { // Will match server 1,2 and server 1 returns unexpected ip, then server 2 returns expected one
  819. clientv4 := client.(feature_dns.IPv4Lookup)
  820. ips, err := clientv4.LookupIPv4("ipv6.google.com")
  821. if err != nil {
  822. t.Fatal("unexpected error: ", err)
  823. }
  824. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 7}}); r != "" {
  825. t.Fatal(r)
  826. }
  827. }
  828. { // Will match server 3,1,2 and server 3 returns expected one
  829. ips, err := client.LookupIP("api.google.com")
  830. if err != nil {
  831. t.Fatal("unexpected error: ", err)
  832. }
  833. if r := cmp.Diff(ips, []net.IP{{8, 8, 7, 7}}); r != "" {
  834. t.Fatal(r)
  835. }
  836. }
  837. { // Will match server 4,3,1,2 and server 4 returns expected one
  838. ips, err := client.LookupIP("v2.api.google.com")
  839. if err != nil {
  840. t.Fatal("unexpected error: ", err)
  841. }
  842. if r := cmp.Diff(ips, []net.IP{{8, 8, 7, 8}}); r != "" {
  843. t.Fatal(r)
  844. }
  845. }
  846. endTime := time.Now()
  847. if startTime.After(endTime.Add(time.Second * 2)) {
  848. t.Error("DNS query doesn't finish in 2 seconds.")
  849. }
  850. }