摘要

  • RFC 1068 描述的 BFTP 把一次 FTP 操作保存成控制主机上的持久请求,由守护进程择时并重试。用户提交之后可以离开,但此时被保存的是意图,不是已经完成的文件副本。
  • 多文件任务以第一次成功的 NLST 结果冻结成员,再逐项记录成功。所谓“完成”既可能指全部送达,也可能指永久失败或重试耗尽,因此判断结果必须回到逐文件记录。

凌晨的链路暂时不通,白天发出的文件是否只能等人守在终端前?RFC 1068 试图拿掉这项人工成本。它在 1988 年提出 BFTP:用户先说明源、目的和操作,控制主机把请求存起来,FTC 文件传输控制守护进程以后再执行。文档的目的在于引发讨论,并没有发明一种新的线上协议。

变化发生在 FTP 周围。原本一次前台会话的失败,往往意味着用户要亲自重新输入命令。BFTP 给这项工作加上了队列、时钟、重试次数、部分进度和邮件通知。请求因此可以比交互会话活得更久,但它要跨越的网络条件没有因为“后台”二字而消失。

提交保存的是一套未来动作

BFTP 允许源主机、目的主机和控制主机各不相同。用户要交出两端的主机名、登录名、口令和路径,还能选择复制、移动或删除源文件,在目的端创建、覆盖、追加或使用唯一名称。FTP 的类型、模式与结构可以指定;通配符可以圈出多个文件;第一次尝试也可以预约到将来某个时刻。

最后,用户留下接收结果的邮箱并执行 submit。交互界面到这里即可退出。队列里新增的是参数、日程和联络地址。它证明控制主机接受了一项工作,却没有证明两台服务器已经在线、凭据仍然有效、数据连接已经建立,更没有证明目的端已写入完整内容。

verify 也不能越过这条边界。两端可达时,它可以登录、检查部分参数并确认源文件当下存在;主机宕机时,有些项目连检查也做不了。即使验证成功,用户之后仍须另行提交,真正传输还在未来。验证是一张瞬时照片,不是对未来可达性、权限或磁盘状态的预约。

三台机器留下三类不同的证据

BFTP 沿用了 RFC 959 中的第三方 FTP。FTC 分别与源服务器和目的服务器建立控制连接,在一边使用 PASV 取得监听地址,再以 PORT 告诉另一边,并配对发出 RETR 与 STOR。数据连接直接连通两个 FTP 服务器,文件字节并不经过保存队列的控制主机。

于是同一项工作至少有三种记录。队列说明控制者想做什么;两条控制连接保存服务器接受或拒绝了哪些命令;数据连接才承载文件。RFC 959 要求传输期间保持控制连接,并等待终结性的 226 或 250 回复后再发下一项传输命令。只有初步应答、套接字接通或数据通道关闭,都不足以单独说明一个文件成功。

这种组合还暴露出实现差异。至少一端必须支持 PASV。RFC 1068 的实践记录提到不规范的 NLST 输出、格式错误的回复,以及服务器把断线错误以永久性的 5xx 返回,而不是可重试的 4xx。守护进程只能依据收到的故障语言行动;分类错误会直接改变下一次尝试是否存在。

重试把可靠性放到了会话之上

临时故障发生后,FTC 记录原因,等待一段时间,再开一组新的 FTP 会话。文档以某个实现为例:起初约等十分钟,随后把间隔加倍,增长到约四小时便封顶。这是一套本地策略的示意,不是分配给整个互联网的常数。

RFC 959 的 4yz 与 5yz 在这里不只是诊断标签。4yz 表示请求的动作尚未发生,但可以不改变请求而再次尝试;5yz 则意味着原样重复不会被鼓励。若网络中断被误报成永久失败,一项本可恢复的任务会提前死去。反过来,永久条件若被当作暂时故障,队列只会反复制造无效流量。

重试总要有终点:成功、永久失败,或达到配置的尝试上限。守护进程随后发邮件。邮件的出现说明工作流已进入终态,并不自动说明这是好消息。结果仍取决于通知中每个文件的状态。

第一次成功列目录,决定了任务究竟包含谁

通配符让持久请求面对一个时间问题。等待期间,源目录可能新增或删除文件。如果每轮重试都重新运行 NLST,同一个任务会悄悄吸收后来出现的成员,或丢掉原本应处理的成员。BFTP 因而保存第一次成功 NLST 得到的清单,以它冻结任务边界。后来的新文件不属于旧请求。

多文件传输又不是一笔原子交易。四个文件已经成功、第五个失败时,BFTP 不会删除目的端的四份副本再从头开始。一个状态指针记住完成的成员,后续周期只处理尚未完成的部分。这减少了重复,却也让一个请求能够同时容纳成功与失败的历史。

RFC 1068 在三种情况下称请求“complete”:所有单项都成功、遇到永久失败,或用完重试次数。这里的完成意为守护进程不再安排动作,而不是所有目的副本都存在。最终邮件必须逐项列出状态,正是因为一个总状态无法区分全成、部分成功和全败。

能找到任务的关键词,并不等于可靠身份

用户可以凭提交时保存的关键词查找并取消请求。作者直接把它称为弱认证:两人选中同一个词时,一方可能看到或取消另一方的工作。取消后发送邮件增加了事后可见性,却不能补造事前授权。

第三方连接还有后来更清楚的安全边界。RFC 2577 说明,代理 FTP 的 PORT 能让服务器朝另一项服务发起连接,形成 FTP bounce 攻击;限制这项能力又可能牺牲代理传输。该文没有证明 BFTP 曾发生这类事件。它只提醒我们:控制者即使不经手数据,也握有决定数据连接去向的权力。

史料能证明什么,又不能证明什么

RFC 1068 记录的是 ISI 数月的使用经验,不能据此推断广泛部署,更不能把现代作业队列写成它的直接后代。RFC 959 提供 FTP 控制与数据路径以及回复语义;RFC 2577 提供后来的第三方目标安全界线。三者都不能证明某个具名文件已传成功、口令得到妥善保护,或今天仍有相同系统在运行。

它留下的历史价值更窄,也更耐用:让意图持久化可以提高重试能力,但会产生一个新的控制系统。这个系统的状态必须逐项解释。队列只能说“请尝试”,文件账本才有资格说“发生了什么”。