aboutsummaryrefslogtreecommitdiff
path: root/src/openvpn/ssl.c
diff options
context:
space:
mode:
authorLev Stipakov2019-10-30 14:44:59 +0200
committerGert Doering2019-11-06 19:55:07 +0100
commit3bd91cd0e68762b861c57cf37f144d8a11704e9d (patch)
tree6055823244dc3234bf990490eed9cc7d4b4d6a57 /src/openvpn/ssl.c
parent3976acda9bf10b5e62375b66ee42d85eda08fbcf (diff)
downloadopenvpn-3bd91cd0e68762b861c57cf37f144d8a11704e9d.zip
openvpn-3bd91cd0e68762b861c57cf37f144d8a11704e9d.tar.gz
Fix broken fragmentation logic when using NCP
This is the 2.4 backport of master patch (commit d22ba6b). NCP negotiation replaces worst case crypto overhead with actual one in data channel frame. That frame params are used by mssfix. Fragment frame still contains worst case overhead. Without this patch, fragmentation logic incorrectly uses max crypto overhead when calculating packet size. It exceeds fragment size and openvpn peforms fragmentation: > sudo tcpdump port 1194 13:59:06.956394 IP server.fi.openvpn > nat2.panoulu.net.openvpn: UDP, length 652 13:59:06.956489 IP server.fi.openvpn > nat2.panoulu.net.openvpn: UDP, length 648 This patch fixes fragmentation calculation by setting actual crypto overhead, and no unnecessary fragmentation is performed: > sudo tcpdump port 1194 13:58:08.685915 IP server.fi.openvpn > nat2.panoulu.net.openvpn: UDP, length 1272 13:58:08.686007 IP server.fi.openvpn > nat2.panoulu.net.openvpn: UDP, length 1272 Trac #1140 Signed-off-by: Lev Stipakov <lev@openvpn.net> Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <1572439499-16276-1-git-send-email-lstipakov@gmail.com> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg18975.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'src/openvpn/ssl.c')
-rw-r--r--src/openvpn/ssl.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 9696e9b..7dcd962 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -1962,7 +1962,8 @@ cleanup:
bool
tls_session_update_crypto_params(struct tls_session *session,
- struct options *options, struct frame *frame)
+ struct options *options, struct frame *frame,
+ struct frame *frame_fragment)
{
if (!session->opt->server
&& 0 != strcmp(options->ciphername, session->opt->config_ciphername)
@@ -2006,6 +2007,22 @@ tls_session_update_crypto_params(struct tls_session *session,
frame_init_mssfix(frame, options);
frame_print(frame, D_MTU_INFO, "Data Channel MTU parms");
+ /*
+ * mssfix uses data channel framing, which at this point contains
+ * actual overhead. Fragmentation logic uses frame_fragment, which
+ * still contains worst case overhead. Replace it with actual overhead
+ * to prevent unneeded fragmentation.
+ */
+
+ if (frame_fragment)
+ {
+ frame_remove_from_extra_frame(frame_fragment, crypto_max_overhead());
+ crypto_adjust_frame_parameters(frame_fragment, &session->opt->key_type,
+ options->use_iv, options->replay, packet_id_long_form);
+ frame_set_mtu_dynamic(frame_fragment, options->ce.fragment, SET_MTU_UPPER_BOUND);
+ frame_print(frame_fragment, D_MTU_INFO, "Fragmentation MTU parms");
+ }
+
return tls_session_generate_data_channel_keys(session);
}