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. 1111 /**

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

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

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

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

  16. 1149 */

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

  18. 1151 throws UnknownHostException {

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

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

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

  22. 1155 }

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. 323 // BEGIN Android-changed: Let loopbackAddresses() return both Inet4 and Inet6 loopbacks.

  30. 324 @Override

  31. 325 public InetAddress[] loopbackAddresses() {

  32. 326 synchronized (Inet6AddressImpl.class) {

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

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

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

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

  37. 331 if (loopbackAddresses == null) {

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

  39. 333 }

  40. 334

  41. 335 return loopbackAddresses;

  42. 336 }

  43. 337 }

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. 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. 164 @Override public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException {

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

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

  11. 167 // thread.

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

  13. 169 if (!isNumericHost) {

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

  15. 171 }

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

  17. 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;

参考

  • android 从java到C层文件读取流程
  • 深入理解Android的file.exists()

得知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. 570__BIONIC_WEAK_FOR_NATIVE_BRIDGE

  9. 571int

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

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

  12. 574{

  13. 575 struct android_net_context netcontext = {

  14. 576 .app_netid = netid,

  15. 577 .app_mark = mark,

  16. 578 .dns_netid = netid,

  17. 579 .dns_mark = mark,

  18. 580 .uid = NET_CONTEXT_INVALID_UID,

  19. 581 };

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

  21. 583}

  22. 584

  23. 585__BIONIC_WEAK_FOR_NATIVE_BRIDGE

  24. 586int

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

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

  27. 589 struct addrinfo **res)

  28. 590{

  29. 591 struct addrinfo sentinel;

  30. 592 struct addrinfo *cur;

  31. 593 int error = 0;

  32. 594 struct addrinfo ai;

  33. 595 struct addrinfo ai0;

  34. 596 struct addrinfo *pai;

  35. 597 const struct explore *ex;

  36. 598

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

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

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

  40. 602 assert(res != NULL);

  41. 603 assert(netcontext != NULL);

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

  43. 605 cur = &sentinel;

  44. 606 pai = &ai;

  45. 607 pai->ai_flags = 0;

  46. 608 pai->ai_family = PF_UNSPEC;

  47. 609 pai->ai_socktype = ANY;

  48. 610 pai->ai_protocol = ANY;

  49. 611 pai->ai_addrlen = 0;

  50. 612 pai->ai_canonname = NULL;

  51. 613 pai->ai_addr = NULL;

  52. 614 pai->ai_next = NULL;

  53. 615

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

  55. 617 return EAI_NONAME;

  56. 618 if (hints) {

  57. 619 /* error check for hints */

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

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

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

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

  62. 624 ERR(EAI_BADFLAGS);

  63. 625 switch (hints->ai_family) {

  64. 626 case PF_UNSPEC:

  65. 627 case PF_INET:

  66. 628#ifdef INET6

  67. 629 case PF_INET6:

  68. 630#endif

  69. 631 break;

  70. 632 default:

  71. 633 ERR(EAI_FAMILY);

  72. 634 }

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

  74. 636

  75. 637 /*

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

  77. 639 * are meaningful combination.

  78. 640 */

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

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

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

  82. 644 continue;

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

  84. 646 continue;

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

  86. 648 continue;

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

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

  89. 651 ERR(EAI_BADHINTS);

  90. 652 }

  91. 653 }

  92. 654 }

  93. 655 }

  94. 656

  95. 657 /*

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

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

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

  99. 661 */

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

  101. 663#ifdef PF_INET6

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

  103. 665#endif

  104. 666 ) {

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

  106. 668

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

  108. 670#ifdef PF_INET6

  109. 671 pai->ai_family = PF_INET6;

  110. 672#else

  111. 673 pai->ai_family = PF_INET;

  112. 674#endif

  113. 675 }

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

  115. 677 if (error)

  116. 678 ERR(error);

  117. 679

  118. 680 *pai = ai0;

  119. 681 }

  120. 682

  121. 683 ai0 = *pai;

  122. 684

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

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

  125. 687 *pai = ai0;

  126. 688

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

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

  129. 691 continue;

  130. 692

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

  132. 694 continue;

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

  134. 696 continue;

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

  136. 698 continue;

  137. 699

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

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

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

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

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

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

  144. 706

  145. 707 if (hostname == NULL)

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

  147. 709 else

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

  149. 711 &cur->ai_next);

  150. 712

  151. 713 if (error)

  152. 714 goto free;

  153. 715

  154. 716 while (cur->ai_next)

  155. 717 cur = cur->ai_next;

  156. 718 }

  157. 719

  158. 720 /*

  159. 721 * XXX

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

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

  162. 724 */

  163. 725 if (sentinel.ai_next)

  164. 726 goto good;

  165. 727

  166. 728 if (hostname == NULL)

  167. 729 ERR(EAI_NODATA);

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

  169. 731 ERR(EAI_NONAME);

  170. 732

  171. 733#if defined(__ANDROID__)

  172. 734 int gai_error = android_getaddrinfo_proxy(

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

  174. 736 if (gai_error != EAI_SYSTEM) {

  175. 737 return gai_error;

  176. 738 }

  177. 739#endif

  178. 740

  179. 741 /*

  180. 742 * hostname as alphabetical name.

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

  182. 744 * outer loop by AFs.

  183. 745 */

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

  185. 747 *pai = ai0;

  186. 748

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

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

  189. 751 continue;

  190. 752

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

  192. 754 WILD_SOCKTYPE(ex))) {

  193. 755 continue;

  194. 756 }

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

  196. 758 WILD_PROTOCOL(ex))) {

  197. 759 continue;

  198. 760 }

  199. 761

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

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

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

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

  204. 766

  205. 767 error = explore_fqdn(

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

  207. 769

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

  209. 771 cur = cur->ai_next;

  210. 772 }

  211. 773

  212. 774 /* XXX */

  213. 775 if (sentinel.ai_next)

  214. 776 error = 0;

  215. 777

  216. 778 if (error)

  217. 779 goto free;

  218. 780 if (error == 0) {

  219. 781 if (sentinel.ai_next) {

  220. 782 good:

  221. 783 *res = sentinel.ai_next;

  222. 784 return SUCCESS;

  223. 785 } else

  224. 786 error = EAI_FAIL;

  225. 787 }

  226. 788 free:

  227. 789 bad:

  228. 790 if (sentinel.ai_next)

  229. 791 freeaddrinfo(sentinel.ai_next);

  230. 792 *res = NULL;

  231. 793 return error;

  232. 794}

DNS 解析器(DNS Resolver)相关推荐

  1. 详解DNS服务、DNS解析、DNS劫持和污染

    简介 DNS(全称:Domain Name System,中文:域名系统)是互联网的一项服务.它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网.1 前言 要想弄清楚 D ...

  2. android 自定义dns解析器,Android中DNS解析

    当服务端IP变化,大量用户还是访问的以前的IP,连接不上服务器. 我们的客户端软件如何通过域名正确访问服务器?这里面主要涉及到DNS缓存的问题. 什么是DNS? DNS 是域名系统 (Domain N ...

  3. UDP编程-DNS解析器的分析与实现(C语言)

    基本知识 基本介绍 域名系统(英文:Domain Name System,缩写:DNS)的作用是将人类可读的域名 (如,www.example.com) 转换为机器可读的 IP 地址 (如,192.0 ...

  4. DNS解析和DNS缓存, 如何清理DNS解析缓存

    一.DNS解析 DNS解析也即是我们说的域名解析,为了方便记忆,网站都是注册了一个域名,通过域名来访问网站.访问网站内容,实际是通过访问IP地址实现的,所以在域名和IP之前存在一种对应关系,而域名解析 ...

  5. 我眼中的 Nginx(六):深入 Nginx/Openresty 服务里的 DNS 解析

    转自:https://www.upyun.com DNS 解析在 Nginx/OpenResty 的服务里是不可分割的一个功能,本文主要来介绍下 Nginx 和 OpenResty 服务里的一些不同的 ...

  6. DNS解析原理与Bind部署DNS服务

    DNS是什么? DNS(Domain Name System,域名系统)是互联网上最核心的带层级的分布式系统,它负责把域名转换为IP地址.反查IP到域名的反向解析以及宣告邮件路由等信息,使得基于域名提 ...

  7. F5 GTM DNS 知识点和实验 3 -加速dns解析

    第三章:加速dns解析 目标: 了解一个请求是如何发送到一个dns资源池中的,并且了解如何监控资源池中成员的健康状态 使用dns缓存对dns请求进行加速 使用dns express进行对dns请求进行 ...

  8. DNS那些事——从浏览器输入域名开始分析DNS解析过程

    我们就从在浏览器输入域名开始分析. 文章目录 1. DNS服务器有哪些? 2. 从浏览器输入https://abc13.ban2.lcy0000.top/,DNS如何解析? 3. hosts文件是什么 ...

  9. 简单的dns解析过程

    1.在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析. 2.如果hosts里没有这个域名的映射,则 ...

  10. DNS 解析过程详解

    1. DNS解析过程 1).在浏览器中输入www.magedu.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析. 2).如果 ...

最新文章

  1. 警告 '_'用作标识符, JavaSE8 之后的发行版中可能不支持使用'_'作为标识符
  2. Git 高级用法,喜欢就拿去用!
  3. 对于一些手机内存概念的思考、深入理解java的finalize,对于内存优化的小总结...
  4. Python—实训day2—爬虫案例1:访问百度贴吧
  5. 火柴人小程序linux,火柴人你瞅啥小程序
  6. 小程序获取openid保存缓存吗_小程序获取openid踩坑
  7. Idea2021激活码
  8. 幼儿园案例经验迁移_幼儿园故事教学的实施策略
  9. DHCP实现跨网段自动分配IP地址
  10. JavaScript 之 学习网站推荐 强推【javascript.info】
  11. BPM平台为企业“增值”
  12. BTC的历史背景及历程
  13. ios中html怎么横屏,苹果xsmax页面怎么横屏
  14. 必得沾福气卡两张,可沾花花卡、敬业福。(扫福攻略、扫福技巧)
  15. c# 实现金山词霸一样的屏幕取词
  16. 使用CSS实现文字的两端对齐方式
  17. 浏览器主页被劫持 解决方法
  18. 广州3日2夜游行程~
  19. linux中的ubiq命令用途,学习Linux命令(一)
  20. 软件工程——软件危机

热门文章

  1. Mysql大字段blob返回是数字_innodb使用大字段text,blob的一些优化建议(转)
  2. 数据结构----线性表
  3. 【Git】3、创建Git版本库、配置Git仓库用户邮箱信息
  4. 1553B总线基础知识
  5. VM+Lamp环境搭建
  6. stm32中的“hello world”
  7. 想学硬件,该学什么啊?
  8. Learning Convolutional Neural Network for Graphs
  9. 关于Python爬虫常见的面试题
  10. SSM+MySQL+JSP教务管理系统设计与实现(附源码下载地址)