简介
Plan9使用了一种叫做9P【PPTTW93】的文件系统协议,它假定附带RPC请求及回应的定界消息序列能够保证分发。局域网或是因特网上都没有标准IP协议【RFC791】适合9P的这种消息传送机制。TCP【RFC793】的创建开销太大,而且不支持定界符。UDP【RFC768】廉价且支持定界符,可又不能够提供可靠的顺序分发。当我们在系统中实现IP、TCP、UDP时,我们尝试着选择一种协议以适合承载(carrying)9P。
我们需要如下的特性:
l 可靠的数据报服务
l 顺序分发
l 使用IP的因特网作业
l 复杂性低效能高
l 超时适应(Adaptive timeouts)
没有一种标准协议能够满足我们的需求,于是我们设计了IL(Internet Link)。
IL是轻型的IP封装协议,它面向连接且对有序消息提供可靠传输。自从该协议被设计为用于客户端和服务端传输RPC消息(一个有着自身流程局限的结构),没有任何规定用于流程控制。一个用于未完成消息的窗口在缓存满时阻挡大量将抵达的消息;窗口外的消息被丢弃,且要求重发。连接设置使用双方握手机制以能够在每次连接结束时产生初始序列号;随后的数据消息对序列号进行递增,同时允许接受方对不需要的消息(out of order messages)重新排序。对比其他的协议,IL忽略了盲目重发。这样设计使较为拥挤的网络性能得到提高,而盲目重发能够导致更为长久的阻塞。类似于TCP,IL具有超时适应功能,所以协议在因特网及局域网的表现都让人满意。协议设置了一个环路计时器(round-trip timer)用于计算确认收到和重发次数以使之能匹配网络速度。
连接
一条IL连接在两个端点间带着一份流数据。由于连接持久,数据在相同的序列里从一端发送往另一端。连接的作用方式通过状态机表现在图1上,图上显示了各状态以及他们之间的跃迁。每种状态的跃迁都标记了导致该跃迁发生的一系列事件,同时通过使用横线分割得知在跃迁上消息是发送或是接收。接下来的文档讨论了这一状态机。

ackok 在 id0 和下一次包含之间的任意序列号
!x 除了 x 以外的任意数值
- 任意的数值
图1
IL状态机具有五种状态:已关闭、发起同步(Syncer)、接收同步(Syncee)、建立连接、关闭中(Closing)。连接通过ip地址及每个末尾的端口号确定。地址附在IP协议头里,而端口号是18位IL头的一部分。下面的变量指出了一个连接的状态:
state 某一状态
laddr 32位本地IP地址
lport 16位本地IL端口
raddr 32位远程IP地址
rport 16位远程IL端口
id0 32位本地端起始序列号
rid0 32位远程起始序列号
next 本地发送的下条消息序号
rcvd 远程接收到的序列消息中的最后一条
unacked 未答复消息序列中的第一条
未使用的连接处于关闭状态,不赋予地址及端口号。『以下两种情况将开启一个连接:消息接收方的地址和端口在已开启的连接中没有匹配,或一个用户明确的打开一个连接。在第一情况中,消息的源地址和端口中变成连接的远程地址和端口,而且消息的目标地址和端口变成本地的地址和端口。连接状态被设定成Syncee,且消息被处理。在第二个情况中,用户指定本地的和远程的地址和端口。连接的状态被设定成Syncer,且发送一sync消息至远程。IP实现时本地的地址强迫使用合法的数值。』
序列号
IL带有数据消息,每条消息通过操作系统和一个简单的‘write’通讯,并且通过一个32位的序列号标识自身。一条连接中每个方向的起始序列号都是随机的且在初始sync消息中发送。随后的数据消息将递增该序号,一个重发消息包含它原有的序号。
传输/重发
每条消息包含两个序列号:ID和回复确认。『回复确认是消息的发送方接收到的最后无序数据消息。对于数据(data)和数据询问(dataquery)消息,ID是它的序列号。对於控制消息的同步(sync),确认(ack),询问(query),状态(state)和关闭(close),ID是比发送数据消息最大序列号大1的值。
发送方用data类型传送数据消息。任何消息在相反方向的传输中携带回复确认。一个ack消息在收到数据消息的200个毫秒内将会被发送,除非一个返回消息对于发送方已经piggy-backed(延迟返回)一个回复确认。
在 IP 中,消息可能被乱序传输,或者因为(网络)拥塞而丢失,或者传输失败。为了克服这些,IL 使用一种修改的"go back n"(回溯n个包)协议,以尝试避免使拥塞的网络更加恶化。(系统)维持着一个平均的round-trip时间,被用来测量在消息的传输和接收到回复确认之间延迟。直到接收到第一个回复确认,否则平均的round-trip时间被假定是100ms。如果一个回复确认在第一未确认消息( 图 1 中的rexmit timeout)后四倍round-trip时间里面没被接收到, IL假设这消息或回复确认被丢失。发送方然后只是重新发送第一个未确认消息,设置为dataquery类型。接收方接收到dataquery(消息)的时候,它用stat消息回复确认已接收到的最大(序列号)的无序数据消息。这可能就是被重新传输消息,或如果接收方已经存储了乱序消息,一些较大(序列号)已被排序的消息。接收方的实现可以自由地选择是否存储乱序消息。我们的实现是向前存储10个(消息)包。当发送方接收stat消息的时候,它将立刻用dataquery类型重新发送下一个未确认的消息。这持续到所有的消息都被是确认。
如果在发送第一个dataquery之后没有接收到回复确认,发送方等待到超时,然后重新发送dataquery消息。在重新传输之间的间隔按指数增加。在300倍round-trip时间(在图 1 中的death timeout)之後,发送方放弃而且假设连接已经死亡。
重新传输也在状态Syncer ,Syncee 和Close中发生。重新传输间隔和数据消息的相同。』
保持活动状态
如果连接到已关闭的系统必须马上察觉并关闭连接以免耗尽资源。同时如果运行中的系统不需要发送任何数据或是所有已发送的数据都被确认接收了,那么协议不再查找这些连接(the protocol described so far will not discover these connetions)。因此在建立连接状态,如果6秒内没有发送其他消息,便发送一个‘query’消息,接收方总是在收到‘query’消息后回复一个‘state’消息指示自身状态。如果30秒内没有回复任何消息,连接将自动中断。这点没有在图中表现出来。
字节需求
所有32位、16位量都首先发送至高字节,如同在IP中自定一样。
格式
下面是C语言描述的IP+IL头,假定没有IP选项:
typedef unsigned char byte;
struct IPIL
{
byte vihl; /* Version and header length */
byte tos; /* Type of service */
byte length[2]; /* packet length */
byte id[2]; /* Identification */
byte frag[2]; /* Fragment information */
byte ttl; /* Time to live */
byte proto; /* Protocol */
byte cksum[2]; /* Header checksum */
byte src[4]; /* Ip source */
byte dst[4]; /* Ip destination */
byte ilsum[2]; /* Checksum including header */
byte illen[2]; /* Packet length */
byte iltype; /* Packet type */
byte ilspec; /* Special */
byte ilsrc[2]; /* Src port */
byte ildst[2]; /* Dst port */
byte ilid[4]; /* Sequence id */
byte ilack[4]; /* Acked sequence */
};
假定数据紧跟消息头。ilspec是用于未来扩展修改的保留字。
校验和通过ilsum和ilspec置0来计算,这是标准的IP校验和。『也就是,在表头和正文中,按照一个16位字一个16位字的填平,所有16位字的总和。计算校验和时如果一个消息包含表头和正文的大小是一个奇数字节数,最後一个字节在右边被零填补以形成一个16位的字,校验和覆盖范围从cksum到数据的尾部。』
可能的iltype值如下:
enum {
sync= 0,
data= 1,
dataquery= 2,
ack= 3,
query= 4,
state= 5,
close= 6,
};
illen域的值是IL头的大小(18bytes)乘上数据大小。
端口号
IL使用的IP协议号为40
已使用的IL端口号:
7 显示所有输入
9 丢弃输入
19 向输出发送标准模式
565 发送IP地址并回显
566 Plan9身份认证协议
17005 Plan9CPU服务,数据
17006 Plan9CPU服务,提示
17007 Plan9扩展文件系统
17008 Plan9文件服务
17009 Plan9远程执行
17030 Alef命名服务
参考
【PPTTW93】Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom, __The Use of Name Spaces in Plan 9__, Op. Sys. Rev., Vol. 27, No. 2, April 1993, pp.72-76, reprinted in this volume.
【RFC791】RFC791, Internet Protocol, DARPA Internet Program Protocol Specification,September 1981.
【RFC793】RFC793, Transmission Control Protocol, DARPA Internet Program ProtocolSpecification, September 1981.
【RFC768】Postel, RFC768, User Datagram Protocol, DARPA Internet Program ProtocolSpecification, August 1980.
『译者注(略有修改)』
IL协议是一种新的网络协议,但它和TCP/IP有着千丝万缕的关系,这可以从两者的状态机看出来。IL和TCP最大的不同就是采用了类似UDP消息报文的数据格式,而TCP是数据流格式。IL其余部分,如数据结构、连接标识和状态转换,可以认为是TCP思想的另一种实现。所以,用IL连接的服务,也可以用TCP模拟。在Plan 9第三版的系统里,也有一个在UNIX下用TCP实现Plan 9的文件服务器的例子,见/sys/src/cmd/unix/u9fs。
从TCP的角度看,IL的五种状态可以这样理解:
Closed:没有活动的或尚未结束的连接,这是所有连接的初始状态。
Syncer:发送方,发出连接请求。
Syncee:接收方,连接请求收到,发送确认。
Established:连接已经建立,等待请求的确认。
Closing:通信双方同时请求关闭连接。
没有评论:
发表评论