一次请求大致流程:
1. 通过输入的主机名去查找对应的IP地址
2. 获取根据DNS域名解析得到的IP地址, 访问指定的服务器
3. 通过IP+地址获取指定的资源
打算从以下几个方面学习DNS域名解析的知识:
- 1、DNS域名解析的流程
- 2、Android端对于DNS的缓存优化
- 3、DNS域名解析中可能会遇到的问题, 以及如何处理
- 4、关于面试DNS会涉及到哪些问题
一、DNS域名解析流程
- 1、Android系统首先检查自身有没有缓存, 如果有, 直接返回缓存的IP地址.
- 2、如果没有, 则会请求本地域名服务器(LDNS)进行解析, 这台服务器一般位于当地, 大于80%左右的域名解析到这里就结束了.
- 3、如果LDNS也没有缓存该IP地址, 则直接跳到ROOT Server域名服务器请求解析
- 4、根域名服务器返回LDNS一个所查询域的主域名服务器(gTLD Server)
- 5、此时LDNS发请求给gTLD Server
- 6、接受请求的gTLD Server返回域名对应的Name Server, Name Server指的是网站注册的域名服务器
- 7、Name Server根据关系映射表找到对应的IP, 返回给LDNS
- 8、LDNS缓存域名与IP
- 9、LDNS将IP返回给访问者
二、Android NDS-IP缓存
根据流程图, 只列出主要流程
2.1 以okhttp中根据主机名获取ip为例
override fun lookup(hostname: String): List<InetAddress> {
try {
return InetAddress.getAllByName(hostname).toList()
} catch (e: NullPointerException) {
throw UnknownHostException("Broken system behaviour for dns lookup of $hostname").apply {
initCause(e)
}
}
}
2.2 Inet6AddressImpl.lookupAllHostAddr
private static InetAddress[] lookupHostByName(String host, int netId)
throws UnknownHostException {
// 1.从缓存中取host对应的IP
Object cachedResult = addressCache.get(host, netId);
// 2.如果缓存存在, 则返回缓存的IP
if (cachedResult != null) {
if (cachedResult instanceof InetAddress[]) {
return (InetAddress[]) cachedResult;
} else {
// 3.结合下文可知, 缓存不仅仅缓存IP, 也可能缓存DNS解析中出现的异常情况, 如果当前
// DNS域名解析失败, 那么在缓存未失效之前, 获取的都是该异常?
throw new UnknownHostException((String) cachedResult);
}
}
try {
// 4.获取IP
InetAddress[] addresses = Libcore.os.android_getaddrinfo(host, hints, netId);
// 5.缓存host对应的IP
addressCache.put(host, netId, addresses);
return addresses;
} catch (GaiException gaiException) {
String detailMessage = "Unable to resolve host \"" + host + "\": " + Libcore.os.gai_strerror(gaiException.error);
// 6.缓存DNS域名解析时出现的异常
addressCache.putUnknownHost(host, netId, detailMessage);
throw gaiException.rethrowAsUnknownHostException(detailMessage);
}
}
2.3 DNS域名解析的IP缓存
www.androidos.net.cn/android/9.0…
private final BasicLruCache<AddressCacheKey, AddressCacheEntry> cache
= new BasicLruCache<AddressCacheKey, AddressCacheEntry>(MAX_ENTRIES);
// MAX_ENTRIES = 16, 默认缓存16个HOST
当缓存的HOST = 16时优先删除, 结合BasicLruCache源码, 其内部使用的是LinkedHashMap
三、DNS域名解析遇到的问题
3.1 域名劫持
域名服务器会保存一大堆域名记录(每条记录包括"域名"和"IP地址"), 当域名服务器收到请求时, 就会返回域名对应的IP地址.
如果域名服务器中保存的域名-IP的映射关系出现了错误, 也就是域名对应的IP地址发生了改变, 那么请求者获取到的IP地址就有问题, 这种就叫作**域名劫持**
3.2 域名污染
zhuanlan.zhihu.com/p/143824884 blog.csdn.net/wangcantian… zhuanlan.zhihu.com/p/79350395