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