蓝图 · 273 字 · 1 分钟阅读

为什么 TCP 被拆成了 TCP 和 IP

最早的 TCP 是一个同时负责路由、可靠性、寻址的协议。1978 年 Jon Postel 主张把它拆成两个,才解锁了 UDP、实时视频、沙漏架构,以及之后的几乎一切。

#TL;DR

1974 年 Vint Cerf 和 Bob Kahn 发表的协议论文,描述的是一个叫 TCP 的单一协议,同时处理寻址、路由、可靠性和排序。到 1978 年,Jon Postel——后来成为互联网最低调但影响最深的那几位之一——已经花了四年时间争论,这样做是错的。他指出,可靠性和路由不是同一个问题;把它们焊在一起意味着网上每一个应用都得为它多数并不需要的那些保证买单。Postel 赢了。这次拆分产生了互联网至今仍在使用的分层栈——底下是 IP,上面是各自独立的 TCP 和 UDP——并让 DNS、VoIP、视频流、联网游戏,最终还有 QUIC,成为可能。

#原版 1974 TCP 干了哪些事

Cerf 和 Kahn 1974 年 5 月发表在 IEEE Transactions on Communications 上的论文——“A Protocol for Packet Network Intercommunication”——描述的是一个协议,它负责把一条消息可靠地从主机 A 经过任意中间网络送到主机 B 所需的全部事情。

它一口气处理:

  • 寻址。 每台主机都有一个全局唯一的标识。
  • 路由。 网络之间的网关决定如何转发数据包。
  • 可靠性。 丢了的包要重传;乱序包要排好序;重复包要丢掉。
  • 流控。 接收端扛不住时,发送端要慢下来。
  • 分片。 大消息要被切成适配发送端与接收端之间最小那段网络的大小。

作为一份研究草案,它很优雅。但它也是一份企图服务所有可能用例的庞然规范,到 1977 年,实现者已经发现很多用例并不需要 TCP 提供的全部东西。更糟的是,他们照样得为此买单。

#Postel 的反对

Jon Postel 从 RFC 40 起就在编 RFC。到 1977 年,他已是整个系列事实上的编辑,意味着他看过 ARPANET 社区出产的每一份协议提案,对哪些设计容易跑通、哪些跑不通,有一种极不寻常的清晰判断。

Postel 的论点——散见于 1977 和 1978 年的一系列 RFC 与设计笔记——是结构性的:

路由是网络的性质。可靠性是对话的性质。

它们运行在不同的时间尺度上,服务不同的利益相关方,为了不同的原因出错。把它们塞进同一个协议意味着:

  • 不需要可靠性的应用也得为它付账。一次 DNS 查询发出一个请求,等一个回应。把它包在一整套三次握手、重传逻辑和连接拆除里,对一次性单查询来说是荒唐的开销。
  • 需要不同可靠性语义的应用拿不到它们想要的。实时音频宁愿丢掉一个迟到的包,也不愿等一次会让播放卡住的重传。
  • 网络层变得更难演进。每次你想改寻址或路由方案,就得连可靠性代码一起动。

Postel 提议做干净的分层:一个协议做寻址和路由;它上面单独一个协议做可靠性;对不想要可靠性的应用,允许直接绕过这一层。

#拆分

从 IEN 2 到 IEN 26,再到 1978、1980 年的 RFC 草案,那个唯一的 TCP 变成了三样东西:

  ┌───────────────────────────────┐
  │            TCP                │   ← 可靠、有序、面向连接
  ├───────────────────────────────┤
  │            UDP                │   ← 不可靠、无序、发出就算
  ├───────────────────────────────┤
  │            IP                 │   ← 寻址与路由,尽力而为
  └───────────────────────────────┘
  • IP 成为网络层。它负责寻址(每台主机有一个 IP 地址)和尽力投递。一个包要么到要么不到。IP 不作任何承诺。
  • TCP 成为跑在 IP 之上的一个传输层。它加上可靠性、排序、连接状态、流控、拥塞控制。想把连接看成字节流?TCP 就是让这个错觉能跑在不可靠 IP 之上的那层东西。
  • UDP 成了另一个传输层,同样跑在 IP 之上,但几乎没有 TCP 的任何保证。UDP 是围绕 IP 的一层薄壳,加上端口号(让同一台主机上多个应用共享一个 IP)和一个校验和。就这样。

这次拆分真正的关键,并不是”在 IP 上多了两个协议”。而是应用有了选择权

#UDP 解锁了什么

如果没有 UDP,一整类应用要么根本不存在,要么得各自从头发明一套”绕过 TCP”的机制。

  • DNS — 每一次域名查询都是一次 UDP 请求 + 一次 UDP 响应,一轮往返搞定。把 DNS 塞进 TCP,往返次数要翻三倍、字节数要翻四倍。以 TCP 开销,1980 年代末 DNS 根就塌了。
  • VoIP 与实时视频 — 音视频对延迟敏感、能容忍丢包。一个迟到的包毫无用处,你宁可丢弃它也不愿等。TCP 的重传行为在这里正好是错的。
  • 联网游戏 — 多人游戏的状态更新走 UDP,因为游戏宁可丢掉一条过时的位置更新,也不愿让玩家卡在那儿等它。
  • DHCP、NTP、SNMP、TFTP — 简单的请求-响应或广播式协议,塞进一个包就搞定。TCP 太重了。
  • 多播和广播 — TCP 是点对点对话。同一个包一次送给多个接收方,需要 UDP 的无连接模型。

UDP 比 TCP 结构上简单,就因为它不作承诺。正是这一点,让它能做 TCP 永远做不到的事情。

#由此产生的沙漏

这次拆分造就了互联网协议设计者开始称为沙漏模型的东西——一张图,抓住了为什么互联网能以先前网络做不到的方式扩展和演进。

    HTTP  SSH  SMTP  DNS  QUIC  WebRTC  ...  ← 众多应用协议
         ╲   │   │   │   │    ╱
           ╲ │   │   │   │  ╱
    ┌──────────────────────────┐
    │      TCP   UDP   ...     │              ← 少数传输协议
    ├──────────────────────────┤
    │           IP             │              ← 仅一个网络协议
    ├──────────────────────────┤
    │      TCP   UDP   ...     │
    │                          │
    └──────────────────────────┘
         ╱   │   │   │   │   ╲
       ╱     │   │   │   │     ╲
  Ethernet  Wi-Fi  4G  5G  光纤  卫星    ← 众多链路层

细腰上只有一个协议——IP——上面下面都是任意的多样性。链路层可以变(Ethernet、Wi-Fi、4G、LTE、5G)而不破应用;新应用协议可以被发明出来(HTTP、WebRTC、QUIC)而不碰网络。唯一不能随便改、一改就要牵动一切的,就是 IP 自己。

这也是为什么 IPv6 花了三十年才铺开:动这个细腰是结构性代价昂贵的。其他层改起来都便宜。

#反事实

如果当年没有拆分会怎样?

我们可以看 ISO 与 TCP/IP 争锋的 OSI 标准,作为一个局部答案。OSI 保留了一个厚得多的栈——七层,会话管理、表示层编码、应用特性全部在网络级别上规范。整个 1980 年代,它都是 ARPANET 协议的官方的、政府背书的接班人。

OSI 完败。众多原因之一,是它的层与层耦合得太紧。你没法推一个小改动。你没法在标准传输上跑一个非标应用协议。等到 OSI 规范被批准时,TCP/IP 已经在分层栈上通过 RFC 自由迭代赶超了它。

拆分也让端到端原则得以成立。如果 TCP 和 IP 不可分,那么加密、拥塞控制、可靠性这些特性就得是网络层的事——被烧进路由器里,不换硬件就没法演进。正因为 TCP 在端点、IP 很薄,端到端创新才一直便宜。

#Postel 真正赢下的

TCP/IP 那篇文章用一段话概括了拆分。容易错过的是:有多少下游架构依赖于它:

  • TLS 能存在,因为 TCP 到应用层加密方案之间有一次干净的交接。一个”TCP 带加密的”一体式方案要演进会难得多。
  • QUIC 能存在,因为 UDP 至今还是笨的、不带立场。要在 UDP 上搭一个新的可靠传输之所以可行,正是因为 UDP 什么都不承诺。你没法在 TCP 上搭一个新的传输,TCP 从上到下已经满是立场。
  • 云规模的负载均衡能工作,因为连接状态住在端点上。一台 L4 负载均衡器可以在后端之间迁移一条 TCP 流,而无需从内部理解 TCP。
  • IPv6 能被部署,因为改网络层不需要改传输层。TCP 和 UDP 稍加调整就能跑在 IPv4 和 IPv6 上。

Postel 的直觉是:可靠性和路由是两个由不同关注点服务的不同问题,应当分别编码。接下来的五十年,行业用”我每建一个新系统都发现它因此更容易”的方式,而不是用争论,来验证这个直觉。

1978 年,把一个协议拆成三个看起来只是一次小清理。事实证明,它是那个让互联网能一直演进下去的决定。