IPv4与IPv6的互操作性

  • Post author:
  • Post category:其他

概述

客户端和服务端应能在对端为IPv4和IPv6下均能正常工作
双栈:IPv4协议栈,IPv6协议栈

在这里插入图片描述

IPv4客户与IPv6服务器

IPv6服务器可处理IPv4客户与IPv6客户
通过使用IPv4映射的IPv6地址实现

在这里插入图片描述

服务器主机既有一个IPv4地址又有一个IPv6地址

在这里插入图片描述

- 收到一个目的地为某个IPv4套接字的IPv4数据报
- 收到一个目的地为某个IPv6套接字的IPv6数据报
- 收到一个目的地为某个IPv6套接字的IPv4数据报
内核把该数据报的源IPv4地址映射为一个IPv6地址,作为accept/recvfrom返回的套接字的对端地址
- 收到一个目的地为某个IPv4套接字的IPv6数据报[不存在]

多数双栈主机处理监听套接字的规则:
- IPv4监听套接字只接受来自IPv4客户的外来连接
- 如服务器有一个绑定了通配地址的IPv6监听套接字,
且该套接字未设置IPV6_V6ONLY套接字选项
则该套接字既能接受来自IPv4客户的外来连接,也能接受来自IPv6客户的外来连接
对来自IPv4客户的连接,其服务端的本地地址是与客户指示的目的IPv4地址映射所得的IPv6地址

服务器IPv6套接字绑定的是无法从本机IPv4地址映射得到的某个IPv6地址或绑定的是通配地址,
且设置了IPV6_V6ONLY时,只接受来自IPv6客户的连接

IPv6客户与IPv4服务器

- 有些IPv6地址是由IPv4地址映射得到的,有些不是
IPv6客户采用IPv4映射的一个IPv6作为目的地址进行connect,
内核自动发送一个IPv4 SYN到服务器
- 服务器响应一个IPv4 SYN/ACK


总结:
1.如一个IPv6的TCP客户指定一个IPv4映射的IPv6地址调用connect
或一个IPv6的UDP客户指定一个IPv4映射的IPv6地址以调用sendto
则内核检测到这个映射地址后,改为发送一个IPv4数据报
对应的IPv4服务端发回的也是IPv4数据报
2.不论调connect还是sendto,IPv4客户不可指定一个IPv6地址

在这里插入图片描述
在这里插入图片描述

最后no*,在IPv6客户选择的目的地址为IPv4映射的IPv6时,内核发出IPv4数据报,可工作

IPv6地址测试宏

对端地址是IPv6时,
验证其属于一个独立的IPv6还是IPv4映射的IPv6
int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr*);
int IN6_IS_ADDR_LOOPBACK(const struct in6_addr*);
int IN6_IS_ADDR_MULTICAST(const struct in6_addr*);
int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr*);
int IN6_IS_ADDR_SITELOCAL(const struct in6_addr*);
int IN6_IS_ADDR_V4MAPPED(const struct in6_addr*);
int IN6_IS_ADDR_V4COMPAT(const struct in6_addr*);

int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr*);
int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr*);
int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr*);
int IN6_IS_ADDR_MC_ORGLOCAL(const struct in6_addr*);
int IN6_IS_ADDR_MC_GLOBAL(const struct in6_addr*);

版权声明:本文为x13262608581原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。