Attention is currently required from: stipa.

Hello plaisthos,

I'd like you to reexamine a change. Please visit

    http://gerrit.openvpn.net/c/openvpn/+/1771?usp=email

to look at the new patch set (#16).


Change subject: oob: fall back quickly when a probe-started handshake is ignored
......................................................................

oob: fall back quickly when a probe-started handshake is ignored

If the server does not accept the third packet of a handshake started
from a probe reply, the client previously stalled for the full
handshake_window (~60s) before recovering.

In a normal handshake, no answer could mean the server is down, so
waiting is right. Here we know it is up, since it answered a probe a
moment ago -- so no answer means it did not accept the reply as a reset,
and waiting 60s is pointless. That happens when a load balancer sends
the probe and the handshake to different instances, when NAT changes the
source port the cookie is bound to, or when the server restarted and
rotated its session-id HMAC key.

Give such a session a short first-response deadline
(min(handshake_window, 5s)); once the server answers, tls_pre_decrypt()
restores the full window so a slow-but-working handshake is not cut off.
If no response arrives, the session times out quickly and the normal
handshake recovery kicks in, so a rejected reply costs a few seconds
instead of ~60.

Change-Id: Icec4696ff263ab39ebab06e8d478395a5ddfaab9
Signed-off-by: Lev Stipakov <[email protected]>
---
M src/openvpn/ssl.c
M src/openvpn/ssl_common.h
2 files changed, 29 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/71/1771/16

diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index ccd5fda..b2e6c8a 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -2569,6 +2569,11 @@
     return session_move_pre_start(session, ks, true);
 }

+/* Seconds to wait for the server's first response to a probe-started handshake
+ * before giving up and falling back to a normal handshake. A couple of
+ * control-channel retransmits; capped at handshake_window by the caller. */
+#define OOB_PROBE_START_FALLBACK_SECS 5
+
 bool
 session_skip_to_pre_start_client(struct tls_session *session, const struct 
session_id *client_sid,
                                  const struct session_id *server_sid,
@@ -2619,6 +2624,12 @@
         return false;
     }
     ks->state = S_PRE_START;
+
+    /* Fail fast if the server ignores it: wait seconds, not handshake_window.
+     * tls_pre_decrypt() restores the full window once the server answers. */
+    ks->oob_probe_start = true;
+    ks->must_negotiate =
+        now + min_int(session->opt->handshake_window, 
OOB_PROBE_START_FALLBACK_SECS);
     return true;
 }

@@ -2867,9 +2878,15 @@
     /* Are we timed out on receive? */
     if (now >= ks->must_negotiate && ks->state >= S_UNDEF && ks->state < 
S_ACTIVE)
     {
+        /* Report the window that actually applied: an unanswered probe-started
+         * handshake times out on the short fallback deadline, not
+         * handshake_window. */
+        int window = ks->oob_probe_start
+                         ? min_int(session->opt->handshake_window, 
OOB_PROBE_START_FALLBACK_SECS)
+                         : session->opt->handshake_window;
         msg(D_TLS_ERRORS,
             "TLS Error: TLS key negotiation failed to occur within %d seconds 
(check your network connectivity)",
-            session->opt->handshake_window);
+            window);
         goto error;
     }

@@ -3950,6 +3967,15 @@
     /* Let our caller know we processed a control channel packet */
     ret = true;

+    /* First valid response to a probe-started handshake: the server accepted 
it,
+     * so restore the normal negotiation window (it was shortened to fail fast 
if
+     * the probe reply had been ignored). */
+    if (ks->oob_probe_start)
+    {
+        ks->oob_probe_start = false;
+        ks->must_negotiate = now + session->opt->handshake_window;
+    }
+
     /*
      * Set our remote address and remote session_id
      */
diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h
index f6392f9..905006c 100644
--- a/src/openvpn/ssl_common.h
+++ b/src/openvpn/ssl_common.h
@@ -227,6 +227,8 @@
     time_t initial;                        /* when we created this session */
     time_t established;                    /* when our state went S_ACTIVE */
     time_t must_negotiate;                 /* key negotiation times out if not 
finished before this time */
+    bool oob_probe_start;                  /* probe-started handshake: 
must_negotiate is a short
+                                            * first-response deadline, not the 
full window */
     time_t must_die;                       /* this object is destroyed at this 
time */
     time_t peer_last_packet;               /* Last time we received a packet 
in this control session */


--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1771?usp=email
To unsubscribe, or for help writing mail filters, visit 
http://gerrit.openvpn.net/settings?usp=email

Gerrit-MessageType: newpatchset
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: Icec4696ff263ab39ebab06e8d478395a5ddfaab9
Gerrit-Change-Number: 1771
Gerrit-PatchSet: 16
Gerrit-Owner: stipa <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: stipa <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to