4. 隧道协议操作 (Tunnel Protocol Operation)
PPTP协议承载的用户数据是PPP数据包。PPP数据包在PAC和PNS之间承载, 封装在GRE数据包中, 而GRE数据包又通过IP承载。封装的PPP数据包本质上是没有任何媒体特定成帧元素的PPP数据包。不包括HDLC标志、位插入、控制字符或控制字符转义。不通过隧道发送CRC。在PAC和PNS之间的隧道上传输的IP数据包具有以下通用结构:
+--------------------------------+
| Media Header |
+--------------------------------+
| IP Header |
+--------------------------------+
| GRE Header |
+--------------------------------+
| PPP Packet |
+--------------------------------+
4.1. 增强的GRE头部 (Enhanced GRE header)
PPTP中使用的GRE头部在当前GRE协议规范 [1,2] 中指定的基础上进行了轻微增强。主要区别涉及新的确认号字段的定义, 用于确定特定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 (位0) - Checksum Present (校验和存在): 设置为零 (0)。
R (位1) - Routing Present (路由存在): 设置为零 (0)。
K (位2) - Key Present (密钥存在): 设置为一 (1)。
S (位3) - Sequence Number Present (序列号存在): 如果存在有效载荷 (数据) 数据包, 则设置为一 (1)。如果不存在有效载荷 (GRE数据包仅为确认), 则设置为零 (0)。
s (位4) - Strict source route present (严格源路由存在): 设置为零 (0)。
Recur (位5-7) - Recursion control (递归控制): 设置为零 (0)。
A (位8) - Acknowledgment sequence number present (确认序列号存在): 如果数据包包含用于确认先前传输的数据的确认号, 则设置为一 (1)。
Flags (位9-12): 必须设置为零 (0)。
Ver (位13-15): 必须包含1 (增强的GRE)。
Protocol Type (协议类型): 设置为十六进制880B [8]。
Key (密钥): 密钥字段的使用取决于实现。PPTP使用方式如下:
- Payload Length (有效载荷长度, 密钥的高2个八位字节): 有效载荷的大小, 不包括GRE头部
- Call ID (呼叫ID, 低2个八位字节): 包含此数据包所属会话的对等方呼叫ID
Sequence Number (序列号): 包含有效载荷的序列号。如果S位 (位3) 为一 (1), 则存在。
Acknowledgment Number (确认号): 包含发送对等方为此用户会话接收到的最高编号GRE数据包的序列号。如果A位 (位8) 为一 (1), 则存在。
有效载荷部分包含没有任何媒体特定成帧元素的PPP数据包。
涉及的序列号是每个数据包的序列号。每个用户会话的序列号在会话启动时设置为零。为给定用户会话发送的包含有效载荷 (并且将S位 (位3) 设置为一) 的每个数据包都被分配该会话的下一个连续序列号。
此协议允许确认与数据一起携带, 使整体协议更有效, 这反过来需要较少的数据包缓冲。
4.2. 滑动窗口协议 (Sliding Window Protocol)
PPTP数据路径上使用的滑动窗口协议用于数据交换的每一侧的流量控制。增强的GRE协议允许数据包确认搭载在数据包上。确认也可以与数据包分开发送。同样, 滑动窗口协议的主要目的是流量控制 - 隧道对等方不执行重传。
4.2.1. 初始窗口大小 (Initial Window Size)
尽管每一侧都已指示其接收窗口的最大大小, 但建议在开始传输数据时采取保守的方法。发送器上的初始窗口大小设置为接收器请求的最大大小的一半, 最小大小为一个数据包。当等待确认的数据包数等于当前窗口大小时, 发送器停止发送数据包。当接收器成功消化每个窗口时, 发送器上的窗口大小增加一个数据包, 直到达到最大值。此方法防止系统淹没已经拥塞的网络, 因为尚未建立历史记录。
4.2.2. 关闭窗口 (Closing the Window)
当数据包确实发生超时时, 发送方将传输窗口的大小调整为其失败时值的一半。分数向上舍入, 最小窗口大小为一。
4.2.3. 打开窗口 (Opening the Window)
每次成功传输一个窗口的数据包而没有超时, 传输窗口大小就增加一个数据包, 直到达到在呼叫连接时另一侧发送的最大窗口大小。如前所述, 超时后不进行重传。超时后, 传输从窗口从发生超时时传输窗口大小的一半开始恢复, 并且每次传输窗口填充数据包并且所有数据包都被确认而没有超时时向上调整一个。
4.2.4. 窗口溢出 (Window Overflow)
当接收方的窗口因传入数据包过多而溢出时, 多余的数据包将被丢弃。如果发送方和接收方正确遵循滑动窗口过程, 则不应出现这种情况。假设在发送侧, 数据包被缓冲以进行传输, 并且当传输缓冲区填满时, 不再从数据包源接受数据包。
4.2.5. 多包确认 (Multi-packet Acknowledgment)
PPTP滑动窗口协议的一个特性是它允许使用单个确认来确认多个数据包。序列号低于或等于确认号的所有未完成数据包都被视为已确认。超时计算使用传输被确认的最高序列号对应的数据包的时间来执行。
仅在收到确认时才执行自适应超时计算。当使用多包确认时, 自适应超时算法的开销减少。PAC不需要传输多包确认; 相反, 它可以在将每个数据包传递给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, 这是PAC最后确认的最高数据包。具有重复序列号的数据包永远不应该发生, 因为PAC和PNS从不重传GRE数据包。健壮的实现将静默丢弃重复的GRE数据包, 如果它收到任何。
4.4. 确认超时 (Acknowledgment Time-Outs)
PPTP使用滑动窗口和超时来提供跨互联网络的用户会话流量控制, 并执行有效的数据缓冲, 以保持PAC-PNS数据通道满而不会导致接收缓冲区溢出。PPTP要求使用超时来从丢失的数据或确认数据包中恢复。确切的超时实现是特定于供应商的。建议实现自适应超时, 并为拥塞控制实施退避。这里提出的超时机制具有以下属性:
-
每个会话的独立超时 (Independent time-outs for each session): 设备 (PAC或PNS) 必须为每个活动会话维护和计算超时。
-
管理员可调整的最大超时 (An administrator-adjustable maximum time-out): MaxTimeOut, 每个设备唯一。
-
补偿不断变化的吞吐量的自适应超时机制 (An adaptive time-out mechanism that compensates for changing throughput): 为了减少数据包处理开销, 供应商可能选择不为每个接收到的确认重新计算自适应超时。这种开销减少的结果是超时不会对快速网络变化响应得那么快。
-
超时时的计时器退避以减少拥塞 (Timer backoff on time-out to reduce congestion): 退避的计时器值受可配置的最大超时值限制。每次发生确认超时时都会执行计时器退避。
一般来说, 此机制具有在超时时快速退避的理想行为, 并且在数据包被传递而没有超时时缓慢降低超时值。
一些定义:
-
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值的计算方式取决于实现, 不需要是可变的 (允许静态超时)。即使在实现中保持恒定, 也必须在呼叫连接序列中交换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以位每秒为单位)
- 如果ConnectRate以字节每秒为单位, 则省略8
- PACFudge不是必需的, 但可以用于考虑PAC的总体处理开销
PPD的值用于使用初始RTT[n-1]值为自适应算法提供种子。
4.4.1. 计算自适应确认超时 (Calculating Adaptive Acknowledgment Time-Out)
我们仍然必须决定允许多少时间让确认返回。如果超时设置得太高, 我们可能会不必要地长时间等待丢失的数据包。如果超时太短, 我们可能在确认到达之前就超时。确认超时也应该是合理的并响应不断变化的网络条件。
下面详细介绍的建议自适应算法基于TCP 1989实现, 并在 [11] 中解释。'n'表示此计算的迭代, 'n-1'指的是上次计算的值。
DIFF[n] = SAMPLE[n] - RTT[n-1]
DEV[n] = DEV[n-1] + (beta * (|DIFF[n]| - DEV[n-1]))
RTT[n] = RTT[n-1] + (alpha * DIFF[n])
ATO[n] = MAX (MinTimeOut, MIN (RTT[n] +
(chi * DEV[n]), MaxTimeOut))
其中:
- DIFF: 表示最后估计的往返时间与测量时间之间的误差。DIFF在每次迭代时计算。
- DEV: 是估计的平均偏差。这近似于标准偏差。DEV在每次迭代时计算并存储以供下次迭代使用。最初设置为0。
- RTT: 是平均数据包的估计往返时间。RTT在每次迭代时计算并存储以供下次迭代使用。最初设置为PPD。
- ATO: 是下一个传输的数据包的自适应超时。ATO在每次迭代时计算。通过MIN函数, 其值被限制为最大为配置的MaxTimeOut值。
- Alpha: 是平均值的增益, 通常为1/8 (0.125)。
- Beta: 是偏差的增益, 通常为1/4 (0.250)。
- Chi: 是超时的增益, 通常设置为4。
为了消除分数增益元素的除法操作, 可以缩放整个方程组。使用建议的增益常数, 它们应该按8缩放以消除所有除法。为简化计算, 所有增益值都保持为2的幂, 以便可以使用移位操作代替乘法或除法。
4.4.2. 拥塞控制: 调整超时 (Congestion Control: Adjusting for Time-Out)
本节描述在发生超时的情况下如何修改ATO的计算。当发生超时时, 超时值应快速向上调整。尽管当发生超时时不重传GRE数据包, 但超时应向最大限制调整。为了补偿移动的互联网络时间延迟, 必须采用策略在超时到期时增加超时 (请注意, 除了增加超时之外, 我们还在缩小窗口的大小, 如下一节所述)。对于发生超时的间隔, 新的ATO计算为:
RTT[n] = delta * RTT[n-1]
DEV[n] = DEV[n-1]
ATO[n] = MAX (MinTimeOut, MIN (RTT[n] +
(chi * DEV[n]), MaxTimeOut))
在此ATO计算中, 仅计算两个既有助于ATO又存储用于下一次迭代的值。RTT由delta缩放, DEV未修改。DIFF不会向前携带, 在此场景中不使用。建议Delta (RTT的超时增益因子) 的值为2。