RFC 8 带读:ARPA Network Functional Specifications——从链路、校验到远程 NLS,早期 ARPANET 功能规格的第一次收束
前言
RFC 8 的标题是 ARPA Network Functional Specifications(ARPA 网络功能规格)。
和前几篇 RFC 相比,这个标题突然显得“正式”了很多。
RFC 1、RFC 2 主要在讨论 Host Software 应该有哪些能力;RFC 6 记录 Steve Crocker 与 Bob Kahn 关于 Host–IMP Interface 的一次谈话;RFC 7 则开始把 UCLA Host 的网络软件拆成 Network Program、Handler Program、Buffer 和 Interface Table。
到了 RFC 8,Gérard Deloche 试图把这些零散设计重新收束起来。
它讨论三大问题:
1 | |
也就是说,RFC 8 不再只回答:
Host 与 IMP 之间的软件应该怎么写?
而是试图从更完整的角度回答:
一个 ARPANET 用户程序怎样经过 Host 网络软件、Host–Host Link 和 IMP 网络,最终在另一台异构主机上建立远程交互?
它甚至给出了一个非常具体的使用场景:
1 | |
这已经不只是“网络能不能传 bit”。
它开始讨论:
- 端到端数据完整性;
- 逻辑连接;
- 控制 Link 与数据 Link;
- 交互式终端;
- 文件传输;
- Host 网络软件分层;
- I/O Handler;
- 远程登录;
- 本地与远端程序如何协作;
- 如何把交互逻辑下载到用户所在 Host 执行。
从今天看,RFC 8 的绝大部分具体机制都已经过时。
1971 年的 RFC 100 已经明确把它标记为:
1 | |
但它仍然是一份很值得软件开发者阅读的历史文档。
因为它展示了一个非常关键的阶段:
ARPANET 的设计者正在从“网络应该具有什么能力”,过渡到“这些能力怎样组合成真正可用的远程计算体验”。
RFC 基本信息
| 项目 | 内容 |
|---|---|
| RFC | RFC 8 |
| 官方英文标题 | ARPA Network Functional Specifications |
| 作者 | G. Deloche(Gérard Deloche) |
| 所属机构 | University of California at Los Angeles(UCLA) |
| 原文日期 | 5 May 1969 |
| NIC 编号 | 4694 |
| RFC Editor 当前状态 | Unknown |
| Stream | Legacy |
| 1971 年历史状态 | Obsolete |
| 原始载体 | 手写扫描稿 |
| RFC Editor 信息页 | RFC 8: ARPA Network Functional Specifications |
| RFC 原文 | RFC 8 PDF |
RFC 8 的原文不是普通文本,而是 12 页手写扫描件。RFC Editor 当前提供的是 PDF with Images。Computer History Museum 保存的一份早期 RFC 档案中还包含后来由 SRI ARC 重录的版本,开头明确标注 RETYPED BY ARC / original attached。这份重录稿帮助恢复了大部分正文,但仍保留若干 (unreadable) 标记,因此阅读 RFC 8 时,必须明确区分“原稿可确认的内容”和“后人根据上下文做出的解释”。
RFC 8 手写首页明确写着:
1 | |
RFC 84、RFC 100、RFC 1012 等后来的 RFC 索引也都采用这个日期。值得注意的是 RFC 9 的日期是 1 May 1969,也就是说早期 RFC 编号并不严格等于时间顺序。
RFC Editor 当前状态字段是 Unknown,但这不代表它今天仍然是一份有效规范。1971 年的 RFC 100 已明确将 RFC 8 标记为 Obsolete。因此今天应该把它视为历史设计文档,而不是现行实现标准。
为什么会有这篇 RFC
一、前面的 RFC 已经有很多“零件”,但还缺一张整体图
到 1969 年 5 月,Network Working Group 已经讨论过不少问题。
RFC 1 提出了:
1 | |
RFC 2 继续讨论:
1 | |
RFC 6 又讨论:
1 | |
RFC 7 则开始设计 UCLA Host 内部的软件:
1 | |
问题是:这些东西怎样组合起来,才能让一个 UCLA 用户真正使用 SRI 的远程系统?RFC 8 就是在回答这个问题。
二、真正目标不是“联网”,而是远程资源共享
ARPANET 的价值不只是:
1 | |
更重要的是:
1 | |
所以网络必须把下面几层同时打通:
flowchart TD
U[用户]
T[本地终端]
A[本地 User Program]
N[Network Program]
H[Transmission Handler]
I1[Local IMP]
NET[ARPANET]
I2[Remote IMP]
RN[Remote Network Program]
RA[Remote Application<br/>例如 NLS]
U --> T --> A --> N --> H --> I1 --> NET --> I2 --> RN --> RA
这比“网络设备成功转发 Packet”复杂得多。
三、异构 Host 让“远程使用”尤其困难
早期 ARPANET 的 Host 并不是同构服务器。UCLA、SRI、UCSB、UTAH 使用不同类型的大型计算机和操作系统。它们在操作系统、字长、字符表示、终端、登录命令和 I/O 模型方面都可能不同。
因此:
1 | |
和:
1 | |
是两个完全不同的问题。
RFC 8 同时处理了这两件事。
四、当时的交互延迟使“每个按键都去远端处理”很昂贵
RFC 1 已经担心远程交互的高延迟。如果每个按键都必须:
1 | |
那么复杂终端会非常难用。
于是早期设计提出把应用分成:
1 | |
其中 Hard Part 是核心应用逻辑,Local Control 则负责用户界面和即时终端反馈。Local Control 可以通过网络发送到用户所在 Host 执行,这就是 DEL 在 RFC 8 中存在的原因。
核心内容
RFC 8 的目录非常清晰:
1 | |
从系统架构角度,可以整理成:
flowchart TD
A[Transmission Integrity]
B[Logical Links]
C[User Application / DEL]
D[Network Program]
E[Transmission Handler]
F[IMP Network]
G[Link Establishment]
H[Remote Login / NLS]
A --> B
B --> C
C --> D
D --> E
E --> F
B --> G
G --> H
一、两层 Transmission Checking
RFC 8 明确区分两类传输检查。
第一层是:
1 | |
使用 cyclic checksum,由 BBN 硬件计算和验证,主要保护 ARPANET 网络内部的 IMP 间传输。
第二层是:
1 | |
使用一个特殊的 16-bit checksum,由 Host Program 计算和检查。
flowchart LR
HA[HOST A]
IA[IMP A]
IB[IMP B]
HB[HOST B]
HA -->|HOST-HOST<br/>16-bit Checksum| IA
IA -->|IMP-IMP<br/>Cyclic Checksum| IB
IB -->|HOST-HOST Validation| HB
两层校验保护的边界不同,因此并不是单纯重复。
二、Host-to-Host Checksum 为什么还需要存在
如果 IMP-to-IMP 已经检查过数据,为什么 Host 还要再检查?RFC 8 给出的理由非常明确:Host-to-Host 检查还希望发现:
1 | |
换句话说:
1 | |
并不自动证明:
1 | |
所以 RFC 8 已经体现出一种很早期的端到端完整性意识:下层可靠性不能完全替代更高层对完整路径的校验。
三、1152-bit 分块与 16-bit Checksum
RFC 8 规定,一个 Host Message 会被拆成若干:
1 | |
对每个 Piece 计算 end-around-carry sum,然后形成一个位置相关的加权 Checksum。根据手稿与 ARC 重录稿,可辨识出的结构是:
1 | |
最终结果为:
1 | |
和单纯的 Sum(A)+Sum(B)+Sum(C) 相比,这种设计让不同位置的分块对最终结果产生不同影响,因此更有机会发现 Packet 顺序被颠倒的情况。
RFC 8 手稿中关于 1152 = ... 的括号说明已无法可靠辨认,所以不能伪造一段完整推导。不过可以观察到:
1 | |
1152 同时可被 24、32、36 这些当时常见机器字长整除,而且 1152 = 4 × 288,与 RFC 2 曾使用的 288-bit checksum field 具有明显关联。这很可能延续了针对异构字长计算机的设计考虑,但应明确把它当成基于前后文的解释,而不是当前手稿中完整可辨认的原文结论。
四、Checksum 放在消息哪里
RFC 8 说明 16-bit Host-to-Host Checksum 位于:
1 | |
概念上可以表示为:
1 | |
这里的 Marking 与 RFC 7 中为了让不同字长机器找到正文边界而加入的 Marking 属于同一早期消息格式思路。
五、32 条 Host-to-Host Link
RFC 8 规定两个 Host 之间可以有:
1 | |
并把它们视为:
1 | |
其中:
1 | |
是特殊的 Control Link,用于 Connection Request、Status 等控制信息。其余 31 条 Link 可以用于:
1 | |
1 | |
六、TTY-like Connection 的定义
RFC 8 给出了 TTY-like Connection 的几个特征:
1 | |
特殊字符包括:
1 | |
所以它带着明确的远程终端语义,而不是简单的通用 Byte Stream。
七、为什么还要 File Transmission Link
TTY-like Link 面向低速、字符级、带特殊控制字符的交互。文件传输则更关注批量吞吐,因此 RFC 8 延续 RFC 1 的思路:在已有 TTY-like Link 旁边,再并行建立 File-like Link。
flowchart LR
A[HOST A]
B[HOST B]
A <-->|TTY-like<br/>交互 / 控制| B
A <-->|File-like<br/>批量数据| B
这体现出一个很早期但非常重要的工程原则:不同通信模式不一定应该强行塞进同一种数据通道。
八、User Program 被分成 Hard Part 和 Local Control Part
RFC 8 认为一个 User Program,例如 SRI 的 NLS,从网络角度可以看成两部分:
flowchart TD
APP[User Program]
H[Hard Part / Body<br/>核心应用逻辑]
L[Local Control Part<br/>用户界面与即时控制]
APP --> H
APP --> L
Hard Part / Body 代表真正的 User Application;Local Control Part 则代表用户界面,负责直接控制终端并对用户输入提供即时反馈。
九、Local Control Program 可以通过网络迁移
为了 facilitate and speed up remote interaction,Local Control Program 可以从 Server Host 传到 User Host。
flowchart LR
S[SRI<br/>NLS]
D[DEL Local Control Program]
U[UCLA Host]
C[Local Compile]
T[UCLA Terminal]
S -->|Transmit| D
D --> U
U --> C
C --> T
这样 UCLA 用户可以获得更接近 SRI 本地终端的交互体验,而网络上更多传输真正需要远端应用处理的数据,而不是每一个用户—终端的细小对话。
十、DEL 在 RFC 8 中承担什么角色
**DEL(Decode Encode Language)**用于描述能够在网络中传输并在另一台 Host 本地编译执行的控制程序。
RFC 8 的含义是:如果 Local Control Program 需要被传到另一台 Host,那么它应该采用 DEL 表达。
这里有一个很有意思的时间顺序:
1 | |
虽然 RFC 5 编号更小,但正式日期反而更晚。这说明 DEL 的设计早已在工作组内部流转,而早期 RFC 的编号、完稿、分发并不是严格按时间顺序发生。
十一、Network Program 的职责
RFC 8 为 Network Program 列出了明确职责:
1 | |
flowchart TD
U1[User Program A]
U2[User Program B]
U3[User Program C]
N[Network Program]
L[Link Management]
F[Message Framing / Heading]
C[HOST-HOST Checksum]
R[RFNM Handling]
H[Handler]
U1 --> N
U2 --> N
U3 --> N
N --> L
N --> F
N --> C
N --> R
N --> H
和 RFC 7 相比,RFC 8 更明显地把 Host-Host Protocol 语义集中到了 Network Program。
十二、Transmission Handler 的职责
Transmission Handler 很短,核心任务是:
1 | |
它可以由 Network Program 启动,也可以由 I/O Interrupt 触发。
1 | |
由于通信是 Full Duplex,RFC 8 还指出 Network Program 和 Handler 都可以概念上拆成 Outgoing / Incoming 两半。
关键机制与工作流程
RFC 8 最有价值的一部分,是它给出了一个“UCLA 如何远程使用 SRI NLS”的端到端例子。
一、通用 Link 建立过程
第一步,建立到 HOST(X) 的 TTY-like Link。连接建立后状态是:
1 | |
远端 Host 提供 Echo,并等待自己的标准 Login Sequence。
随后用户可以通过这条 Link 发送和接收字符。
如果还需要大数据传输,则双方 User Program 再共同建立一条与现有 TTY-like Link 平行的 File Transmission Link,然后通过 File-like Link 发送和接收批量数据。
二、UCLA → SRI NLS:阶段 A,本地准备
UCLA 用户首先:
1 | |
此时已经进入 Sigma Operating System 的 Command Level。
然后用户可以启动自己预先写好的程序,由它控制:
1 | |
或者直接选择标准 UCLA Communication Program,它被设想为“简单控制远端 Host”的标准选项。
三、阶段 B:建立到 SRI 的连接
本地 User Program 请求 UCLA Network Program:
1 | |
Network Program 首先选择一条空闲 Link。RFC 8 的例子是:
1 | |
真正的建链请求却通过:
1 | |
发送。
sequenceDiagram
participant U as UCLA User Program
participant UN as UCLA Network Program
participant SN as SRI Network Program
U->>UN: Initiate Link to SRI
UN->>UN: Select free Link = 25
UN->>SN: Link 0: Request connection on Link 25
SN-->>UN: Link 0: Accept Link 25
UN-->>U: Link 25 established
这就是一种非常早期的:
1 | |
模式。
四、双方同时抢 Link 25 怎么办
如果 UCLA 和 SRI 恰好同时尝试建立 Link 25,则更高优先级的 Host 获胜。RFC 8 建议:
1 | |
这是一种非常简单的确定性冲突消解规则:两端只要看到同一组 Host ID,就能独立计算出同一个赢家。
五、连接建立以后仍然只是 Pre-login
Link 建立成功并不代表已经进入 NLS。
状态大致是:
stateDiagram-v2
[*] --> NoLink
NoLink --> TTYPreLogin: Link 0 建链成功
TTYPreLogin --> SRICommandLevel: SRI Login
SRICommandLevel --> NLSRunning: 启动 NLS
NLSRunning --> LocalControlRequested: 请求 DEL Local Control
LocalControlRequested --> LocalControlActive: 下载并本地编译 DEL
SRI 的 Login Sequence 可以由 UCLA User Program 自动完成,也可以由 UCLA 用户手工输入。登录完成以后,UCLA 用户才真正处于 SRI Operating System 的 Command Level,然后进一步启动 NLS。
六、阶段 C:请求 Local Control Program
当 SRI NLS 已经运行,UCLA 端程序向 SRI User Program 发请求:
1 | |
SRI 返回一段用 DEL 编写的 Local Control Program。UCLA 在本地编译它,然后把 TTY Link 和 Terminal 的控制交给刚刚编译出的 DEL 程序。
sequenceDiagram
participant UT as UCLA Terminal
participant UC as UCLA Communication Program
participant SN as SRI NLS
participant DC as DEL Compiler
UT->>UC: 用户操作
UC->>SN: Request Local Control Program
SN-->>UC: DEL Local Control Program
UC->>DC: Compile DEL
DC-->>UC: Executable Local Control
UC->>UT: 本地 DEL 程序接管终端控制
七、为什么要本地编译
如果 SRI 直接把 SRI 机器的原生机器码发给 UCLA,Sigma 7 根本无法执行。
DEL 的目标就是提供一种中立的程序表示,让 Server Host 发送“程序描述/源程序”,User Host 则在本地转换为适合自己机器和终端的执行形式。
这是一种非常早期的 mobile code(移动代码) 思路。
八、为什么 Local Control 能降低交互延迟
纯远程模式:
1 | |
DEL Local Control 模式:
1 | |
于是高频、简单、延迟敏感的交互可以从 Remote Round Trip 变成 Local Execution。
重点概念与术语
ARPA Network
即当时正在建设中的 ARPANET。RFC 8 讨论的是最早期 ARPANET Host 软件和 Host-Host 使用方式。
HOST
连接到 ARPANET 的大型计算机系统。不同 Host 可以拥有完全不同的硬件、操作系统、字长和字符表示。
IMP
IMP(Interface Message Processor,接口报文处理机),ARPANET 的分组交换节点,负责 Host 接入和网络内部传输。
IMP-to-IMP Checksum
IMP 网络内部使用的 cyclic checksum,由 BBN 硬件负责。
HOST-to-HOST Checksum
由 Host Program 计算与验证的 16-bit checksum,用于覆盖更完整的端到端路径。
End-Around-Carry Sum
End-Around-Carry Sum(回卷进位加法)。当加法最高位产生 Carry 时,把 Carry 再加回低位。
1152-bit Piece
Host-to-Host Checksum 计算时的消息分块单位:
1 | |
每块 1152 bits。
Marking
Host Heading 后的一段标记,用于帮助不同字长机器定位正文边界。RFC 8 把 Host-to-Host Checksum 放在 Marking 后面。
Link
两个 Host 之间的逻辑通信路径。RFC 8 设定 32 条,并将其视为 Full Duplex。
Link 0
特殊 Control Link,用于连接请求、状态和其他控制信息。
TTY-like Connection
模拟远程 Teletype 的逻辑连接,具有 ASCII、Remote Echo、Break/Interrupt、低速字符交互等特征。
File-like Connection
与 TTY-like Connection 平行建立、用于文件和批量数据传输的逻辑连接。
Pre-login State
TTY-like Link 建好但尚未完成远端操作系统 Login 的状态。
Hard Part / Body
RFC 8 对 User Program 核心应用逻辑的称呼。
Local Control Part
直接面向终端的本地控制部分,负责 User Interface 和即时反馈。
DEL
DEL(Decode Encode Language),用于描述可通过网络传输并在用户 Host 本地编译执行的控制程序。
NLS
NLS(oN-Line System),SRI 的交互式在线系统,也是 RFC 8 远程使用示例中的核心应用。
Network Program
Host 网络软件的较高层组件,负责 Multiplex、Distribution、Link Initiation、Message Heading、Host-to-Host Checksum、RFNM 和 Handler Supervision。
Transmission Handler
靠近硬件的 I/O 程序,负责控制 Channel Hardware,并可由 Network Program 或 I/O Interrupt 启动。
RFNM
RFNM(Request for Next Message),ARPANET IMP 的流量控制反馈。它表示某条 Link 可以继续发送下一条 Message,而不是远端应用已经处理成功。
需要特别注意的点
1. RFC 8 是手写工作稿,不是现代精修标准
当前官方原始资料就是扫描手稿。对于已经无法辨认的内容,不应该为了让协议显得“完整”而擅自补齐。
2. RFC 100 在 1971 年明确把 RFC 8 标记为 Obsolete
因此 RFC 8 今天没有现行 Host-Host Protocol 的规范意义。
3. RFC 33 没有在元数据上直接写 Obsoletes RFC 8
RFC 33 正式写的是:
1 | |
并说明相对 RFC 11 中旧的 Host-Host Protocol 做了大量修改。RFC 8 明显属于这套更早的设计阶段,但严谨地说,RFC 8 的历史失效状态是 RFC 100 明确记录的 Obsolete,而不是 RFC 33 元数据直接标出的替代关系。
4. 32 条 Full-Duplex Link 很快就会变化
RFC 8 使用 32 条 Full-Duplex Link。到 RFC 9、RFC 11、RFC 33,Link 数量、方向和 Connection 抽象都继续变化。RFC 33 已经讨论 256 条逻辑路径,并把 Link 视为 Unidirectional。
5. Link 不是 TCP Connection
RFC 8 的 Link、Connection、Full Duplex 与 TCP 的层次和状态语义不同,不能直接等同。
6. RFNM 不是 TCP ACK
RFNM 是 IMP 网络的发送节流反馈,不代表远端应用已经处理成功,也不是后来 TCP 的字节流确认。
7. Host-to-Host Checksum 不是安全 Hash
它用于发现传输错误、接口错误和 Packet 顺序问题,不提供现代密码学完整性、认证或防篡改能力。
8. 1152-bit 的括号解释已经不完整
虽然它与 24/32/36-bit 字长的整除关系非常明显,但当前原稿相关说明无法完整辨认,因此不能把推断冒充原文明文。
9. 加权 Checksum 公式也应按可辨识程度表述
手稿和 ARC 重录稿足以支持 Sum(A)+2×Sum(B)+4×Sum(C)+... 这一结构,但没有必要把模糊的后续项强行扩写成现代形式化规范。
10. TTY-like Connection 不是 TELNET
RFC 8 早于成熟 TELNET Protocol,不能倒灌成 telnet host 23。
11. File Transmission Connection 也不是 FTP
RFC 8 只是描述一种用于批量文件数据的并行 Link,没有 FTP 后来的命令、Reply Code、控制/数据连接和文件系统语义。
12. RFC 8 中的 ASCII 约定仍然很早期
RFC 8 只提到 TTY-like Connection 使用 standard subset of ASCII。RFC 20 到 1969 年 10 月才更明确规定 standard 7-bit ASCII embedded in an 8-bit byte,并用于 Host-Host Primary Connection。
13. DEL 在 RFC 8 中出现早于 RFC 5 的正式日期
这不是矛盾,而是早期 RFC 工作方式的结果。编号、内部讨论、完稿和分发并不是严格线性发生。
14. Local Control Program 不是 JavaScript
它们都可以被理解成“远端提供逻辑、本地执行、降低交互延迟”的设计,但 DEL 没有 Web Runtime、DOM、Same-Origin Policy、HTTP 等现代 Web 技术基础,因此不能建立直接技术谱系。
15. RFC 8 几乎没有现代远程代码安全模型
今天看到:
1 | |
一定会追问认证、签名、Sandbox、权限、资源限制和恶意代码问题。RFC 8 基本没有这些安全机制。
16. HOST Identification Number 只是一种简单 Tie-Breaker
它适合小规模系统解决同时建链冲突,但不具备现代分布式系统的 Term、Epoch、Lease、Fencing、Retry、Partition 等完整故障模型。
17. Network Program / Handler 不是现代 TCP 栈 / Linux Driver 的精确映射
两者职责确实类似“协议逻辑 vs 底层 I/O”,但运行环境和硬件模型差异巨大,只能作为概念类比。
18. RFC 8 的价值恰恰在于它还不稳定
它不是最后答案。后续 RFC 很快继续修改 Link、Host-Host Protocol、ASCII、DEL/NIL 和 NCP。读 RFC 8 的重点不是记住旧字段,而是观察设计如何收敛。
从今天的视角重新看这篇 RFC
一、这是一个很早的“端到端完整性”实例
RFC 8 最值得现代开发者注意的设计之一,是 IMP 内部已经有 Checksum,Host 仍然再做一次 Checksum。
今天也经常遇到:
1 | |
因为不同层保护的 Failure Boundary 不同。
需要注意:RFC 8 不是后来正式理论化的 End-to-End Argument 本身,但它非常早地体现了相似工程直觉。
二、错误检测应覆盖真正关心的边界
RFC 8 不满足于 IMP A → IMP B 正确,它关心的是:
1 | |
整体是否正确。现代系统设计也应先问“真正要保证的边界在哪里”,而不是只看某个局部组件有没有校验。
三、位置敏感的 Checksum 说明“顺序错误”也是完整性错误
单纯加法满足:
1 | |
RFC 8 给不同 Piece 不同权重,目的是让位置参与结果。今天的完整性设计同样不仅要考虑 bit 是否变化,还要考虑顺序、分块和重组是否正确。
四、Control Channel 和 Data Channel 分离是自然的架构结果
RFC 8 的:
1 | |
与现代 Control Plane / Data Plane、Signaling / Media、Metadata / Payload 在思想上具有相似性。原因不是历史继承,而是控制信息和大规模数据天然具有不同生命周期和语义。
五、交互式数据和批量数据的优化目标不同
TTY-like 更看重低延迟和字符级交互,File-like 更看重批量吞吐。今天 Interactive RPC、Streaming、Large Object Transfer 仍然需要不同的优化策略。
六、把延迟敏感逻辑移近用户仍然是现代系统核心方法
DEL Local Control 可以压缩成:
1 | |
现代 Browser-side UI、Edge Computing、Game Client Prediction、Remote IDE、CDN Compute 都会面对相同的物理规律:一次网络 RTT 永远比一次本地执行昂贵得多。
七、Local Control / Hard Part 很像前端与后端职责拆分,但只是思想类比
RFC 8 的:
1 | |
和现代 Backend / Frontend 在职责分配上非常相似,但没有 REST、SPA、Browser Runtime、JSON、React 等现代技术基础。
八、“下载程序再执行”天然引出代码安全问题
RFC 8 主要解决 Latency 和 Terminal Compatibility。现代系统则必须同时解决 Sandbox、Capability、Origin、Permission、Code Signing 和 Isolation。越灵活的远程代码执行,往往意味着越大的攻击面。
九、Network Program 已经是一个明确的共享系统服务
RFC 8 不让每个应用直接操作 IMP,而是:
1 | |
这体现出一个持久的软件工程原则:共享网络资源应该由公共网络子系统统一管理,而不是每个应用自行驱动硬件。
十、Handler 说明协议语义与设备 I/O 应该分离
Network Program 负责 Link、Checksum、Header、Multiplexing;Handler 负责 Channel Hardware 和 I/O Interrupt。这样协议代码不需要直接充斥硬件寄存器和中断细节。
十一、RFC 8 已经在做共享网络资源的多用户调度
同一 Host 上多个 User Program 共享一套 Network Program、一个 Host-IMP Interface 和有限 Link,因此必须 Multiplex、Distribute、Track Link、Handle Flow Control。这是共享基础设施必然出现的资源管理问题。
十二、协议版本演化应当保留历史,而不是覆盖旧答案
RFC 8 很快就 Obsolete,但没有从历史中消失。后续 RFC 继续通过新编号记录改变,因此今天仍能看到:
1 | |
怎样变成:
1 | |
以及 TTY/File Link 怎样逐渐演化出 Connection、Socket、NCP、Control Command 等更成熟抽象。
这篇 RFC 带来的影响
RFC 8 本身没有成为后来互联网的长期协议标准,但它位于几条非常关键的早期演化线上。
一、它把前几篇 RFC 的想法第一次压缩成一套完整功能图
RFC 8 同时包含:
1 | |
因此它很像早期 ARPANET Host 侧设计的一份阶段性系统总览。
二、RFC 9 很快继续修改 Link 模型
RFC 8 是 32 Links、Link 0 Control、31 TTY/File、Full Duplex。RFC 9 已经开始使用 256 logical links,并继续细化 Primary / Auxiliary 等概念。这说明 RFC 8 并没有稳定多久。
三、RFC 11 把这些想法映射进 UCLA 的 GORDO 操作系统
RFC 11《Implementation of the Host-Host Software Procedures in GORDO》继续把 Host-Host Procedure、Network Program、Handler、Buffer、Link Table、System Call 映射到 UCLA Sigma 7 的 GORDO 操作系统。
flowchart LR
A[RFC 7<br/>Host-IMP Software Architecture]
B[RFC 8<br/>Functional Specifications]
C[RFC 9<br/>Host Software Refinement]
D[RFC 11<br/>GORDO Implementation]
E[RFC 33<br/>New HOST-HOST Protocol]
A --> B --> C --> D --> E
这是一条内容演化脉络,而不是说其中每一篇都存在正式的 Updates / Obsoletes 元数据关系。
四、RFC 33 会正式淘汰 RFC 11 那套旧 Host-Host Protocol
RFC 33 在 1970 年明确说它相对 RFC 11 的 old protocol 做了很多修改,并正式 Obsoletes RFC 11。它开始采用更成熟的 NCP、Connection、Socket、Control Command、256 Link 等概念。
因此 RFC 8 的 TTY-like Link、File-like Link、32 Full-Duplex Links 应该被理解为 RFC 33 以前的早期 Host-Host 设计阶段。
五、ASCII 问题在 RFC 20 中进一步标准化
RFC 8 只说 TTY-like Connection 使用 standard subset of ASCII。RFC 20 在 1969 年 10 月进一步提出:
1 | |
并用于 Host-Host Primary Connection。字符互操作从工程约定逐渐变成独立、明确的网络交换规范。
六、DEL 后来继续演化为 NIL 思路
RFC 8 使用 DEL 传输 Local Control Program。后来的 RFC 历史回顾说明 DEL 思路继续演化成 Network Interchange Language(NIL),RFC 51 在 1970 年进一步提出 Abstract Network Machine 和 Network Interchange Language。
也就是说,早期 Network Working Group 曾持续探索:
能不能让异构 Host 不只交换数据,还交换一种中立的可执行行为表示?
七、但互联网最终没有把“通用远程程序语言”放进网络核心
DEL / NIL 没有成为 TCP/IP 基础层。后来更成功的路线是:
1 | |
而不是要求所有 Host 都实现一门网络通用程序语言。
八、“本地执行”这个问题却不断重新出现
虽然 DEL/NIL 没成为互联网核心协议,但:
1 | |
五十多年后仍然是 Cloud、Browser、Mobile、CDN、Edge Computing 的核心架构问题。
九、NLS 不只是历史名词,而是真正的协议驱动力
如果 ARPANET 只用于 Batch Job,很多终端延迟问题并不重要。希望从 UCLA 像本地一样操作 SRI NLS,则迫使协议设计者处理 Remote Echo、Terminal Control、Local Feedback、Program Migration、Character Set 和 Interactive Latency。
应用需求从一开始就在反过来塑造网络协议。
十、它最大的历史价值是展示“协议、操作系统、应用”三者同时演化
RFC 8 很难塞进现代单一层次。它同时讨论 IMP Checksum、Host Checksum、Link、Network Program、Handler、TTY、File、DEL、NLS、Login,因为当时这些边界还没有成熟。
互联网后来清晰的分层体系,就是从这种混合设计中一点一点拆出来的。
总结
RFC 8 是一篇很特别的早期 RFC。
标题叫:
ARPA Network Functional Specifications。
但它并不是后来意义上的完整正式协议标准,而更像:
1969 年 5 月,UCLA 对“ARPANET 怎样从底层传输一直工作到远程应用”的阶段性系统设计总结。
它先从传输完整性开始。
网络内部:
1 | |
有由 BBN 硬件处理的:
1 | |
但 Host 之间仍然再做:
1 | |
因为系统还需要覆盖 Host→IMP、IMP→Host 和 Packet 顺序/重组等更完整的端到端风险。
Host Message 被分成:
1 | |
通过:
1 | |
形成校验值。
随后 RFC 8 定义:
1 | |
其中:
1 | |
TTY-like Link 面向 ASCII、Remote Echo、Break/Interrupt 和低速交互;File-like Link 则用于批量数据和文件传输。
再往上,Host 软件被拆成:
1 | |
Network Program 负责:
1 | |
Handler 则专注 Channel Hardware 和 I/O Interrupt。
最后,RFC 8 用 UCLA → SRI NLS 演示整个系统。
UCLA 用户先登录本地 Sigma 7,再请求 Network Program 建立到 SRI 的 Link。Network Program 选择例如 Link 25,然后通过 Link 0 发送建链请求。如果双方同时抢 Link 25,则按 Host Identification Number 决定优先级。
连接建立后仍处于 Pre-login。用户完成 SRI 标准登录,启动 NLS。
随后发生最有意思的一步:
1 | |
目的很简单:
1 | |
从今天看,这篇 RFC 的具体机制几乎全部退出历史舞台:
1 | |
RFC 100 到 1971 年已经把 RFC 8 明确标记为 Obsolete,后续 RFC 9、11、20、33、51 会继续重构其中不同部分。
但 RFC 8 留下了一组直到今天仍然非常熟悉的问题:
1 | |
RFC 8 没有给出今天的答案。
它给出的答案属于 1969 年:
1 | |
但真正重要的是:
这些问题已经被问出来了。
从 RFC 1 到 RFC 8,可以明显看到 ARPANET 设计正在发生变化:
1 | |
互联网的早期历史并不是一串已经完成的“伟大发明”。
它更像一组不断变化的问题,以及一群工程师不断写下的新答案。
RFC 8,就是其中一次非常完整的阶段性答案。