GRE的Key和Sequence Number扩展( 二 )


序列号的取值范围从0到(2**32)-1 。第一个数据报发送时序列号为0 。这样序列号就是一个自由运行的由模2**32表示的计数器 。接收方保留上一次成功拆封的报文的序列号值 。在建立GRE隧道时,这个值应该设为(2**32)-1 。
当拆封者接收到一个无效序列号的数据报文时 , 它应该静静的丢弃该数据报文 。当收到的数据报文的序列号小于或等于上一次成功拆封的数据报文的序列号时 , 收到的报文被视为序列号无效 。收到消息的序列号的值假如处于上一次成功收到的序列号和该序列号的前2**31-1个值之间时(包括这两个值) , 它被认为是小于或者等于上一次成功收到的序列号 。
假如接收到的数据报文序列号有效 , 它被成功拆封 。序列号有效的数据报文是序列号比上一个成功拆封数据报文的序列号正好大1(模2**32),或者sequencenumber域不出现的数据报文(S位没有置位) 。
假如接收到的数据报文既不是有效序列号的数据报 , 也不是无效序列号的数据报 , 表明出现了一个序列号缺口(sequencenumbergap) 。接收者可以试图执行较小的缓冲来恢复已发送数据报文的最初的顺序 。在这种情况下,数据报文可以放在以序列号排序的缓冲区中 。假如收到一个有效序列号的数据报文并被成功拆封 。接收者应该查询缓冲区的头部来判定是否下一个有效序列号的数据报文已经到达 。假如是,接收者应该同缓冲区中可能出现的其他紧接着的有效序列号报文一样进行拆封 。“上一个成功拆封的序列号”应该随后被置为最后一个从缓冲区中拆封的数据报的序列号 。
在任何情况下 , 缓冲区中的任何一个数据报都不会等待超过OUTOFORDER_TIMER微秒 。假如一个数据报文已经等待了那么长时间,接收者必须立即按所排的顺序遍历缓冲区 , 拆封报文(忽略任意序列号缺口)直到缓冲区中没有等待超过OUTOFORDER_TIMER微秒的数据报文 。“上一个成功拆封的序列号”应该随后被置为最后一个从缓冲区中拆封的数据报的序列号 。
接收者可以对每一个业务流(拥有同一个Key值的数据报文属于同一个业务流)的缓冲报文的数量加以限制 , 假如可导致接收者在一个给定缓冲区中放置多于MAX_PERFLOW_BUFFER个数据报文,那么缓冲区头的数据报文立即被拆封 , 而不管起序列号 , “上一个成功拆封的序列号”置为其序列号 。然后把新到达的数据报文放到缓冲区中 。
注重序列号用来检测丢失的数据报文与/或恢复在传输中可能已经失序的数据报文的最初顺序(使用缓冲) 。应该适当地使用序列号选项;非凡地,当隧道协议的高层协议包括有效序列号传输机制或者可忍受失序传输时 , 避免使用序列号选项将不失为一个好主意 。仅在特定情况下GRE隧道携带的协议要求有序交付时,仅相应的封装在GRE中数据报文可以在发送时设置sequence比特位 。
失序数据报文的重新排序可以由拆封者执行 , 以提高性能以及对网络重新排序的容错性 。当高层协议使用了含状态压缩或加密时 , 提供一个小的重排序缓冲区(MAX_PERFLOW_BUFFER)将有助于提高性能 。因为含状态压缩或加密的状态因为报文的丢失而重置 , 缓冲将有助于提高网络对少数报文的重排序的容忍性 。
3.安全方面的考虑
本文档描述了GRE头部(参考文献[1])可能携带的两个扩展域即Key和SequenceNumber 。当使用Sequencenumber域时,通过给报文填入一个随意的序列号从而发起一个拒绝服务攻击(DenialofService)是可能的 。为了防止受此类攻击,必须使用IP安全协议(参考文献[4])来保护GRE头部以及隧道的净载 。ESP(封装安全净载 , EncapsulatingSecurityPayload , 参考文献[5])或者AH(认证头 , 参考文献[6])必须用来保护GRE头部 。假如使用ESP , 它保护IP净载包括GRE 。假如使用AH,对整个数据报文而不是某些域进行认证 。注重在排序或安全方面都不涉及(不管它的名字的意义) 。

推荐阅读