前言

最近看了挺多RFC文档,RFC文档有不同的状态、更新、淘汰某文档等等概念,如何正确阅读RFC文档能为我们节省不少时间,也会对其更了解,本文翻译至IETF官方文章地址>,原文写于2018年9月。


正文

无论好坏,RFCs是IETF组织详细说明许多互联网协议是怎样的。这些文档被开发者看作神圣的文档,他们翻译并了解其中隐藏的含义,然后因为不了解的地方会被跳过。这通常会导致挫折感,严重的甚至导致操作性和安全性。然而,能够深入了解它们是如果构建和发布的,你会更容易理解你所看到的内容。

从哪里开始

RFC Editor Web Site是一个查找RFCs的标准地址。然而,正如下面所说,有一些关键信息是会错过的,所以更多的人会使用tools.ietf.org

尽管找到一个正确的RFC是很困难的,因为有非常多的文档(截止2008年,大概9千)。很明显,你可以通过一般的Web搜索引擎找到它们。而且RFC Editor网站有一个极好的搜索功能(地址传送门)。

另一个选择是rfc.fyi地址(地址传送门),该网站可以通过标题、关键词和标签进行搜索RFC。

文本类型的RFCs是很难读且接近于丑这事已经不是秘密了,但是事情即将好转;21年RFC Editor包装RFC使用了其它新格式,令人满意的呈现和定制化的选择。与此同时,如果你想更多可用的RFCs,你可以将一些选定的使用第三方仓库存储;例如,greenbytes网站专注于与WebDAV相关的RFCs,而且HTTP Working Group维护着关于HTTP协议的一部分。


RFC的类型是什么?

所有的RFCs在顶部都有个横幅,看上去如下所示:
image-1703995135974
在顶部的左边,有句“Internet Engineering Task Force (IETF)”表示它是IETF生成的;尽管它不是很广为人知,但是还有其它方法可以发布不需要IETF一致同意的RFC;例如,independent stream(提供了一个渠道,允许在没有IETF的共识下,可以发布一些重要的想法等)。

实际上,可以在很多“流”上发布文档,但仅仅IETF流表明了整个IETF已经审核并且声明了对协议规范的一致意见。

旧的文档(RFC5705之前)对应着“Network Working Group”不是IETF,所有你需要进一步了解它们是否代表IETF工识,从“Status of This Memo”段落下开始。

在声明“IETF”下面是“Request for Comments”。如果展示的是“Internet-Draft”,那么它不是一个RFC文档,它仅仅是一个提案,任何人都可以写(地址)。因为,它还只是一个提案,并不意味着将会被IETF采纳。

Category可以是“Standards Track”、“Information”、“Experimental”、“Best Current Practice”。它们之间的区别有时候会被混淆。如果它是IETF生成的(如上面所示,Standards Track),表示它已经被相当次数的审查了。然而,标记为“Information”和“Experimental”则不是标准,尽管它是IETF共识后发布。

最后,这个文档的作者是罗列在头部的右边。不像在学术届,它并没有列出全部参与文档的人,全部的人名通常在最底部“致谢”部分完成的。在RFCs中,这个上面主要是“编辑文档的人”,经常看到的Ed. 表示它们作为编辑者,往往因为文档是预先存在的(如当一个RFC被修改)。

文档的主要作者是 R. Fielding(Adobe)和 J. Reschke(greenbytes),两位作者都标记为编辑(Ed.)。


现在是什么?

RFCs是一系列归档文档,它们不能改变,即使是一个字符(RFC7158和RFC7159是一个极端的例子,它们弄错了年份)。

因此,确定看的是一个正确的文档是非常重要的。文档头部包括了2种信息可以提供帮助:

  • Obsoletes(淘汰):列出了RFCs文档被完全取到了;比如,你应该使用这个文档,而不是那个。注意一个老版本的协议没必要淘汰当一个新的协议出来;例如,HTTP/2不会淘汰HTTP/1.1,因为它仍是正当合法的去实现老版协议。然而,RFC7230确实淘汰了 RFC2616,因为它是该协议的参考。

  • Updates(更新):列出了RFCs文档发生了实质性的修改;换言之,如果你读了其它的文档,你也应该读当前的这个。

尽管是最新的RFC文档也会经常有问题,在文档顶部,你将看到这个“Errata Exist”标识,上面还有勘误的连接。

Errata勘误表是对不值得发布新RFC文档的更正和澄清。有时候它们会对RFC中有关实现的方式产生重大影响(如果规范中的一个Bug导致了重大的误解),它们值得一看。

例如,下面连接是RFC7230的勘误表,当读勘误表的时候,记住它们的状态,一些人被拒绝是因为它们误解了这个信息。


读懂内容

对开发者来说,查看RFC然后实现看到的,做与作者意图相反的事情,这种情况比你想象的更常见。

因为在有选择性的阅读规范时,以不会被误解的方式编写规范是极其困难的。

因此,直接读相关的文本和任何它关联的内容是有必要的,不管是同一种还是不同的,在紧要关头,如果你不能阅读整个文档,读任何可能相关的章节是有帮助的。

同等重要的要记住有些协议初始化IANA注册表管理扩展点;这些,不是规范,而是真相的来源。例如,HTTP方法的规范是位于此注册表中,而不是任何HTTP规范。


解释 Requirements

几乎所有的RFCs在顶部都有如下的标准格式文字:
image-1704027921745
这些RFC2119有助于定义互操作性,但它们有时使开发者迷惑,很常见的一种情况是一个规范会像如下表诉:
image-1704028105316
这个要求被放到协议构件“Foo Message”提出的,如果你正在发生一个消息,那么它显然不应该包含Bar头部;如果你包含了一个,那么它就不是一个符合标准的消息。

然而,这个接收者的行为就不是那么清楚了,如果你看到了Foo Message 在一个Bar的头部,你会做什么?

一些开发者会拒绝这个包含它(Foo Mssage)的消息,尽管这个描述没有说任何事要这么做。其他开发者将会执行这个消息,但是会去掉这个Bar头部或者忽视它-尽管正文明确的说所有的头部都需要被执行。

所有这些事情可能无意的导致了互操作性问题。正确应该做的是遵循标题的正确执行,除非这些有相反的明确要求。

因为在通常情况下,规范的编写是为了公开的指定行为;也就是说,每个事没有被明确禁止就是允许的。因此,过多的解读规范,可能会无意中造成伤害,因为你将会引入其他人不得不绕过的行为。

理想情况下,规范将会按照处理消息的人的行为进行定义,,如下:
image-1704029949199

在没有具体指导的情况下,最好去寻找其它部分关于错误处理更加一般性的建议(例如,HTTP的符合性和错误处理章节

另外,记住requirements的目标;大部分的规范有高度发达的术语集,它们用来在不同的协议中区分角色。

SHOULD

没错,SHOULD 应该有它自己的章节。这种模棱两可的术语困扰许多RFCs,尽管在努力消除它。RFC2119描述:
image-1704031101083

在实践中,作者经常使用“SHOULD” 和 “SHOULD NOT”来说明“我们希望你这样做,但我们不能总是要求你”。


阅读示例

另一个非常普遍的困难是区阅读示例的规范和实现它们做什么。

不幸的是,典型的示例被作者关注的很少,因为每一次改变协议都需要被更新。

结果,它们通常是规格中最不可靠的一部分,作者决定应该在发表之前再次检查示例,但是错误还是会漏掉。

即使一个完美的示例可能无法说明你正在寻找的协议的各个方面,它们经常被截断,或者在解码步骤发生后显示。

尽管阅读示例花费更多的时间,但最好阅读实际的文本,示例并不是规范


安全考虑

从RFC3552之后,RFC发布包括“Security Considerations”章节。

结果,很少RFC发布没有安全部分的章节;这个审核过程不允许一个提案直接说“该协议没有安全章节”。

因此,阅读及确认理解安全协议是值得的,不管是实现还是部署协议,如果你不了解,很可能会什么事情在路上阻挡你。

遵循它的参考文献也是个好主意,如果没有,尽量寻找一些来了解正在讨论的问题的术语。


寻找更多

如果一个RFC不能回答你的问题,或者你不能确定它的内容的意图,最好的方式是找到相关的工作组,然后邮件问问题。如果没有找到问题相关的工作组,尝试在该地方找对应的邮件列表。

归档勘误表通常不是你应该采取的第一步——先和某人谈谈。

一些工作组现在使用Github来管理他们的规范;如果你对活跃的规范有问题,提交issue。如果它是一个RFC,通常最好是使用邮件除非你找到了相反的方向。


总结

RFC(Request for Comments)是不能被修改的规范文件,它是由互联网工程工作组IETF进行发布的备忘录。一旦经过IETF共识,说明它是被讨论是作为一个行业规范。RFC包括了不同的状态、不同的类型,一般RFC头部会有想过信息,注意查看最新的而不是被过时的RFC。

RFC Editor是一个比较有权威的网站,发布RFCs,同时支持搜索。

也需要注意勘误、要求解释和协议示例,不然很容易理解错误。