为什么这么设计(Why’s THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点、对具体实现造成的影响。如果你有想要了解的问题,可以在文章下面留言。
网络层协议承担了分组(Packet)转发和路由选择两大功能,它能够为上层提供在不同主机之间运输分组的职责,IP 协议作为网络层协议,它虽然只能提供无连接的、不可靠的服务,但是它在今天的互联网中起到了极其关键的作用。
图 1 - 互联网协议簇
在一般情况下,当我们想要访问其他主机提供的服务时,都需要通过 IP 地址来访问目标主机,只有拥有了 IP 地址才能在互联网上被其他主机访问。IP 地址就像家庭住址,我们需要保证所有主机 IP 地址的唯一性,这样才能找到正确的主机。
作为在 1974 年诞生的 IP 协议[^1],第一个主要版本 IPv4 使用 32 位表示地址,总共可以提供 2^32 (4,294,967,296) 个 IP 地址[^2]。42 亿个 IP 地址虽然看起来很多,但是可用的 IPv4 地址数量在最近几年一直在减少,早在 2011 年,顶级的 IPv4 地址就已经被全部分配出去了[^3]。
图 2 - IPv4 地址的小数表示
为了解决 IP 地址即将被耗尽的问题,IETF 在 1998 年就发布了 IPv6 协议的草稿[^4]并在 2017 年正式成为互联网标准[^5]。IPv6 使用 128 位的 IP 地址,总共可以表示 2^128 个地址,IPv6 甚至可以为地球上的沙子分配独立的地址[^6]:
新版本的互联网协议 IPv6 不仅能够一劳永逸地解决 IP 地址即将被耗尽的问题,还能提高网络的传输速度以及安全性。IPv6 协议的设计者最初认为随着 IPv4 地址的快速减少,IPv6 会被快速采纳,它们最初估计 IPv6 协议会在 2003 年在全球部署,但是从今天的角度来看,这些预测还是过于乐观了[^7]。
本文想要分析的问题是,为什么 IPv6 协议有如此之多的好处并且能够解决 IPv4 的地址短缺问题,但是哪怕在最初预估的 2003 年后又过了 17 年,IPv6 协议也没有被大规模采纳。我们在这里会讨论以下几个原因:
- NAT 技术很大程度上缓解了 IPv4 地址短缺的问题;
- IPv6 协议在设计时没有考虑与 IPv4 的兼容性问题;
- 更细粒度的管控 IPv4 地址并回收闲置的资源;
NAT
网络地址转换(Network Address Translation、NAT)是一种在 IP 数据包通过路由器时修改网络地址的技术,它能够将当前地址空间中的 IP 地址映射到另一个地址空间。当切换网络或者上游的 ISP 出现改变时,NAT 技术可以避免修改网络中全部节点的 IP,我们可以将 NAT 技术理解成一个转换表,其中存储着外部地址和端口到内部地址和端口的转换关系。
图 3 - 网络地址转换技术
当数据包从内部访问外部网络时,NAT 会为当前请求分配一个端口、覆写数据包中的源地址和端口并将地址和端口信息存储到本地的转换表中;当数据包从外部进入网络内部时,NAT 会根据数据包的 IP 地址和端口号查找到私有网络中对应的主机和端口号并覆写数据包中的目的地址和端口。
图 4 - NAT 转换表
通过 NAT 这一中间层,我们不仅可保护私有的网络,还能缓解 IP 地址的短缺问题。不过 NAT 技术也并不是只有好处,它也带来了很多的问题,在 NAT 网络下的主机并不能与对端建立起真正的端到端连接,也不能参与部分因特网协议[^8],除此之外,NAT 协议带来的以下问题也备受争议[^9]:
- NAT 使用的端口号是用于进程寻址的,而不是用于主机寻址的;
- NAT 路由器作为第三层(网络层)的设备,它应当只处理达到网络层的分组;
- NAT 违反了主机应当直接彼此对话的原则;
虽然 NAT 带来了很多的争议和问题,但是 NAT 已经成为了整个互联网中广泛使用的技术,工程师也尝试通过各种 NAT 穿越技术来解决它带来的问题,例如:SOCKS、UPnP 和 ALG 等[^10]。
兼容性
软件和协议都会遵循当下以及可预测的未来进行设计,但是我们很难预测未来的具体走势,当下的设计也会随着场景的变换变得逐渐不适用。所有的软件和协议都是需要更新迭代的,在更新的过程中我们就需要考虑兼容性,兼容性一般可以分成向前兼容(Forward compatibility)和向后兼容(Backward compatibility)两种:
- 向前兼容:老版本系统可以接收并处理新版本系统产生的数据;
- 向后兼容:新版本系统可以接收并处理老版本系统产生的数据;
图 5 - 系统的兼容性
这两种不同的兼容性可以起到不同的作用,如果 IPv6 协议与 IPv4 是向前兼容的,那么用于处理 IPv4 协议的硬件设备可以不用更新就能处理 IPv6 的数据,不过不更新系统也无法享受 IPv6 带来的好处;如果 IPv6 协议与 IPv4 协议是向后兼容的,那么 IPv6 的硬件可以同时处理 IPv4 和 IPv6 的数据包,只要使用 IPv6 设备替换 IPv4 设备就可以给整个网络无缝升级。
如果 IPv4 和 IPv6 能够具有向前兼容性或者向后兼容性,那么 IPv6 协议的推进也可能也没有这么复杂,但是 IPv6 协议在设计时就没有考虑与更早版本协议的兼容性。虽然 IPv4 和 IPv6 虽然都是 IP 协议,不过因为它们两者互不兼容,所以我们只能通过双协议栈、隧道技术或者 NAT64 实现协议的过渡:
图 6 - 双协议栈
IPv6 协议想要摆脱历史的包袱,实现完全不兼容的设计是可以理解的,在过去几十年应用 IP 协议的过程中,我们遇到了很多的问题,如果要背着历史的包袱继续前行也不是不可以,但是作为互联网的核心协议,虽然 IP 协议的设计者承认 IPv6 没有实现向前兼容是最大的错误[^11],但是作者认为通过不兼容的方式快速摆脱历史的包袱从长期来看也是好事。
地址管控
IPv4 的地址虽然从总体上来看确实是稀缺资源,不过与其他的稀缺资源一样,如何合理分配资源并提供使用率一直都是比较大的问题。IANA(Internet Assigned Numbers Authority) 和 RIR(Regional Internet Registries) 是负责分配 IP 地址的组织,除了一些为专有网络预留的 IP 地址之外,剩余的地址一般都是通过子网以地址块的形式分配。
在互联网协议的早期开发阶段,子网是通过 IP 地址最左侧的 8 位划分子网,但是因为这种方式只允许划分 256 个网络,所以在 1981 年被分类网络架构(Classful Network Architecture)迅速替代。分类网络架构中包含 A、B 和 C 三类网络[^12]:
Class | 网络数 | 主机数 |
---|---|---|
A | 128 | 16,777,214 |
B | 16,384 | 65,534 |
C | 2,097,152 | 254 |
A 类地址只能分配给 128 个不同的网络,每个网络中可以包含 1,600 万主机,而 C 类地址可以分配给 200 万组织,网络中可以包含 200 多个主机。通过对 IP 地址的分类,我们能够更合理地分配 IP 地址块,不过虽然它对 IP 地址进行了分类,但是它对地址的划分还是比较粗糙。
IETF 在 1993 年提出的无类别域间路由(Classless Inter-Domain Routing、CIDR)替代了分类网络架构,CIDR 基于可变长子网掩码(Variable-length Subnet Masking、VLSM),它的主要目的有两个[^13]:
- 缓解互联网中路由器中转发表的增长速度;
- 缓解 IPv4 地址耗尽的速度;
分类网络架构中对地址的划分还是有些过于理想,过小的地址块往往不够用、稍大的地址块却会造成较大的浪费。与分类网络架构只使用 8、16 和 24 固定长度的子网掩码将 IP 地址块划分成三类不同,CIDR 会使用可变长度的子网掩码来划分地址块,如下所示的 CIDR 表示中,N 表示前缀长度,它可以是从 0 到 32 的任意值:
代码语言:javascript复制A.B.C.D/N
A.B.C.D/8
、A.B.C.D/16
和 A.B.C.D/24
就可以分别表示分类网络架构中的 A、B 和 C 三类不同的地址块,同时也可以使用其他的数字更灵活的表示特定网络数和主机数的子网。
除了更细粒度的地址分配之外,回收不再使用的 IP 资源并投入再利用也是延长 IPv4 寿命的重要手段,不过在这里我们就不做展开了。从 IP 地址的分配中,我们能看到资源从充足到稀缺,人对于资源使用态度的转变,从最开始粗糙的分配方式到后来细粒度的管控,充足的资源总是会被滥用,只有当资源真正变得稀缺时,我们才开始精打细算。
总结
IPv4 协议从 1981 年发布到今天已经过去了将近 40 年,在过去的这段时间里,它作为互联网协议簇中的重要协议承担着分组转发和路由选择的重要责任,随着网络环境和终端设备变得越来越复杂,我们也需要更多的 IP 地址满足今天的需求。
图 7 - 访问 Google 的 IPv6 协议采纳率[^14]
IPv6 协议摆脱了很多历史的包袱轻装前行,虽然越来越多的网站和网络设备都开始支持 IPv6,但是因为很多原因 IPv6 最终也很难完全取代 IPv4 协议,我们重新回顾一下本文的内容:
- NAT 技术可以很大程度上缓解 IPv4 的地址短缺问题并且能够保护私有内部的网络,提供防火墙的功能;
- IPv4 与 IPv6 协议完全不兼容,我们需要引入双协议栈、隧道技术或者 NAT64 解决兼容性问题,而应用这些技术也需要额外的成本;
- 通过对资源的细粒度管控并回收不再使用的 IP 地址,可以延缓 IP 地址耗尽的时间;
工程师的想象力是无穷的,在过去的十几年间,我们尝试通过各种办法为 IPv4 协议续命延缓 IP 资源耗尽的时间,不过在可预见的未来 IPv4 协议也终将被 IPv6 替代,我们也会拥有几乎用不完的 IP 地址。到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:
- IPv5 协议是做什么的?为什么没有听说过 IPv5 协议?
- 你觉得 IPv6 协议的份额会在多久之后超过 IPv4?