目前在测试IPV6 DNS解析的时候发现一个问题,这里记录一下

问题是:当dhcpv6服务器分配的IPV6 dns是fe80类型的dns时,无法发送dns请求,抓包看不到有目标地址为fe80::1的dns报文

首先我这边使用dumpsys netd查看了下是否有fe80::1这个dns设置到系统中

发现是有设置到系统中的,而且可以看到dns请求的数据统计都是internal errors,那么表示错误产生在内部,并未实际发出dns报文

接下来只能查dns解析接口getaddrinfo了,看其中是否有会挡住fe80::1为目标地址的请求的地方

分析getaddrinfo流程时,发现一段代码的注释挺可疑的(注释写的好真的很有帮助),就让我锁定了目标

cp = strchr(hostname, SCOPE_DELIMITER);
if (cp == NULL)return explore_numeric(pai, hostname, servname, res, hostname);/*
* Handle special case of <scoped_address><delimiter><scope id>
*/
hostname2 = strdup(hostname);
if (hostname2 == NULL)return EAI_MEMORY;
/* terminate at the delimiter */
hostname2[cp - hostname] = '\0';
addr = hostname2;
scope = cp + 1;error = explore_numeric(pai, addr, servname, res, hostname);
if (error == 0) {u_int32_t scopeid;for (cur = *res; cur; cur = cur->ai_next) {if (cur->ai_family != AF_INET6)continue;sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {free(hostname2);return(EAI_NODATA); /* XXX: is return OK? */}sin6->sin6_scope_id = scopeid;}
}

在系统设置dns的时候会对dns地址调用一次getaddrinfo(这个大家可以去追一下android 设置dns的流程),比如说getaddrinfo(fe80::1,......),这个时候走到这里我看到这么一句注释

这里可以理解成对特殊的dns地址进行处理,这个地址由scoped_address+delimiter+scope id组成,让我比较奇怪的地址就是一串字符串,为什么还会有特殊的地址需要处理,解析来我就看看到底是什么样的地址被认为是特殊地址

cp = strchr(hostname, SCOPE_DELIMITER);
if (cp == NULL)return explore_numeric(pai, hostname, servname, res, hostname);

这段代码的意思就是查看hostname字符串种是否包含SCOPE_DELIMITER,不包含就会return,也就是说包含了SCOPE_DELIMITER的就是特殊dns地址

/** Scope delimit character*/
#define SCOPE_DELIMITER '%'

SCOPE_DELIMITER就是%,也就是说特殊dns地址是需要包含%的,到这里还不是知道特殊地址为什么要带%,就假设目前是特殊地址了,会怎么处理

/* terminate at the delimiter */
hostname2[cp - hostname] = '\0';
addr = hostname2;
scope = cp + 1;

通过这里的字符串处理,特殊地址被分成两部分,%前的和%后面的,addr就是%前的,scope就是%后的,%前面的就是dns地址,这里主要看下%后的是什么,有什么作用

for (cur = *res; cur; cur = cur->ai_next) {if (cur->ai_family != AF_INET6)continue;sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {free(hostname2);return(EAI_NODATA); /* XXX: is return OK? */}sin6->sin6_scope_id = scopeid;
}

这里调用ip6_str2scopeid对上面的scope参数进行了处理,也就是我们说的%后面的部分,然后将scopeid赋值给了sin6->sin6_scope_id(sin6_scope_id的作用这里就不写了,可以自行研究内核)

/* convert a string to a scope identifier. XXX: IPv6 specific */
static int
ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
{u_long lscopeid;struct in6_addr *a6;char *ep;assert(scope != NULL);assert(sin6 != NULL);assert(scopeid != NULL);a6 = &sin6->sin6_addr;/* empty scopeid portion is invalid */if (*scope == '\0')return -1;if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {/** We currently assume a one-to-one mapping between links* and interfaces, so we simply use interface indices for* like-local scopes.*/*scopeid = if_nametoindex(scope);if (*scopeid == 0)goto trynumeric;return 0;}......
}

这个函数的作用就是将scope转换成scopeid,看看这里的注释写的应该挺明显了,将interface转换成索引值

看到这里明白了,如果是fe80这种link local地址的dns,应该是需要携带%后面跟interface,也就是fe80::1%eth0设置到系统中,在这里进行特殊处理后确定scope id,否则内核会找不到网口索引,导致报文发不出去

至于内核对于link local地址为什么需要scope id,这里贴一段代码(net/ipv6/af_inet6.c),大家可以研究一下

if (__ipv6_addr_needs_scope_id(addr_type)) {if (addr_len >= sizeof(struct sockaddr_in6) &&addr->sin6_scope_id) {/* Override any existing binding, if another one* is supplied by user.*/sk->sk_bound_dev_if = addr->sin6_scope_id;}/* Binding to link-local address requires an interface */if (!sk->sk_bound_dev_if) {err = -EINVAL;goto out_unlock;}
}

Android 关于IPV6 DNS的问题相关推荐

  1. android配置ipv6 dns解析,13-IPv6域名解析配置

    1IPv6域名解析 IPv6网络中,DNS客户端通过IPv6域名解析功能实现域名与IPv6地址的转换.IPv6 DNS与IPv4 DNS相同,分为静态域名解析和动态域名解析.两种域名解析的作用和实现方 ...

  2. 思科三层交换机开启ipv6路由功能_网络工程实战之三层交换机配置IPv6 DNS 示例...

    组网需求 如图 所示,设备SwitchA 作为IPv6 DNS Client 端和IPv6 DNS Server 配合,使得 SwitchA 通过域名(huawei.com)能够访问IP 地址为200 ...

  3. 常用IPV6 DNS地址-供公网测试IPV6使用

    谷歌IPV6 DNS地址: 首选:2001:4860:4860::8888 备用:2001:4860:4860::8844 阿里 IPv6 DNS (Alidns) 阿里云公共DNS已支持IPv6协议 ...

  4. 使用IPv6 DNS解析IPv6域名(不必修改hosts文件)

    原文地址为: 使用IPv6 DNS解析IPv6域名(不必修改hosts文件) 很多网站,例如google,都是IPv4和IPv6双线接入的,www.google.com解析对应许多个IP,其中IPv4 ...

  5. 【IPv6基础系列科普视频】IPv6地址、IPv6 DNS、DHCPv6...精华视频一键打包,谁看谁会!

    为何引进IPv6地址?IPv6地址只是扩大了地址空间吗? IPv6的演进过程是怎样的? IPv6 DNS是什么?为什么需要IPv6 DNS? 为什么需要ND?ND只是替代了IPv4的ARP吗? NAT ...

  6. 给网站添加IPv6 DNS记录

    一. 1) 使6box提供的DNS64服务,解析出自己网站对应的IPv6域名 Windows: Win+R打开运行,输入cmd,打开命令提示符,输入以下命令 Nslookup www.6box.cn  ...

  7. 解决 Android ping IPv6 地址显示 network is unreachable 的问题

    最近在搞 4G Volte 的漏洞分析,在一个 Android 测试机上模拟了一个 SIP 包发送给现网,结果根本发不出去. 检查了半天发现抓包数据中手机发给现网的数据包未发送成功,ping 了一下显 ...

  8. fedora下配置ipv6 dns服务器

    操作系统:fedora14 DNS版本:dnsmasq2.52  或者 bind9.x dnsmasq2.52是fedora14自带的,所以我选择了这个,而且使用起来也很方便,是一种轻量级的dns s ...

  9. ipv6 dns修改方法

    what the fuck ,一台虚拟机被人盯上了,dns和hosts 被人改了,装了360没开主动防御,说不定就被哪个大户人家盯上了 hosts 67.198.211.58 server.lejsq ...

最新文章

  1. AR设备单目视觉惯导SLAM算法综述与评价
  2. Android基于监听的事件处理机制
  3. 洛谷P1119 灾后重建 图论 脑洞题
  4. [转] Java @interface 自定义注解
  5. Cannot add or update a child row: a foreign key constraint fails (`university`.`instructor`, CONSTRA
  6. [异常解决] ubuntu上安采用sudo启动的firefox,ibus输入法失效问题解决
  7. 算法设计与分析——动态规划——最长公共子序列
  8. mysql安装显示3534_MySQL安装成功之后启动错误 3534、28000和简单使用
  9. DEDE常见的错误(转)
  10. 最大团问题和最大独立子集
  11. cppcheck下载及使用
  12. 对腾讯云qcloud音视频通信SDK的调研(优缺点)
  13. 1.图灵学院-----阿里/京东/滴滴/美团整理----高频JAVA并发篇
  14. Vue中如何关闭语法检查
  15. oracle数据库设计思维导图,Oracle
  16. 多生成树协议,冗余备份,负载均衡
  17. Juery的基本的基本操作用法
  18. 这三种目的投简历,投了也是白投
  19. 从键盘中读入最多不超过50个学生的学生信息(包括空格隔开的姓名、学号、年龄信息,以学号从低到高排序)
  20. Java NIO通信框架在电信领域的实践

热门文章

  1. xiuno论坛部署及常见问题处理
  2. XiunoBBS ax_date 插件 日期显示不正确 修复
  3. IT职场人生:学外语
  4. 游戏中BUFF的实现
  5. centos如何在官网下载以前的版本
  6. 2022年要怎么把PayPal里的美元提到国内?
  7. speedoffice(Word)文字怎么修改字体颜色
  8. 世界名著《平凡的世界》读后感3800字范文
  9. 华为鸿蒙vivo,vivo的OriginOS系统开启公测 华为鸿蒙OS迎来劲敌
  10. HBase 记忆内容(简答题)