IPv6 - linux网络编程

发布时间 2023-08-05 15:07:55作者: 某某人8265

IPv6 网络编程

假设双栈服务器有一个IPv4地址、和一个IPv6地址:

  1. IPv6 服务器启动后创建一个IPv6的监听套接字,假设绑定通配地址
  2. 客户端调用 connect,发送要给 IPv4 SYN 给服务端
  3. 服务端接收 IPv4 SYN 设置一个标识指示本连接使用IPv4映射的IPv6地址,然后响应一个 IPv4 SYN/ACK。连接建立后由accept返回一个 IPv4 映射的 IPv6 地址给用户进程
  4. 客户端和服务器端所有通信都使用 IPv4 传输数据
  5. 除非显示检查,例如使用 IN6_IS_ADDR_V4MAPPED

双栈主机处理监听套接字规则:

  • IPv4 套接字只接收 v4 版本连接
  • 绑定了通配地址的 IPv6 监听套接字,且未设置 IPV6_V6ONLY,则能处理 v4 和 v6 版本
  • 绑定了除 IPv4 映射的IPv6 地址外的某个非通配 IPv6 地址,或通配地址设置了 IPV6_V6ONLY 则只能接收 IPv6 连接

带*的表示取决于用户操作:通过AAAA记录发送v6数据报则不能工作,通过A记录获得一个IPv4映射的IPv6地址返回给客户则能工作

// IPv6地址测试宏
#include <netinet/in.h>

// 若为指定类型的地址,返回非0值,否则返回0
int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr* a);
int IN6_IS_ADDR_LOOPBACK(const struct in6_addr* a);
int IN6_IS_ADDR_MULTICAST(const struct in6_addr* a);
int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr* a);
int IN6_IS_ADDR_SITELOCAL(const struct in6_addr* a)
int IN6_IS_ADDR_SITELOCAL(const struct in6_addr* a);
int IN6_IS_ADDR_V4MAPPED(const struct in6_addr* a);
int IN6_IS_ADDR_V4COMPAT(const struct in6_addr* a);

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