Section 4. Tunnel Protocol Operation

The user data carried by the PPTP protocol are PPP data packets.  PPP
   packets are carried between the PAC and PNS, encapsulated in GRE
   packets which in turn are carried over IP.  The encapsulated PPP
   packets are essentially PPP data packets less any media specific
   framing elements.  No HDLC flags, bit insertion, control characters,
   or control character escapes are included. No CRCs are sent through
   the tunnel. The IP packets transmitted over the tunnels between a PAC
   and PNS has the following general structure:
      +--------------------------------+
      |          Media Header          |
      +--------------------------------+
      |           IP Header            |
      +--------------------------------+
      |           GRE Header           |
      +--------------------------------+
      |           PPP Packet           |
      +--------------------------------+
4.1.  Enhanced GRE header
   The GRE header used in PPTP is enhanced slightly from that specified
   in the current GRE protocol specification [1,2].  The main difference
   involves the definition of a new Acknowledgment Number field, used to
   determine if a particular GRE packet or set of packets has arrived at
   the remote end of the tunnel.  This Acknowledgment capability is not
   used in conjunction with any retransmission of user data packets.  It
   is used instead to determine the rate at which user data packets are
   to be transmitted over the tunnel for a given user session.  The
   format of the enhanced GRE header is as follows:
    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.  Set to zero (0).
   R
      (Bit 1) Routing Present.  Set to zero (0).
   K
      (Bit 2) Key Present.  Set to one (1).
   S
      (Bit 3) Sequence Number Present.  Set to one (1) if a payload
      (data) packet is present.  Set to zero (0) if payload is not
      present (GRE packet is an Acknowledgment only).
   s
      (Bit 4) Strict source route present.  Set to zero (0).
   Recur
      (Bits 5-7) Recursion control.  Set to zero (0).
   A
      (Bit 8) Acknowledgment sequence number present.  Set to one (1) if
      packet contains Acknowledgment Number to be used for acknowledging
      previously transmitted data.
   Flags
      (Bits 9-12) Must be set to zero (0).
   Ver
      (Bits 13-15) Must contain 1 (enhanced GRE).
   Protocol Type
      Set to hex 880B [8].
   Key
      Use of the Key field is up to the implementation.  PPTP uses it as
      follows:
         Payload Length
            (High 2 octets of Key) Size of the payload, not including
            the GRE header
         Call ID
            (Low 2 octets) Contains the Peer's Call ID for the session
            to which this packet belongs.
         Sequence Number
            Contains the sequence number of the payload.  Present if S
            bit (Bit 3) is one (1).
         Acknowledgment Number
            Contains the sequence number of the highest numbered GRE
            packet received by the sending peer for this user session.
            Present if A bit (Bit 8) is one (1).
         The payload section contains a PPP data packet without any
         media specific framing elements.
         The sequence numbers involved are per packet sequence numbers.
         The sequence number for each user session is set to zero at
         session startup.  Each packet sent for a given user session
         which contains a payload (and has the S bit (Bit 3) set to one)
         is assigned the next consecutive sequence number for that
         session.
         This protocol allows acknowledgments to be carried with the
         data and makes the overall protocol more efficient, which in
         turn requires less buffering of packets.
4.2.  Sliding Window Protocol
   The sliding window protocol used on the PPTP data path is used for
   flow control by each side of the data exchange.  The enhanced GRE
   protocol allows packet acknowledgments to be piggybacked on data
   packets.  Acknowledgments can also be sent separately from data
   packets.  Again, the main purpose of the sliding window protocol is
   for flow control--retransmissions are not performed by the tunnel
   peers.
4.2.1.  Initial Window Size
   Although each side has indicated the maximum size of its receive
   window, it is recommended that a conservative approach be taken when
   beginning to transmit data.  The initial window size on the
   transmitter is set to half the maximum size the receiver requested,
   with a minimum size of one packet.  The transmitter stops sending
   packets when the number of packets awaiting acknowledgment is equal
   to the current window size.  As the receiver successfully digests
   each window, the window size on the transmitter is bumped up by one
   packet until the maximum is reached.  This method prevents a system
   from flooding an already congested network because no history has
   been established.
4.2.2.  Closing the Window
   When a time-out does occur on a packet, the sender adjusts the size
   of the transmit window down to one half its value when it failed.
   Fractions are rounded up, and the minimum window size is one.
4.2.3.  Opening the Window
   With every successful transmission of a window's worth of packets
   without a time-out, the transmit window size is increased by one
   packet until it reaches the maximum window size that was sent by the
   other side when the call was connected.  As stated earlier, no
   retransmission is done on a time-out. After a time-out, the
   transmission resumes with the window starting at one half the size of
   the transmit window when the time-out occurred and adjusting upward
   by one each time the transmit window is filled with packets that are
   all acknowledged without time-outs.
4.2.4.  Window Overflow
   When a receiver's window overflows with too many incoming packets,
   excess packets are thrown away.  This situation should not arise if
   the sliding window procedures are being properly followed by the
   transmitter and receiver. It is assumed that, on the transmit side,
   packets are buffered for transmission and are no longer accepted from
   the packet source when the transmit buffer fills.
4.2.5.  Multi-packet Acknowledgment
   One feature of the PPTP sliding window protocol is that it allows the
   acknowledgment of multiple packets with a single acknowledgment. All
   outstanding packets with a sequence number lower or equal to the
   acknowledgment number are considered acknowledged. Time-out
   calculations are performed using the time the packet corresponding to
   the highest sequence number being acknowledged was transmitted.
   Adaptive time-out calculations are only performed when an
   Acknowledgment is received.  When multi-packet acknowledgments are
   used, the overhead of the adaptive time-out algorithm is reduced. The
   PAC is not required to transmit multi-packet acknowledgments; it can
   instead acknowledge each packet individually as it is delivered to
   the PPP client.
4.3.  Out-of-sequence Packets
   Occasionally packets lose their sequencing across a complicated
   internetwork.  Say, for example that a PNS sends packets 0 to 5 to a
   PAC.  Because of rerouting in the internetwork, packet 4 arrives at
   the PAC before packet 3. The PAC acknowledges packet 4, and may
   assume packet 3 is lost. This acknowledgment grants window credit
   beyond packet 4.
   When the PAC does receive packet 3, it MUST not attempt to transmit
   it to the corresponding PPP client.  To do so could cause problems,
   as proper PPP protocol operation is premised upon receiving packets
   in sequence.  PPP does properly deal with the loss of packets, but
   not with reordering so out of sequence packets between the PNS and
   PAC MUST be silently discarded, or they may be reordered by the
   receiver.  When packet 5 comes in, it is acknowledged by the PAC
   since it has a higher sequence number than 4, which was the last
   highest packet acknowledged by the PAC.  Packets with duplicate
   sequence numbers should never occur since the PAC and PNS never
   retransmit GRE packets.  A robust implementation will silently
   discard duplicate GRE packets, should it receive any.
4.4.  Acknowledgment Time-Outs
   PPTP uses sliding windows and time-outs to provide both user session
   flow-control across the internetwork and to perform efficient data
   buffering to keep the PAC-PNS data channels full without causing
   receive buffer overflow.  PPTP requires that a time-out be used to
   recover from dropped data or acknowledgment packets.  The exact
   implementation of the time-out is vendor-specific.  It is suggested
   that an adaptive time-out be implemented with backoff for congestion
   control.  The time-out mechanism proposed here has the following
   properties:
      Independent time-outs for each session. A device (PAC or PNS) will
      have to maintain and calculate time-outs for every active session.
      An administrator-adjustable maximum time-out, MaxTimeOut, unique
      to each device.
      An adaptive time-out mechanism that compensates for changing
      throughput.  To reduce packet processing overhead, vendors may
      choose not to recompute the adaptive time-out for every received
      acknowledgment.  The result of this overhead reduction is that the
      time-out will not respond as quickly to rapid network changes.
      Timer backoff on time-out to reduce congestion. The backed-off
      timer value is limited by the configurable maximum time-out value.
      Timer backoff is done every time an acknowledgment time-out
      occurs.
   In general, this mechanism has the desirable behavior of quickly
   backing off upon a time-out and of slowly decreasing the time-out
   value as packets are delivered without time-outs.
   Some definitions:
      Packet Processing Delay (PPD) is the amount of time required for
      each side to process the maximum amount of data buffered in their
      receive packet sliding window. The PPD is the value exchanged
      between the PAC and PNS when a call is established. For the PNS,
      this number should be small.  For a PAC making modem connections,
      this number could be significant.
      Sample is the actual amount of time incurred receiving an
      acknowledgment for a packet. The Sample is measured, not
      calculated.
      Round-Trip Time (RTT) is the estimated round-trip time for an
      Acknowledgment to be received for a given transmitted packet. When
      the network link is a local network, this delay will be minimal
      (if not zero). When the network link is the Internet, this delay
      could be substantial and vary widely. RTT is adaptive: it will
      adjust to include the PPD and whatever shifting network delays
      contribute to the time between a packet being transmitted and
      receiving its acknowledgment.
      Adaptive Time-Out (ATO) is the time that must elapse before an
      acknowledgment is considered lost.  After a time-out, the sliding
      window is partially closed and the ATO is backed off.
   The Packet Processing Delay (PPD) parameter is a 16-bit word
   exchanged during the Call Control phase that represents tenths of a
   second (64 means 6.4 seconds). The protocol only specifies that the
   parameter is exchanged, it does not specify how it is calculated. The
   way values for PPD are calculated is implementation-dependent and
   need not be variable (static time-outs are allowed). The PPD must be
   exchanged in the call connect sequences, even if it remains constant
   in an implementation. One possible way to calculate the PPD is:
   PPD' = ((PPP_MAX_DATA_MTU - Header) * WindowSize * 8) / ConnectRate
   PPD = PPD' + PACFudge
   Header is the total size of the IP and GRE headers, which is 36. The
   MTU is the overall MTU for the internetwork link between the PAC and
   PNS.  WindowSize represents the number of packets in the sliding
   window, and is implementation-dependent. The latency of the
   internetwork could be used to pick a window size sufficient to keep
   the current session's pipe full. The constant 8 converts octets to
   bits (assuming ConnectRate is in bits per second).  If ConnectRate is
   in bytes per second, omit the 8.  PACFudge is not required but can be
   used to take overall processing overhead of the PAC into account.
   The value of PPD is used to seed the adaptive algorithm with the
   initial RTT[n-1] value.
4.4.1.  Calculating Adaptive Acknowledgment Time-Out
   We still must decide how much time to allow for acknowledgments to
   return. If the time-out is set too high, we may wait an unnecessarily
   long time for dropped packets. If the time-out is too short, we may
   time out just before the acknowledgment arrives. The acknowledgment
   time-out should also be reasonable and responsive to changing network
   conditions.
   The suggested adaptive algorithm detailed below is based on the TCP
   1989 implementation and is explained in [11].  'n' means this
   iteration of the calculation, and 'n-1' refers to values from the
   last calculation.
      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 represents the error between the last estimated round-trip
      time and the measured time. DIFF is calculated on each iteration.
      DEV is the estimated mean deviation. This approximates the
      standard deviation.  DEV is calculated on each iteration and
      stored for use in the next iteration. Initially, it is set to 0.
      RTT is the estimated round-trip time of an average packet. RTT is
      ycalculated on each iteration and stored for use in the next
      iteration.  Initially, it is set to PPD.
      ATO is the adaptive time-out for the next transmitted packet. ATO
      is calculated on each iteration.  Its value is limited, by the MIN
      function, to be a maximum of the configured MaxTimeOut value.
      Alpha is the gain for the average and is typically 1/8 (0.125).
      Beta is the gain for the deviation and is typically 1/4 (0.250).
      Chi is the gain for the time-out and is typically set to 4.
   To eliminate division operations for fractional gain elements, the
   entire set of equations can be scaled. With the suggested gain
   constants, they should be scaled by 8 to eliminate all division.  To
   simplify calculations, all gain values are kept to powers of two so
   that shift operations can be used in place of multiplication or
   division.
4.4.2.  Congestion Control: Adjusting for Time-Out
   This section describes how the calculation of ATO is modified in the
   case where a time-out does occur.  When a time-out occurs, the time-
   out value should be adjusted rapidly upward.  Although the GRE
   packets are not retransmitted when a time-out occurs, the time-out
   should be adjusted up toward a maximum limit.  To compensate for
   shifting internetwork time delays, a strategy must be employed to
   increase the time-out when it expires (notice that in addition to
   increasing the time-out, we are also shrinking the size of the window
   as described in the next section).  For an interval in which a time-
   out occurs, the new
   ATO is calculated as:
      RTT[n] = delta * RTT[n-1]
      DEV[n] = DEV[n-1]
      ATO[n] = MAX (MinTimeOut, MIN (RTT[n] +
               (chi * DEV[n]), MaxTimeOut))
   In this calculation of ATO, only the two values that both contribute
   to ATO and are stored for the next iteration are calculated.  RTT is
   scaled by delta, and DEV is unmodified.  DIFF is not carried forward
   and is not used in this scenario.  A value of 2 for Delta, the time-
   out gain factor for RTT, is suggested.