dns_test.go 25 KB

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