根據(jù)RFC 6724中 規(guī)定 android 會優(yōu)先選擇IPv6 地址而不是 IPv4 地址闷盔,當(dāng)整個網(wǎng)絡(luò)中,同時支持IPv4和IPv6 地址時磕潮,設(shè)備中的應(yīng)用請求服務(wù)器DNS時吵取,會優(yōu)先返回IPv6地址嵌屎。
假如IPv6服務(wù)器支持內(nèi)容不夠完善赠制,則應(yīng)用顯示內(nèi)容會與IPv4服務(wù)器不一致浮定,甚至有問題征讲。
因此有需求是定制設(shè)備平臺扇苞,使得 IPV4優(yōu)先IPV6欺殿,主要修改2個地方:
1. 當(dāng)設(shè)備或平臺連接網(wǎng)絡(luò)時寄纵,原來是先請求ipv6地址,再請求ipv4地址祈餐,這樣會使用應(yīng)用會先拿到ipv6地址屏箍,所以需要調(diào)整順序仓坞,讓ipv4先請求dhcp地址货裹,再請求ipv6氨距。
2. DNS域名解析時,調(diào)整解析DNS的優(yōu)先順序蜒谤,即先解析IPv4地址山宾,再解析IPv6地址,注:android 12在DnsResolver代碼中鳍徽。
接下來對這2個修改點(diǎn)進(jìn)行逐一修改并說明资锰。
1. 當(dāng)設(shè)備或平臺連接網(wǎng)絡(luò)時,原來是先請求ipv6地址阶祭,再請求ipv4地址绷杜,這樣會使用應(yīng)用會先拿到ipv6地址,所以需要調(diào)整順序濒募,讓ipv4先請求dhcp地址鞭盟,再請求ipv6。
文件:packages/modules/NetworkStack/src/android/net/ip/IpClient.java
修改差異如下:
--- a/modules/NetworkStack/src/android/net/ip/IpClient.java
+++ b/modules/NetworkStack/src/android/net/ip/IpClient.java
@@ -161,6 +161,8 @@
private final NetworkInformationShim mShim = NetworkInformationShimImpl.newInstance();
private final IpProvisioningMetrics mIpProvisioningMetrics = new IpProvisioningMetrics();
private final NetworkQuirkMetrics mNetworkQuirkMetrics;
+ //CN project let get ipv4 first and then ipv6, tiangui.tang @2023.9.7
//用于區(qū)別自定義code與AOSP
+ private final boolean bStartIPv6AfterIPv4 = true;
/**
* Dump all state machine and connectivity packet logs to the specified writer.
@@ -1734,7 +1736,21 @@
recordMetric(failureType);
mCallback.onProvisioningFailure(mLinkProperties);
}
+ private void enqueueJumpToStoppingState(final DisconnectCode code) {
+ deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING, code.getNumber()));
+ }
+ private void startIPv6AfterIPv4() {
+ if (bStartIPv6AfterIPv4 == false) {
+ return;
+ }
+ Log.d(mTag, "startIPv6AfterIPv4");
+ if (mConfiguration.mEnableIPv6 && !startIPv6()) {
+ doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
+ enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV6);
+ return;
+ }
+ }
private boolean startIPv4() {
// If we have a StaticIpConfiguration attempt to apply it and
// handle the result accordingly.
@@ -1744,6 +1760,7 @@
} else {
return false;
}
+ startIPv6AfterIPv4();
} else {
if (mDhcpClient != null) {
Log.wtf(mTag, "DhcpClient should never be non-null in startIPv4()");
@@ -2229,7 +2246,7 @@
mPacketTracker = createPacketTracker();
if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
- if (mConfiguration.mEnableIPv6 && !startIPv6()) {
+ if ((bStartIPv6AfterIPv4 == false) && mConfiguration.mEnableIPv6 && !startIPv6()) {
doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV6);
return;
@@ -2414,6 +2431,7 @@
}
case EVENT_DHCPACTION_TIMEOUT:
+ startIPv6AfterIPv4();
stopDhcpAction();
break;
@@ -2431,6 +2449,7 @@
case DhcpClient.CMD_CONFIGURE_LINKADDRESS: {
final LinkAddress ipAddress = (LinkAddress) msg.obj;
+ startIPv6AfterIPv4();
if (mInterfaceCtrl.setIPv4Address(ipAddress)) {
mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
} else {
2. DNS域名解析時瑰剃,調(diào)整解析DNS的優(yōu)先順序齿诉,即先解析IPv4地址,再解析IPv6地址晌姚,注:android 12在DnsResolver代碼中粤剧。
diff --git a/modules/DnsResolver/getaddrinfo.cpp b/modules/DnsResolver/getaddrinfo.cpp
--- a/modules/DnsResolver/getaddrinfo.cpp
+++ b/modules/DnsResolver/getaddrinfo.cpp
@@ -1147,7 +1147,8 @@
return 1;
} else {
/* All other IPv6 addresses, including global unicast addresses. */
//DNS解析出來的地址進(jìn)行排序,IPv4(return 35) 比IPv6(改為return 34)更高優(yōu)先級
- return 40;
+ LOG(DEBUG) << __func__ << " ttgctt force 34 for ipv6";
+ return 34;
}
} else {
return 1;
@@ -1406,16 +1407,17 @@
query_ipv6 = have_ipv6(netcontext->app_mark, netcontext->uid);
query_ipv4 = have_ipv4(netcontext->app_mark, netcontext->uid);
}
//調(diào)整順序挥唠,先請求IPv4對應(yīng)的DNS抵恋,再請求IPv6
- if (query_ipv6) {
- q.qtype = T_AAAA;
- if (query_ipv4) {
+ //query_ipv6 = 0;
+ if (query_ipv4) {
+ q.qtype = T_A;
+ if (query_ipv6) {
q.next = &q2;
q2.name = name;
q2.qclass = C_IN;
- q2.qtype = T_A;
+ q2.qtype = T_AAAA;
}
- } else if (query_ipv4) {
- q.qtype = T_A;
+ } else if (query_ipv6) {
+ q.qtype = T_AAAA;
} else {
return EAI_NODATA;
}
@@ -1452,7 +1454,7 @@
cur->ai_next = ai;
while (cur && cur->ai_next) cur = cur->ai_next;
}
if (q.next) {
ai = getanswer(q2.answer, q2.n, q2.name, q2.qtype, pai, &he);
if (ai) cur->ai_next = ai;
}