IPv4 or IPv6 Prefer
如果apn的protocol设置为IPv4/IPv6的话,那么使用DNS解析某地址时,可能会同时返回IPv4和IPv6的地址。
但是某些服务端并未作好对IPv6地址的访问服务,导致无法访问IPv6地址的情况。
当IPv6访问超时时,才会去使用IPv4的地址尝试,这就可能导致访问某些网页或者应用联网卡顿的问题
838 2015-10-20 20:11:54.040608 10.48.98.29 221.130.33.60 DNS 75 Standard query 0x0a2f AAAA ic.snssdk.com
840 2015-10-20 20:11:54.207105 221.130.33.60 10.48.98.29 DNS 103 Standard query response 0x0a2f AAAA ::111.13.7.48
841 2015-10-20 20:11:54.207742 10.48.98.29 221.130.33.60 DNS 75 Standard query 0xdb2c A ic.snssdk.com
842 2015-10-20 20:11:54.239197 221.130.33.60 10.48.98.29 DNS 91 Standard query response 0xdb2c A 111.13.7.48
//v6
843 2015-10-20 20:11:54.242039 2409:8890:8e18:e329::1 ::111.13.7.48 TCP 96 44627→80 [SYN] Seq=0 Win=65535 Len=0 MSS=1350 SACK_PERM=1 TSval=1386209 TSecr=0 WS=64
844 2015-10-20 20:11:55.235675 2409:8890:8e18:e329::1 ::111.13.7.48 TCP 96 [TCP Retransmission] 44627→80 [SYN] Seq=0 Win=65535 Len=0 MSS=1350 SACK_PERM=1 TSval=1386309 TSecr=0 WS=64
845 2015-10-20 20:11:57.235650 2409:8890:8e18:e329::1 ::111.13.7.48 TCP 96 [TCP Retransmission] 44627→80 [SYN] Seq=0 Win=65535 Len=0 MSS=1350 SACK_PERM=1 TSval=1386509 TSecr=0 WS=64
846 2015-10-20 20:12:01.245694 2409:8890:8e18:e329::1 ::111.13.7.48 TCP 96 [TCP Retransmission] 44627→80 [SYN] Seq=0 Win=65535 Len=0 MSS=1350 SACK_PERM=1 TSval=1386910 TSecr=0 WS=64
//v4
854 2015-10-20 20:12:09.258663 10.48.98.29 111.13.7.48 TCP 76 48521→80 [SYN] Seq=0 Win=65535 Len=0 MSS=1370 SACK_PERM=1 TSval=1387711 TSecr=0 WS=64
855 2015-10-20 20:12:09.307788 111.13.7.48 10.48.98.29 TCP 72 80→48521 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1394 TSval=180186210 TSecr=1387711
[SOLUTION]
如果同时拥有IPv4和IPv6的地址,是会默认优先上报IPv6的地址,若需要修改为IPv4 prefer,可以按如下方式修改
/bionic/libc/dns/net/getaddrinfo.c 文件
static int
_dns_getaddrinfo(void *rv, void *cb_data, va_list ap) 方法,将原来的:
if (query_ipv6) {
q.qtype = T_AAAA;
if (query_ipv4) {
q.next = &q2;
q2.name = name;
q2.qclass = C_IN;
q2.qtype = T_A;
q2.answer = buf2->buf;
q2.anslen = sizeof(buf2->buf);
}
} else if (query_ipv4) {
q.qtype = T_A;
}
修改为
if(query_ipv4) {
q.qtype = T_A;
if(query_ipv6) {
q.next = &q2;
q2.name = name;
q2.qclass = C_IN;
q2.qtype = T_AAAA;
q2.answer = buf2->buf;
q2.anslen = sizeof(buf2->buf);
}
}else if(query_ipv6) {
q.qtype = T_AAAA;
}