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