DNS 解析器(DNS Resolver)

时间:2025-04-06 08:20:17
  • 562__BIONIC_WEAK_FOR_NATIVE_BRIDGE

  • 563int

  • 564getaddrinfo(const char *hostname, const char *servname,

  • 565 const struct addrinfo *hints, struct addrinfo **res)

  • 566{

  • 567 return android_getaddrinfofornet(hostname, servname, hints, NETID_UNSET, MARK_UNSET, res);

  • 568}

  •  
  • 570__BIONIC_WEAK_FOR_NATIVE_BRIDGE

  • 571int

  • 572android_getaddrinfofornet(const char *hostname, const char *servname,

  • 573 const struct addrinfo *hints, unsigned netid, unsigned mark, struct addrinfo **res)

  • 574{

  • 575 struct android_net_context netcontext = {

  • 576 .app_netid = netid,

  • 577 .app_mark = mark,

  • 578 .dns_netid = netid,

  • 579 .dns_mark = mark,

  • 580 .uid = NET_CONTEXT_INVALID_UID,

  • 581 };

  • 582 return android_getaddrinfofornetcontext(hostname, servname, hints, &netcontext, res);

  • 583}

  • 584

  • 585__BIONIC_WEAK_FOR_NATIVE_BRIDGE

  • 586int

  • 587android_getaddrinfofornetcontext(const char *hostname, const char *servname,

  • 588 const struct addrinfo *hints, const struct android_net_context *netcontext,

  • 589 struct addrinfo **res)

  • 590{

  • 591 struct addrinfo sentinel;

  • 592 struct addrinfo *cur;

  • 593 int error = 0;

  • 594 struct addrinfo ai;

  • 595 struct addrinfo ai0;

  • 596 struct addrinfo *pai;

  • 597 const struct explore *ex;

  • 598

  • 599 /* hostname is allowed to be NULL */

  • 600 /* servname is allowed to be NULL */

  • 601 /* hints is allowed to be NULL */

  • 602 assert(res != NULL);

  • 603 assert(netcontext != NULL);

  • 604 memset(&sentinel, 0, sizeof(sentinel));

  • 605 cur = &sentinel;

  • 606 pai = &ai;

  • 607 pai->ai_flags = 0;

  • 608 pai->ai_family = PF_UNSPEC;

  • 609 pai->ai_socktype = ANY;

  • 610 pai->ai_protocol = ANY;

  • 611 pai->ai_addrlen = 0;

  • 612 pai->ai_canonname = NULL;

  • 613 pai->ai_addr = NULL;

  • 614 pai->ai_next = NULL;

  • 615

  • 616 if (hostname == NULL && servname == NULL)

  • 617 return EAI_NONAME;

  • 618 if (hints) {

  • 619 /* error check for hints */

  • 620 if (hints->ai_addrlen || hints->ai_canonname ||

  • 621 hints->ai_addr || hints->ai_next)

  • 622 ERR(EAI_BADHINTS); /* xxx */

  • 623 if (hints->ai_flags & ~AI_MASK)

  • 624 ERR(EAI_BADFLAGS);

  • 625 switch (hints->ai_family) {

  • 626 case PF_UNSPEC:

  • 627 case PF_INET:

  • 628#ifdef INET6

  • 629 case PF_INET6:

  • 630#endif

  • 631 break;

  • 632 default:

  • 633 ERR(EAI_FAMILY);

  • 634 }

  • 635 memcpy(pai, hints, sizeof(*pai));

  • 636

  • 637 /*

  • 638 * if both socktype/protocol are specified, check if they

  • 639 * are meaningful combination.

  • 640 */

  • 641 if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {

  • 642 for (ex = explore; ex->e_af >= 0; ex++) {

  • 643 if (pai->ai_family != ex->e_af)

  • 644 continue;

  • 645 if (ex->e_socktype == ANY)

  • 646 continue;

  • 647 if (ex->e_protocol == ANY)

  • 648 continue;

  • 649 if (pai->ai_socktype == ex->e_socktype

  • 650 && pai->ai_protocol != ex->e_protocol) {

  • 651 ERR(EAI_BADHINTS);

  • 652 }

  • 653 }

  • 654 }

  • 655 }

  • 656

  • 657 /*

  • 658 * check for special cases. (1) numeric servname is disallowed if

  • 659 * socktype/protocol are left unspecified. (2) servname is disallowed

  • 660 * for raw and other inet{,6} sockets.

  • 661 */

  • 662 if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)

  • 663#ifdef PF_INET6

  • 664 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)

  • 665#endif

  • 666 ) {

  • 667 ai0 = *pai; /* backup *pai */

  • 668

  • 669 if (pai->ai_family == PF_UNSPEC) {

  • 670#ifdef PF_INET6

  • 671 pai->ai_family = PF_INET6;

  • 672#else

  • 673 pai->ai_family = PF_INET;

  • 674#endif

  • 675 }

  • 676 error = get_portmatch(pai, servname);

  • 677 if (error)

  • 678 ERR(error);

  • 679

  • 680 *pai = ai0;

  • 681 }

  • 682

  • 683 ai0 = *pai;

  • 684

  • 685 /* NULL hostname, or numeric hostname */

  • 686 for (ex = explore; ex->e_af >= 0; ex++) {

  • 687 *pai = ai0;

  • 688

  • 689 /* PF_UNSPEC entries are prepared for DNS queries only */

  • 690 if (ex->e_af == PF_UNSPEC)

  • 691 continue;

  • 692

  • 693 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))

  • 694 continue;

  • 695 if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))

  • 696 continue;

  • 697 if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))

  • 698 continue;

  • 699

  • 700 if (pai->ai_family == PF_UNSPEC)

  • 701 pai->ai_family = ex->e_af;

  • 702 if (pai->ai_socktype == ANY && ex->e_socktype != ANY)

  • 703 pai->ai_socktype = ex->e_socktype;

  • 704 if (pai->ai_protocol == ANY && ex->e_protocol != ANY)

  • 705 pai->ai_protocol = ex->e_protocol;

  • 706

  • 707 if (hostname == NULL)

  • 708 error = explore_null(pai, servname, &cur->ai_next);

  • 709 else

  • 710 error = explore_numeric_scope(pai, hostname, servname,

  • 711 &cur->ai_next);

  • 712

  • 713 if (error)

  • 714 goto free;

  • 715

  • 716 while (cur->ai_next)

  • 717 cur = cur->ai_next;

  • 718 }

  • 719

  • 720 /*

  • 721 * XXX

  • 722 * If numeric representation of AF1 can be interpreted as FQDN

  • 723 * representation of AF2, we need to think again about the code below.

  • 724 */

  • 725 if (sentinel.ai_next)

  • 726 goto good;

  • 727

  • 728 if (hostname == NULL)

  • 729 ERR(EAI_NODATA);

  • 730 if (pai->ai_flags & AI_NUMERICHOST)

  • 731 ERR(EAI_NONAME);

  • 732

  • 733#if defined(__ANDROID__)

  • 734 int gai_error = android_getaddrinfo_proxy(

  • 735 hostname, servname, hints, res, netcontext->app_netid);

  • 736 if (gai_error != EAI_SYSTEM) {

  • 737 return gai_error;

  • 738 }

  • 739#endif

  • 740

  • 741 /*

  • 742 * hostname as alphabetical name.

  • 743 * we would like to prefer AF_INET6 than AF_INET, so we'll make a

  • 744 * outer loop by AFs.

  • 745 */

  • 746 for (ex = explore; ex->e_af >= 0; ex++) {

  • 747 *pai = ai0;

  • 748

  • 749 /* require exact match for family field */

  • 750 if (pai->ai_family != ex->e_af)

  • 751 continue;

  • 752

  • 753 if (!MATCH(pai->ai_socktype, ex->e_socktype,

  • 754 WILD_SOCKTYPE(ex))) {

  • 755 continue;

  • 756 }

  • 757 if (!MATCH(pai->ai_protocol, ex->e_protocol,

  • 758 WILD_PROTOCOL(ex))) {

  • 759 continue;

  • 760 }

  • 761

  • 762 if (pai->ai_socktype == ANY && ex->e_socktype != ANY)

  • 763 pai->ai_socktype = ex->e_socktype;

  • 764 if (pai->ai_protocol == ANY && ex->e_protocol != ANY)

  • 765 pai->ai_protocol = ex->e_protocol;

  • 766

  • 767 error = explore_fqdn(

  • 768 pai, hostname, servname, &cur->ai_next, netcontext);

  • 769

  • 770 while (cur && cur->ai_next)

  • 771 cur = cur->ai_next;

  • 772 }

  • 773

  • 774 /* XXX */

  • 775 if (sentinel.ai_next)

  • 776 error = 0;

  • 777

  • 778 if (error)

  • 779 goto free;

  • 780 if (error == 0) {

  • 781 if (sentinel.ai_next) {

  • 782 good:

  • 783 *res = sentinel.ai_next;

  • 784 return SUCCESS;

  • 785 } else

  • 786 error = EAI_FAIL;

  • 787 }

  • 788 free:

  • 789 bad:

  • 790 if (sentinel.ai_next)

  • 791 freeaddrinfo(sentinel.ai_next);

  • 792 *res = NULL;

  • 793 return error;

  • 794}