]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Restore pre-NCP frame parameters for new sessions
authorSteffan Karger <steffan@karger.me>
Mon, 8 May 2017 21:44:38 +0000 (23:44 +0200)
committerDavid Sommerseth <davids@openvpn.net>
Tue, 9 May 2017 13:12:49 +0000 (15:12 +0200)
As reported in trac #879, as of the introduction of NCP we always adjust
the frame parameters on session negotiations, but do not reset the frame
state for a new session on an existing state instance.  That caused the
frame parameters to be reduced for each reconnect, resulting in smaller
and smaller packet size limits until no traffic could go through the
tunnel at all.  This patch resolves that omission.

Trac: #879
Signed-off-by: Steffan Karger <steffan@karger.me>
Acked-by: David Sommerseth <davids@openvpn.net>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1494279878-24601-1-git-send-email-steffan@karger.me>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14589.html
Signed-off-by: David Sommerseth <davids@openvpn.net>
src/openvpn/forward.c
src/openvpn/init.c
src/openvpn/openvpn.h
src/openvpn/ssl.c
src/openvpn/ssl.h

index 8102e94975b46d35366d344bf98e7cec3137998f..2f3f3c5dae74969abee730d7854a14ab9f17622c 100644 (file)
@@ -866,9 +866,16 @@ process_incoming_link_part1(struct context *c, struct link_socket_info *lsi, boo
              * will load crypto_options with the correct encryption key
              * and return false.
              */
+            uint8_t opcode = *BPTR(&c->c2.buf) >> P_OPCODE_SHIFT;
             if (tls_pre_decrypt(c->c2.tls_multi, &c->c2.from, &c->c2.buf, &co,
                                 floated, &ad_start))
             {
+                /* Restore pre-NCP frame parameters */
+                if (is_hard_reset(opcode, c->options.key_method))
+                {
+                    c->c2.frame = c->c2.frame_initial;
+                }
+
                 interval_action(&c->c2.tmp_int);
 
                 /* reset packet received timer if TLS packet */
index ee14f672a9ab159caec19efd7c7a7780349c6bac..3c22d67a46a54cf1229ac7f5cb924af30e2a6dd1 100644 (file)
@@ -4051,6 +4051,8 @@ init_instance(struct context *c, const struct env_set *env, const unsigned int f
         c->c2.did_open_tun = do_open_tun(c);
     }
 
+    c->c2.frame_initial = c->c2.frame;
+
     /* print MTU info */
     do_print_data_channel_mtu_parms(c);
 
index 893296edc539800db6463b5861e6f7c83cbac115..f8682d1735d4b13cd945351fb6975aa4465d5e76 100644 (file)
@@ -263,7 +263,8 @@ struct context_2
     struct link_socket_actual from;             /* address of incoming datagram */
 
     /* MTU frame parameters */
-    struct frame frame;
+    struct frame frame;                         /* Active frame parameters */
+    struct frame frame_initial;                 /* Restored on new session */
 
 #ifdef ENABLE_FRAGMENT
     /* Object to handle advanced MTU negotiation and datagram fragmentation */
index fca1e7c530ac7586b784bd1f721e296212714380..b1f0f6b9e8780eb1aac8ca37836243016cf0e404 100644 (file)
@@ -832,14 +832,7 @@ print_key_id(struct tls_multi *multi, struct gc_arena *gc)
     return BSTR(&out);
 }
 
-/*
- * Given a key_method, return true if op
- * represents the required form of hard_reset.
- *
- * If key_method = 0, return true if any
- * form of hard reset is used.
- */
-static bool
+bool
 is_hard_reset(int op, int key_method)
 {
     if (!key_method || key_method == 1)
index ed1344e7b2f3b58b9de792bb36bd9dc9f4105c7c..03688ca6e6bd407e5c22229eba1460849ef373cc 100644 (file)
@@ -591,6 +591,14 @@ void show_tls_performance_stats(void);
 /*#define EXTRACT_X509_FIELD_TEST*/
 void extract_x509_field_test(void);
 
+/**
+ * Given a key_method, return true if opcode represents the required form of
+ * hard_reset.
+ *
+ * If key_method == 0, return true if any form of hard reset is used.
+ */
+bool is_hard_reset(int op, int key_method);
+
 #endif /* ENABLE_CRYPTO */
 
 #endif /* ifndef OPENVPN_SSL_H */