1. 从早期 TCP 到现代 TCP/IP
TCP 的最早版本由 Robert Elliot Kahn 和 Vinton Gray Cerf 在 1973 年提出。当时,它被称为 Transmission Control Program(传输控制程序),而不是如今的 Transmission Control Protocol(传输控制协议)。尽管名称不同,但早期 TCP 的目标与现代 TCP 的目标基本一致:
- 网络连接:网关确保多个网络之间的连接
- 分布式控制:没有中心化的网络控制和管理节点
- 错误恢复:发送的数据包能够正确到达目标(通过重传机制)
- 黑盒模型:将一个网络连接到另一个网络时,不需要修改其内部结构
不过,当时的 TCP 同时负责网络路由和数据传输。换句话说,IP 并未参与其中。因此,像数据包的源地址和目标地址这样的信息,都是由 TCP 来处理的。
RFC 675 详细记录了这一早期版本的 TCP。其中一个最能体现早期与现代 TCP 差异的点是它们的头部结构。下图总结了早期 TCP 的头部格式:
随着网络变得越来越复杂,对网络路由和传输进行分层的需求也日益增长。因此,在 1976 年,人们开始着手将早期 TCP 向现代 TCP/IP 转型。最终,RFC 791 和 RFC 793 在 1981 年正式发布了现代 TCP/IP 协议。
随着网络路由由 IP 协议接管,TCP 的头部信息也相应简化。下图展示了现代 TCP 的基本头部格式:
2. TCP/IP 中的伪头部(Pseudo-Header)
从早期 TCP 向现代 TCP/IP 的过渡带来了不少挑战。一个显著的例子是:TCP 本质上是一个端到端的协议,因此源地址和目的地址在 TCP 通信中起着至关重要的作用。
例如,TCP 校验和必须包含端点地址等信息,以确保这些数据在传输过程中没有被损坏。然而,在 TCP/IP 架构中,这些信息现在位于 IP 头部,而不是 TCP 头部。此时,IP 成为了 TCP 的封装层。
为了解决这个问题,TCP 引入了“伪头部”的概念。伪头部包含 IP 头部的部分信息,用于保留 TCP 的端到端特性,同时避免在 TCP 头部中重复 IP 头部中的数据。
伪头部共 12 字节,包括以下字段:
- 源 IP 地址(Src IP Address):来自 IP 头部的源地址
- 目的 IP 地址(Dst IP Address):来自 IP 头部的目的地址
- 保留字段(Reserved):8 位的 0
- 协议(Protocol):IP 头部中的协议字段。对于 TCP 来说,该值为 6。其他传输层协议(如 UDP)也会使用伪头部,因此它们的协议值不同
- TCP 长度(TCP Length):TCP 段的长度,包括 TCP 头部和数据部分
下图展示了伪头部的组成结构:
2.1 TCP 校验和(TCP Checksum)
伪头部的一个重要用途是用于计算 TCP 的校验和。除了伪头部外,TCP 校验和还会对 TCP 头部和数据进行校验。计算完成后,校验和值会被写入 TCP 头部的 checksum 字段。
需要注意的是,伪头部并不是真实传输的数据。也就是说,它不会随数据包一起发送。以校验和为例,发送方在计算校验和时临时构造伪头部,计算完成后丢弃。接收方在收到数据包后,也会根据当前 IP 头部信息重新构造伪头部,用于校验数据的完整性。
3. 当下的伪头部
使用伪头部的一个历史原因是出于安全考虑。设计者希望通过在 TCP 中引入加密和认证机制来保护地址信息,从而抵御中间人攻击等安全威胁。
然而,这些安全机制由于各种原因并未广泛推广。但正如我们在前面提到的,TCP 校验和仍然依赖伪头部。因此,TCP 一直保留了伪头部。
不过,伪头部也带来了一些挑战。由于它依赖 IP 头部信息,所以每当 IP 协议发生变化时,TCP 都需要做出相应的调整。例如,从 IPv4 过渡到 IPv6 时,伪头部的结构也需要随之变化,进而影响 TCP 校验和的计算方式。
因此,在未来网络协议的设计中,是否继续保留伪头部,是一个值得深思的问题。
4. 总结
本文我们探讨了 TCP/IP 中伪头部的作用和演变。首先回顾了 TCP 从早期版本演进到现代 TCP/IP 的过程,接着深入解析了伪头部的结构和应用场景,最后分析了伪头部在当下网络环境中的挑战和前景。
虽然早期 TCP 中关于安全和认证的设计并未普及,但伪头部在 TCP 校验和中的应用,使其在今天依然具有实用价值。未来,随着网络架构的不断演进,是否继续保留伪头部,仍需进一步评估。