Changeset d6834e0 in mod_gnutls for src/gnutls_ocsp.c


Ignore:
Timestamp:
Jun 10, 2016, 9:34:08 AM (3 years ago)
Author:
Thomas Klute <thomas2.klute@…>
Branches:
debian/master, debian/stretch-backports, master, upstream
Children:
15b22cb
Parents:
aa68232
git-author:
Thomas Klute <thomas2.klute@…> (06/10/16 09:29:57)
git-committer:
Thomas Klute <thomas2.klute@…> (06/10/16 09:34:08)
Message:

OCSP refresh mutex: Prevent parallel requests

Add a global mutex which a thread must hold before updating a cached
OCSP response. This avoids two threads updating the same response in
parallel. The impact of parallel updates may be small with the
experimental file-based mechanism, but an extra OCSP request over HTTP
would add a lot of overhead.

Note that the new 'gnutls-ocsp' mutex is a global mutex, not one per
virtual host, because a mutex must be registered in pre_config for the
Mutex directive to work.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_ocsp.c

    raa68232 rd6834e0  
    450450    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ctxt->c,
    451451                  "No valid OCSP response in cache, trying to update.");
    452     apr_status_t rv = mgs_cache_ocsp_response(ctxt->c->base_server);
     452
     453    apr_status_t rv = apr_global_mutex_trylock(ctxt->sc->ocsp_mutex);
     454    if (APR_STATUS_IS_EBUSY(rv))
     455    {
     456        /* Another thread is currently holding the mutex, wait. */
     457        apr_global_mutex_lock(ctxt->sc->ocsp_mutex);
     458        /* Check if this other thread updated the response we need. It
     459         * would be better to have a vhost specific mutex, but at the
     460         * moment there's no good way to integrate that with the
     461         * Apache Mutex directive. */
     462        *ocsp_response = ctxt->sc->cache->fetch(ctxt, fingerprint);
     463        if (ocsp_response->size > 0
     464            && check_ocsp_response_expiry(ctxt, ocsp_response)
     465            == GNUTLS_E_SUCCESS)
     466        {
     467            /* Got a valid response now, unlock mutex and return. */
     468            apr_global_mutex_unlock(ctxt->sc->ocsp_mutex);
     469            return GNUTLS_E_SUCCESS;
     470        }
     471        else
     472        {
     473            gnutls_free(ocsp_response->data);
     474            ocsp_response->data = NULL;
     475        }
     476    }
     477
     478    rv = mgs_cache_ocsp_response(ctxt->c->base_server);
    453479    if (rv != APR_SUCCESS)
    454480    {
    455481        ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, ctxt->c,
    456482                      "Updating OCSP response cache failed");
     483        apr_global_mutex_unlock(ctxt->sc->ocsp_mutex);
    457484        goto fail_cleanup;
    458485    }
     486    apr_global_mutex_unlock(ctxt->sc->ocsp_mutex);
    459487
    460488    /* retry reading from cache */
Note: See TracChangeset for help on using the changeset viewer.