摘要
- RFC 2133 保留了核心 socket 函数的调用形式,因为它们本来就传递不透明地址指针和长度;IPv6 仍需要
PF_INET6、sockaddr_in6以及新的名称和地址转换接口。 - 旧
PF_INET程序继续与 IPv4 节点通信,和新PF_INET6程序把 IPv4 对端表示为映射地址,是两项不同的兼容承诺;两者都不能代替实际连通性证据。
最能说明问题的不是创建 socket,而是交接。一个进程把仍然打开的 socket 留给下一个进程;接手者照旧调用 getpeername(),却按错误的结构解释返回地址。1997 年的 RFC 2133 专门讨论了这种情况。它是一份 Informational 文件,后来被 RFC 2553 废止,因此适合分析当年的设计取舍,不宜当成今天的编程规范。
当时的基本矛盾很具体:IPv4 地址为 32 位,IPv6 地址为 128 位。核心 socket 函数把地址作为指针并附带长度传递,所以 bind()、connect()、sendto()、accept() 的语法可以沿用;但是 IPv4 的 sockaddr_in 即使有闲置字节,也装不下完整的 IPv6 地址、地址族和端口。规范于是增设 AF_INET6 与 PF_INET6,定义 sockaddr_in6,并补上地址文本转换、名称解析等接口。4.3BSD 与 4.4BSD 对新结构的长度及族字段还有不同布局。调用名不变,缓冲区大小、强制类型转换和二进制布局仍可能出错。
规范先保护原有程序。实现新接口的系统仍须接受 PF_INET 与 sockaddr_in,使旧应用的源码和二进制继续按原来的方式同 IPv4 节点通信。这不是让未改动的程序自动理解 IPv6。另一个承诺给新程序:使用 PF_INET6 时,可以把 IPv4 对端编码进 sockaddr_in6,形如 ::FFFF:<IPv4-address>。这只是 API 中表示 IPv4 对端的方式。看到 128 位外形,不能推断对端说的是 IPv6,更不能把它计作原生 IPv6 业务成功。
通配和回环地址也有自己的范围。IPv6 的未指定地址可用于让系统选择本地地址;回环地址指向本机。调用用了这些常量,不能推出所有网络族都在监听,也不能推出远端用户能访问。规范描述接口允许什么,没有提供任何特定网络的部署测量。
跨进程交接揭示了更深的状态限制。RFC 2133 提出 IPV6_ADDRFORM,让接手的程序改变打开的 socket 对外呈现的 PF_INET 或 PF_INET6 地址视图。若要降为 PF_INET,已关联的非通配地址必须全部是 IPv4 映射地址。这个条件说明,转换不只是换一个标签:已有的内核地址状态限制了哪些视图合理。它是历史提案中的选项,不能据此假定现代系统都以同样方式实现。
接口索引又把判断带回本机。规范用 if_nametoindex 等函数对应接口名与内核分配的索引;多播选项可选发送接口或本地入组接口。索引和入组设置证明的是本地选择,不是数据已到达别的主机。名称查询返回地址也只是准备好一次调用的输入,不是连接完成的回执。
RFC 2133 的历史贡献,是把旧程序兼容、新程序的跨族表示和真实网络结果拆开陈述。恒路谈运行代码优先时强调观察运行系统;这里借用的是证据视角,而非把他的评论当作 RFC 的技术条款。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance

