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>
... | ... |
@@ -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 */ |