]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Use exponential backoff for caching in tls_authentication_status
authorArne Schwabe <arne@rfc2549.org>
Mon, 10 May 2021 13:13:56 +0000 (15:13 +0200)
committerGert Doering <gert@greenie.muc.de>
Sat, 15 May 2021 15:22:13 +0000 (17:22 +0200)
The caching in tls_authentication_status broke the quick reaction to
authentication status in the code paths that did not do caching like
PUSH_REQUEST reply code path.

This patch introduces exponential backoff for the caching so we still
retain the quick reaction while still keeping the benefit of caching.

Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <20210510131356.968965-1-arne@rfc2549.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg22327.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/multi.c
src/openvpn/push.c
src/openvpn/ssl.c
src/openvpn/ssl.h
src/openvpn/ssl_common.h
src/openvpn/ssl_verify.c
src/openvpn/ssl_verify.h

index c97bc20ba41cd2c7de40b63aaf57b752c85b8eb3..def5dd40b00c3977b1281e82b80e07697a3bbd6b 100644 (file)
@@ -2595,8 +2595,7 @@ static const multi_client_connect_handler client_connect_handlers[] = {
 static void
 multi_connection_established(struct multi_context *m, struct multi_instance *mi)
 {
-    if (tls_authentication_status(mi->context.c2.tls_multi, TLS_MULTI_AUTH_STATUS_INTERVAL)
-        != TLS_AUTHENTICATION_SUCCEEDED)
+    if (tls_authentication_status(mi->context.c2.tls_multi) != TLS_AUTHENTICATION_SUCCEEDED)
     {
         return;
     }
index ad83c597db7d32844360bbc9eef1f2aa55de30a2..85f9488a51b9b180201363d57823d437fec41da8 100644 (file)
@@ -860,7 +860,7 @@ process_incoming_push_request(struct context *c)
     int ret = PUSH_MSG_ERROR;
 
 
-    if (tls_authentication_status(c->c2.tls_multi, TLS_MULTI_AUTH_STATUS_INTERVAL) == TLS_AUTHENTICATION_FAILED
+    if (tls_authentication_status(c->c2.tls_multi) == TLS_AUTHENTICATION_FAILED
         || c->c2.tls_multi->multi_state == CAS_FAILED)
     {
         const char *client_reason = tls_client_reason(c->c2.tls_multi);
index b16f6bcc5d06111916ee06933c1bb59f0afd6966..e843b21529fce67bb5a85ec3861c519e5980aba0 100644 (file)
@@ -3110,7 +3110,7 @@ tls_multi_process(struct tls_multi *multi,
 
     update_time();
 
-    enum tls_auth_status tas = tls_authentication_status(multi, TLS_MULTI_AUTH_STATUS_INTERVAL);
+    enum tls_auth_status tas = tls_authentication_status(multi);
 
     /*
      * If lame duck session expires, kill it.
index 769d885a38c301386baad1b7ed5830c17e547c48..88f89876a8fcb734eb62259154242a626fb19af2 100644 (file)
@@ -91,9 +91,6 @@
 #define TLS_MULTI_HORIZON 2     /* call tls_multi_process frequently for n seconds after
                                  * every packet sent/received action */
 
-/* Interval that tls_multi_process should call tls_authentication_status */
-#define TLS_MULTI_AUTH_STATUS_INTERVAL 10
-
 /*
  * Buffer sizes (also see mtu.h).
  */
index 11d4c70404446c234886ef1114128cfa85b73c29..61cae7419c8968ec5c6c4c8611943aa7d8eb0de9 100644 (file)
@@ -561,10 +561,13 @@ struct tls_multi
     char *locked_username;
     struct cert_hash_set *locked_cert_hash_set;
 
-    /* Time of last when we updated the cached state of
+    /** Time of last when we updated the cached state of
      * tls_authentication_status deferred files */
     time_t tas_cache_last_update;
 
+    /** The number of times we updated the cache */
+    unsigned int tas_cache_num_updates;
+
     /*
      * An error message to send to client on AUTH_FAILED
      */
index 0bcc03f361e05922825555d6ad903d79e2338425..0b41eea2dbd05b2f47402d98af2008d2e993dcf5 100644 (file)
@@ -1073,8 +1073,28 @@ key_state_test_auth_control_file(struct auth_deferred_status *ads, bool cached)
     return ACF_DISABLED;
 }
 
+/**
+ * The minimum times to have passed to update the cache. Older versions
+ * of OpenVPN had code path that did not do any caching, so we start
+ * with no caching (0) here as well to have the same super quick initial
+ * reaction.
+ */
+static time_t cache_intervals[] = {0, 0, 0, 0, 0, 1, 1, 2, 2, 4, 8};
+
+/**
+ * uses cache_intervals times to determine if we should update the
+ * cache.
+ */
+static bool
+tls_authentication_status_use_cache(struct tls_multi *multi)
+{
+    unsigned int idx = min_uint(multi->tas_cache_num_updates, SIZE(cache_intervals) - 1);
+    time_t latency = cache_intervals[idx];
+    return multi->tas_cache_last_update + latency >= now;
+}
+
 enum tls_auth_status
-tls_authentication_status(struct tls_multi *multi, const int latency)
+tls_authentication_status(struct tls_multi *multi)
 {
     bool deferred = false;
 
@@ -1087,7 +1107,7 @@ tls_authentication_status(struct tls_multi *multi, const int latency)
     /* at least one key already failed authentication */
     bool failed_auth = false;
 
-    bool cached = multi->tas_cache_last_update + latency >= now;
+    bool cached = tls_authentication_status_use_cache(multi);
 
     for (int i = 0; i < KEY_SCAN_SIZE; ++i)
     {
@@ -1143,6 +1163,7 @@ tls_authentication_status(struct tls_multi *multi, const int latency)
     if (!cached)
     {
         multi->tas_cache_last_update = now;
+        multi->tas_cache_num_updates++;
     }
 
 #if 0
index 8de5ee12241a8942784dff4a530de4960a5f4588..88c3d540a33ee4496ed4285cd8360bf4baab6f4d 100644 (file)
@@ -75,7 +75,7 @@ enum tls_auth_status
 /**
  * Return current session authentication state of the tls_multi structure
  * This will return TLS_AUTHENTICATION_SUCCEEDED only if the session is
- * fully authenicated, i.e. VPN traffic is allowed over it.
+ * fully authenticated, i.e. VPN traffic is allowed over it.
  *
  * Checks the status of all active keys and checks if the deferred
  * authentication has succeeded.
@@ -84,15 +84,12 @@ enum tls_auth_status
  * from KS_AUTH_DEFERRED to KS_AUTH_FALSE/KS_AUTH_TRUE if the deferred
  * authentication has succeeded after last call.
  *
- * @param   latency     if not null, return a cached result from the last
- *                      call if the last call for this multi struct has 
- *                      been less than latency seconds ago
  * @param   multi       the tls_multi struct to operate on
  *
  * @return              Current authentication status of the tls_multi
  */
 enum tls_auth_status
-tls_authentication_status(struct tls_multi *multi, const int latency);
+tls_authentication_status(struct tls_multi *multi);
 
 /** Check whether the \a ks \c key_state has finished the key exchange part
  *  of the OpenVPN hand shake. This is that the key_method_2read/write