summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/ssl/ssl_engine_mutex.c18
-rw-r--r--modules/ssl/ssl_private.h12
-rw-r--r--modules/ssl/ssl_scache.c48
-rw-r--r--modules/ssl/ssl_scache_dbm.c25
-rw-r--r--modules/ssl/ssl_scache_dc.c2
-rw-r--r--modules/ssl/ssl_scache_memcache.c2
-rw-r--r--modules/ssl/ssl_scache_shmcb.c22
7 files changed, 79 insertions, 50 deletions
diff --git a/modules/ssl/ssl_engine_mutex.c b/modules/ssl/ssl_engine_mutex.c
index bbcd92ad64..7c6145cbcd 100644
--- a/modules/ssl/ssl_engine_mutex.c
+++ b/modules/ssl/ssl_engine_mutex.c
@@ -39,12 +39,24 @@ int ssl_mutex_init(server_rec *s, apr_pool_t *p)
SSLModConfigRec *mc = myModConfig(s);
apr_status_t rv;
- if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
+ /* A mutex is only needed if a session cache is configured, and
+ * the provider used is not internally multi-process/thread
+ * safe. */
+ if (!mc->sesscache
+ || (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) == 0) {
return TRUE;
+ }
if (mc->pMutex) {
return TRUE;
}
+ else if (mc->nMutexMode == SSL_MUTEXMODE_NONE) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "An SSLMutex is required for the '%s' session cache",
+ mc->sesscache->name);
+ return FALSE;
+ }
+
if ((rv = apr_global_mutex_create(&mc->pMutex, mc->szMutexFile,
mc->nMutexMech, s->process->pool))
!= APR_SUCCESS) {
@@ -97,8 +109,6 @@ int ssl_mutex_on(server_rec *s)
SSLModConfigRec *mc = myModConfig(s);
apr_status_t rv;
- if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
- return TRUE;
if ((rv = apr_global_mutex_lock(mc->pMutex)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s,
"Failed to acquire SSL session cache lock");
@@ -112,8 +122,6 @@ int ssl_mutex_off(server_rec *s)
SSLModConfigRec *mc = myModConfig(s);
apr_status_t rv;
- if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
- return TRUE;
if ((rv = apr_global_mutex_unlock(mc->pMutex)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s,
"Failed to release SSL session cache lock");
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index 0f20b535a2..76f08c61d3 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -354,8 +354,20 @@ typedef struct {
#define MODSSL_SESSCACHE_PROVIDER_GROUP "mod_ssl-sesscache"
#define MODSSL_SESSCACHE_PROVIDER_VERSION "0"
+/* If this flag is set, the store/retrieve/delete/status interfaces of
+ * the provider are NOT safe to be called concurrently from multiple
+ * processes or threads, and an external global mutex must be used to
+ * serialize access to the provider. */
+#define MODSSL_SESSCACHE_FLAG_NOTMPSAFE (0x0001)
+
/* Session cache provider vtable. */
typedef struct {
+ /* Canonical provider name: */
+ const char *name;
+
+ /* Bitmask of MODSSL_SESSCACHE_FLAG_* flags: */
+ unsigned int flags;
+
/* Create a session cache based on the given configuration string
* ARG. Returns NULL on success, or an error string on failure.
* Pool TMP should be used for any temporary allocations, pool P
diff --git a/modules/ssl/ssl_scache.c b/modules/ssl/ssl_scache.c
index 3d97ee8d16..db4dad12e8 100644
--- a/modules/ssl/ssl_scache.c
+++ b/modules/ssl/ssl_scache.c
@@ -90,6 +90,7 @@ BOOL ssl_scache_store(server_rec *s, UCHAR *id, int idlen,
SSLModConfigRec *mc = myModConfig(s);
unsigned char encoded[SSL_SESSION_MAX_DER], *ptr;
unsigned int len;
+ BOOL rv;
/* Serialise the session. */
len = i2d_SSL_SESSION(sess, NULL);
@@ -102,8 +103,18 @@ BOOL ssl_scache_store(server_rec *s, UCHAR *id, int idlen,
ptr = encoded;
len = i2d_SSL_SESSION(sess, &ptr);
- return mc->sesscache->store(mc->sesscache_context, s, id, idlen,
- expiry, encoded, len);
+ if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_on(s);
+ }
+
+ rv = mc->sesscache->store(mc->sesscache_context, s, id, idlen,
+ expiry, encoded, len);
+
+ if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_off(s);
+ }
+
+ return rv;
}
SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen,
@@ -113,9 +124,20 @@ SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen,
unsigned char dest[SSL_SESSION_MAX_DER];
unsigned int destlen = SSL_SESSION_MAX_DER;
MODSSL_D2I_SSL_SESSION_CONST unsigned char *ptr;
-
- if (mc->sesscache->retrieve(mc->sesscache_context, s, id, idlen,
- dest, &destlen, p) == FALSE) {
+ BOOL rv;
+
+ if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_on(s);
+ }
+
+ rv = mc->sesscache->retrieve(mc->sesscache_context, s, id, idlen,
+ dest, &destlen, p);
+
+ if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_off(s);
+ }
+
+ if (rv == FALSE) {
return NULL;
}
@@ -129,9 +151,15 @@ void ssl_scache_remove(server_rec *s, UCHAR *id, int idlen,
{
SSLModConfigRec *mc = myModConfig(s);
+ if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_on(s);
+ }
+
mc->sesscache->delete(mc->sesscache_context, s, id, idlen, p);
- return;
+ if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_off(s);
+ }
}
/* _________________________________________________________________
@@ -153,8 +181,16 @@ static int ssl_ext_status_hook(request_rec *r, int flags)
ap_rputs("</td></tr>\n", r);
ap_rputs("<tr><td bgcolor=\"#ffffff\">\n", r);
+ if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_on(r->server);
+ }
+
mc->sesscache->status(mc->sesscache_context, r, flags, r->pool);
+ if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_off(r->server);
+ }
+
ap_rputs("</td></tr>\n", r);
ap_rputs("</table>\n", r);
return OK;
diff --git a/modules/ssl/ssl_scache_dbm.c b/modules/ssl/ssl_scache_dbm.c
index acd2487222..5959d5ee81 100644
--- a/modules/ssl/ssl_scache_dbm.c
+++ b/modules/ssl/ssl_scache_dbm.c
@@ -71,7 +71,6 @@ static apr_status_t ssl_scache_dbm_init(void *context, server_rec *s, apr_pool_t
}
/* open it once to create it and to make sure it _can_ be created */
- ssl_mutex_on(s);
apr_pool_clear(ctx->pool);
if ((rv = apr_dbm_open(&dbm, ctx->data_file,
@@ -79,7 +78,6 @@ static apr_status_t ssl_scache_dbm_init(void *context, server_rec *s, apr_pool_t
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
"Cannot create SSLSessionCache DBM file `%s'",
ctx->data_file);
- ssl_mutex_off(s);
return rv;
}
apr_dbm_close(dbm);
@@ -108,7 +106,6 @@ static apr_status_t ssl_scache_dbm_init(void *context, server_rec *s, apr_pool_t
}
}
#endif
- ssl_mutex_off(s);
ssl_scache_dbm_expire(ctx, s);
return APR_SUCCESS;
@@ -173,7 +170,6 @@ static BOOL ssl_scache_dbm_store(void *context, server_rec *s, UCHAR *id, int id
memcpy((char *)dbmval.dptr+sizeof(time_t), ucaData, nData);
/* and store it to the DBM file */
- ssl_mutex_on(s);
apr_pool_clear(ctx->pool);
if ((rv = apr_dbm_open(&dbm, ctx->data_file,
@@ -182,7 +178,6 @@ static BOOL ssl_scache_dbm_store(void *context, server_rec *s, UCHAR *id, int id
"Cannot open SSLSessionCache DBM file `%s' for writing "
"(store)",
ctx->data_file);
- ssl_mutex_off(s);
free(dbmval.dptr);
return FALSE;
}
@@ -191,12 +186,10 @@ static BOOL ssl_scache_dbm_store(void *context, server_rec *s, UCHAR *id, int id
"Cannot store SSL session to DBM file `%s'",
ctx->data_file);
apr_dbm_close(dbm);
- ssl_mutex_off(s);
free(dbmval.dptr);
return FALSE;
}
apr_dbm_close(dbm);
- ssl_mutex_off(s);
/* free temporary buffers */
free(dbmval.dptr);
@@ -231,7 +224,6 @@ static BOOL ssl_scache_dbm_retrieve(void *context, server_rec *s, const UCHAR *i
* XXX: Should we open the dbm against r->pool so the cleanup will
* do the apr_dbm_close? This would make the code a bit cleaner.
*/
- ssl_mutex_on(s);
apr_pool_clear(ctx->pool);
if ((rc = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
SSL_DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
@@ -239,18 +231,15 @@ static BOOL ssl_scache_dbm_retrieve(void *context, server_rec *s, const UCHAR *i
"Cannot open SSLSessionCache DBM file `%s' for reading "
"(fetch)",
ctx->data_file);
- ssl_mutex_off(s);
return FALSE;
}
rc = apr_dbm_fetch(dbm, dbmkey, &dbmval);
if (rc != APR_SUCCESS) {
apr_dbm_close(dbm);
- ssl_mutex_off(s);
return FALSE;
}
if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(time_t)) {
apr_dbm_close(dbm);
- ssl_mutex_off(s);
return FALSE;
}
@@ -258,7 +247,6 @@ static BOOL ssl_scache_dbm_retrieve(void *context, server_rec *s, const UCHAR *i
nData = dbmval.dsize-sizeof(time_t);
if (nData > *destlen) {
apr_dbm_close(dbm);
- ssl_mutex_off(s);
return FALSE;
}
@@ -267,7 +255,6 @@ static BOOL ssl_scache_dbm_retrieve(void *context, server_rec *s, const UCHAR *i
memcpy(dest, (char *)dbmval.dptr + sizeof(time_t), nData);
apr_dbm_close(dbm);
- ssl_mutex_off(s);
/* make sure the stuff is still not expired */
now = time(NULL);
@@ -292,7 +279,6 @@ static void ssl_scache_dbm_remove(void *context, server_rec *s, UCHAR *id, int i
dbmkey.dsize = idlen;
/* and delete it from the DBM file */
- ssl_mutex_on(s);
apr_pool_clear(ctx->pool);
if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
@@ -301,12 +287,10 @@ static void ssl_scache_dbm_remove(void *context, server_rec *s, UCHAR *id, int i
"Cannot open SSLSessionCache DBM file `%s' for writing "
"(delete)",
ctx->data_file);
- ssl_mutex_off(s);
return;
}
apr_dbm_delete(dbm, dbmkey);
apr_dbm_close(dbm);
- ssl_mutex_off(s);
return;
}
@@ -333,10 +317,7 @@ static void ssl_scache_dbm_expire(struct context *ctx, server_rec *s)
*/
tNow = time(NULL);
- ssl_mutex_on(s);
-
if (tNow < ctx->last_expiry + sc->session_cache_timeout) {
- ssl_mutex_off(s);
return;
}
@@ -415,7 +396,6 @@ static void ssl_scache_dbm_expire(struct context *ctx, server_rec *s)
if (keyidx < KEYMAX)
break;
}
- ssl_mutex_off(s);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"Inter-Process Session Cache (DBM) Expiry: "
@@ -437,7 +417,6 @@ static void ssl_scache_dbm_status(void *context, request_rec *r,
nElem = 0;
nSize = 0;
- ssl_mutex_on(r->server);
apr_pool_clear(ctx->pool);
if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
@@ -446,7 +425,6 @@ static void ssl_scache_dbm_status(void *context, request_rec *r,
"Cannot open SSLSessionCache DBM file `%s' for status "
"retrival",
ctx->data_file);
- ssl_mutex_off(r->server);
return;
}
/*
@@ -461,7 +439,6 @@ static void ssl_scache_dbm_status(void *context, request_rec *r,
nSize += dbmval.dsize;
}
apr_dbm_close(dbm);
- ssl_mutex_off(r->server);
if (nSize > 0 && nElem > 0)
nAverage = nSize / nElem;
else
@@ -473,6 +450,8 @@ static void ssl_scache_dbm_status(void *context, request_rec *r,
}
const modssl_sesscache_provider modssl_sesscache_dbm = {
+ "dbm",
+ MODSSL_SESSCACHE_FLAG_NOTMPSAFE,
ssl_scache_dbm_create,
ssl_scache_dbm_init,
ssl_scache_dbm_kill,
diff --git a/modules/ssl/ssl_scache_dc.c b/modules/ssl/ssl_scache_dc.c
index fa0ff5393c..9067db9165 100644
--- a/modules/ssl/ssl_scache_dc.c
+++ b/modules/ssl/ssl_scache_dc.c
@@ -171,6 +171,8 @@ static void ssl_scache_dc_status(void *context, request_rec *r, int flags, apr_p
}
const modssl_sesscache_provider modssl_sesscache_dc = {
+ "distcache",
+ 0,
ssl_scache_dc_create,
ssl_scache_dc_init,
ssl_scache_dc_kill,
diff --git a/modules/ssl/ssl_scache_memcache.c b/modules/ssl/ssl_scache_memcache.c
index 52917e29ca..4622c223f3 100644
--- a/modules/ssl/ssl_scache_memcache.c
+++ b/modules/ssl/ssl_scache_memcache.c
@@ -292,6 +292,8 @@ static void ssl_scache_mc_status(void *context, request_rec *r,
}
const modssl_sesscache_provider modssl_sesscache_mc = {
+ "memcache",
+ 0,
ssl_scache_mc_create,
ssl_scache_mc_init,
ssl_scache_mc_kill,
diff --git a/modules/ssl/ssl_scache_shmcb.c b/modules/ssl/ssl_scache_shmcb.c
index 6c9b114e8c..0eddf23549 100644
--- a/modules/ssl/ssl_scache_shmcb.c
+++ b/modules/ssl/ssl_scache_shmcb.c
@@ -429,33 +429,28 @@ static BOOL ssl_scache_shmcb_store(void *context, server_rec *s,
unsigned char *encoded,
unsigned int len_encoded)
{
- BOOL to_return = FALSE;
struct context *ctx = context;
SHMCBHeader *header = ctx->header;
SHMCBSubcache *subcache = SHMCB_MASK(header, id);
- ssl_mutex_on(s);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"ssl_scache_shmcb_store (0x%02x -> subcache %d)",
SHMCB_MASK_DBG(header, id));
if (idlen < 4) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided "
"(%u bytes)", idlen);
- goto done;
+ return FALSE;
}
if (!shmcb_subcache_store(s, header, subcache, encoded,
len_encoded, id, idlen, timeout)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
"can't store a session!");
- goto done;
+ return FALSE;
}
header->stat_stores++;
- to_return = TRUE;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"leaving ssl_scache_shmcb_store successfully");
-done:
- ssl_mutex_off(s);
- return to_return;
+ return TRUE;
}
static BOOL ssl_scache_shmcb_retrieve(void *context, server_rec *s,
@@ -468,7 +463,6 @@ static BOOL ssl_scache_shmcb_retrieve(void *context, server_rec *s,
SHMCBSubcache *subcache = SHMCB_MASK(header, id);
BOOL rv;
- ssl_mutex_on(s);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"ssl_scache_shmcb_retrieve (0x%02x -> subcache %d)",
SHMCB_MASK_DBG(header, id));
@@ -484,7 +478,6 @@ static BOOL ssl_scache_shmcb_retrieve(void *context, server_rec *s,
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"leaving ssl_scache_shmcb_retrieve successfully");
- ssl_mutex_off(s);
return rv;
}
@@ -495,14 +488,13 @@ static void ssl_scache_shmcb_remove(void *context, server_rec *s,
SHMCBHeader *header = ctx->header;
SHMCBSubcache *subcache = SHMCB_MASK(header, id);
- ssl_mutex_on(s);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"ssl_scache_shmcb_remove (0x%02x -> subcache %d)",
SHMCB_MASK_DBG(header, id));
if (idlen < 4) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided "
"(%u bytes)", idlen);
- goto done;
+ return;
}
if (shmcb_subcache_remove(s, header, subcache, id, idlen))
header->stat_removes_hit++;
@@ -510,8 +502,6 @@ static void ssl_scache_shmcb_remove(void *context, server_rec *s,
header->stat_removes_miss++;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"leaving ssl_scache_shmcb_remove successfully");
-done:
- ssl_mutex_off(s);
}
static void ssl_scache_shmcb_status(void *context, request_rec *r,
@@ -530,7 +520,6 @@ static void ssl_scache_shmcb_status(void *context, request_rec *r,
/* Perform the iteration inside the mutex to avoid corruption or invalid
* pointer arithmetic. The rest of our logic uses read-only header data so
* doesn't need the lock. */
- ssl_mutex_on(s);
/* Iterate over the subcaches */
for (loop = 0; loop < header->subcache_num; loop++) {
SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
@@ -549,7 +538,6 @@ static void ssl_scache_shmcb_status(void *context, request_rec *r,
min_expiry = ((idx_expiry < min_expiry) ? idx_expiry : min_expiry);
}
}
- ssl_mutex_off(s);
index_pct = (100 * total) / (header->index_num *
header->subcache_num);
cache_pct = (100 * cache_total) / (header->subcache_data_size *
@@ -832,6 +820,8 @@ static BOOL shmcb_subcache_remove(server_rec *s, SHMCBHeader *header,
}
const modssl_sesscache_provider modssl_sesscache_shmcb = {
+ "shmcb",
+ MODSSL_SESSCACHE_FLAG_NOTMPSAFE,
ssl_scache_shmcb_create,
ssl_scache_shmcb_init,
ssl_scache_shmcb_kill,