在Android11 版本的rom 产品开发过程中,遇到一个问题,发现分配的DNS不可用的情况,所以需要设置备用DNS。
直接上代码
//frameworks/base/services/core/java/com/android/server/ConnectivityService
//ConnectivityService.java -->
//updateLinkProperties() -->
//updateDnses(newLp, oldLp, netId);
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
return; // no updating necessary
}
final NetworkAgentInfo defaultNai = getDefaultNetwork();
final boolean isDefaultNetwork = (defaultNai != null && defaultNai.network.netId == netId);
if (DBG) {
final Collection<InetAddress> dnses = newLp.getDnsServers();
log("Setting DNS servers for network " + netId + " to " + dnses);
}
try {
mDnsManager.noteDnsServersForNetwork(netId, newLp);
// TODO: netd should listen on [::1]:53 and proxy queries to the current
// default network, and we should just set net.dns1 to ::1, not least
// because applications attempting to use net.dns resolvers will bypass
// the privacy protections of things like DNS-over-TLS.
if (isDefaultNetwork) mDnsManager.setDefaultDnsSystemProperties(newLp.getDnsServers());
mDnsManager.flushVmDnsCache();
} catch (Exception e) {
loge("Exception in setDnsConfigurationForNetwork: " + e);
}
}
在这里,我们添加如下代码:
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
return; // no updating necessary
}
final NetworkAgentInfo defaultNai = getDefaultNetwork();
final boolean isDefaultNetwork = (defaultNai != null && defaultNai.network.netId == netId);
if (DBG) {
final Collection<InetAddress> dnses = newLp.getDnsServers();
log("Setting DNS servers for network " + netId + " to " + dnses);
}
try {
//add code here
List<InetAddress> dnsServers = newLp.getDnsServers();
dnsServers.add(InetAddress.getByName("xxxxxxxxxx"));
dnsServers.add(InetAddress.getByName("xxxxxxxxxx"));
//-----------
mDnsManager.noteDnsServersForNetwork(netId, newLp);
// TODO: netd should listen on [::1]:53 and proxy queries to the current
// default network, and we should just set net.dns1 to ::1, not least
// because applications attempting to use net.dns resolvers will bypass
// the privacy protections of things like DNS-over-TLS.
if (isDefaultNetwork) mDnsManager.setDefaultDnsSystemProperties(newLp.getDnsServers());
mDnsManager.flushVmDnsCache();
} catch (Exception e) {
loge("Exception in setDnsConfigurationForNetwork: " + e);
}
}
添加完,单编services,发现报错:Exception in setDnsConfigurationForNetwork: java.lang.UnsupportedOperationException
发现报错原因在于:
/**
* Returns all the {@link InetAddress} for DNS servers on this link.
*
* @return An unmodifiable {@link List} of {@link InetAddress} for DNS servers on
* this link.
*/
public @NonNull List<InetAddress> getDnsServers() {
return Collections.unmodifiableList(mDnses);
}
既然不能对原有的List做修改,那就曲线来一把,如下:
List<InetAddress> oriServers = newLp.getDnsServers();
List<InetAddress> dnsServers = new ArrayList<InetAddress>();
dnsServers.addAll(oriServers);
dnsServers.add(InetAddress.getByName("xxxxxxxxxx"));
dnsServers.add(InetAddress.getByName("xxxxxxxxxx"));
newLp.setDnsServers(dnsServers);
编译验证,可以看到,如果分配的DNS不可用的时候,系统就会使用备用的DNS!!!