Changeset c005645 in mod_gnutls for src/gnutls_cache.c


Ignore:
Timestamp:
Jun 8, 2016, 3:31:29 PM (3 years ago)
Author:
Thomas Klute <thomas2.klute@…>
Branches:
debian/master, debian/stretch-backports, master, upstream
Children:
c55902b
Parents:
eb63377
Message:

Mutex for DBM cache access

I noticed that with a DBM cache enabled and session tickets disabled
even a handful of parallel connections trashed the cache database, and
consequently the error log. According to comments and documentation on
mod_socache_dbm the APR DBM module is not thread or multi-process
safe, so a global mutex is necessary. With the mutex the cache
corruption disappears in my benchmarks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_cache.c

    reb63377 rc005645  
    2929
    3030#include "ap_mpm.h"
     31#include <util_mutex.h>
    3132
    3233#include <unistd.h>
     
    3637#include "unixd.h"
    3738#endif
     39
     40/* default cache timeout */
     41#define MGS_DEFAULT_CACHE_TIMEOUT 300
    3842
    3943/* it seems the default has some strange errors. Use SDBM
     
    354358    deleted = 0;
    355359
     360    apr_global_mutex_lock(sc->cache_mutex);
     361
    356362    rv = apr_dbm_open_ex(&dbm, db_type(sc),
    357363            sc->cache_config, APR_DBM_RWCREATE,
     
    359365    if (rv != APR_SUCCESS) {
    360366        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s,
    361                 "[gnutls_cache] error opening cache searcher '%s'",
     367                "[gnutls_cache] error opening cache '%s'",
    362368                sc->cache_config);
     369        apr_global_mutex_unlock(sc->cache_mutex);
    363370        apr_pool_destroy(spool);
    364371        return;
     
    386393    apr_dbm_close(dbm);
    387394
     395    rv = apr_global_mutex_unlock(sc->cache_mutex);
     396
    388397    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
    389398            "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d",
     
    403412    apr_status_t rv;
    404413
     414    apr_global_mutex_lock(ctxt->sc->cache_mutex);
     415
    405416    rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc),
    406417            ctxt->sc->cache_config, APR_DBM_READONLY,
     
    410421                      "error opening cache '%s'",
    411422                      ctxt->sc->cache_config);
     423        apr_global_mutex_unlock(ctxt->sc->cache_mutex);
    412424        return data;
    413425    }
     
    417429    if (rv != APR_SUCCESS) {
    418430        apr_dbm_close(dbm);
     431        apr_global_mutex_unlock(ctxt->sc->cache_mutex);
    419432        return data;
    420433    }
     
    423436        apr_dbm_freedatum(dbm, dbmval);
    424437        apr_dbm_close(dbm);
     438        apr_global_mutex_unlock(ctxt->sc->cache_mutex);
    425439        return data;
    426440    }
     
    432446        apr_dbm_freedatum(dbm, dbmval);
    433447        apr_dbm_close(dbm);
     448        apr_global_mutex_unlock(ctxt->sc->cache_mutex);
    434449        return data;
    435450    }
     
    443458    apr_dbm_freedatum(dbm, dbmval);
    444459    apr_dbm_close(dbm);
     460    apr_global_mutex_unlock(ctxt->sc->cache_mutex);
    445461
    446462    return data;
     
    484500    memcpy((char *) dbmval.dptr + sizeof (apr_time_t),
    485501            data.data, data.size);
     502
     503    apr_global_mutex_lock(sc->cache_mutex);
    486504
    487505    rv = apr_dbm_open_ex(&dbm, db_type(sc),
     
    493511                     "error opening cache '%s'",
    494512                     sc->cache_config);
     513        apr_global_mutex_unlock(sc->cache_mutex);
    495514        apr_pool_destroy(spool);
    496515        return -1;
     
    504523                     sc->cache_config);
    505524        apr_dbm_close(dbm);
     525        apr_global_mutex_unlock(sc->cache_mutex);
    506526        apr_pool_destroy(spool);
    507527        return -1;
    508528    }
     529
     530    apr_dbm_close(dbm);
     531    apr_global_mutex_unlock(sc->cache_mutex);
    509532
    510533    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
    511534                 "stored %ld bytes of data (%ld byte key) in cache '%s'",
    512535                 dbmval.dsize, dbmkey.dsize, sc->cache_config);
    513 
    514     apr_dbm_close(dbm);
    515536
    516537    apr_pool_destroy(spool);
     
    543564    apr_datum_t dbmkey = {(char*) tmpkey.data, tmpkey.size};
    544565
     566    apr_global_mutex_lock(ctxt->sc->cache_mutex);
     567
    545568    rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc),
    546569            ctxt->sc->cache_config, APR_DBM_RWCREATE,
     
    551574                "[gnutls_cache] error opening cache '%s'",
    552575                ctxt->sc->cache_config);
     576        apr_global_mutex_unlock(ctxt->sc->cache_mutex);
    553577        return -1;
    554578    }
     
    562586                ctxt->sc->cache_config);
    563587        apr_dbm_close(dbm);
     588        apr_global_mutex_unlock(ctxt->sc->cache_mutex);
    564589        return -1;
    565590    }
    566591
    567592    apr_dbm_close(dbm);
     593    apr_global_mutex_unlock(ctxt->sc->cache_mutex);
    568594
    569595    return 0;
     
    620646    /* if GnuTLSCacheTimeout was never explicitly set: */
    621647    if (sc->cache_timeout == -1)
    622         sc->cache_timeout = apr_time_from_sec(300);
     648        sc->cache_timeout = apr_time_from_sec(MGS_DEFAULT_CACHE_TIMEOUT);
     649
     650    /* initialize mutex only once */
     651    if (sc->cache_mutex == NULL)
     652    {
     653        apr_status_t rv = ap_global_mutex_create(&sc->cache_mutex, NULL,
     654                                                 MGS_CACHE_MUTEX_NAME,
     655                                                 NULL, s, p, 0);
     656        if (rv != APR_SUCCESS)
     657            return rv;
     658    }
    623659
    624660    if (sc->cache_type == mgs_cache_dbm
     
    626662        return dbm_cache_post_config(p, s, sc);
    627663    }
    628     return 0;
     664
     665    return APR_SUCCESS;
    629666}
    630667
Note: See TracChangeset for help on using the changeset viewer.