Seldom but from time to time I encounter networks that my VPN struggles with. Sometimes the VPN tunnel is established just fine, pings are going through the tunnel but web browsing and other download activities just don't work. The effect is caused by fragmentation, i.e. the IP packet size of the downlink is too large for some part of the network between me and the server and hence the IP packet is split somewhere or simply discarded because it has become too long.
The remedy for such behavior is to reduce the Maximum Transfer Unit (MTU) for the tunnel interface on my computer to a lower values such as 1200 bytes and things come back to life. What I always wondered, though but never had the time to figure out was how the server is notified of the reduced MTU!?
When I recently encountered the scenario again I had a closer look at the TCP connection establishment and found that the MTU size is contained in the first IP SYNchronize packet in the TCP header. The parameter that conveys the maximum size a TCP packet can have is contained in the Maximum Segment Size (MSS) parameter. The first image on the left shows the default MSS over my Ethernet at home, 1460 bytes. Together with the additional IP overhead the IP packet size is 1506 bytes. The MTU size configured on my Ethernet interface is 1500 bytes.
When I change the MTU size on the fly on my Linux machine with 'sudo ifconfig eth1 mtu 800', my MTU size shown by 'ifconfig' becomes 800. The MSS size then becomes 760 bytes and the Ethernet packet is 814 bytes long. The 14 extra bytes are for the Ethernet header that is not counted in the maximum MTU size because the Ethernet header is discarded at the next router and replaced by another Ethernet header or some other protocol if the next hop is over a different network technology.
There we go, another mystery solved.