Changeset f233a23 in mod_gnutls for src/gnutls_ocsp.c


Ignore:
Timestamp:
Apr 19, 2018, 3:27:08 PM (2 years ago)
Author:
Fiona Klute <fiona.klute@…>
Branches:
debian/master, master, proxy-ticket
Children:
fa6d0bb
Parents:
3d30543
Message:

Logic for fuzzy OCSP update timing

If a server has a lot of virtual hosts using OCSP stapling with
identical OCSP cache lifetime settings (e.g. the defaults), this will
spread update intervals so requests don't happen all at once.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_ocsp.c

    r3d30543 rf233a23  
    2525#include <apr_lib.h>
    2626#include <apr_time.h>
     27#include <gnutls/crypto.h>
    2728#include <gnutls/ocsp.h>
    2829#include <mod_watchdog.h>
     
    928929
    929930
     931/** The maximum random fuzz interval that will not overflow. The
     932 * permitted values are limited to whatever will not make an
     933 * `apr_interval_time_t` variable overflow when multiplied with
     934 * `APR_UINT16_MAX`. With apr_interval_time_t being a 64 bit signed
     935 * integer the maximum fuzz interval is about 4.5 years, which should
     936 * be more than plenty. */
     937#define MAX_FUZZ_TIME (APR_INT64_MAX / APR_UINT16_MAX)
     938
    930939/**
    931940 * Perform an asynchronous OCSP cache update. This is a callback for
     
    963972    apr_status_t rv = mgs_cache_ocsp_response(server, &expiry);
    964973
    965     /* TODO: fuzzy interval */
    966     apr_interval_time_t next_interval = expiry - apr_time_now();
     974    /* TODO: Make maximum fuzz time configurable and compare to
     975     * allowed maximum during config */
     976    ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, server,
     977                 "%s: Maximum fuzz time without overflow: %" APR_INT64_T_FMT
     978                 " seconds",
     979                 __func__, apr_time_sec(MAX_FUZZ_TIME));
     980
     981    apr_interval_time_t next_interval;
    967982    if (rv != APR_SUCCESS)
    968983        next_interval = sc->ocsp_failure_timeout;
     984    else
     985    {
     986        apr_uint16_t random_bytes;
     987        int res = gnutls_rnd(GNUTLS_RND_NONCE, &random_bytes,
     988                             sizeof(random_bytes));
     989        if (__builtin_expect(res < 0, 0))
     990        {
     991            /* Shouldn't ever happen, because a working random number
     992             * generator is required for establishing TLS sessions. */
     993            random_bytes = (apr_uint16_t) apr_time_now();
     994            ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EGENERAL, server,
     995                         "Error getting random number for fuzzy update "
     996                         "interval: %s Falling back on truncated time.",
     997                         gnutls_strerror(res));
     998        }
     999
     1000        /* Base fuzz is half the maximum (sc->ocsp_cache_time / 8 at
     1001         * the moment). The actual fuzz is between the maximum and
     1002         * half that. */
     1003        apr_interval_time_t base_fuzz = sc->ocsp_cache_time / 16;
     1004        apr_interval_time_t fuzz =
     1005            base_fuzz + base_fuzz * random_bytes / APR_UINT16_MAX;
     1006
     1007        /* With an extremly short timeout or weird nextUpdate value
     1008         * next_interval <= 0 might happen. Use the failure timeout to
     1009         * avoid endlessly repeating updates. */
     1010        next_interval = expiry - apr_time_now();
     1011        if (next_interval <= 0)
     1012        {
     1013            next_interval = sc->ocsp_failure_timeout;
     1014            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server,
     1015                         "OCSP cache expiration time of the response for "
     1016                         "%s:%d is in the past, repeating after failure "
     1017                         "timeout (GnuTLSOCSPFailureTimeout).",
     1018                         server->server_hostname, server->addrs->host_port);
     1019        }
     1020
     1021        /* It's possible to compare maximum fuzz and configured OCSP
     1022         * cache timeout at configuration time, but the interval until
     1023         * the nextUpdate value expires (or the failure timeout
     1024         * fallback above) might be shorter. Make sure that we don't
     1025         * end up with a negative interval. */
     1026        while (fuzz > next_interval)
     1027            fuzz /= 2;
     1028        next_interval -= fuzz;
     1029    }
     1030
    9691031    sc->singleton_wd->set_callback_interval(sc->singleton_wd->wd,
    9701032                                            next_interval,
Note: See TracChangeset for help on using the changeset viewer.