Tuning TCP-based connections

In this recipe, we focus on some of the basic techniques for optimizing TCP-based VPN tunnels. In a TCP-based VPN setup, the connection between the VPN endpoints is a regular TCP connection. This has advantages and drawbacks. The main advantage is that it is often easier to set up a TCP connection than a UDP connection, mostly due to firewall restrictions. The main drawback of tunneling TCP traffic over a TCP-based tunnel is that there is chance of severe performance penalties, especially when the network connection is poor. This performance penalty is caused by the tcp-over-tcp syndrome. The TCP protocol guarantees the ordered delivery of packets, thus if a packet is dropped along the way, the packet will be resent. Once the new packet is received, the packet order is restored. Until that time, all packets after the lost packet are on hold. The problem with tunneling TCP traffic over a TCP connection is that both layers want to guarantee ordered packet delivery. This can lead to a large amount of retransmits and hence to a large performance penalty.

When tuned correctly, however, an OpenVPN tunnel over a TCP connection can achieve the same performance as an OpenVPN tunnel over a UDP connection. In this recipe, we will show some techniques for tuning such a TCP-based OpenVPN connection.

Getting ready

We use the following network layout:

Getting ready

Set up the client and server certificates using the Setting up the public and private keys recipe from Chapter 2Client-server IP-only Networks. For this recipe, the server computer was running CentOS 6 Linux and OpenVPN 2.3.11. The client was running Windows 7 64bit and OpenVPN 2.3.11. Keep the configuration file basic-udp-server.conf from the Server-side routing recipe from Chapter 2Client-server IP-only Networks, as well as the client configuration file basic-udp-client.ovpn from the Using an ifconfig-pool block recipe.

How to do it...

  1. Create the server configuration file:
            proto tcp 
            port 1194 
            dev tun 
            server 10.200.0.0 255.255.255.0 
     
            ca       /etc/openvpn/cookbook/ca.crt 
            cert     /etc/openvpn/cookbook/server.crt 
            key      /etc/openvpn/cookbook/server.key 
            dh       /etc/openvpn/cookbook/dh2048.pem 
            tls-auth /etc/openvpn/cookbook/ta.key 0 
     
            persist-key 
            persist-tun 
            keepalive 10 60 
     
            topology subnet 
     
            user  nobody 
            group nobody 
     
            daemon 
            log-append /var/log/openvpn.log 
     
            tcp-nodelay 
    
  2. Save it as example8-9-server.conf.
  3. Start the server:
    [root@server]# openvpn --config example8-9-server.conf
    
  4. Next, create the client configuration file:
            client 
            proto tcp 
            remote openvpnserver.example.com 
            port 1194 
     
            dev tun 
            nobind 
     
            remote-cert-tls server 
            ca       "c:/program files/openvpn/config/ca.crt" 
            cert     "c:/program files/openvpn/config/client2.crt" 
            key      "c:/program files/openvpn/config/client2.key" 
            tls-auth "c:/program files/openvpn/config/ta.key" 1 
    
  5. Save it as example8-9.ovpn.
  6. Start the client:
    How to do it...
  7. Next, start iperf on the server:
    [server]$ iperf -s
    
  8. Then, measure the performance of the tunnel:
    [WinClient]> iperf -c 10.200.0.1 -w 128k
    

On this particular network, the following settings were tested:

Protocol

Result

UDP

147 Mbits/sec

TCP

115 Mbits/sec

TCP with tcp-nodelay

146 Mbits/sec

As can be seen, the performance of running OpenVPN over TCP is almost identical to the performance of OpenVPN over UDP, when the --tcp-nodelay directive is used.

How it works...

When OpenVPN uses TCP as its underlying protocol, all packets are transferred over a regular TCP connection. By default, TCP connections make use of the Nagle algorithm, where smaller packets are held back and collected before they are sent. For an OpenVPN tunnel, this has an adverse effect on performance in most cases, hence it makes sense to disable the Nagle algorithm. By adding the --tcp-nodelay directive, we disable the Nagle algorithm and we see an immediate increase in performance.

There's more...

The two important parameters that can be tweaked for TCP-based connections are:

  • The --tcp-nodelay directive
  • The MTU size of the TUN/TAP-Win32 adapter via either the --tun-mtu or  --link-mtu directives

On Linux, the MTU size of the TUN (or TAP) adapter can be adjusted on-the-fly, but on Windows, this is not as easy. OpenVPN must be configured to match the MTU size as specified on the server. Before the new MTU size is used, however, the MTU of the TAP adapter must be adjusted. Starting with Windows Vista, it is now also possible to do this on-the-fly, using the netsh command:

  • First, find the right sub-interface number:
    [winclient]C:> netsh interface ipv4 show subinterfaces
    
  • Next, in order to change the MTU size of a sub-interface, use:
    [winclient]C:> netsh interface ipv4 set subinterface "1" 
            mtu=1400
    

Note that these commands must be run with elevated privileges.

If the MTU setting of the Windows TAP-Win32 adapter is larger than the MTU size configured by OpenVPN, the following message can appear in the OpenVPN log file:

... read from TUN/TAP  [State=AT?c Err=[c:src21	ap-win32	apdrvr.c/2447] #O=4 Tx=[29510,0] Rx=[15309,0] IrpQ=[0,1,16] PktQ=[0,22,64] InjQ=[0,1,16]]: More data is available.  (code=234) 

For this particular network, all changes made to the MTU size (with the appropriate Windows reboot) did not have a positive effect on performance.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.27.119