摘要
- 客户端把 RRQ 或 WRQ 发给服务器的已知端口 69;服务器接受后另选一个 TID,与客户端 TID 一同成为本次传输余下报文的 UDP 端口边界。
- 错误源 TID 会收到错误码 5,却不应打断已接受的会话;后来的重传修正、块大小和窗口扩展都没有把这个短期边界升级成身份认证。
69 端口只负责接单
TFTP 的“简单”不是没有状态。RFC 783 为内存和功能都有限的环境规定了一种读写文件办法:没有目录浏览,没有完整的 FTP 控制语言,也没有用户认证。它把必要状态压缩到少数报文类型、块编号、计时器和传输标识符中。
客户端首先选择自己的 TID,并把 RRQ 或 WRQ 送到服务器的已知 TID 69。读取获得许可时,服务器从自己选择的 TID 发出 DATA 1;写入获得许可时,它从该 TID 发出 ACK 0。两个 TID 被交给 UDP 作为源、目的端口,之后的报文都沿用这一对数值。
因此,69 表示“这里可以提出新请求”,不表示“所有数据都必须从这里回来”。服务器可以继续在 69 上接收新请求,同时用不同 TID 隔离并发传输。只按静态服务端口观察 TFTP,会看见一次合法的端点迁移,却把它误报成异常。
第一份正面答复确定边界
RFC 1350 要求 TID 尽量随机选择,降低短时间内重复使用同一数值的机会。客户端收到第一份正面答复后,服务端 TID 就确定下来。其后的源 TID 必须匹配。
这条规则解决的不只是恶意输入,也包括网络自身制造的重复。若最初的请求被复制,服务器可能为两份请求分别创建传输,并从两个不同 TID 回复。客户端接受先到的那一份;后到的答复属于另一段对话。它应被丢弃,发送错误码 5“Unknown transfer ID”,而已经选中的传输继续运行。
这正是 RFC 1350 特别指出的非终止错误。多数 ERROR 报文意味着交换结束,而且 ERROR 本身既不确认也不重传。错误 TID 不同:它的意义是“你不属于这次交换”,如果顺手终止正确交换,边界便失去了保护作用。
但 TID 的证明力必须止于这里。随机端口不是密码学身份,不验证服务器,也不保证文件来源、内容或权限。它只说明某个数据报是否落在双方已经接受的短期二元组内。
一个块就是全部未决状态
基础 TFTP 采用停等方式。DATA 从块 1 开始,每一块在下一块发送前都要收到对应 ACK。固定 512 字节的块让发送方只需保留当前块,接收方无需为乱序重组保存窗口。短于 512 字节的 DATA 表示结束;文件长度正好是 512 的整数倍时,还要用一块零长度 DATA 明确终点。
最后一个 ACK 也可能丢失。接收方发送它后可以短暂等待;若终止 DATA 再次到来,就再次确认。完成不是某个瞬间的主观判断,而是双方对最后一块的可重复闭合。
这种设计把进度证据放在很小的组合里:预期 TID、块编号和计时器。块号前进代表新状态;旧块或旧 ACK 代表重复;错误 TID 属于别的交换;超时才可能授权重发。
旧确认曾经复制出拥塞
早期规则允许任何一方在收到旧的重复数据报后重发当前报文。一次延迟与超时就可能触发连锁反应:旧 DATA 到达,接收方再发 ACK;旧 ACK 到达,发送方又发 DATA;此后每一块和每一个确认都出现两份。
RFC 1123 把它称为“魔法学徒综合征”。文件内容未必错误,传输仍可能失败。重复流量加重最初造成延迟的拥塞,制造更多超时,最终让一个本应简单的交换被自己的恢复机制拖垮。
修正明确收回了旧 ACK 的触发权:DATA 发送方不能仅因收到重复 ACK 就重发当前块。重传应由相关超时或状态规则授权,而不是由任何陈旧信号授权。RFC 1350 取代 RFC 783 时纳入了修正。
扩大吞吐仍要先达成一致
停等对小型实现友好,对高时延或大文件效率不高。RFC 2347 把选项附在初始 RRQ 或 WRQ 中,但只有客户端能发起协商。服务器只能在 OACK 中确认客户端确实请求过的选项;不支持的选项可以省略,未获确认的选项视为从未提出。
读取时,客户端用 ACK 0 接受 OACK;写入时,用 DATA 1 接受。RFC 2348 允许协商块大小,RFC 2349 允许协商重传间隔并预告传输大小。RFC 7440 又允许连续发送一个窗口的 DATA,再用窗口末块的 ACK 确认;窗口为 1 时仍是原来的停等。
这些扩展改变了“确认前允许多少工作”,没有改变“哪两个端点属于本次传输”。更大的块和窗口也没有增加认证、保密、访问控制或文件真伪证明。容量增加,责任反而更需要显式保存。
协议之外才是授权
实际部署还要回答 TFTP 无法回答的问题:哪些地址可以请求,服务器公开哪一段文件树,是否允许写入,启动镜像由谁签署,NAT 或防火墙如何只为已接受的 TID 建立有限状态,日志如何把 69 端口上的请求与后续动态端口关联。
如果中间设备只放行 69,合法传输会在第一块失败;如果为了兼容而放开所有 UDP 端口,又会抹去本应精确的边界。正确做法是观察初始请求和第一份正面答复之间的状态转换,而不是选择“全封”或“全开”。
TFTP 的历史因此展示了一种很小却耐用的分权:公共端口拥有接收请求的职责,双方拥有选择临时端点的职责,块编号拥有证明进度的职责,超时拥有触发恢复的职责。任何一个字段都不应越权替代文件授权和来源信任。
来源与边界
基础历史来自 RFC 783、RFC 1123 与 RFC 1350。选项机制见 RFC 2347、RFC 2348、RFC 2349 和 RFC 7440;IANA 登记表记录 69 端口。这些资料不统计 2026 年部署,也不证明 TID 能认证端点、授权文件或校验内容。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
