PPTP packet reordering
This page documents the NetServers extensions to pptpclient, a free PPTP client for Linux developed by C. S. Ananian and many others. NetServers is distributing these extensions as freely available patches to pptpclient. They have been integrated into the latest CVS version of pptpclient, and will hopefully be in the next major release at some point.
Patch and documentation written by Chris Wilson for Netservers.
The main goal of this patch is to support packet reordering, which allows packets to be received by the client out of order, and returns them to the correct order for pppd. The standard client will simply throw away out-of-order packets, with a log message like discarding out-of-order? seq is 1657 seqrecv is 1658.
Normally, out-of-order packets are very rare on the Internet. However, one ISP in Britain, NTL's cable modem service, reorders small packets ahead of large ones. This is probably supposed to make interactive sessions respond better when large downloads are in progress, but it also makes pptpclient almost unusable in some situations.
You can easily test this by running a command like 'ping -s 1510 188.8.131.52', where 184.108.40.206 is a host running pptpclient, on the other side of your tunnel, and 1510 is just higher than the MTU of the tunnel. This will cause a pattern of large-fragment small-fragment GRE packets to be sent to the other side. If the other side is an NTL cable modem, the small packets will almost always arrive before the large ones, and pptpclient will drop them.
We have added several new features to pptpclient:
Reduces the optimisation level (gcc's -O flag) to zero (none), to make debugging easier. This is optional.
Inclusion of pqueue.c and pqueue.h
Adds two new files, pqueue.c and pqueue.h, to the pptp executable. pqueue.c implements the packet queue used by the reordering code, and pqueue.h describes its public interface. The queue is implemented as a linked list. This is required for reordering.
Adds a new command-line option, --debug, to pptpclient. Currently, all this does it prevent pptpclient from going into the background. It also tidies up the indenting of the option-handling code in pptp.c. This is optional.
Calls the daemon(3) function to change the current directory and close the standard file descriptors. This prevents your shell from hanging open if you start pptpclient remotely and leave it running.
Packets are added to the queue by decaps_gre if their sequence number is higher than expected, but within the window. The default window is defined as 30 packets.
Packets which are below the window (older than the most recent packet read) or above the window (too far ahead) are discarded, to protect against denial-of-service attacks.
The new function dequeue_gre retrieves packets from the head of the queue which are:
- Next in sequence (unwrapped or wrapped)
- Older than five seconds (assuming that the intermediate packets have been lost by the network).
The function will continue to read packets from the head of the queue until it finds one which doesn't match these criteria, and then stop.
There are some limitations with this patch:
- The receive window is hardcoded at 50 packets. I couldn't see where to get the negotiated and/or current window size from.
- The timeout is hardcoded at 5 seconds. A packet which was received and queued within the window, but which should have been preceded by other packets which never appeared, will be accepted anyway after this time (increasing the sequence number to its own).
- There may be memory leaks or other bugs in the reordering code.
The latest version of our code will always be available in pptpclient's own CVS. You can find instructions to download it here:
Please be aware that the CVS contains the very latest version of the software, and as such has not been extensively tested.
The version used in our FireRack firewalls is the CVS tree from 16/08/2002. You can download a patch below which contains all our code, and a few changes by other developers. This patch applies to the last stable release of pptpclient, version 1.1.0, and upgrades to to that CVS version.