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