DNS 解析器(DNS Resolver)

DNS 解析器(DNS Resolver)

DNS 解析器模块可保护用户免受 DNS 拦截和配置更新攻击,并改进了 DNS 解析的网络性能。此模块包含用于实现 DNS 桩解析器的代码,该解析器可将 www.google.com 等名称转换为 IP 地址(例如 2001:db8::1)。DNS 桩解析器支持 Java API 元素(如 InetAddress#getAllByName 和 Network#getAllByName)以及原生网络功能,且可发送和接收 DNS 查询以及缓存结果。

Android 10 中的变化

在搭载 Android 9 及更低版本的设备上,DNS 解析器代码分布在 Bionic 和 netd 上。DNS 查找操作集中在 netd 守护程序中,以便进行系统级缓存,而应用在 Bionic 中调用函数(例如 getaddrinfo)。查询会通过 UNIX 套接字发送到 /dev/socket/dnsproxyd,再到 netd 守护程序,该守护程序会解析请求并再次调用 getaddrinfo,以发出 DNS 查找请求,然后它会缓存结果以供其他应用使用。DNS 解析器实现主要包含在 bionic/libc/dns/ 中,部分包含在 system/netd/server/dns 中。

Android 10 将 DNS 解析器代码移至 system/netd/resolv,,将其转换为 C++,然后对代码进行了翻新和重构。由于应用兼容性方面的原因,Bionic 中的代码继续存在,但系统不会再调用它们。以下源文件路径受到重构的影响:

  • bionic/libc/dns
  • system/netd/client
  • system/netd/server/dns
  • system/netd/server/DnsProxyListener.*
  • system/netd/resolv

(1)获取ip地址(域名–>IP地址)

ConnectivityService.updateDnses() ->

DnsManager.setDnsConfigurationForNetwork() ->

mDnsResolver.setResolverConfiguration() -> IDnsResolver.aidl ()

DnsResolverService.setResolverConfiguration()  ->

ResolverController.setResolverConfiguration() ->

res_cache.int resolv_set_nameservers_for_net() ->

getaddrinfo.getaddrinfo_numeric() -> getaddrinfo.android_getaddrinfofornetcontext(hostname, servname, &hints, &netcontext, result);

 

(2)DNS server list 设置(set name servers for a network)

_resolv_set_nameservers_for_net

 


http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/java/net/InetAddress.java#1105

 
  1. 1077 /**

  2. 1078 * Determines the IP address of a host, given the host's name.

  3. 1097 * @param host the specified host, or {@code null}.

  4. 1098 * @return an IP address for the given host name.

  5. 1104 */

  6. 1105 public static InetAddress getByName(String host)

  7. 1106 throws UnknownHostException {

  8. 1107 // Android-changed: Rewritten on the top of Libcore.os.

  9. 1108 return impl.lookupAllHostAddr(host, NETID_UNSET)[0];

  10. 1109 }

  11.  
  12. 1111 /**

  13. 1112 * Given the name of a host, returns an array of its IP addresses,

  14. 1113 * based on the configured name service on the system.

  15. 1139 * @param host the name of the host, or {@code null}.

  16. 1140 * @return an array of all the IP addresses for a given host name.

  17. 1149 */

  18. 1150 public static InetAddress[] getAllByName(String host)

  19. 1151 throws UnknownHostException {

  20. 1152 // Android-changed: Resolves a hostname using Libcore.os.

  21. 1153 // Also, returns both the Inet4 and Inet6 loopback for null/empty host

  22. 1154 return impl.lookupAllHostAddr(host, NETID_UNSET).clone();

  23. 1155 }

  24.  
  25.  

lookupAllHostAddr在Android M上的名字叫做getAllByNameImpl

http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/java/net/Inet6AddressImpl.java#88

 
  1. 79 // BEGIN Android-changed: Rewrote hostname lookup methods on top of Libcore.os.

  2. 80 /*

  3. 81 public native String getLocalHostName() throws UnknownHostException;

  4. 82 public native InetAddress[]

  5. 83 lookupAllHostAddr(String hostname) throws UnknownHostException;

  6. 84 public native String getHostByAddr(byte[] addr) throws UnknownHostException;

  7. 85 private native boolean isReachable0(byte[] addr, int scope, int timeout, byte[] inf, int ttl, int if_scope) throws IOException;

  8. 86 */

  9. 87 @Override

  10. 88 public InetAddress[] lookupAllHostAddr(String host, int netId) throws UnknownHostException {

  11. 89 if (host == null || host.isEmpty()) {

  12. 90 // Android-changed: Return both the Inet4 and Inet6 loopback addresses

  13. 91 // when host == null or empty.

  14. 92 return loopbackAddresses();

  15. 93 }

  16. 94

  17. 95 // Is it a numeric address?

  18. 96 InetAddress result = InetAddress.parseNumericAddressNoThrow(host);

  19. 97 if (result != null) {

  20. 98 result = InetAddress.disallowDeprecatedFormats(host, result);

  21. 99 if (result == null) {

  22. 100 throw new UnknownHostException("Deprecated IPv4 address format: " + host);

  23. 101 }

  24. 102 return new InetAddress[] { result };

  25. 103 }

  26. 104

  27. 105 return lookupHostByName(host, netId);

  28. 106 }

  29.  
  30. 323 // BEGIN Android-changed: Let loopbackAddresses() return both Inet4 and Inet6 loopbacks.

  31. 324 @Override

  32. 325 public InetAddress[] loopbackAddresses() {

  33. 326 synchronized (Inet6AddressImpl.class) {

  34. 327 // We avoid initializing anyLocalAddress during <clinit> to avoid issues

  35. 328 // caused by the dependency chains of these classes. InetAddress depends on

  36. 329 // InetAddressImpl, but Inet6Address & Inet4Address are its subclasses.

  37. 330 // Also see {@code anyLocalAddress).

  38. 331 if (loopbackAddresses == null) {

  39. 332 loopbackAddresses = new InetAddress[]{Inet6Address.LOOPBACK, Inet4Address.LOOPBACK};

  40. 333 }

  41. 334

  42. 335 return loopbackAddresses;

  43. 336 }

  44. 337 }

  45.  
  46.  

http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/java/net/InetAddress.java#1622

 
  1. 1622 static InetAddress parseNumericAddressNoThrow(String address) {

  2. 1623 // Accept IPv6 addresses (only) in square brackets for compatibility.

  3. 1624 if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {

  4. 1625 address = address.substring(1, address.length() - 1);

  5. 1626 }

  6. 1627 StructAddrinfo hints = new StructAddrinfo();

  7. 1628 hints.ai_flags = AI_NUMERICHOST;

  8. 1629 InetAddress[] addresses = null;

  9. 1630 try {

  10. 1631 addresses = Libcore.os.android_getaddrinfo(address, hints, NETID_UNSET);

  11. 1632 } catch (GaiException ignored) {

  12. 1633 }

  13. 1634 return (addresses != null) ? addresses[0] : null;

  14. 1635 }

http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/java/net/Inet6AddressImpl.java#115

 
  1. 108 /**

  2. 109 * Resolves a hostname to its IP addresses using a cache.

  3. 110 *

  4. 111 * @param host the hostname to resolve.

  5. 112 * @param netId the network to perform resolution upon.

  6. 113 * @return the IP addresses of the host.

  7. 114 */

  8. 115 private static InetAddress[] lookupHostByName(String host, int netId)

  9. 116 throws UnknownHostException {

  10. 117 BlockGuard.getThreadPolicy().onNetwork();

  11. 118 // Do we have a result cached?

  12. 119 Object cachedResult = addressCache.get(host, netId);

  13. 120 if (cachedResult != null) {

  14. 121 if (cachedResult instanceof InetAddress[]) {

  15. 122 // A cached positive result.

  16. 123 return (InetAddress[]) cachedResult;

  17. 124 } else {

  18. 125 // A cached negative result.

  19. 126 throw new UnknownHostException((String) cachedResult);

  20. 127 }

  21. 128 }

  22. 129 try {

  23. 130 StructAddrinfo hints = new StructAddrinfo();

  24. 131 hints.ai_flags = AI_ADDRCONFIG;

  25. 132 hints.ai_family = AF_UNSPEC;

  26. 133 // If we don't specify a socket type, every address will appear twice, once

  27. 134 // for SOCK_STREAM and one for SOCK_DGRAM. Since we do not return the family

  28. 135 // anyway, just pick one.

  29. 136 hints.ai_socktype = SOCK_STREAM;

  30. 137 InetAddress[] addresses = Libcore.os.android_getaddrinfo(host, hints, netId);

  31. 138 // TODO: should getaddrinfo set the hostname of the InetAddresses it returns?

  32. 139 for (InetAddress address : addresses) {

  33. 140 address.holder().hostName = host;

  34. 141 address.holder().originalHostName = host;

  35. 142 }

  36. 143 addressCache.put(host, netId, addresses);

  37. 144 return addresses;

  38. 145 } catch (GaiException gaiException) {

  39. 146 // If the failure appears to have been a lack of INTERNET permission, throw a clear

  40. 147 // SecurityException to aid in debugging this common mistake.

  41. 148 // http://code.google.com/p/android/issues/detail?id=15722

  42. 149 if (gaiException.getCause() instanceof ErrnoException) {

  43. 150 if (((ErrnoException) gaiException.getCause()).errno == EACCES) {

  44. 151 throw new SecurityException("Permission denied (missing INTERNET permission?)", gaiException);

  45. 152 }

  46. 153 }

  47. 154 // Otherwise, throw an UnknownHostException.

  48. 155 String detailMessage = "Unable to resolve host \"" + host + "\": " + Libcore.os.gai_strerror(gaiException.error);

  49. 156 addressCache.putUnknownHost(host, netId, detailMessage);

  50. 157 throw gaiException.rethrowAsUnknownHostException(detailMessage);

  51. 158 }

  52. 159 }

上面都调用了Libcore.os.android_getaddrinfo

http://androidxref.com/9.0.0_r3/xref/libcore/luni/src/main/java/libcore/io/Libcore.java#19

 
  1. 19public final class Libcore {

  2. 20 private Libcore() { }

  3. 21

  4. 22 /**

  5. 23 * Direct access to syscalls. Code should strongly prefer using {@link #os}

  6. 24 * unless it has a strong reason to bypass the helpful checks/guards that it

  7. 25 * provides.

  8. 26 */

  9. 27 public static Os rawOs = new Linux();

  10. 28

  11. 29 /**

  12. 30 * Access to syscalls with helpful checks/guards.

  13. 31 */

  14. 32 public static Os os = new BlockGuardOs(rawOs);

  15. 33}

Os对象是一系列系统调用的抽象接口,从LibCore.java中可以看出它是通过Linux这个类实现的

http://androidxref.com/9.0.0_r3/xref/libcore/luni/src/main/java/libcore/io/Linux.java#53

 
  1. 48public final class Linux implements Os {

  2. 49 Linux() { }

  3.  
  4. 53 public native InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;

http://androidxref.com/9.0.0_r3/xref/libcore/luni/src/main/java/libcore/io/BlockGuardOs.java#164

 
  1. 40/**

  2. 41 * Informs BlockGuard of any activity it should be aware of.

  3. 42 */

  4. 43public class BlockGuardOs extends ForwardingOs {

  5. 44 public BlockGuardOs(Os os) {

  6. 45 super(os);

  7. 46 }

  8.  
  9.  
  10. 164 @Override public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException {

  11. 165 // With AI_NUMERICHOST flag set, the node must a numerical network address, therefore no

  12. 166 // host address lookups will be performed. In this case, it is fine to perform on main

  13. 167 // thread.

  14. 168 boolean isNumericHost = (hints.ai_flags & AI_NUMERICHOST) != 0;

  15. 169 if (!isNumericHost) {

  16. 170 BlockGuard.getThreadPolicy().onNetwork();

  17. 171 }

  18. 172 return os.android_getaddrinfo(node, hints, netId);

  19. 173 }

再找OS类

http://androidxref.com/9.0.0_r3/xref/libcore/luni/src/main/java/libcore/io/Os.java#50

 
  1. 47public interface Os {

  2. 50 public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;

参考

得知Linux.java通过JNI (libcore_io_Linux.cpp)调用linux的posix API,那么知道了,C层的实现都在libcore_io_Linux.cpp中,咱们来看下。

http://androidxref.com/9.0.0_r3/xref/libcore/luni/src/main/native/libcore_io_Linux.cpp#1244

 
  1. 1244static jobjectArray Linux_android_getaddrinfo(JNIEnv* env, jobject, jstring javaNode,

  2. 1245 jobject javaHints, jint netId) {

  3. 1246 ScopedUtfChars node(env, javaNode);

  4. 1247 if (node.c_str() == NULL) {

  5. 1248 return NULL;

  6. 1249 }

  7. 1250

  8. 1251 static jfieldID flagsFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_flags", "I");

  9. 1252 static jfieldID familyFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_family", "I");

  10. 1253 static jfieldID socktypeFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_socktype", "I");

  11. 1254 static jfieldID protocolFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_protocol", "I");

  12. 1255

  13. 1256 addrinfo hints;

  14. 1257 memset(&hints, 0, sizeof(hints));

  15. 1258 hints.ai_flags = env->GetIntField(javaHints, flagsFid);

  16. 1259 hints.ai_family = env->GetIntField(javaHints, familyFid);

  17. 1260 hints.ai_socktype = env->GetIntField(javaHints, socktypeFid);

  18. 1261 hints.ai_protocol = env->GetIntField(javaHints, protocolFid);

  19. 1262

  20. 1263 addrinfo* addressList = NULL;

  21. 1264 errno = 0;

  22. 1265 int rc = android_getaddrinfofornet(node.c_str(), NULL, &hints, netId, 0, &addressList);

  23. 1266 std::unique_ptr<addrinfo, addrinfo_deleter> addressListDeleter(addressList);

  24. 1267 if (rc != 0) {

  25. 1268 throwGaiException(env, "android_getaddrinfo", rc);

  26. 1269 return NULL;

  27. 1270 }

  28. 1271

  29. 1272 // Count results so we know how to size the output array.

  30. 1273 int addressCount = 0;

  31. 1274 for (addrinfo* ai = addressList; ai != NULL; ai = ai->ai_next) {

  32. 1275 if (ai->ai_family == AF_INET || ai->ai_family == AF_INET6) {

  33. 1276 ++addressCount;

  34. 1277 } else {

  35. 1278 ALOGE("android_getaddrinfo unexpected ai_family %i", ai->ai_family);

  36. 1279 }

  37. 1280 }

  38. 1281 if (addressCount == 0) {

  39. 1282 return NULL;

  40. 1283 }

  41. 1284

  42. 1285 // Prepare output array.

  43. 1286 jobjectArray result = env->NewObjectArray(addressCount, JniConstants::inetAddressClass, NULL);

  44. 1287 if (result == NULL) {

  45. 1288 return NULL;

  46. 1289 }

  47. 1290

  48. 1291 // Examine returned addresses one by one, save them in the output array.

  49. 1292 int index = 0;

  50. 1293 for (addrinfo* ai = addressList; ai != NULL; ai = ai->ai_next) {

  51. 1294 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {

  52. 1295 // Unknown address family. Skip this address.

  53. 1296 ALOGE("android_getaddrinfo unexpected ai_family %i", ai->ai_family);

  54. 1297 continue;

  55. 1298 }

  56. 1299

  57. 1300 // Convert each IP address into a Java byte array.

  58. 1301 sockaddr_storage& address = *reinterpret_cast<sockaddr_storage*>(ai->ai_addr);

  59. 1302 ScopedLocalRef<jobject> inetAddress(env, sockaddrToInetAddress(env, address, NULL));

  60. 1303 if (inetAddress.get() == NULL) {

  61. 1304 return NULL;

  62. 1305 }

  63. 1306 env->SetObjectArrayElement(result, index, inetAddress.get());

  64. 1307 ++index;

  65. 1308 }

  66. 1309 return result;

  67. 1310}

调用android_getaddrinfofornet()

http://androidxref.com/9.0.0_r3/xref/libcore/luni/src/main/native/Portability.h#28

 
  1. 28static inline int android_getaddrinfofornet(const char* hostname, const char* servname,

  2. 29 const struct addrinfo* hints, unsigned /*netid*/, unsigned /*mark*/, struct addrinfo** res) {

  3. 30 return getaddrinfo(hostname, servname, hints, res);

  4. 31}

最终调用到bionic/libc/dns/net/getaddrinfo.c

http://androidxref.com/9.0.0_r3/xref/bionic/libc/dns/net/getaddrinfo.c#564

 
  1. 562__BIONIC_WEAK_FOR_NATIVE_BRIDGE

  2. 563int

  3. 564getaddrinfo(const char *hostname, const char *servname,

  4. 565 const struct addrinfo *hints, struct addrinfo **res)

  5. 566{

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

  7. 568}

  8.  
  9. 570__BIONIC_WEAK_FOR_NATIVE_BRIDGE

  10. 571int

  11. 572android_getaddrinfofornet(const char *hostname, const char *servname,

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

  13. 574{

  14. 575 struct android_net_context netcontext = {

  15. 576 .app_netid = netid,

  16. 577 .app_mark = mark,

  17. 578 .dns_netid = netid,

  18. 579 .dns_mark = mark,

  19. 580 .uid = NET_CONTEXT_INVALID_UID,

  20. 581 };

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

  22. 583}

  23. 584

  24. 585__BIONIC_WEAK_FOR_NATIVE_BRIDGE

  25. 586int

  26. 587android_getaddrinfofornetcontext(const char *hostname, const char *servname,

  27. 588 const struct addrinfo *hints, const struct android_net_context *netcontext,

  28. 589 struct addrinfo **res)

  29. 590{

  30. 591 struct addrinfo sentinel;

  31. 592 struct addrinfo *cur;

  32. 593 int error = 0;

  33. 594 struct addrinfo ai;

  34. 595 struct addrinfo ai0;

  35. 596 struct addrinfo *pai;

  36. 597 const struct explore *ex;

  37. 598

  38. 599 /* hostname is allowed to be NULL */

  39. 600 /* servname is allowed to be NULL */

  40. 601 /* hints is allowed to be NULL */

  41. 602 assert(res != NULL);

  42. 603 assert(netcontext != NULL);

  43. 604 memset(&sentinel, 0, sizeof(sentinel));

  44. 605 cur = &sentinel;

  45. 606 pai = &ai;

  46. 607 pai->ai_flags = 0;

  47. 608 pai->ai_family = PF_UNSPEC;

  48. 609 pai->ai_socktype = ANY;

  49. 610 pai->ai_protocol = ANY;

  50. 611 pai->ai_addrlen = 0;

  51. 612 pai->ai_canonname = NULL;

  52. 613 pai->ai_addr = NULL;

  53. 614 pai->ai_next = NULL;

  54. 615

  55. 616 if (hostname == NULL && servname == NULL)

  56. 617 return EAI_NONAME;

  57. 618 if (hints) {

  58. 619 /* error check for hints */

  59. 620 if (hints->ai_addrlen || hints->ai_canonname ||

  60. 621 hints->ai_addr || hints->ai_next)

  61. 622 ERR(EAI_BADHINTS); /* xxx */

  62. 623 if (hints->ai_flags & ~AI_MASK)

  63. 624 ERR(EAI_BADFLAGS);

  64. 625 switch (hints->ai_family) {

  65. 626 case PF_UNSPEC:

  66. 627 case PF_INET:

  67. 628#ifdef INET6

  68. 629 case PF_INET6:

  69. 630#endif

  70. 631 break;

  71. 632 default:

  72. 633 ERR(EAI_FAMILY);

  73. 634 }

  74. 635 memcpy(pai, hints, sizeof(*pai));

  75. 636

  76. 637 /*

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

  78. 639 * are meaningful combination.

  79. 640 */

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

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

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

  83. 644 continue;

  84. 645 if (ex->e_socktype == ANY)

  85. 646 continue;

  86. 647 if (ex->e_protocol == ANY)

  87. 648 continue;

  88. 649 if (pai->ai_socktype == ex->e_socktype

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

  90. 651 ERR(EAI_BADHINTS);

  91. 652 }

  92. 653 }

  93. 654 }

  94. 655 }

  95. 656

  96. 657 /*

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

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

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

  100. 661 */

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

  102. 663#ifdef PF_INET6

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

  104. 665#endif

  105. 666 ) {

  106. 667 ai0 = *pai; /* backup *pai */

  107. 668

  108. 669 if (pai->ai_family == PF_UNSPEC) {

  109. 670#ifdef PF_INET6

  110. 671 pai->ai_family = PF_INET6;

  111. 672#else

  112. 673 pai->ai_family = PF_INET;

  113. 674#endif

  114. 675 }

  115. 676 error = get_portmatch(pai, servname);

  116. 677 if (error)

  117. 678 ERR(error);

  118. 679

  119. 680 *pai = ai0;

  120. 681 }

  121. 682

  122. 683 ai0 = *pai;

  123. 684

  124. 685 /* NULL hostname, or numeric hostname */

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

  126. 687 *pai = ai0;

  127. 688

  128. 689 /* PF_UNSPEC entries are prepared for DNS queries only */

  129. 690 if (ex->e_af == PF_UNSPEC)

  130. 691 continue;

  131. 692

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

  133. 694 continue;

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

  135. 696 continue;

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

  137. 698 continue;

  138. 699

  139. 700 if (pai->ai_family == PF_UNSPEC)

  140. 701 pai->ai_family = ex->e_af;

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

  142. 703 pai->ai_socktype = ex->e_socktype;

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

  144. 705 pai->ai_protocol = ex->e_protocol;

  145. 706

  146. 707 if (hostname == NULL)

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

  148. 709 else

  149. 710 error = explore_numeric_scope(pai, hostname, servname,

  150. 711 &cur->ai_next);

  151. 712

  152. 713 if (error)

  153. 714 goto free;

  154. 715

  155. 716 while (cur->ai_next)

  156. 717 cur = cur->ai_next;

  157. 718 }

  158. 719

  159. 720 /*

  160. 721 * XXX

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

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

  163. 724 */

  164. 725 if (sentinel.ai_next)

  165. 726 goto good;

  166. 727

  167. 728 if (hostname == NULL)

  168. 729 ERR(EAI_NODATA);

  169. 730 if (pai->ai_flags & AI_NUMERICHOST)

  170. 731 ERR(EAI_NONAME);

  171. 732

  172. 733#if defined(__ANDROID__)

  173. 734 int gai_error = android_getaddrinfo_proxy(

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

  175. 736 if (gai_error != EAI_SYSTEM) {

  176. 737 return gai_error;

  177. 738 }

  178. 739#endif

  179. 740

  180. 741 /*

  181. 742 * hostname as alphabetical name.

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

  183. 744 * outer loop by AFs.

  184. 745 */

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

  186. 747 *pai = ai0;

  187. 748

  188. 749 /* require exact match for family field */

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

  190. 751 continue;

  191. 752

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

  193. 754 WILD_SOCKTYPE(ex))) {

  194. 755 continue;

  195. 756 }

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

  197. 758 WILD_PROTOCOL(ex))) {

  198. 759 continue;

  199. 760 }

  200. 761

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

  202. 763 pai->ai_socktype = ex->e_socktype;

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

  204. 765 pai->ai_protocol = ex->e_protocol;

  205. 766

  206. 767 error = explore_fqdn(

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

  208. 769

  209. 770 while (cur && cur->ai_next)

  210. 771 cur = cur->ai_next;

  211. 772 }

  212. 773

  213. 774 /* XXX */

  214. 775 if (sentinel.ai_next)

  215. 776 error = 0;

  216. 777

  217. 778 if (error)

  218. 779 goto free;

  219. 780 if (error == 0) {

  220. 781 if (sentinel.ai_next) {

  221. 782 good:

  222. 783 *res = sentinel.ai_next;

  223. 784 return SUCCESS;

  224. 785 } else

  225. 786 error = EAI_FAIL;

  226. 787 }

  227. 788 free:

  228. 789 bad:

  229. 790 if (sentinel.ai_next)

  230. 791 freeaddrinfo(sentinel.ai_next);

  231. 792 *res = NULL;

  232. 793 return error;

  233. 794}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值