4. 隧道协议操作 (Tunnel Protocol Operation)
PPTP 协议承载的用户数据是 PPP 数据包。PPP 数据包在 PAC 和 PNS 之间传输时,封装在 GRE 数据包中,而 GRE 数据包又通过 IP 承载。封装的 PPP 数据包本质上是去除了任何媒体特定成帧元素的 PPP 数据包。不包括 HDLC 标志、比特插入、控制字符或控制字符转义。不通过隧道发送 CRC。在 PAC 和 PNS 之间的隧道上传输的 IP 数据包具有以下一般结构:
+--------------------------------+
| Media Header |
| (媒体头部) |
+--------------------------------+
| IP Header |
| (IP 头部) |
+--------------------------------+
| GRE Header |
| (GRE 头部) |
+--------------------------------+
| PPP Packet |
| (PPP 数据包) |
+--------------------------------+
4.1. 增强的 GRE 头部 (Enhanced GRE Header)
PPTP 中使用的 GRE 头部相对于当前 GRE 协议规范 [1,2] 中规定的进行了轻微增强。主要区别在于定义了一个新的确认号 (Acknowledgment Number) 字段,用于确定特定的 GRE 数据包或一组数据包是否已到达隧道的远端。此确认能力不与用户数据包的任何重传结合使用。相反,它用于确定给定用户会话的用户数据包通过隧道传输的速率。增强的 GRE 头部格式如下:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|C|R|K|S|s|Recur|A| Flags | Ver | Protocol Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Key (HW) Payload Length | Key (LW) Call ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number (Optional) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number (Optional) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
字段说明
C (Bit 0) - Checksum Present (校验和存在)
- 设置为 0。
R (Bit 1) - Routing Present (路由存在)
- 设置为 0。
K (Bit 2) - Key Present (密钥存在)
- 设置为 1。
S (Bit 3) - Sequence Number Present (序列号存在)
- 如果存在有效载荷(数据)包,则设置为 1。如果没有有效载荷(GRE 数据包仅是确认),则设置为 0。
s (Bit 4) - Strict Source Route Present (严格源路由存在)
- 设置为 0。
Recur (Bits 5-7) - Recursion Control (递归控制)
- 设置为 0。
A (Bit 8) - Acknowledgment Sequence Number Present (确认序列号存在)
- 如果数据包包含用于确认先前传输的数据的确认号,则设置为 1。
Flags (Bits 9-12)
- 必须 (MUST) 设置为 0。
Ver (Bits 13-15) - Version (版本)
- 必须 (MUST) 包含 1(增强型 GRE)。
Protocol Type (协议类型)
- 设置为十六进制 880B [8]。
Key (密钥)
- 密钥字段的使用取决于实现。PPTP 按如下方式使用它:
- Payload Length (有效载荷长度)(密钥的高 2 个八位字节):有效载荷的大小,不包括 GRE 头部
- Call ID (呼叫 ID)(低 2 个八位字节):包含此数据包所属会话的对等方呼叫 ID
Sequence Number (序列号)
- 包含有效载荷的序列号。如果 S 位(Bit 3)为 1,则存在。
Acknowledgment Number (确认号)
- 包含此用户会话的发送对等方收到的最高编号 GRE 数据包的序列号。如果 A 位(Bit 8)为 1,则存在。
有效载荷部分包含一个 PPP 数据包,不包含任何媒体特定的成帧元素。
涉及的序列号是每个数据包的序列号。每个用户会话的序列号在会话启动时设置为零。为给定用户会话发送的每个包含有效载荷(并且 S 位(Bit 3)设置为 1)的数据包都被分配该会话的下一个连续序列号。
此协议允许确认与数据一起携带,使整个协议更高效,从而需要更少的数据包缓冲。
4.2. 滑动窗口协议 (Sliding Window Protocol)
PPTP 数据路径上使用的滑动窗口协议用于数据交换双方的流量控制。增强的 GRE 协议允许数据包确认搭载在数据包上。确认也可以与数据包分开发送。同样,滑动窗口协议的主要目的是流量控制——隧道对等方不执行重传。
4.2.1. 初始窗口大小 (Initial Window Size)
尽管每一方都已指示其接收窗口的最大大小,但建议在开始传输数据时采取保守的方法。发送方的初始窗口大小设置为接收方请求的最大大小的一半,最小大小为一个数据包。当等待确认的数据包数量等于当前窗口大小时,发送方停止发送数据包。随着接收方成功消化每个窗口,发送方的窗口大小增加一个数据包,直到达到最大值。此方法可防止系统淹没已拥塞的网络,因为尚未建立历史记录。
4.2.2. 关闭窗口 (Closing the Window)
当数据包发生超时时,发送方将传输窗口的大小调整为失败时值的一半。分数向上舍入,最小窗口大小为 1。
4.2.3. 打开窗口 (Opening the Window)
每次成功传输一个窗口的数据包而不超时,传输窗口大小就增加一个数据包,直到达到呼叫连接时另一方发送的最大窗口大小。如前所述,超时时不进行重传。超时后,传输以窗口大小为超时发生时传输窗口大小的一半开始恢复,每次传输窗口填充的所有数据包都得到确认而不超时时向上调整一个。
4.2.4. 窗口溢出 (Window Overflow)
当接收方的窗口因传入数据包过多而溢出时,多余的数据包将被丢弃。如果发送方和接收方正确遵循滑动窗口过程,则不应出现这种情况。假设在发送侧,数据包被缓冲以进行传输,当传输缓冲区填满时,不再从数据包源接受数据包。
4.2.5. 多包确认 (Multi-packet Acknowledgment)
PPTP 滑动窗口协议的一个特性是它允许用单个确认来确认多个数据包。所有序列号小于或等于确认号的未完成数据包都被视为已确认。超时计算使用与所确认的最高序列号对应的数据包的传输时间来执行。
自适应超时计算仅在收到确认时执行。当使用多包确认时,自适应超时算法的开销会降低。PAC 不需要 (not required) 传输多包确认;它可以在每个数据包传递到 PPP 客户端时单独确认。
4.3. 乱序数据包 (Out-of-sequence Packets)
有时数据包会在复杂的互联网络中失去其顺序。例如,假设 PNS 向 PAC 发送数据包 0 到 5。由于互联网络中的重新路由,数据包 4 在数据包 3 之前到达 PAC。PAC 确认数据包 4,并可能假设数据包 3 丢失。此确认授予超过数据包 4 的窗口信用。
当 PAC 确实收到数据包 3 时,它必须不 (MUST NOT) 尝试将其传输到相应的 PPP 客户端。这样做可能会导致问题,因为正确的 PPP 协议操作的前提是按顺序接收数据包。PPP 确实正确处理数据包丢失,但不处理重新排序,因此 PNS 和 PAC 之间的乱序数据包必须 (MUST) 被静默丢弃,或者它们可以由接收方重新排序。当数据包 5 到来时,PAC 确认它,因为它的序列号高于 4,4 是 PAC 确认的最后最高数据包。由于 PAC 和 PNS 从不重传 GRE 数据包,因此永远不应出现具有重复序列号的数据包。健壮的实现将静默丢弃重复的 GRE 数据包(如果收到)。
4.4. 确认超时 (Acknowledgment Time-Outs)
PPTP 使用滑动窗口和超时来提供跨互联网络的用户会话流量控制,并执行高效的数据缓冲,以保持 PAC-PNS 数据通道充满而不导致接收缓冲区溢出。PPTP 要求使用超时来从丢失的数据或确认数据包中恢复。超时的确切实现是特定于供应商的。建议实施具有退避的自适应超时以进行拥塞控制。此处提出的超时机制具有以下属性:
- 每个会话的独立超时:设备(PAC 或 PNS)必须为每个活动会话维护和计算超时。
- 管理员可调整的最大超时 (MaxTimeOut):每个设备唯一。
- 自适应超时机制:补偿不断变化的吞吐量。为了减少数据包处理开销,供应商可以选择不为每个接收到的确认重新计算自适应超时。此开销减少的结果是超时不会对快速的网络变化做出如此快速的响应。
- 超时时的定时器退避:以减少拥塞。退避的定时器值受可配置的最大超时值限制。每次发生确认超时时都会进行定时器退避。
一般来说,这种机制具有在超时时快速退避和在无超时的情况下传递数据包时慢慢减少超时值的理想行为。
定义
Packet Processing Delay (PPD) - 数据包处理延迟
- 每一方处理其接收数据包滑动窗口中缓冲的最大数据量所需的时间。PPD 是在建立呼叫时在 PAC 和 PNS 之间交换的值。对于 PNS,此数字应该很小。对于进行调制解调器连接的 PAC,此数字可能很大。
Sample (样本)
- 接收数据包确认所实际发生的时间量。样本是测量的,而不是计算的。
Round-Trip Time (RTT) - 往返时间
- 为给定传输的数据包接收确认的估计往返时间。当网络链路是本地网络时,此延迟将最小(如果不为零)。当网络链路是互联网时,此延迟可能很大且变化很大。RTT 是自适应的:它将调整以包括 PPD 和任何变化的网络延迟,这些延迟对数据包传输和接收其确认之间的时间有所贡献。
Adaptive Time-Out (ATO) - 自适应超时
- 在确认被视为丢失之前必须经过的时间。超时后,滑动窗口部分关闭,ATO 退避。
数据包处理延迟 (PPD) 参数是在呼叫控制阶段交换的 16 位字,表示十分之一秒(64 表示 6.4 秒)。协议仅规定交换参数,不规定如何计算它。PPD 值的计算方式取决于实现,不需要是可变的(允许静态超时)。即使在实现中保持不变,也必须 (MUST) 在呼叫连接序列中交换 PPD。计算 PPD 的一种可能方法是:
PPD' = ((PPP_MAX_DATA_MTU - Header) * WindowSize * 8) / ConnectRate
PPD = PPD' + PACFudge
其中:
- Header 是 IP 和 GRE 头部的总大小,为 36
- MTU 是 PAC 和 PNS 之间互联网络链路的总体 MTU
- WindowSize 表示滑动窗口中的数据包数量,取决于实现
- 常数 8 将八位字节转换为比特(假设 ConnectRate 以比特每秒为单位)
- PACFudge 不是必需的,但可用于考虑 PAC 的整体处理开销
PPD 的值用于使用初始 RTT[n-1] 值为自适应算法设定种子。
4.4.1. 计算自适应确认超时 (Calculating Adaptive Acknowledgment Time-Out)
我们仍然必须决定允许多少时间来返回确认。如果超时设置得太高,我们可能会为丢失的数据包等待不必要的长时间。如果超时太短,我们可能会在确认到达之前超时。确认超时也应该是合理的,并对不断变化的网络条件做出响应。
建议的自适应算法基于 TCP 1989 实现,并在 [11] 中解释。'n' 表示当前数据包,'n-1' 表示前一个数据包:
Err[n] = Sample[n] - RTT[n-1]
RTT[n] = RTT[n-1] + (g * Err[n])
Dev[n] = Dev[n-1] + h * (|Err[n]| - Dev[n-1])
ATO[n] = RTT[n] + (f * Dev[n])
其中:
- g 是增益因子(建议值为 0.125)
- h 是偏差增益因子(建议值为 0.25)
- f 是偏差乘数因子(建议值为 4)
4.4.2. 拥塞控制:超时调整 (Congestion Control: Adjusting for Time-Out)
本节描述在发生超时的情况下如何修改 ATO 的计算。当发生超时时,超时值应快速向上调整。尽管当发生超时时 GRE 数据包不会重传,但超时应向最大限制调整。为了补偿不断变化的互联网络时间延迟,必须采用策略在超时到期时增加超时(请注意,除了增加超时之外,我们还在缩小窗口的大小,如下一节所述)。
对于发生超时的间隔:
ATO[n] = MIN(2 * ATO[n-1], MaxTimeOut)
其中 MaxTimeOut 是管理员配置的最大超时值。