跳到主要内容

1. 简介 (INTRODUCTION)

本文档是一对文档中的一篇, 定义并讨论互联网协议套件 (Internet protocol suite) 的主机 (host) 系统实现要求. 本 RFC 涵盖应用层 (application layer) 和支持协议. 其配套 RFC "互联网主机要求 -- 通信层" [INTRO:1] 涵盖较低层的协议: 传输层 (transport layer)、IP 层和链路层 (link layer).

这些文档旨在为互联网通信软件的供应商、实现者和用户提供指导. 它们代表了由互联网研究界和供应商社区的成员所贡献的大量技术经验与智慧的共识.

本 RFC 列举了连接到互联网的主机必须 (MUST) 使用的标准协议, 并通过引用纳入了描述这些协议当前规范的 RFC 及其他文档. 它纠正了引用文档中的错误, 并为实现者补充了额外的讨论和指导.

对于每种协议, 本文档还包含一组明确的要求、建议和选项. 读者必须理解, 本文档中的要求列表本身并不完整; 互联网主机的完整要求集主要定义在各标准协议规范文档中, 本 RFC 包含的是对它们的更正、修订和补充.

一份善意的 (good-faith) 协议实现, 如果是在仔细阅读相关 RFC 并与互联网技术社区有一定交流之后产出的, 并且遵循了良好的通信软件工程实践, 那么它应当只在本文档要求的次要方面与之不同. 因此, 在许多情况下, 本 RFC 中的"要求"已经在标准协议文档中陈述或暗示, 所以把它们收录在这里在某种意义上是冗余的. 然而, 之所以收录它们, 是因为过去的一些实现做出了错误的选择, 导致了互操作性、性能和/或健壮性方面的问题.

本文档包含对许多要求和建议的讨论与解释. 仅仅给出一个简单的要求列表是危险的, 因为:

  • 某些必需的特性比其他的更重要, 而某些特性是可选的.

  • 为受限环境设计的特定厂商产品, 可能有正当理由选择使用不同的规范.

然而, 要实现"在互联网系统的多样性和复杂性之中任意主机相互操作"这一总体目标, 就必须遵循本文档的规范. 尽管当前大多数实现在各种方面 (有些是次要的, 有些是重大的) 未能满足这些要求, 本规范仍然是我们需要努力趋近的理想.

这些要求基于当前互联网架构的水平. 本文档将按需更新, 以便在规范仍在演进的领域提供进一步的澄清或纳入更多的信息.

本导论一节首先向主机软件供应商提供一般性建议, 然后就如何阅读本文档的其余部分给出一些指导. 第 2 节包含可能适用于所有应用和支持协议的一般性要求. 第 3、4 和 5 节分别包含三大应用 -- Telnet、文件传输和电子邮件 -- 的协议要求. 第 6 节涵盖支持应用: 域名系统 (domain name system)、系统初始化和管理. 最后, 所有参考文献见第 7 节.

1.1 互联网架构 (The Internet Architecture)​

关于从主机视角对互联网架构的简要介绍, 见 [INTRO:1] 的第 1.1 节. 该节还包含关于互联网架构一般背景的推荐参考文献.

1.2 一般考量 (General Considerations)​

互联网主机软件的供应商已经吸取了两个重要的教训, 任何新的供应商都应当认真考虑它们.

1.2.1 互联网的持续演进 (Continuing Internet Evolution)​

互联网的巨大增长揭示了一个基于数据报 (datagram) 的大型分组通信系统在管理和扩展方面的种种问题. 这些问题正在被解决, 因此本文档所述的规范将持续演进. 这些变更将被仔细规划和控制, 因为供应商以及负责网络运营的组织广泛参与了这一规划.

开发、演化和修订是当今计算机网络协议的特征, 这种状况还将持续多年. 一家为互联网协议套件 (或任何其他协议套件!) 开发计算机通信软件、随后却不为适应规范变化而维护和更新该软件的供应商, 将会留下一串不满的客户. 互联网是一个大型的通信网络, 用户通过它保持着持续的联络. 经验表明, 有关厂商软件缺陷的消息会在互联网技术社区中迅速传播.

1.2.2 健壮性原则 (Robustness Principle)​

在协议的每一层, 都有一条通用规则, 其应用可以在健壮性和互操作性方面带来巨大的好处:

"对你所接受的内容保持宽容, 对你所发送的内容保持保守" ("Be liberal in what you accept, and conservative in what you send")

软件应当被编写为能够处理每一种可以想见的错误, 无论它看起来多么不可能发生; 迟早会有一个数据包携带着那种特定的错误与属性组合到达, 而如果软件没有做好准备, 混乱就可能随之而来. 一般而言, 最好假定网络中充满了恶意实体, 它们会发送旨在产生最坏可能影响的数据包. 这种假定会带来恰当的防护性设计, 尽管互联网上最严重的问题其实是由低概率事件触发的、未曾预料的机制所造成的; 单纯的人类恶意绝不会走出如此迂回的路线!

适应变化的能力必须被设计进互联网主机软件的所有层次. 举个简单的例子: 考虑一份对某个特定首部字段的取值进行了枚举的协议规范 -- 例如一个类型字段、一个端口号或一个错误代码; 这种枚举必须被假定是不完整的. 因此, 如果协议规范定义了四种可能的错误代码, 那么当第五种代码出现时, 软件禁止 (MUST NOT) 因此崩溃. 未定义的代码可以被记录下来 (见下文), 但它禁止导致失败.

原则的第二部分几乎同样重要: 其他主机上的软件可能存在种种缺陷, 使得利用合法但晦涩的协议特性成为不明智之举. 偏离显而易见和简单的做法太远是不明智的, 以免在别处造成不良后果. 由此得到的一个推论是 "提防行为不当的主机" ("watch out for misbehaving hosts"); 主机软件不仅应当准备好在其他行为不当的主机面前生存下来, 还应当与其协作, 以限制这类主机能够对共享通信设施造成的破坏.

1.2.3 错误日志 (Error Logging)​

互联网包含各种各样的主机和网关 (gateway) 系统, 每个系统都实现了许多协议和协议层次, 其中一些系统的互联网协议软件中存在着缺陷 (bug) 和不良特性. 由于功能的复杂性、多样性和分布性, 用户问题的诊断往往非常困难.

如果主机实现包含一个经过精心设计的、用于记录错误或"异常"协议事件的设施, 问题诊断将得到很大帮助. 在记录错误时, 尽可能多地包含诊断信息非常重要. 特别地, 记录引发错误的数据包的首部往往很有用. 然而, 必须注意确保错误日志不会消耗多到令人望而却步的资源, 或者以其他方式干扰主机的正常运行.

异常但无害的协议事件往往会使错误日志文件被撑爆; 这可以通过使用"循环" (circular) 日志, 或只在诊断某个已知故障时才启用日志来避免. 对重复出现的连续消息进行过滤和计数可能会很有用. 一种看起来行之有效的策略是: (1) 始终对异常进行计数, 并使这些计数可以通过管理协议访问 (见第 6.3 节); 以及 (2) 允许有选择地启用对各种事件的记录. 例如, 能够"记录所有内容"或"记录主机 X 的所有内容"可能是有用的.

请注意, 不同的管理机构对于主机中通常应启用多少错误日志可能有不同的策略. 有些会说 "如果它不伤害我, 我就不想知道它", 而另一些则希望在检测和消除协议异常方面采取更加警觉和积极的态度.

1.2.4 配置 (Configuration)​

如果互联网协议套件的主机实现能够完全自我配置, 那将是最理想的. 这将允许把整个套件实现于 ROM 之中或固化到硅片里, 将简化无盘工作站, 对疲于奔命的局域网 (LAN) 管理员和系统供应商来说也是一大福音. 我们还没有达到这一理想; 事实上, 我们甚至相去甚远.

在本文档的许多地方, 你会发现这样一项要求: 某个参数必须是一个可配置的选项. 这些要求背后有几种不同的原因. 在少数情况下, 关于最佳取值目前尚存不确定性或分歧, 将来可能有必要更新推荐值. 在另一些情况下, 取值实际上取决于外部因素 -- 例如主机的规模及其通信负载的分布, 或者邻近网络的速度和拓扑 -- 而自调谐算法不可用, 即使可用也可能不够充分. 在某些情况下, 之所以需要可配置性, 是出于管理上的要求.

最后, 某些配置选项是为了与协议的过时或错误实现进行通信所必需的; 这些实现未随源码一同分发, 却不幸在互联网的许多地方持续存在. 为了让正确的系统能够与这些有故障的系统共存, 管理员常常不得不对正确的系统进行"错误配置" ("mis-configure"). 随着有故障的系统被逐步淘汰, 这个问题会逐渐自行消失, 但供应商不能忽视它.

当我们说某个参数必须 (MUST) 可配置时, 我们并不打算要求在每次引导时都从配置文件中显式读取它的值. 我们建议实现者为每个参数设置一个默认值, 这样配置文件只需用来覆盖那些在特定安装环境中不合适的默认值. 因此, 可配置性要求是一种保证: 必要时将有可能 (POSSIBLE) 覆盖默认值, 即使是在只提供二进制形式或基于 ROM 的产品中.

本文档在某些情况下对这类默认值规定了特定的取值. 当配置项控制的是对现存故障系统的迁就时, 默认值的选择是一个敏感问题. 如果互联网要成功地收敛到完全的互操作性, 那么实现中内建的默认值必须实现官方协议, 而不是用来迁就故障实现的"错误配置". 尽管市场营销方面的考虑已经使一些厂商选择了错误配置的默认值, 我们仍敦促厂商选择符合标准的默认值.

最后, 我们指出, 供应商需要就所有配置参数及其限制和效果提供充分的文档.

1.3 阅读本文档 (Reading this Document)​

1.3.1 组织结构 (Organization)​

一般而言, 每个主要章节都组织为以下小节:

(1) 导论 (Introduction)

(2) 协议走查 (Protocol Walk-Through) -- 逐节审视协议规范文档, 纠正其中的错误, 陈述可能含糊或定义不清的要求, 并提供进一步的澄清或解释.

(3) 具体问题 (Specific Issues) -- 讨论未包含在走查之中的协议设计与实现问题.

(4) 接口 (Interfaces) -- 讨论通向更高一层的业务接口.

(5) 总结 (Summary) -- 包含本节各项要求的摘要.

在本文档的许多具体主题之下, 存在标注为 "DISCUSSION" (讨论) 或 "IMPLEMENTATION" (实现) 的括注材料. 这些材料旨在对前面的要求文本给出澄清和解释. 它还包括一些关于可能的未来方向或发展的建议. 实现类材料包含实现者可能想要考虑的推荐方法.

总结各节旨在作为正文的指南和索引, 但它们必然是简略且不完整的. 绝不应脱离完整的 RFC 而单独使用或引用这些总结.

1.3.2 要求 (Requirements)​

在本文档中, 用于定义每个特定要求之重要性的词语均大写. 这些词语是:

  • "MUST" (必须)

    此词或形容词 "REQUIRED" 意味着该项目是本规范的绝对要求.

  • "SHOULD" (应当)

    此词或形容词 "RECOMMENDED" 意味着在特定情况下可能存在忽略此项目的正当理由, 但在选择不同做法之前, 应当充分理解其全部含义并仔细权衡.

  • "MAY" (可以)

    此词或形容词 "OPTIONAL" 意味着该项目是真正可选的. 例如, 一个厂商可能因为特定市场需要或它能增强产品而选择包含该项目; 另一个厂商则可以省略同一项目.

如果一个实现未能满足它所实现协议的一条或多条 MUST 要求, 则它是不合规的. 满足其协议的全部 MUST 要求和全部 SHOULD 要求的实现被称为 "无条件合规" ("unconditionally compliant"); 满足其协议的全部 MUST 要求但未满足全部 SHOULD 要求的实现被称为 "有条件合规" ("conditionally compliant").

1.3.3 术语 (Terminology)​

本文档使用以下技术术语:

段 (Segment)

段 (segment) 是 TCP 协议中端到端传输的单位. 一个段由一个 TCP 首部后跟应用数据组成. 段通过封装在 IP 数据报 (datagram) 中进行传输.

消息 (Message)

某些应用层协议 (特别是 SMTP) 用这个术语指代应用数据单元.

数据报 (Datagram)

[UDP] 数据报是 UDP 协议中端到端传输的单位.

多宿主 (Multihomed)

如果一个主机拥有多个 IP 地址以连接到多个网络, 则称该主机为多宿主 (multihomed) 主机.

1.4 致谢 (Acknowledgments)​

本文档吸收了大批互联网协议专家的贡献和意见, 其中包括大学和研究实验室、供应商以及政府机构的代表. 它主要由主机要求工作组 (Host Requirements Working Group) 汇编而成. 编辑尤其要感谢以下人员的不懈奉献 -- 在过去 18 个月里, 为完成本文档, 他们参加了许多漫长的会议并产生了 300 万字节的电子邮件: Philip Almquist, Dave Borman (Cray Research), Noel Chiappa, Dave Crocker (DEC), Steve Deering (Stanford), Mike Karels (Berkeley), Phil Karn (Bellcore), John Lekashman (NASA), Charles Lynn (BBN), Keith McCloghrie (TWG), Paul Mockapetris (ISI), Thomas Narten (Purdue), Craig Partridge (BBN), Drew Perkins (CMU), 以及 James Van Bokkelen (FTP Software).

此外, 以下人员为这项工作做出了重大贡献: Bill Barns (Mitre), Steve Bellovin (AT&T), Mike Brescia (BBN), Ed Cain (DCA), Annette DeSchon (ISI), Martin Gross (DCA), Phill Gross (NRI), Charles Hedrick (Rutgers), Van Jacobson (LBL), John Klensin (MIT), Mark Lottor (SRI), Milo Medin (NASA), Bill Melohn (Sun Microsystems), Greg Minshall (Kinetics), Jeff Mogul (DEC), John Mullen (CMC), Jon Postel (ISI), John Romkey (Epilogue Technology), 以及 Mike StJohns (DCA). 以下人员也对特定领域做出了重要贡献: Eric Allman (Berkeley), Rob Austein (MIT), Art Berggreen (ACC), Keith Bostic (Berkeley), Vint Cerf (NRI), Wayne Hathaway (NASA), Matt Korn (IBM), Erik Naggum (Naggum Software, Norway), Robert Ullmann (Prime Computer), David Waitzman (BBN), Frank Wancho (USA), Arun Welch (Ohio State), Bill Westfield (Cisco), 以及 Rayan Zachariassen (Toronto).

我们感谢所有人, 包括任何可能被无意中遗漏在本名单之外的贡献者.