As a general rule, UDP is a better option for VPN traffic than TCP. TCP works very hard to
ensure that every single packet makes it across the wire (or any other medium) uncorrupted
and in order. For some things, such as SSH, file transfers, and web traffic, this is a good
thing; we expect the resulting content to be legible and generally in its original form.
When connectivity is reliable with relatively little packet loss, TCP can function just fine for
VPN. When that link drops packets and becomes unreliable, the problem can be amplified
dramatically when the encapsulated traffic is also using TCP. The resulting traffic includes
retransmit from both the OpenVPN processes at either end and the encapsulated traffic at
both ends. This results in potentially four times the packet count.
By its nature, UDP is a connectionless protocol. UDP is great for data where it is acceptable
to receive packets out of order or when packets can go missing. The out-of-order packets
are typically discarded since the application has likely already moved on to processing the
later packets and processing earlier packets would be disruptive.
Voice over Internet Protocol (VoIP) is one good example of this scenario. In a voice or
video conversation with someone, we are listening and/or viewing the conversation in real
time. It would be undesirable to hear words or see facial expression out of order. The
conversation quickly would become incomprehensible; it is much preferable to simply
ignore a dropped consonant or see a short hang in the video stream. On a smaller scale,
rendering a portion of a frame or part of a word that is a second or more old is of little use.
Traffic across a VPN is similar. The encapsulated traffic is already going to be engineered to
handle either transmission assurance (TCP) or packet loss and delay in a graceful manner.
So, using UDP for the overall VPN traffic, we allow the application transiting the VPN to
handle any connection quality issues.
Sometimes using TCP for a VPN tunnel is unavoidable, but do so if you
can. The community support staff often references two links for why TCP
within TCP is a bad idea:
Because of this connectionless state of a UDP tunnel, neither the client or server truly know
when the link to the other end has gone away or failed. To help deal with lost connections,
OpenVPN has the –ping and –ping-restart options.
If you are using UDP for your OpenVPN tunnel and traffic periodically stops working,
adding the –ping-restart option will help OpenVPN detect connection failures and
reconnect the tunnel to a useful state.
UDP and firewalls
Because UDP is connectionless, another hurdle for this traffic is the border firewall. Some
firewalls will attempt to perform a fake keep-state on the traffic pattern with some level of
default timeout when no further traffic witnessed.
Using the –ping option, OpenVPN will spend periodic ping packets across VPN to the
remote endpoint to keep these fake keep-state sessions active. Without this, the firewall may
determine no further traffic is expected and shut down the session. This will not prevent
traffic from leaving the firewall, but will block the other side from talking in to that
This can potentially happen for either side, but it is typically a client-side problem. The
server side will normally have an explicit rule in the firewall that allows the inbound UDP
traffic, whereas the client side uses a random high-numbered port.
If the client is having connection problems, there may be a large delay on the server side
before that system is listed as disconnected. This will delay updates to things such as the —
status log or the execution of –client-disconnect. There is a client-side option
available named –explicit-exit-notify, which will cause the client system to notify
the remote OpenVPN server that it is exiting.