Browse code

Restore pre-NCP frame parameters for new sessions

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>

Steffan Karger authored on 2017/05/09 06:44:38
Showing 5 changed files
... ...
@@ -866,9 +866,16 @@ process_incoming_link_part1(struct context *c, struct link_socket_info *lsi, boo
866 866
              * will load crypto_options with the correct encryption key
867 867
              * and return false.
868 868
              */
869
+            uint8_t opcode = *BPTR(&c->c2.buf) >> P_OPCODE_SHIFT;
869 870
             if (tls_pre_decrypt(c->c2.tls_multi, &c->c2.from, &c->c2.buf, &co,
870 871
                                 floated, &ad_start))
871 872
             {
873
+                /* Restore pre-NCP frame parameters */
874
+                if (is_hard_reset(opcode, c->options.key_method))
875
+                {
876
+                    c->c2.frame = c->c2.frame_initial;
877
+                }
878
+
872 879
                 interval_action(&c->c2.tmp_int);
873 880
 
874 881
                 /* reset packet received timer if TLS packet */
... ...
@@ -4051,6 +4051,8 @@ init_instance(struct context *c, const struct env_set *env, const unsigned int f
4051 4051
         c->c2.did_open_tun = do_open_tun(c);
4052 4052
     }
4053 4053
 
4054
+    c->c2.frame_initial = c->c2.frame;
4055
+
4054 4056
     /* print MTU info */
4055 4057
     do_print_data_channel_mtu_parms(c);
4056 4058
 
... ...
@@ -263,7 +263,8 @@ struct context_2
263 263
     struct link_socket_actual from;             /* address of incoming datagram */
264 264
 
265 265
     /* MTU frame parameters */
266
-    struct frame frame;
266
+    struct frame frame;                         /* Active frame parameters */
267
+    struct frame frame_initial;                 /* Restored on new session */
267 268
 
268 269
 #ifdef ENABLE_FRAGMENT
269 270
     /* Object to handle advanced MTU negotiation and datagram fragmentation */
... ...
@@ -832,14 +832,7 @@ print_key_id(struct tls_multi *multi, struct gc_arena *gc)
832 832
     return BSTR(&out);
833 833
 }
834 834
 
835
-/*
836
- * Given a key_method, return true if op
837
- * represents the required form of hard_reset.
838
- *
839
- * If key_method = 0, return true if any
840
- * form of hard reset is used.
841
- */
842
-static bool
835
+bool
843 836
 is_hard_reset(int op, int key_method)
844 837
 {
845 838
     if (!key_method || key_method == 1)
... ...
@@ -591,6 +591,14 @@ void show_tls_performance_stats(void);
591 591
 /*#define EXTRACT_X509_FIELD_TEST*/
592 592
 void extract_x509_field_test(void);
593 593
 
594
+/**
595
+ * Given a key_method, return true if opcode represents the required form of
596
+ * hard_reset.
597
+ *
598
+ * If key_method == 0, return true if any form of hard reset is used.
599
+ */
600
+bool is_hard_reset(int op, int key_method);
601
+
594 602
 #endif /* ENABLE_CRYPTO */
595 603
 
596 604
 #endif /* ifndef OPENVPN_SSL_H */