server_test.go 22 KB

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