关于 TCP/IP 详解卷一(中文版本)中 ISN 产生方法的一个翻译错误(4ms)备忘

TCP-IP卷1中译版本第18章18.2.3中关于 ISN 的翻译错误


原书作者: W. Richard Stevens 著作的第一版本. 英文版本可以在 JD 找到买书链接.
想看电子版本的可以在这里找:CSDN 要分的链接. 如果没有积分想下载.可以私我. 顺便说下这个链接不是我的账号.我找了好久才找到的这一个要分少的链接.

由于之前网络知识断层.所以回顾一下 TCP/IP 相关的知识. 找时间读了下经典著作.豆瓣链接:TCP/IP详解 卷1:协议
译文如下:

发送第一个S Y N的一端将执行主动打开( active open)。接收这个S Y N并发回下一个S Y N 
的另一端执行被动打开( passive open)(在18.8节我们将介绍双方如何都执行主动打开)。
当一端为建立连接而发送它的 S Y N时,它为连接选择一个初始序号。 I S N随时间而变化, 
因此每个连接都将具有不同的 ISN。RFC 793 [Postel 1981c]指出ISN可看作是一个32比特的计 数器,每4ms加1。 
这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送, 而 导致某个连接的一方对它作错误的解释。

如何进行序号选择? 在4.4BSD(和多数的伯克利的实现版)中,系统初始化时初 始的发送序号被初始化为1。
这种方法违背了Host Requirements RFC(在这个代码中的 一个注释确认这是一个错误)。
这个变量每 0 . 5秒增加6 4 0 0 0,并每隔9 . 5小时又回到0 (对应这个计数器每8 ms加1,而不是每4 ms加1)。
另外,每次建立一个连接后,这个 变量将增加64000。

读到这里,发现总觉得哪有些不对.4ms 加1的计时器.那一个32 BITs 的计数器一秒的加计数是 250. 因此 0.5 秒应该是 125. 而上文的BSD 系统的加
计数是0.5秒增加了64000.(即使如原文中所说的实现为8ms 加1. 为原来的时间的一倍. 那计数也应该是 62.5 而不是64000 所以这里的时间是有问题)

查看英文原文如下:

When each end sends its SYN to establish the connection, it chooses an initial sequence number for that connection. 
The ISN should change over time, so that each connection has a different ISN. RFC 793 [Postel 1981c] specifies that 
the ISN should be viewed as a 32-bit counter that increments by one every 4 microseconds. The purpose in these 
sequence numbers is to prevent packets that get delayed in the network from being delivered later and then 
misinterpreted as part of an existing connection.

How are the sequence numbers chosen? In 4.4BSD (and most Berkeley-derived implementations) when the system is 
initialized the initial send sequence number is initialized to 1. This practice violates the Host Requirements RFC. 
(A comment in the code acknowledges that this is wrong.) This variable is then incremented by 64,000 every 
half-second, and will cycle back to 0 about every 9.5 hours. (This corresponds to a counter that is incremented 
every 8 microseconds, not every 4 microseconds.) Additionally, each time a connection is established, 
this variable is incremented by 64,000.

这里的原文是:RFC 793 [Postel 1981c] specifies that the ISN should be viewed as a 32-bit counter that increments by one every 4 microseconds,也就是说原来单位是4us ( 而不是译文中的4ms): microsecond ,不是 millisecond.这样4us 加1.那一秒可以加的数量是:

1000 000 / 4 = 250 000 (每秒)

对于一半的速度(8us +1)则为

1000 000 / 8 = 125 000 (每秒) 

对于0.5秒的计数为: 125000 / 2 = 62500,约等于文中所说的64 000. 这样32BIT 的计数器溢出一周是:( 2^32 / 128000 ) / 3600 = 9.32 小时
也是文中所说的大约9.5小时.

下面再看看 RFC 973的原文怎样说的,地址: https://tools.ietf.org/html/rfc793

To avoid confusion we must prevent segments from one incarnation of a
connection from being used while the same sequence numbers may still
be present in the network from an earlier incarnation. We want to
assure this, even if a TCP crashes and loses all knowledge of the
sequence numbers it has been using. When new connections are created,
an initial sequence number (ISN) generator is employed which selects a
new 32 bit ISN. The generator is bound to a (possibly fictitious) 32
bit clock whose low order bit is incremented roughly every 4
microseconds. Thus, the ISN cycles approximately every 4.55 hours.
Since we assume that segments will stay in the network no more than
the Maximum Segment Lifetime (MSL) and that the MSL is less than 4.55
hours we can reasonably assume that ISN's will be unique.

为了避免混乱,我们必须阻止从一个连接的实体的报文(segments)被使用(重用),同时来自于一个更早的连接实体的相同序号(的报文)仍在网络上可见.
我们想要确保如此,在一个 TCP 崩溃并且丢失了所有的它正在使用的序列号的信息. 当一个新连接创建的时候,一个初始序列号(ISN)生成器被用来选
择一个新的32BIT 的 ISN. 这个生成器绑定到一个32位的时钟上.(它的最低有效位每4个 us 加1)这样,ISN 周期性的大约4.55小时溢出一次. 由于我
们假定报文将不会在网络上保持超过最大报文生命周期(MSL) 并且 MSL 小于4.55小时. 所以我们可以合理的假定 ISN 将会是唯一的.

这个可以很明确的在 RFC 里面是说明一时间是4us.但是由于我们的中文译本中存在错误,导致中文区的朋友一直都是在错误的教材上进行学习研究.
目前在网上找得到的所有相关的资料,基本也是使用了这个错误的引用.像这个
看这个博客,相信至少也是比较花时间整理出来的.但是这些"引经据曲"的论述还是在错误的教材上.着实有些可惜.希望有看到此文章的读者.能有幸帮传达
这个正确的知识点给你.

听说这本书后面还出了第二版(已经不是 stevens 大神的作品了. stevens 大神英年早逝.)看看是否在新版本的翻译中纠正了此错误.
特此我找了相关的书如下:

英文原版: (直接使用了 us,相信翻译者的英文再渣也不会翻译错了.)

 The ISN should change over time, so that each connection has a different one. [RFC0793] specifies 
 that the ISN should be viewed as a 32-bit counter that increments by 1 every 4μs.

中文译文:

 在发送用于建立连接的SYN之前,通信双方会选择一个初始序列号。初始序列号会随 时间而改变,因此每一个连接都拥有不同的初始序列号。 
 [RFCO793]指出初始序列号可被视 为一个32位的计数器。该计数器的数值每4微秒加1.此举的目的在于为一个连接的报文段 安排序列号,
 以防止出现与其他连接的序列号重叠的情况。尤其对于同一连接的两个不同实 例而言,新的序列号也不能出现重叠的情况

说明:
第二版本已经对第一版本进行了大量的重写.已经完全和第一版本的行文不一样了.不过好在这个翻译错误被避免了.
第二版英文版本在2011年出版.2016年翻译为中文版本引入了国内.

关于 ISN 的讨论.你还可以参考这个知乎文章: TCP/IP协议中,在建立连接的时候ISN序号分配问题

posted @ 2021-02-17 02:07  firfor  阅读(144)  评论(0编辑  收藏  举报