dns_test.go 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. package dns_test
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/google/go-cmp/cmp"
  6. "github.com/miekg/dns"
  7. "github.com/xtls/xray-core/app/dispatcher"
  8. . "github.com/xtls/xray-core/app/dns"
  9. "github.com/xtls/xray-core/app/policy"
  10. "github.com/xtls/xray-core/app/proxyman"
  11. _ "github.com/xtls/xray-core/app/proxyman/outbound"
  12. "github.com/xtls/xray-core/app/router"
  13. "github.com/xtls/xray-core/common"
  14. "github.com/xtls/xray-core/common/net"
  15. "github.com/xtls/xray-core/common/serial"
  16. "github.com/xtls/xray-core/core"
  17. feature_dns "github.com/xtls/xray-core/features/dns"
  18. "github.com/xtls/xray-core/proxy/freedom"
  19. "github.com/xtls/xray-core/testing/servers/udp"
  20. )
  21. type staticHandler struct{}
  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. switch {
  37. case 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. case 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. case 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. case 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. case 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. case 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. case q.Name == "notexist.google.com." && q.Qtype == dns.TypeAAAA:
  63. ans.MsgHdr.Rcode = dns.RcodeNameError
  64. case 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. case 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. case 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. case 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. case 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. case 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. case 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", feature_dns.IPOption{
  129. IPv4Enable: true,
  130. IPv6Enable: true,
  131. FakeEnable: false,
  132. })
  133. if err != nil {
  134. t.Fatal("unexpected error: ", err)
  135. }
  136. if r := cmp.Diff(ips, []net.IP{{8, 8, 4, 4}}); r != "" {
  137. t.Fatal(r)
  138. }
  139. }
  140. func TestUDPServer(t *testing.T) {
  141. port := udp.PickPort()
  142. dnsServer := dns.Server{
  143. Addr: "127.0.0.1:" + port.String(),
  144. Net: "udp",
  145. Handler: &staticHandler{},
  146. UDPSize: 1200,
  147. }
  148. go dnsServer.ListenAndServe()
  149. time.Sleep(time.Second)
  150. config := &core.Config{
  151. App: []*serial.TypedMessage{
  152. serial.ToTypedMessage(&Config{
  153. NameServers: []*net.Endpoint{
  154. {
  155. Network: net.Network_UDP,
  156. Address: &net.IPOrDomain{
  157. Address: &net.IPOrDomain_Ip{
  158. Ip: []byte{127, 0, 0, 1},
  159. },
  160. },
  161. Port: uint32(port),
  162. },
  163. },
  164. }),
  165. serial.ToTypedMessage(&dispatcher.Config{}),
  166. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  167. serial.ToTypedMessage(&policy.Config{}),
  168. },
  169. Outbound: []*core.OutboundHandlerConfig{
  170. {
  171. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  172. },
  173. },
  174. }
  175. v, err := core.New(config)
  176. common.Must(err)
  177. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  178. {
  179. ips, err := client.LookupIP("google.com", feature_dns.IPOption{
  180. IPv4Enable: true,
  181. IPv6Enable: true,
  182. FakeEnable: false,
  183. })
  184. if err != nil {
  185. t.Fatal("unexpected error: ", err)
  186. }
  187. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  188. t.Fatal(r)
  189. }
  190. }
  191. {
  192. ips, err := client.LookupIP("facebook.com", feature_dns.IPOption{
  193. IPv4Enable: true,
  194. IPv6Enable: true,
  195. FakeEnable: false,
  196. })
  197. if err != nil {
  198. t.Fatal("unexpected error: ", err)
  199. }
  200. if r := cmp.Diff(ips, []net.IP{{9, 9, 9, 9}}); r != "" {
  201. t.Fatal(r)
  202. }
  203. }
  204. {
  205. _, err := client.LookupIP("notexist.google.com", feature_dns.IPOption{
  206. IPv4Enable: true,
  207. IPv6Enable: true,
  208. FakeEnable: false,
  209. })
  210. if err == nil {
  211. t.Fatal("nil error")
  212. }
  213. if r := feature_dns.RCodeFromError(err); r != uint16(dns.RcodeNameError) {
  214. t.Fatal("expected NameError, but got ", r)
  215. }
  216. }
  217. {
  218. ips, err := client.LookupIP("ipv4only.google.com", feature_dns.IPOption{
  219. IPv4Enable: false,
  220. IPv6Enable: true,
  221. FakeEnable: false,
  222. })
  223. if err != feature_dns.ErrEmptyResponse {
  224. t.Fatal("error: ", err)
  225. }
  226. if len(ips) != 0 {
  227. t.Fatal("ips: ", ips)
  228. }
  229. }
  230. dnsServer.Shutdown()
  231. {
  232. ips, err := client.LookupIP("google.com", feature_dns.IPOption{
  233. IPv4Enable: true,
  234. IPv6Enable: true,
  235. FakeEnable: false,
  236. })
  237. if err != nil {
  238. t.Fatal("unexpected error: ", err)
  239. }
  240. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  241. t.Fatal(r)
  242. }
  243. }
  244. }
  245. func TestPrioritizedDomain(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: 9999, /* unreachable */
  267. },
  268. },
  269. NameServer: []*NameServer{
  270. {
  271. Address: &net.Endpoint{
  272. Network: net.Network_UDP,
  273. Address: &net.IPOrDomain{
  274. Address: &net.IPOrDomain_Ip{
  275. Ip: []byte{127, 0, 0, 1},
  276. },
  277. },
  278. Port: uint32(port),
  279. },
  280. PrioritizedDomain: []*NameServer_PriorityDomain{
  281. {
  282. Type: DomainMatchingType_Full,
  283. Domain: "google.com",
  284. },
  285. },
  286. },
  287. },
  288. }),
  289. serial.ToTypedMessage(&dispatcher.Config{}),
  290. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  291. serial.ToTypedMessage(&policy.Config{}),
  292. },
  293. Outbound: []*core.OutboundHandlerConfig{
  294. {
  295. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  296. },
  297. },
  298. }
  299. v, err := core.New(config)
  300. common.Must(err)
  301. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  302. startTime := time.Now()
  303. {
  304. ips, err := client.LookupIP("google.com", feature_dns.IPOption{
  305. IPv4Enable: true,
  306. IPv6Enable: true,
  307. FakeEnable: false,
  308. })
  309. if err != nil {
  310. t.Fatal("unexpected error: ", err)
  311. }
  312. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  313. t.Fatal(r)
  314. }
  315. }
  316. endTime := time.Now()
  317. if startTime.After(endTime.Add(time.Second * 2)) {
  318. t.Error("DNS query doesn't finish in 2 seconds.")
  319. }
  320. }
  321. func TestUDPServerIPv6(t *testing.T) {
  322. port := udp.PickPort()
  323. dnsServer := dns.Server{
  324. Addr: "127.0.0.1:" + port.String(),
  325. Net: "udp",
  326. Handler: &staticHandler{},
  327. UDPSize: 1200,
  328. }
  329. go dnsServer.ListenAndServe()
  330. time.Sleep(time.Second)
  331. config := &core.Config{
  332. App: []*serial.TypedMessage{
  333. serial.ToTypedMessage(&Config{
  334. NameServers: []*net.Endpoint{
  335. {
  336. Network: net.Network_UDP,
  337. Address: &net.IPOrDomain{
  338. Address: &net.IPOrDomain_Ip{
  339. Ip: []byte{127, 0, 0, 1},
  340. },
  341. },
  342. Port: uint32(port),
  343. },
  344. },
  345. }),
  346. serial.ToTypedMessage(&dispatcher.Config{}),
  347. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  348. serial.ToTypedMessage(&policy.Config{}),
  349. },
  350. Outbound: []*core.OutboundHandlerConfig{
  351. {
  352. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  353. },
  354. },
  355. }
  356. v, err := core.New(config)
  357. common.Must(err)
  358. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  359. {
  360. ips, err := client.LookupIP("ipv6.google.com", feature_dns.IPOption{
  361. IPv4Enable: false,
  362. IPv6Enable: true,
  363. FakeEnable: false,
  364. })
  365. if err != nil {
  366. t.Fatal("unexpected error: ", err)
  367. }
  368. if r := cmp.Diff(ips, []net.IP{{32, 1, 72, 96, 72, 96, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136}}); r != "" {
  369. t.Fatal(r)
  370. }
  371. }
  372. }
  373. func TestStaticHostDomain(t *testing.T) {
  374. port := udp.PickPort()
  375. dnsServer := dns.Server{
  376. Addr: "127.0.0.1:" + port.String(),
  377. Net: "udp",
  378. Handler: &staticHandler{},
  379. UDPSize: 1200,
  380. }
  381. go dnsServer.ListenAndServe()
  382. time.Sleep(time.Second)
  383. config := &core.Config{
  384. App: []*serial.TypedMessage{
  385. serial.ToTypedMessage(&Config{
  386. NameServers: []*net.Endpoint{
  387. {
  388. Network: net.Network_UDP,
  389. Address: &net.IPOrDomain{
  390. Address: &net.IPOrDomain_Ip{
  391. Ip: []byte{127, 0, 0, 1},
  392. },
  393. },
  394. Port: uint32(port),
  395. },
  396. },
  397. StaticHosts: []*Config_HostMapping{
  398. {
  399. Type: DomainMatchingType_Full,
  400. Domain: "example.com",
  401. ProxiedDomain: "google.com",
  402. },
  403. },
  404. }),
  405. serial.ToTypedMessage(&dispatcher.Config{}),
  406. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  407. serial.ToTypedMessage(&policy.Config{}),
  408. },
  409. Outbound: []*core.OutboundHandlerConfig{
  410. {
  411. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  412. },
  413. },
  414. }
  415. v, err := core.New(config)
  416. common.Must(err)
  417. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  418. {
  419. ips, err := client.LookupIP("example.com", feature_dns.IPOption{
  420. IPv4Enable: true,
  421. IPv6Enable: true,
  422. FakeEnable: false,
  423. })
  424. if err != nil {
  425. t.Fatal("unexpected error: ", err)
  426. }
  427. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  428. t.Fatal(r)
  429. }
  430. }
  431. dnsServer.Shutdown()
  432. }
  433. func TestIPMatch(t *testing.T) {
  434. port := udp.PickPort()
  435. dnsServer := dns.Server{
  436. Addr: "127.0.0.1:" + port.String(),
  437. Net: "udp",
  438. Handler: &staticHandler{},
  439. UDPSize: 1200,
  440. }
  441. go dnsServer.ListenAndServe()
  442. time.Sleep(time.Second)
  443. config := &core.Config{
  444. App: []*serial.TypedMessage{
  445. serial.ToTypedMessage(&Config{
  446. NameServer: []*NameServer{
  447. // private dns, not match
  448. {
  449. Address: &net.Endpoint{
  450. Network: net.Network_UDP,
  451. Address: &net.IPOrDomain{
  452. Address: &net.IPOrDomain_Ip{
  453. Ip: []byte{127, 0, 0, 1},
  454. },
  455. },
  456. Port: uint32(port),
  457. },
  458. Geoip: []*router.GeoIP{
  459. {
  460. CountryCode: "local",
  461. Cidr: []*router.CIDR{
  462. {
  463. // inner ip, will not match
  464. Ip: []byte{192, 168, 11, 1},
  465. Prefix: 32,
  466. },
  467. },
  468. },
  469. },
  470. },
  471. // second dns, match ip
  472. {
  473. Address: &net.Endpoint{
  474. Network: net.Network_UDP,
  475. Address: &net.IPOrDomain{
  476. Address: &net.IPOrDomain_Ip{
  477. Ip: []byte{127, 0, 0, 1},
  478. },
  479. },
  480. Port: uint32(port),
  481. },
  482. Geoip: []*router.GeoIP{
  483. {
  484. CountryCode: "test",
  485. Cidr: []*router.CIDR{
  486. {
  487. Ip: []byte{8, 8, 8, 8},
  488. Prefix: 32,
  489. },
  490. },
  491. },
  492. {
  493. CountryCode: "test",
  494. Cidr: []*router.CIDR{
  495. {
  496. Ip: []byte{8, 8, 8, 4},
  497. Prefix: 32,
  498. },
  499. },
  500. },
  501. },
  502. },
  503. },
  504. }),
  505. serial.ToTypedMessage(&dispatcher.Config{}),
  506. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  507. serial.ToTypedMessage(&policy.Config{}),
  508. },
  509. Outbound: []*core.OutboundHandlerConfig{
  510. {
  511. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  512. },
  513. },
  514. }
  515. v, err := core.New(config)
  516. common.Must(err)
  517. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  518. startTime := time.Now()
  519. {
  520. ips, err := client.LookupIP("google.com", feature_dns.IPOption{
  521. IPv4Enable: true,
  522. IPv6Enable: true,
  523. FakeEnable: false,
  524. })
  525. if err != nil {
  526. t.Fatal("unexpected error: ", err)
  527. }
  528. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  529. t.Fatal(r)
  530. }
  531. }
  532. endTime := time.Now()
  533. if startTime.After(endTime.Add(time.Second * 2)) {
  534. t.Error("DNS query doesn't finish in 2 seconds.")
  535. }
  536. }
  537. func TestLocalDomain(t *testing.T) {
  538. port := udp.PickPort()
  539. dnsServer := dns.Server{
  540. Addr: "127.0.0.1:" + port.String(),
  541. Net: "udp",
  542. Handler: &staticHandler{},
  543. UDPSize: 1200,
  544. }
  545. go dnsServer.ListenAndServe()
  546. time.Sleep(time.Second)
  547. config := &core.Config{
  548. App: []*serial.TypedMessage{
  549. serial.ToTypedMessage(&Config{
  550. NameServers: []*net.Endpoint{
  551. {
  552. Network: net.Network_UDP,
  553. Address: &net.IPOrDomain{
  554. Address: &net.IPOrDomain_Ip{
  555. Ip: []byte{127, 0, 0, 1},
  556. },
  557. },
  558. Port: 9999, /* unreachable */
  559. },
  560. },
  561. NameServer: []*NameServer{
  562. {
  563. Address: &net.Endpoint{
  564. Network: net.Network_UDP,
  565. Address: &net.IPOrDomain{
  566. Address: &net.IPOrDomain_Ip{
  567. Ip: []byte{127, 0, 0, 1},
  568. },
  569. },
  570. Port: uint32(port),
  571. },
  572. PrioritizedDomain: []*NameServer_PriorityDomain{
  573. // Equivalent of dotless:localhost
  574. {Type: DomainMatchingType_Regex, Domain: "^[^.]*localhost[^.]*$"},
  575. },
  576. Geoip: []*router.GeoIP{
  577. { // Will match localhost, localhost-a and localhost-b,
  578. CountryCode: "local",
  579. Cidr: []*router.CIDR{
  580. {Ip: []byte{127, 0, 0, 2}, Prefix: 32},
  581. {Ip: []byte{127, 0, 0, 3}, Prefix: 32},
  582. {Ip: []byte{127, 0, 0, 4}, Prefix: 32},
  583. },
  584. },
  585. },
  586. },
  587. {
  588. Address: &net.Endpoint{
  589. Network: net.Network_UDP,
  590. Address: &net.IPOrDomain{
  591. Address: &net.IPOrDomain_Ip{
  592. Ip: []byte{127, 0, 0, 1},
  593. },
  594. },
  595. Port: uint32(port),
  596. },
  597. PrioritizedDomain: []*NameServer_PriorityDomain{
  598. // Equivalent of dotless: and domain:local
  599. {Type: DomainMatchingType_Regex, Domain: "^[^.]*$"},
  600. {Type: DomainMatchingType_Subdomain, Domain: "local"},
  601. {Type: DomainMatchingType_Subdomain, Domain: "localdomain"},
  602. },
  603. },
  604. },
  605. StaticHosts: []*Config_HostMapping{
  606. {
  607. Type: DomainMatchingType_Full,
  608. Domain: "hostnamestatic",
  609. Ip: [][]byte{{127, 0, 0, 53}},
  610. },
  611. {
  612. Type: DomainMatchingType_Full,
  613. Domain: "hostnamealias",
  614. ProxiedDomain: "hostname.localdomain",
  615. },
  616. },
  617. }),
  618. serial.ToTypedMessage(&dispatcher.Config{}),
  619. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  620. serial.ToTypedMessage(&policy.Config{}),
  621. },
  622. Outbound: []*core.OutboundHandlerConfig{
  623. {
  624. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  625. },
  626. },
  627. }
  628. v, err := core.New(config)
  629. common.Must(err)
  630. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  631. startTime := time.Now()
  632. { // Will match dotless:
  633. ips, err := client.LookupIP("hostname", feature_dns.IPOption{
  634. IPv4Enable: true,
  635. IPv6Enable: true,
  636. FakeEnable: false,
  637. })
  638. if err != nil {
  639. t.Fatal("unexpected error: ", err)
  640. }
  641. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
  642. t.Fatal(r)
  643. }
  644. }
  645. { // Will match domain:local
  646. ips, err := client.LookupIP("hostname.local", feature_dns.IPOption{
  647. IPv4Enable: true,
  648. IPv6Enable: true,
  649. FakeEnable: false,
  650. })
  651. if err != nil {
  652. t.Fatal("unexpected error: ", err)
  653. }
  654. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
  655. t.Fatal(r)
  656. }
  657. }
  658. { // Will match static ip
  659. ips, err := client.LookupIP("hostnamestatic", feature_dns.IPOption{
  660. IPv4Enable: true,
  661. IPv6Enable: true,
  662. FakeEnable: false,
  663. })
  664. if err != nil {
  665. t.Fatal("unexpected error: ", err)
  666. }
  667. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 53}}); r != "" {
  668. t.Fatal(r)
  669. }
  670. }
  671. { // Will match domain replacing
  672. ips, err := client.LookupIP("hostnamealias", feature_dns.IPOption{
  673. IPv4Enable: true,
  674. IPv6Enable: true,
  675. FakeEnable: false,
  676. })
  677. if err != nil {
  678. t.Fatal("unexpected error: ", err)
  679. }
  680. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
  681. t.Fatal(r)
  682. }
  683. }
  684. { // Will match dotless:localhost, but not expectIPs: 127.0.0.2, 127.0.0.3, then matches at dotless:
  685. ips, err := client.LookupIP("localhost", feature_dns.IPOption{
  686. IPv4Enable: true,
  687. IPv6Enable: true,
  688. FakeEnable: false,
  689. })
  690. if err != nil {
  691. t.Fatal("unexpected error: ", err)
  692. }
  693. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 2}}); r != "" {
  694. t.Fatal(r)
  695. }
  696. }
  697. { // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
  698. ips, err := client.LookupIP("localhost-a", feature_dns.IPOption{
  699. IPv4Enable: true,
  700. IPv6Enable: true,
  701. FakeEnable: false,
  702. })
  703. if err != nil {
  704. t.Fatal("unexpected error: ", err)
  705. }
  706. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 3}}); r != "" {
  707. t.Fatal(r)
  708. }
  709. }
  710. { // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
  711. ips, err := client.LookupIP("localhost-b", feature_dns.IPOption{
  712. IPv4Enable: true,
  713. IPv6Enable: true,
  714. FakeEnable: false,
  715. })
  716. if err != nil {
  717. t.Fatal("unexpected error: ", err)
  718. }
  719. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 4}}); r != "" {
  720. t.Fatal(r)
  721. }
  722. }
  723. { // Will match dotless:
  724. ips, err := client.LookupIP("Mijia Cloud", feature_dns.IPOption{
  725. IPv4Enable: true,
  726. IPv6Enable: true,
  727. FakeEnable: false,
  728. })
  729. if err != nil {
  730. t.Fatal("unexpected error: ", err)
  731. }
  732. if r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != "" {
  733. t.Fatal(r)
  734. }
  735. }
  736. endTime := time.Now()
  737. if startTime.After(endTime.Add(time.Second * 2)) {
  738. t.Error("DNS query doesn't finish in 2 seconds.")
  739. }
  740. }
  741. func TestMultiMatchPrioritizedDomain(t *testing.T) {
  742. port := udp.PickPort()
  743. dnsServer := dns.Server{
  744. Addr: "127.0.0.1:" + port.String(),
  745. Net: "udp",
  746. Handler: &staticHandler{},
  747. UDPSize: 1200,
  748. }
  749. go dnsServer.ListenAndServe()
  750. time.Sleep(time.Second)
  751. config := &core.Config{
  752. App: []*serial.TypedMessage{
  753. serial.ToTypedMessage(&Config{
  754. NameServers: []*net.Endpoint{
  755. {
  756. Network: net.Network_UDP,
  757. Address: &net.IPOrDomain{
  758. Address: &net.IPOrDomain_Ip{
  759. Ip: []byte{127, 0, 0, 1},
  760. },
  761. },
  762. Port: 9999, /* unreachable */
  763. },
  764. },
  765. NameServer: []*NameServer{
  766. {
  767. Address: &net.Endpoint{
  768. Network: net.Network_UDP,
  769. Address: &net.IPOrDomain{
  770. Address: &net.IPOrDomain_Ip{
  771. Ip: []byte{127, 0, 0, 1},
  772. },
  773. },
  774. Port: uint32(port),
  775. },
  776. PrioritizedDomain: []*NameServer_PriorityDomain{
  777. {
  778. Type: DomainMatchingType_Subdomain,
  779. Domain: "google.com",
  780. },
  781. },
  782. Geoip: []*router.GeoIP{
  783. { // Will only match 8.8.8.8 and 8.8.4.4
  784. Cidr: []*router.CIDR{
  785. {Ip: []byte{8, 8, 8, 8}, Prefix: 32},
  786. {Ip: []byte{8, 8, 4, 4}, Prefix: 32},
  787. },
  788. },
  789. },
  790. },
  791. {
  792. Address: &net.Endpoint{
  793. Network: net.Network_UDP,
  794. Address: &net.IPOrDomain{
  795. Address: &net.IPOrDomain_Ip{
  796. Ip: []byte{127, 0, 0, 1},
  797. },
  798. },
  799. Port: uint32(port),
  800. },
  801. PrioritizedDomain: []*NameServer_PriorityDomain{
  802. {
  803. Type: DomainMatchingType_Subdomain,
  804. Domain: "google.com",
  805. },
  806. },
  807. Geoip: []*router.GeoIP{
  808. { // Will match 8.8.8.8 and 8.8.8.7, etc
  809. Cidr: []*router.CIDR{
  810. {Ip: []byte{8, 8, 8, 7}, Prefix: 24},
  811. },
  812. },
  813. },
  814. },
  815. {
  816. Address: &net.Endpoint{
  817. Network: net.Network_UDP,
  818. Address: &net.IPOrDomain{
  819. Address: &net.IPOrDomain_Ip{
  820. Ip: []byte{127, 0, 0, 1},
  821. },
  822. },
  823. Port: uint32(port),
  824. },
  825. PrioritizedDomain: []*NameServer_PriorityDomain{
  826. {
  827. Type: DomainMatchingType_Subdomain,
  828. Domain: "api.google.com",
  829. },
  830. },
  831. Geoip: []*router.GeoIP{
  832. { // Will only match 8.8.7.7 (api.google.com)
  833. Cidr: []*router.CIDR{
  834. {Ip: []byte{8, 8, 7, 7}, Prefix: 32},
  835. },
  836. },
  837. },
  838. },
  839. {
  840. Address: &net.Endpoint{
  841. Network: net.Network_UDP,
  842. Address: &net.IPOrDomain{
  843. Address: &net.IPOrDomain_Ip{
  844. Ip: []byte{127, 0, 0, 1},
  845. },
  846. },
  847. Port: uint32(port),
  848. },
  849. PrioritizedDomain: []*NameServer_PriorityDomain{
  850. {
  851. Type: DomainMatchingType_Full,
  852. Domain: "v2.api.google.com",
  853. },
  854. },
  855. Geoip: []*router.GeoIP{
  856. { // Will only match 8.8.7.8 (v2.api.google.com)
  857. Cidr: []*router.CIDR{
  858. {Ip: []byte{8, 8, 7, 8}, Prefix: 32},
  859. },
  860. },
  861. },
  862. },
  863. },
  864. }),
  865. serial.ToTypedMessage(&dispatcher.Config{}),
  866. serial.ToTypedMessage(&proxyman.OutboundConfig{}),
  867. serial.ToTypedMessage(&policy.Config{}),
  868. },
  869. Outbound: []*core.OutboundHandlerConfig{
  870. {
  871. ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
  872. },
  873. },
  874. }
  875. v, err := core.New(config)
  876. common.Must(err)
  877. client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
  878. startTime := time.Now()
  879. { // Will match server 1,2 and server 1 returns expected ip
  880. ips, err := client.LookupIP("google.com", feature_dns.IPOption{
  881. IPv4Enable: true,
  882. IPv6Enable: true,
  883. FakeEnable: false,
  884. })
  885. if err != nil {
  886. t.Fatal("unexpected error: ", err)
  887. }
  888. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
  889. t.Fatal(r)
  890. }
  891. }
  892. { // Will match server 1,2 and server 1 returns unexpected ip, then server 2 returns expected one
  893. ips, err := client.LookupIP("ipv6.google.com", feature_dns.IPOption{
  894. IPv4Enable: true,
  895. IPv6Enable: false,
  896. FakeEnable: false,
  897. })
  898. if err != nil {
  899. t.Fatal("unexpected error: ", err)
  900. }
  901. if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 7}}); r != "" {
  902. t.Fatal(r)
  903. }
  904. }
  905. { // Will match server 3,1,2 and server 3 returns expected one
  906. ips, err := client.LookupIP("api.google.com", feature_dns.IPOption{
  907. IPv4Enable: true,
  908. IPv6Enable: true,
  909. FakeEnable: false,
  910. })
  911. if err != nil {
  912. t.Fatal("unexpected error: ", err)
  913. }
  914. if r := cmp.Diff(ips, []net.IP{{8, 8, 7, 7}}); r != "" {
  915. t.Fatal(r)
  916. }
  917. }
  918. { // Will match server 4,3,1,2 and server 4 returns expected one
  919. ips, err := client.LookupIP("v2.api.google.com", feature_dns.IPOption{
  920. IPv4Enable: true,
  921. IPv6Enable: true,
  922. FakeEnable: false,
  923. })
  924. if err != nil {
  925. t.Fatal("unexpected error: ", err)
  926. }
  927. if r := cmp.Diff(ips, []net.IP{{8, 8, 7, 8}}); r != "" {
  928. t.Fatal(r)
  929. }
  930. }
  931. endTime := time.Now()
  932. if startTime.After(endTime.Add(time.Second * 2)) {
  933. t.Error("DNS query doesn't finish in 2 seconds.")
  934. }
  935. }