4. File Transfer (文件传输)
4. 文件传输 (FILE TRANSFER)
4.1 文件传输协议 -- FTP (FILE TRANSFER PROTOCOL -- FTP)
4.1.1 引言 (INTRODUCTION)
文件传输协议 (FTP) 是互联网文件传输的首要标准. 当前规范包含在 RFC-959 [FTP:1] 中.
FTP 使用相互独立且并发的 TCP 连接分别用于控制与数据传输. FTP 协议包含许多特性, 其中一些并不常被实现. 然而, FTP 的每一项特性都至少存在一个实现. RFC-959 定义的最小实现过小, 因此本文定义一个稍大一些的最小实现.
多年来, 有缺陷的 FTP 实现给互联网用户造成了不必要的负担. 协议实现者一直受一种错误观点之害, 即实现 FTP 应当是一件小而琐碎的任务. 这是错误的, 因为 FTP 有用户界面, 因为它必须 (正确地) 处理可能发生的各种各样的通信与操作系统错误, 还因为它必须应对现实世界中文件系统的巨大多样性.
4.1.2 协议逐步分析 (PROTOCOL WALK-THROUGH)
4.1.2.1 LOCAL 类型 (LOCAL Type): RFC-959 第 3.1.1.4 节
FTP 程序必须支持 (MUST) TYPE I ("IMAGE" 或二进制类型) 以及 TYPE L 8 (逻辑字节长度为 8 的 "LOCAL" 类型). 内存组织为 m 位字 (m 不是 8 的倍数) 的机器还可以 (MAY) 支持 TYPE L m.
讨论 (DISCUSSION):
"TYPE L 8" 常常用于在内存组织为 (例如) 36 位字的机器与 8 位字节组织的机器之间传输二进制数据. 对 8 位字节机器而言, TYPE L 8 等价于 IMAGE.
在两台 m 位字机器上, 有时会指定 "TYPE L m", 以确保本机模式二进制文件从一台机器正确传输到另一台. 然而, 对这些机器而言, 该命令的效果应当与 "TYPE I" 相同.
4.1.2.2 Telnet 格式控制 (Telnet Format Control): RFC-959 第 3.1.1.5.2 节
不区分 TYPE N 与 TYPE T 的主机, 应当 (SHOULD) 把 TYPE T 实现为与 TYPE N 相同.
讨论 (DISCUSSION):
这一条款应当能简化与那些确实做了这一区分的主机之间的互操作.
许多主机把文本文件在内部表示为 ASCII 字符串, 使用内嵌的 ASCII 格式控制字符 (LF, BS, FF, ...) 在打印文件时控制格式. 对这类主机而言, "可打印" 文件与其他文件没有区别. 然而, 使用记录结构文件的系统通常需要一种用于可打印文件的特殊格式 (例如 ASA 走纸控制). 对后一类主机, FTP 允许在 TYPE N 与 TYPE T 之间选择.
4.1.2.3 页结构 (Page Structure): RFC-959 第 3.1.2.3 节与附录 I
一般而言, 不推荐 (NOT RECOMMENDED) 实现页结构. 但是, 如果某主机系统确实需要为 "随机访问" 或 "带洞" (holey) 文件实现 FTP, 它必须使用 (MUST) 已定义的页结构格式, 而不是定义新的私有 FTP 格式.
4.1.2.4 数据结构变换 (Data Structure Transformations): RFC-959 第 3.1.2 节
记录结构与文件结构之间的 FTP 变换应当 (SHOULD) 是可逆的, 以在使结果在目标主机上有用的前提下尽可能做到.
讨论 (DISCUSSION):
RFC-959 要求记录结构与文件结构之间严格可逆, 但在实践中, 效率与便利常常使其无法实现. 因此该要求被放宽. 传输文件有两个不同目标: 在目标主机上处理它, 或仅做存储. 对存储而言, 严格可逆很重要. 对处理而言, 在目标主机上创建的文件需要符合该主机上应用程序所期望的格式.
作为这一冲突的例子, 设想一个面向记录的操作系统, 它要求数据文件的每条记录恰好 80 字节. 在向这样的主机 STOR 文件时, FTP 服务器必须能够把每行或每条记录填充到 80 字节; 此后对这样一个文件的检索就无法做到严格可逆.
4.1.2.5 数据连接管理 (Data Connection Management): RFC-959 第 3.3 节
使用 STREAM 模式的 User-FTP 应当 (SHOULD) 在发出每个传输命令之前发送一条 PORT 命令来指定一个非默认数据端口.
讨论 (DISCUSSION):
这是必需的, 因为 TCP 连接关闭后要经过很长时间其套接字对才能被重用, 而这样做允许在单个 FTP 会话期间进行多次传输. 如果使用流以外的传输模式, 并让数据传输连接在多次传输之间保持打开, 就可以避免发送 PORT 命令.
4.1.2.6 PASV 命令 (PASV Command): RFC-959 第 4.1.2 节
server-FTP 必须实现 (MUST) PASV 命令.
如果要在同一会话期间执行多次第三方传输, 则必须在每个传输命令之前发出 (MUST) 一条新的 PASV 命令, 以获得一个唯一的端口对.
实现 (IMPLEMENTATION):
对 PASV 命令的 227 应答的格式没有很好的标准化. 特别是, FTP 客户端不能假定 RFC-959 第 40 页展示的括号一定存在 (事实上, 第 43 页的图 3 就省略了它们). 因此, 解释 PASV 应答的 User-FTP 程序必须在应答中扫描主机与端口号的第一个数字.
注意, 主机号 h1,h2,h3,h4 是发送该应答的服务器主机的 IP 地址, 而 p1,p2 是 PASV 分配的一个非默认数据传输端口.
4.1.2.7 LIST 与 NLST 命令 (LIST and NLST Commands): RFC-959 第 4.1.3 节
NLST 命令返回的数据必须只包含 (MUST) 一个合法路径名的简单列表, 使得服务器可以把它们直接用作后续针对单个文件的数据传输命令的参数.
LIST 或 NLST 命令返回的数据应当 (SHOULD) 使用隐含的 TYPE AN, 除非当前类型为 EBCDIC, 此时应使用 (SHOULD) 隐含的 TYPE EN.
讨论 (DISCUSSION):
许多 FTP 客户端支持宏命令, 用 NLST 获取一个路径名列表, 以获取或放置匹配通配符规格的文件. "multiple-put" 的展开是客户端本地的事, 但 "multiple-get" 需要服务器配合.
LIST 与 NLST 的隐含类型旨在提供与既有 User-FTP 的兼容性, 特别是与 multiple-get 命令的兼容性.
4.1.2.8 SITE 命令 (SITE Command): RFC-959 第 4.1.3 节
Server-FTP 应当 (SHOULD) 把 SITE 命令用于非标准特性, 而不是发明新的私有命令或对既有命令做未标准化的扩展.
4.1.2.9 STOU 命令 (STOU Command): RFC-959 第 4.1.3 节
STOU 命令向一个唯一命名的文件存储. 当收到 STOU 命令时, Server-FTP 必须 (MUST) 在传输之前的 "125 Transfer Starting" 或 "150 Opening Data Connection" 消息中返回实际文件名 (RFC-959 提到的 250 应答码是错误的). 这些消息的确切格式在此定义为:
125 FILE: pppp
150 FILE: pppp
其中 pppp 代表将被写入的文件的唯一路径名.
4.1.2.10 Telnet 行结束码 (Telnet End-of-line Code): RFC-959, 第 34 页
实现者禁止 (MUST NOT) 假定控制连接上的 READ 边界与 Telnet EOL 序列 (CR LF) 之间存在任何对应关系.
讨论 (DISCUSSION):
因此, server-FTP (或 User-FTP) 必须持续从控制连接读取字符, 直到遇到一个完整的 Telnet EOL 序列, 才处理命令 (或应答). 反过来, 从控制连接的一次 READ 可能包含不止一条 FTP 命令.
4.1.2.11 FTP 应答 (FTP Replies): RFC-959 第 4.2 节, 第 35 页
Server-FTP 必须 (MUST) 在控制连接上只发送格式正确的应答. 注意, RFC-959 (与 FTP 规范的早期版本不同) 没有 "自发" (spontaneous) 应答消息的规定.
Server-FTP 应当 (SHOULD) 在适用时使用 RFC-959 定义的应答码. 然而, 需要时 server-FTP 可以 (MAY) 使用不同的应答码, 只要遵循第 4.2 节的一般规则. 当实现者在 4xx 与 5xx 应答码之间做选择时, 如果失败的 FTP 存在任何合理的可能在几小时后成功, Server-FTP 应当 (SHOULD) 发送 4xx (临时失败) 码.
User-FTP 一般应当 (SHOULD) 只用 3 位应答码的最高位数字来做规程性决策, 以防 Server-FTP 使用非标准应答码时出现困难.
User-FTP 必须能够 (MUST) 处理多行应答. 如果实现对应答行数施加了限制且该限制被超出, User-FTP 必须恢复 (MUST), 例如忽略多余的行直到多行应答结束.
User-FTP 不应当 (SHOULD NOT) 特殊对待 421 应答码 ("Service not available, closing control connection"), 而应当 (SHOULD) 通过检测服务器对控制连接的关闭来处理.
讨论 (DISCUSSION):
不严格遵循应答规则的服务器实现常使 FTP 用户程序挂起. 注意, RFC-959 解决了早期 FTP 规范中应答规则的歧义, 必须遵循之.
选择能够正确区分临时失败与永久失败的 FTP 应答码很重要, 这样文件传输客户端守护程序才能成功工作. 这些程序依赖应答码来决定是否重试失败的传输; 对临时错误使用永久失败码 (5xx) 会让这些程序不必要地放弃.
当某个应答的含义与 RFC-959 展示的文本完全一致时, 逐字使用 RFC-959 的文本将增强一致性. 然而, 在合适时, 鼓励 Server-FTP 实现者选择能传达特定系统相关信息的应答文本.
4.1.2.12 连接 (Connections): RFC-959 第 5.2 节
RFC-959 该节第二段中的 "and the port used" 一语是错误的 (历史遗留), 应当忽略.
在多宿主服务器主机上, 默认数据传输端口 (L-1) 必须与 (MUST) 对应控制连接所用端口 L 关联到同一本地 IP 地址.
user-FTP 禁止在 (MUST NOT) FTP 控制连接上发送 SYNCH 与 IP 之外的任何 Telnet 控制. 特别是, 它禁止尝试 (MUST NOT) 在控制连接上协商 Telnet 选项. 但是, server-FTP 必须能够 (MUST) 接受并拒绝 Telnet 协商 (即发送 DONT/WONT).
讨论 (DISCUSSION):
尽管 RFC 说: "Server- 与 User- 进程应当遵循 Telnet 协议的约定...[在控制连接上]", 其意图并不是要采用 Telnet 选项协商.
4.1.2.13 最小实现 (Minimum Implementation): RFC-959 第 5.1 节
以下命令与选项必须被 (MUST) 每个 server-FTP 与 user-FTP 支持, 除非底层文件系统或操作系统不允许或不支持某个特定命令.
Type: ASCII Non-print, IMAGE, LOCAL 8
Mode: Stream
Structure: File, Record*
Commands:
USER, PASS, ACCT,
PORT, PASV,
TYPE, MODE, STRU,
RETR, STOR, APPE,
RNFR, RNTO, DELE,
CWD, CDUP, RMD, MKD, PWD,
LIST, NLST,
SYST, STAT,
HELP, NOOP, QUIT.
- 仅对文件系统支持记录结构的主机才要求 (REQUIRED) 记录结构.
讨论 (DISCUSSION):
鼓励厂商实现协议的更大子集. 例如, 协议中有一些重要的健壮性特性 (如 Restart, ABOR, 块模式) 会对一些互联网用户有所帮助, 但尚未被广泛实现.
文件系统中没有记录结构的主机仍可以接受 STRU R 的文件, 按字面记录字节流.
4.1.3 具体问题 (SPECIFIC ISSUES)
4.1.3.1 非标准命令动词 (Non-standard Command Verbs)
FTP 允许 "实验性" 命令, 其名称以 "X" 开头. 如果这些命令随后被采纳为标准, 可能仍存在使用 "X" 形式的既有实现. 目前, 目录命令就是如此:
RFC-959 "Experimental"
MKD XMKD
RMD XRMD
PWD XPWD
CDUP XCUP
CWD XCWD
所有 FTP 实现应当 (SHOULD) 同时识别这些命令的两种形式, 只需在命令查找表中把它们与额外条目等价起来即可.
实现 (IMPLEMENTATION):
User-FTP 可以通过实现一个模式开关来访问只支持 "X" 形式的服务器, 或者自动使用以下规程: 如果上述某条命令的 RFC-959 形式被 500 或 502 响应码拒绝, 则尝试实验形式; 其他任何响应都会传递给用户.
4.1.3.2 空闲超时 (Idle Timeout)
Server-FTP 进程应当 (SHOULD) 有一个空闲超时: 如果服务器长时间不活动 (即没有正在进行的命令或数据传输), 它将终止该进程并关闭控制连接. 空闲超时时长应当 (SHOULD) 可配置, 默认值应当至少 5 分钟.
客户端 FTP 进程 (RFC-959 中的 "User-PI") 只有在被程序调用时才需要对应答设置超时.
讨论 (DISCUSSION):
没有超时的话, 如果对应的客户端崩溃而未关闭控制连接, Server-FTP 进程可能被无限期搁置.
4.1.3.3 数据与控制的并发 (Concurrency of Data and Control)
讨论 (DISCUSSION):
FTP 设计者的意图是: 用户应当能够在数据传输进行中的任何时刻发送 STAT 命令, 并且 server-FTP 会立即以状态信息应答 -- 例如迄今已传输的字节数. 类似地, 在数据传输期间的任何时刻都应当可以发出 ABOR 命令.
遗憾的是, 一些小型机操作系统使这种并发编程变得困难, 而另一些实现者追求最小化方案, 因此一些 FTP 实现不允许并发使用数据连接与控制连接. 即便是这种最小化的服务器, 也必须准备好接受并推迟在数据传输期间到达的 STAT 或 ABOR 命令.
4.1.3.4 FTP 重启机制 (FTP Restart Mechanism)
RFC-959 第 40-41 页对 110 应答的描述不正确; 正确描述如下. 由接收方 FTP 经控制连接发送给 User-FTP 的重启应答消息, 格式为:
110 MARK ssss = rrrr
其中:
-
ssss 是一个文本字符串, 它出现在数据流的一个 Restart Marker 中, 并编码发送方文件系统中的一个位置;
-
rrrr 编码接收方文件系统中的对应位置.
这种编码特定于具体的文件系统与网络实现, 总是由同一系统 (发送方或接收方) 生成并解释.
当实现了重启的 FTP 在数据流中收到 Restart Marker 时, 它应当 (SHOULD) 在编码对应位置 rrrr 之前, 强制把截至该点的数据写入稳定存储. 发送 Restart Marker 的 FTP 禁止假定 (MUST NOT) 110 应答会与数据同步返回, 即它禁止在发送更多数据之前等待 110 应答.
在此为重启传输时遇到的错误定义两个新的应答码:
554 Requested action not taken: invalid REST parameter.
554 应答可能由跟在 REST 命令之后的 FTP 服务命令产生. 该应答表示 Server-FTP 处的既有文件无法按 REST 的指定重新定位.
555 Requested action not taken: type or stru mismatch.
555 应答可能由 APPE 命令或跟在 REST 命令之后的任何 FTP 服务命令产生. 该应答表示当前传输参数 (type 与 stru) 与既有文件的属性之间存在某种不匹配.
讨论 (DISCUSSION):
注意, FTP 重启机制要求数据传输使用 Block 或 Compressed 模式, 以便把 Restart Marker 纳入数据流. Restart Marker 的频率可以很低.
Restart Marker 标记数据流中的一个位置, 但接收方在把数据写入稳定存储时可能正在对数据做某种变换. 一般而言, 接收方的编码必须包含在该 FTP 数据流的任意点上重启这一变换所需的全部状态信息. 例如, 在 TYPE A 传输中, 一些接收主机把磁盘上的 CR LF 序列转换为单个 LF 字符. 如果一个 Restart Marker 恰好落在 CR 与 LF 之间, 接收方必须在 rrrr 中编码 "已见过并丢弃 CR" 的状态.
注意, 无论数据类型如何, Restart Marker 都被要求编码为可打印 ASCII 字符的字符串.
RFC-959 说重启信息要返回 "给用户". 这不应按字面理解. 一般而言, User-FTP 应当把重启信息 (ssss,rrrr) 保存到稳定存储, 例如把它追加到一个重启控制文件中. 重启控制文件应在传输首次开始时创建为空, 并在传输成功完成时自动删除. 建议该文件的名称以一种易于辨认的方式从被传输文件的名称与远程主机名派生; 这类似于许多文本编辑器命名 "备份" 文件的做法.
FTP 重启有三种情形.
(1) 用户到服务器传输 (User-to-Server Transfer)
User-FTP 在数据流中的便利位置放置 Restart Marker <ssss>. 当 Server-FTP 收到 Marker 时, 它把此前所有数据写入磁盘, 把其文件系统位置与变换状态编码为 rrrr, 并经控制连接返回 "110 MARK ssss = rrrr" 应答. User-FTP 把 (ssss,rrrr) 对追加到其重启控制文件.
要重启传输, User-FTP 从重启控制文件取出最后一个 (ssss,rrrr) 对, 用 ssss 重定位其本地文件系统与变换状态, 并向 Server-FTP 发送命令 "REST rrrr".
(2) 服务器到用户传输 (Server-to-User Transfer)
Server-FTP 在数据流中的便利位置放置 Restart Marker <ssss>. 当 User-FTP 收到 Marker 时, 它把此前所有数据写入磁盘, 把其文件系统位置与变换状态编码为 rrrr, 并把 (rrrr,ssss) 对追加到其重启控制文件.
要重启传输, User-FTP 从重启控制文件取出最后一个 (rrrr,ssss) 对, 用 rrrr 重定位其本地文件系统与变换状态, 并向 Server-FTP 发送命令 "REST ssss".
(3) 服务器到服务器 ("第三方") 传输 (Server-to-Server ("Third-Party") Transfer)
发送方 Server-FTP 在数据流中的便利位置放置 Restart Marker <ssss>. 接收方 Server-FTP 收到 Marker 时, 把此前所有数据写入磁盘, 把其文件系统位置与变换状态编码为 rrrr, 并经控制连接向用户发送 "110 MARK ssss = rrrr" 应答. User-FTP 把 (ssss,rrrr) 对追加到其重启控制文件.
要重启传输, User-FTP 从重启控制文件取出最后一个 (ssss,rrrr) 对, 向发送方 Server-FTP 发送 "REST ssss", 并向接收方 Server-FTP 发送 "REST rrrr".
4.1.4 FTP/用户界面 (FTP/USER INTERFACE)
本节讨论 User-FTP 程序的用户界面.
4.1.4.1 路径名规格 (Pathname Specification)
由于 FTP 旨在用于异构环境, User-FTP 实现必须 (MUST) 支持把远程路径名作为任意字符串处理, 使其形式与内容不受本地操作系统约定的限制.
讨论 (DISCUSSION):
特别是, 远程路径名可以有任意长度, 并且必须允许所有可打印 ASCII 字符以及空格 (0x20). RFC-959 允许路径名包含除 CR 或 LF 之外的任何 7 位 ASCII 字符.
4.1.4.2 "QUOTE" 命令 ("QUOTE" Command)
User-FTP 程序必须实现 (MUST) 一个 "QUOTE" 命令, 它把任意字符串传递给服务器, 并把产生的所有响应消息显示给用户.
为使 "QUOTE" 命令有用, User-FTP 应当 (SHOULD) 在用户输入传输控制命令时就发给服务器, 而不是把所有命令存起来直到数据传输开始才发给服务器.
讨论 (DISCUSSION):
"QUOTE" 命令至关重要, 它让用户能够访问需要系统特定命令 (例如 SITE 或 ALLO) 的服务器, 或调用 User-FTP 未实现的新特性或可选特性. 例如, 即使 User-FTP 不认识 "TYPE A T", 也可以用 "QUOTE" 来指定它, 向要求这一区分的主机发送打印文件.
4.1.4.3 向用户显示应答 (Displaying Replies to User)
User-FTP 应当 (SHOULD) 把它收到的所有错误应答消息的完整文本显示给用户. 它应当 (SHOULD) 有一个 "verbose" 模式, 显示它发送的所有命令以及收到的完整文本与应答码, 以便诊断问题.
4.1.4.4 维持同步 (Maintaining Synchronization)
User-FTP 中的状态机应当 (SHOULD) 容忍缺失与意料之外的应答消息, 以维持与服务器的命令同步.
4.1.5 FTP 要求摘要 (FTP REQUIREMENTS SUMMARY)
| | | | |S| |
| | | | |H| |F
| | | | |O|M|o
| | |S| |U|U|o
| | |H| |L|S|t
| |M|O| |D|T|n
| |U|U|M| | |o
| |S|L|A|N|N|t
| |T|D|Y|O|O|t
FEATURE |SECTION | | | |T|T|e
-------------------------------------------|---------------|-|-|-|-|-|--
Implement TYPE T if same as TYPE N |4.1.2.2 | |x| | | |
File/Record transform invertible if poss. |4.1.2.4 | |x| | | |
User-FTP send PORT cmd for stream mode |4.1.2.5 | |x| | | |
Server-FTP implement PASV |4.1.2.6 |x| | | | |
PASV is per-transfer |4.1.2.6 |x| | | | |
NLST reply usable in RETR cmds |4.1.2.7 |x| | | | |
Implied type for LIST and NLST |4.1.2.7 | |x| | | |
SITE cmd for non-standard features |4.1.2.8 | |x| | | |
STOU cmd return pathname as specified |4.1.2.9 |x| | | | |
Use TCP READ boundaries on control conn. |4.1.2.10 | | | | |x|
| | | | | | |
Server-FTP send only correct reply format |4.1.2.11 |x| | | | |
Server-FTP use defined reply code if poss. |4.1.2.11 | |x| | | |
New reply code following Section 4.2 |4.1.2.11 | | |x| | |
User-FTP use only high digit of reply |4.1.2.11 | |x| | | |
User-FTP handle multi-line reply lines |4.1.2.11 |x| | | | |
User-FTP handle 421 reply specially |4.1.2.11 | | | |x| |
| | | | | | |
Default data port same IP addr as ctl conn |4.1.2.12 |x| | | | |
User-FTP send Telnet cmds exc. SYNCH, IP |4.1.2.12 | | | | |x|
User-FTP negotiate Telnet options |4.1.2.12 | | | | |x|
Server-FTP handle Telnet options |4.1.2.12 |x| | | | |
Handle "Experimental" directory cmds |4.1.3.1 | |x| | | |
Idle timeout in server-FTP |4.1.3.2 | |x| | | |
Configurable idle timeout |4.1.3.2 | |x| | | |
Receiver checkpoint data at Restart Marker |4.1.3.4 | |x| | | |
Sender assume 110 replies are synchronous |4.1.3.4 | | | | |x|
| | | | | | |
Support TYPE: | | | | | | |
ASCII - Non-Print (AN) |4.1.2.13 |x| | | | |
ASCII - Telnet (AT) -- if same as AN |4.1.2.2 | |x| | | |
ASCII - Carriage Control (AC) |959 3.1.1.5.2 | | |x| | |
EBCDIC - (any form) |959 3.1.1.2 | | |x| | |
IMAGE |4.1.2.1 |x| | | | |
LOCAL 8 |4.1.2.1 |x| | | | |
LOCAL m |4.1.2.1 | | |x| | |2
| | | | | | |
Support MODE: | | | | | | |
Stream |4.1.2.13 |x| | | | |
Block |959 3.4.2 | | |x| | |
| | | | | | |
Support STRUCTURE: | | | | | | |
File |4.1.2.13 |x| | | | |
Record |4.1.2.13 |x| | | | |3
Page |4.1.2.3 | | | |x| |
| | | | | | |
Support commands: | | | | | | |
USER |4.1.2.13 |x| | | | |
PASS |4.1.2.13 |x| | | | |
ACCT |4.1.2.13 |x| | | | |
CWD |4.1.2.13 |x| | | | |
CDUP |4.1.2.13 |x| | | | |
SMNT |959 5.3.1 | | |x| | |
REIN |959 5.3.1 | | |x| | |
QUIT |4.1.2.13 |x| | | | |
| | | | | | |
PORT |4.1.2.13 |x| | | | |
PASV |4.1.2.6 |x| | | | |
TYPE |4.1.2.13 |x| | | | |1
STRU |4.1.2.13 |x| | | | |1
MODE |4.1.2.13 |x| | | | |1
| | | | | | |
RETR |4.1.2.13 |x| | | | |
STOR |4.1.2.13 |x| | | | |
STOU |959 5.3.1 | | |x| | |
APPE |4.1.2.13 |x| | | | |
ALLO |959 5.3.1 | | |x| | |
REST |959 5.3.1 | | |x| | |
RNFR |4.1.2.13 |x| | | | |
RNTO |4.1.2.13 |x| | | | |
ABOR |959 5.3.1 | | |x| | |
DELE |4.1.2.13 |x| | | | |
RMD |4.1.2.13 |x| | | | |
MKD |4.1.2.13 |x| | | | |
PWD |4.1.2.13 |x| | | | |
LIST |4.1.2.13 |x| | | | |
NLST |4.1.2.13 |x| | | | |
SITE |4.1.2.8 | | |x| | |
STAT |4.1.2.13 |x| | | | |
SYST |4.1.2.13 |x| | | | |
HELP |4.1.2.13 |x| | | | |
NOOP |4.1.2.13 |x| | | | |
| | | | | | |
User Interface: | | | | | | |
Arbitrary pathnames |4.1.4.1 |x| | | | |
Implement "QUOTE" command |4.1.4.2 |x| | | | |
Transfer control commands immediately |4.1.4.2 | |x| | | |
Display error messages to user |4.1.4.3 | |x| | | |
Verbose mode |4.1.4.3 | |x| | | |
Maintain synchronization with server |4.1.4.4 | |x| | | |
Footnotes:
(1) For the values shown earlier.
(2) Here m is number of bits in a memory word.
(3) Required for host with record-structured file system, optional
otherwise.
注: 以上要求摘要表为英文原文原样保留 (列含义: MUST / SHOULD / MAY / SHOULD NOT / MUST NOT / FOOTNOTE).
4.2 简单文件传输协议 -- TFTP (TRIVIAL FILE TRANSFER PROTOCOL -- TFTP)
4.2.1 引言 (INTRODUCTION)
简单文件传输协议 (TFTP) 定义于 RFC-783 [TFTP:1].
TFTP 以 UDP 作为传输协议, 使用简单的停等 (stop-and-wait) 确认系统提供自己的可靠交付. 由于 TFTP 的有效窗口只有一个 512 八位组的段, 它只能在时延*带宽积较小的路径上提供良好性能. TFTP 的文件接口非常简单, 不提供任何访问控制或安全机制.
TFTP 最重要的应用是在本地网络上引导 (bootstrap) 一台主机, 因为它足够简单和小巧, 可以很容易地在 EPROM 中实现 [BOOT:1, BOOT:2]. 强烈敦促厂商支持用 TFTP 引导.
4.2.2 协议逐步分析 (PROTOCOL WALK-THROUGH)
TFTP 规范 [TFTP:1] 以开放的笔法写成, 并未完整规定协议的许多部分.
4.2.2.1 传输模式 (Transfer Modes): RFC-783, 第 3 页
"mail" 传输模式不应当 (SHOULD NOT) 被支持.
4.2.2.2 UDP 头部 (UDP Header): RFC-783, 第 17 页
UDP 头部的 Length 字段定义有误; 它把 UDP 头部自身的长度 (8) 也计入在内.
4.2.3 具体问题 (SPECIFIC ISSUES)
4.2.3.1 巫师学徒综合症 (Sorcerer's Apprentice Syndrome)
协议规范中存在一个被称为 "巫师学徒综合症" (Sorcerer's Apprentice Syndrome) 的严重缺陷. 虽然它不会导致传输的不正确运行 (只要传输完成, 文件总是被正确传输), 但这一缺陷可能引起过度重传, 从而可能导致传输超时.
实现必须包含 (MUST) 对这一问题的修复: 发送方 (即发起 DATA 分组的一方) 在收到重复 ACK 时绝不能重发当前的 DATA 分组.
讨论 (DISCUSSION):
该缺陷由协议的一条规则引起: 任何一方在收到旧的重复数据报时都可以重发当前数据报. 如果一个分组在网络中被延迟, 而在任一方超时并重传了一个分组之后又成功到达, 就可能产生响应的重复副本. 如果另一方对这个重复又以自己的重复作为响应, 那么在传输的剩余时间里每个数据报都会被重复发送 (除非某个数据报丢失, 打破了重复). 更糟的是, 由于延迟常由拥塞引起, 这种重复传输通常会造成更多拥塞, 进而导致更多被延迟的分组, 如此循环.
下面的例子有助于说明这个问题.
TFTP A TFTP B
(1) Receive ACK X-1
Send DATA X
(2) Receive DATA X
Send ACK X
(ACK X is delayed in network,
and A times out):
(3) Retransmit DATA X
(4) Receive DATA X again
Send ACK X again
(5) Receive (delayed) ACK X
Send DATA X+1
(6) Receive DATA X+1
Send ACK X+1
(7) Receive ACK X again
Send DATA X+1 again
(8) Receive DATA X+1 again
Send ACK X+1 again
(9) Receive ACK X+1
Send DATA X+2
(10) Receive DATA X+2
Send ACK X+3
(11) Receive ACK X+1 again
Send DATA X+2 again
(12) Receive DATA X+2 again
Send ACK X+3 again
注意, 一旦那个被延迟的 ACK 到达, 协议就稳定地进入把后续所有分组都重复发送的状态 (序列 5-8 与 9-12). 这一问题的根源不是任何一方超时, 而是双方在收到重复分组时都重传当前分组.
修复方法是打破重传循环, 如上所述. 这与 TCP 的行为类似. 此后就可以移除接收方的重传计时器, 因为重发的 ACK 永远不会引发任何动作; 这在 TFTP 被用于引导程序时是一个有用的简化. 保留该计时器也没有问题, 并且如果重传的 ACK 恰好顶替了一个在网络中真正丢失的 ACK, 它可能还有帮助. 当然, 发送方仍然需要重传计时器.
4.2.3.2 超时算法 (Timeout Algorithms)
TFTP 实现必须使用 (MUST) 自适应超时.
实现 (IMPLEMENTATION):
TCP 的重传算法提供了一个有用的基础. 至少需要对重传超时做指数退避.
4.2.3.3 扩展 (Extensions)
对 TFTP 已做了多种非标准扩展, 包括额外的传输模式与一种安全操作模式 (带口令). 这些都没有被标准化.
4.2.3.4 访问控制 (Access Control)
服务器 TFTP 实现应当 (SHOULD) 包含某种可配置的访问控制, 约束 TFTP 操作中允许的路径名.
4.2.3.5 广播请求 (Broadcast Request)
发往广播地址的 TFTP 请求应当 (SHOULD) 被静默忽略.
讨论 (DISCUSSION):
由于 TFTP 的访问控制能力薄弱, 把 TFTP 请求定向广播到随机网络可能造成重大的安全漏洞.
4.2.4 TFTP 要求摘要 (TFTP REQUIREMENTS SUMMARY)
| | | | |S| |
| | | | |H| |F
| | | | |O|M|o
| | |S| |U|U|o
| | |H| |L|S|t
| |M|O| |D|T|n
| |U|U|M| | |o
| |S|L|A|N|N|t
| |T|D|Y|O|O|t
FEATURE |SECTION | | | |T|T|e
-------------------------------------------------|--------|-|-|-|-|-|--
Fix Sorcerer's Apprentice Syndrome |4.2.3.1 |x| | | | |
Transfer modes: | | | | | | |
netascii |RFC-783 |x| | | | |
octet |RFC-783 |x| | | | |
mail |4.2.2.1 | | | |x| |
extensions |4.2.3.3 | | |x| | |
Use adaptive timeout |4.2.3.2 |x| | | | |
Configurable access control |4.2.3.4 | |x| | | |
Silently ignore broadcast request |4.2.3.5 | |x| | | |
-------------------------------------------------|--------|-|-|-|-|-|--
-------------------------------------------------|--------|-|-|-|-|-|--
注: 以上要求摘要表为英文原文原样保留 (列含义: MUST / SHOULD / MAY / SHOULD NOT / MUST NOT / FOOTNOTE).