diff options
author | Joe Orton <jorton@apache.org> | 2008-02-25 21:09:38 +0100 |
---|---|---|
committer | Joe Orton <jorton@apache.org> | 2008-02-25 21:09:38 +0100 |
commit | 09e2a2f67a00a5102a988f3c3030dc887e27b7fe (patch) | |
tree | e8df105a7bbbcefdff9117ec29eb38d6e3bf310b | |
parent | * modules/ssl/ssl_engine_init.c (ssl_init_FindCAList): Cast return (diff) | |
download | apache2-09e2a2f67a00a5102a988f3c3030dc887e27b7fe.tar.xz apache2-09e2a2f67a00a5102a988f3c3030dc887e27b7fe.zip |
Session cache interface redesign, Part 4:
Move provider-specific configuration handling down into the provider
code. Eliminate all use of SSLModConfigRec within provider code.
* modules/ssl/ssl_private.h (modssl_sesscache_provider): Add 'create'
function which creates and configures the cache provider, before
initialisation. Change 'init' function to take the context pointer
as an input parameter, and reorder to be first.
* modules/ssl/ssl_scache.c (ssl_scache_init): Adjust accordingly.
* modules/ssl/ssl_scache_memcache.c (struct context): Add servers
field.
(ssl_scache_mc_create): New function.
(ssl_scache_mc_init): Use servers from context not SSLModConfigRec.
* modules/ssl/ssl_scache_dbm.c (struct context): Define.
(ssl_scache_dbm_create): New function.
(ssl_scache_dbm_init, ssl_scache_dbm_kill): Adjust to use filename
and pool from context.
(ssl_scache_dbm_store, ssl_scache_dbm_retrieve,
ssl_scache_dbm_status): Use filename from context. Use context pool
for temp storage of the DBM object, and clear before use.
(ssl_scache_dbm_expire): Remove static tLast; use last_expiry from
context. Use context pool for temp storage and clear before use.
* modules/ssl/ssl_scache_dc.c (struct context): Add target field.
(ssl_scache_dc_init, ssl_scache_dc_status): Use target from context.
* modules/ssl/ssl_scache_shmcb.c (struct context): Add data_file,
shm_size fields.
(ssl_scache_shmcb_create): New function; moved argument parsing
logic from ssl_cmd_SSLSessionCache
(ssl_scache_shmcb_init, ssl_scache_shmcb_status): Use config from
context.
* modules/ssl/ssl_engine_config.c (ssl_config_global_create): Remove
handling of old provider-specific fields.
(ssl_cmd_SSLSessionCache): Call provider ->create function to parse
the argument and create provider-specific context structure.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@630974 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | modules/ssl/ssl_engine_config.c | 76 | ||||
-rw-r--r-- | modules/ssl/ssl_private.h | 18 | ||||
-rw-r--r-- | modules/ssl/ssl_scache.c | 2 | ||||
-rw-r--r-- | modules/ssl/ssl_scache_dbm.c | 181 | ||||
-rw-r--r-- | modules/ssl/ssl_scache_dc.c | 40 | ||||
-rw-r--r-- | modules/ssl/ssl_scache_memcache.c | 30 | ||||
-rw-r--r-- | modules/ssl/ssl_scache_shmcb.c | 73 |
7 files changed, 214 insertions, 206 deletions
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index 95a4663c6f..5194e454a7 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -59,8 +59,6 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) * initialize per-module configuration */ mc->nSessionCacheMode = SSL_SCMODE_UNSET; - mc->szSessionCacheDataFile = NULL; - mc->nSessionCacheDataSize = 0; mc->sesscache = NULL; mc->nMutexMode = SSL_MUTEXMODE_UNSET; mc->nMutexMech = APR_LOCK_DEFAULT; @@ -954,7 +952,6 @@ const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd, { SSLModConfigRec *mc = myModConfig(cmd->server); const char *err, *colon; - char *cp, *cp2; int arglen = strlen(arg); if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { @@ -967,21 +964,15 @@ const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd, if (strcEQ(arg, "none")) { mc->nSessionCacheMode = SSL_SCMODE_NONE; - mc->szSessionCacheDataFile = NULL; } else if (strcEQ(arg, "nonenotnull")) { mc->nSessionCacheMode = SSL_SCMODE_NONE_NOT_NULL; - mc->szSessionCacheDataFile = NULL; } else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) { mc->nSessionCacheMode = SSL_SCMODE_DBM; mc->sesscache = &modssl_sesscache_dbm; - mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4); - if (!mc->szSessionCacheDataFile) { - return apr_psprintf(cmd->pool, - "SSLSessionCache: Invalid cache file path %s", - arg+4); - } + err = mc->sesscache->create(&mc->sesscache_context, arg + 4, + cmd->pool, mc->pPool); } else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) || ((arglen > 6) && strcEQn(arg, "shmht:", 6)) || @@ -992,74 +983,37 @@ const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd, mc->nSessionCacheMode = SSL_SCMODE_SHMCB; mc->sesscache = &modssl_sesscache_shmcb; colon = ap_strchr_c(arg, ':'); - mc->szSessionCacheDataFile = - ap_server_root_relative(mc->pPool, colon+1); - if (!mc->szSessionCacheDataFile) { - return apr_psprintf(cmd->pool, - "SSLSessionCache: Invalid cache file path %s", - colon+1); - } - mc->nSessionCacheDataSize = 1024*512; /* 512KB */ - - if ((cp = strchr(mc->szSessionCacheDataFile, '('))) { - *cp++ = NUL; - - if (!(cp2 = strchr(cp, ')'))) { - return "SSLSessionCache: Invalid argument: " - "no closing parenthesis"; - } - - *cp2 = NUL; - - mc->nSessionCacheDataSize = atoi(cp); - - if (mc->nSessionCacheDataSize < 8192) { - return "SSLSessionCache: Invalid argument: " - "size has to be >= 8192 bytes"; - - } - - if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) { - return apr_psprintf(cmd->pool, - "SSLSessionCache: Invalid argument: " - "size has to be < %d bytes on this " - "platform", APR_SHM_MAXSIZE); - - } - } + err = mc->sesscache->create(&mc->sesscache_context, colon + 1, + cmd->pool, mc->pPool); } else if ((arglen > 3) && strcEQn(arg, "dc:", 3)) { #ifdef HAVE_DISTCACHE mc->nSessionCacheMode = SSL_SCMODE_DC; mc->sesscache = &modssl_sesscache_dc; - mc->szSessionCacheDataFile = apr_pstrdup(mc->pPool, arg+3); - if (!mc->szSessionCacheDataFile) { - return apr_pstrcat(cmd->pool, - "SSLSessionCache: Invalid cache file path: ", - arg+3, NULL); - } + err = mc->sesscache->create(&mc->sesscache_context, arg + 3, + cmd->pool, mc->pPool); #else - return "SSLSessionCache: distcache support disabled"; + err = "distcache support disabled"; #endif } else if ((arglen > 3) && strcEQn(arg, "memcache:", 9)) { #ifdef HAVE_SSL_CACHE_MEMCACHE mc->nSessionCacheMode = SSL_SCMODE_MC; mc->sesscache = &modssl_sesscache_mc; - mc->szSessionCacheDataFile = apr_pstrdup(mc->pPool, arg+9); - if (!mc->szSessionCacheDataFile) { - return apr_pstrcat(cmd->pool, - "SSLSessionCache: Invalid memcache config: ", - arg+9, NULL); - } + err = mc->sesscache->create(&mc->sesscache_context, arg + 9, + cmd->pool, mc->pPool); #else - return "SSLSessionCache: memcache support disabled"; + err = "memcache support disabled"; #endif } else { - return "SSLSessionCache: Invalid argument"; + err = "Invalid argument"; } + if (err) { + return apr_psprintf(cmd->pool, "SSLSessionCache: %s", err); + } + return NULL; } diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index c913075647..62fb206731 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -366,10 +366,18 @@ typedef struct { /* Session cache provider vtable. */ typedef struct { - /* Initialize the cache. Return APR error code. The context - * pointer returned in *CONTEXT will be passed as the first - * argument to subsequent invocations. */ - apr_status_t (*init)(server_rec *s, void **context, apr_pool_t *pool); + /* 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 + * should be used for any allocations lasting as long as the + * lifetime of the return context. + * + * The context pointer returned in *CONTEXT will be passed as the + * first argument to subsequent invocations. */ + const char *(*create)(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p); + /* Initialize the cache. Return APR error code. */ + apr_status_t (*init)(void *context, server_rec *s, apr_pool_t *pool); /* Destroy a given cache context. */ void (*destroy)(void *context, server_rec *s); /* Store an object in the cache. */ @@ -398,8 +406,6 @@ typedef struct { apr_pool_t *pPool; BOOL bFixed; int nSessionCacheMode; - char *szSessionCacheDataFile; - int nSessionCacheDataSize; /* The configured provider, and associated private data * structure. */ diff --git a/modules/ssl/ssl_scache.c b/modules/ssl/ssl_scache.c index ea944942a2..948078d124 100644 --- a/modules/ssl/ssl_scache.c +++ b/modules/ssl/ssl_scache.c @@ -67,7 +67,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p) return; } - rv = mc->sesscache->init(s, &mc->sesscache_context, p); + rv = mc->sesscache->init(mc->sesscache_context, s, p); if (rv) { /* ABORT ABORT etc. */ ssl_die(); diff --git a/modules/ssl/ssl_scache_dbm.c b/modules/ssl/ssl_scache_dbm.c index 5723d84752..50b5660b09 100644 --- a/modules/ssl/ssl_scache_dbm.c +++ b/modules/ssl/ssl_scache_dbm.c @@ -26,19 +26,43 @@ #include "ssl_private.h" -static void ssl_scache_dbm_expire(void *context, server_rec *s); +/* Use of the context structure must be thread-safe after the initial + * create/init; callers must hold the mutex. */ +struct context { + const char *data_file; + /* Pool must only be used with the mutex held. */ + apr_pool_t *pool; + time_t last_expiry; +}; + +static void ssl_scache_dbm_expire(struct context *ctx, server_rec *s); static void ssl_scache_dbm_remove(void *context, server_rec *s, UCHAR *id, int idlen, apr_pool_t *p); -static apr_status_t ssl_scache_dbm_init(server_rec *s, void **context, apr_pool_t *p) +static const char *ssl_scache_dbm_create(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p) +{ + struct context *ctx; + + *context = ctx = apr_pcalloc(p, sizeof *ctx); + + ctx->data_file = ap_server_root_relative(p, arg); + if (!ctx->data_file) { + return apr_psprintf(tmp, "Invalid cache file path %s", arg); + } + + return NULL; +} + +static apr_status_t ssl_scache_dbm_init(void *context, server_rec *s, apr_pool_t *p) { - SSLModConfigRec *mc = myModConfig(s); + struct context *ctx = context; apr_dbm_t *dbm; apr_status_t rv; /* for the DBM we need the data file */ - if (mc->szSessionCacheDataFile == NULL) { + if (ctx->data_file == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); return APR_EINVAL; @@ -46,11 +70,13 @@ static apr_status_t ssl_scache_dbm_init(server_rec *s, void **context, apr_pool_ /* open it once to create it and to make sure it _can_ be created */ ssl_mutex_on(s); - if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, - APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { + apr_pool_clear(ctx->pool); + + if ((rv = apr_dbm_open(&dbm, ctx->data_file, + APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot create SSLSessionCache DBM file `%s'", - mc->szSessionCacheDataFile); + ctx->data_file); ssl_mutex_off(s); return rv; } @@ -63,46 +89,42 @@ static apr_status_t ssl_scache_dbm_init(server_rec *s, void **context, apr_pool_ * cannot exactly determine the suffixes we try all possibilities. */ if (geteuid() == 0 /* is superuser */) { - chown(mc->szSessionCacheDataFile, unixd_config.user_id, -1 /* no gid change */); - if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL), + chown(ctx->data_file, unixd_config.user_id, -1 /* no gid change */); + if (chown(apr_pstrcat(p, ctx->data_file, SSL_DBM_FILE_SUFFIX_DIR, NULL), unixd_config.user_id, -1) == -1) { - if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL), + if (chown(apr_pstrcat(p, ctx->data_file, ".db", NULL), unixd_config.user_id, -1) == -1) - chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL), + chown(apr_pstrcat(p, ctx->data_file, ".dir", NULL), unixd_config.user_id, -1); } - if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL), + if (chown(apr_pstrcat(p, ctx->data_file, SSL_DBM_FILE_SUFFIX_PAG, NULL), unixd_config.user_id, -1) == -1) { - if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL), + if (chown(apr_pstrcat(p, ctx->data_file, ".db", NULL), unixd_config.user_id, -1) == -1) - chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL), + chown(apr_pstrcat(p, ctx->data_file, ".pag", NULL), unixd_config.user_id, -1); } } #endif ssl_mutex_off(s); - ssl_scache_dbm_expire(context, s); + ssl_scache_dbm_expire(ctx, s); return APR_SUCCESS; } static void ssl_scache_dbm_kill(void *context, server_rec *s) { - SSLModConfigRec *mc = myModConfig(s); - apr_pool_t *p; - - apr_pool_create_ex(&p, mc->pPool, NULL, NULL); - if (p != NULL) { - /* the correct way */ - unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL)); - unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL)); - /* the additional ways to be sure */ - unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL)); - unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL)); - unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL)); - unlink(mc->szSessionCacheDataFile); - apr_pool_destroy(p); - } + struct context *ctx = context; + + /* the correct way */ + unlink(apr_pstrcat(ctx->pool, ctx->data_file, SSL_DBM_FILE_SUFFIX_DIR, NULL)); + unlink(apr_pstrcat(ctx->pool, ctx->data_file, SSL_DBM_FILE_SUFFIX_PAG, NULL)); + /* the additional ways to be sure */ + unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".dir", NULL)); + unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".pag", NULL)); + unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".db", NULL)); + unlink(ctx->data_file); + return; } @@ -110,16 +132,11 @@ static BOOL ssl_scache_dbm_store(void *context, server_rec *s, UCHAR *id, int id time_t expiry, unsigned char *ucaData, unsigned int nData) { - SSLModConfigRec *mc = myModConfig(s); + struct context *ctx = context; apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; apr_status_t rv; - apr_pool_t *p; - - /* ### This is not in any way sane, a persistent pool which gets - * cleared each time is needed. */ - apr_pool_create(&p, s->process->pool); /* be careful: do not try to store too much bytes in a DBM file! */ #ifdef PAIRMAX @@ -155,36 +172,35 @@ static BOOL ssl_scache_dbm_store(void *context, server_rec *s, UCHAR *id, int id /* and store it to the DBM file */ ssl_mutex_on(s); - if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, - APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, p)) != APR_SUCCESS) { + apr_pool_clear(ctx->pool); + + if ((rv = apr_dbm_open(&dbm, ctx->data_file, + APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot open SSLSessionCache DBM file `%s' for writing " "(store)", - mc->szSessionCacheDataFile); + ctx->data_file); ssl_mutex_off(s); - apr_pool_destroy(p); free(dbmval.dptr); return FALSE; } if ((rv = apr_dbm_store(dbm, dbmkey, dbmval)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot store SSL session to DBM file `%s'", - mc->szSessionCacheDataFile); + ctx->data_file); apr_dbm_close(dbm); ssl_mutex_off(s); - apr_pool_destroy(p); free(dbmval.dptr); return FALSE; } apr_dbm_close(dbm); ssl_mutex_off(s); - apr_pool_destroy(p); /* free temporary buffers */ free(dbmval.dptr); /* allow the regular expiring to occur */ - ssl_scache_dbm_expire(context, s); + ssl_scache_dbm_expire(ctx, s); return TRUE; } @@ -193,7 +209,7 @@ static BOOL ssl_scache_dbm_retrieve(void *context, server_rec *s, const UCHAR *i unsigned char *dest, unsigned int *destlen, apr_pool_t *p) { - SSLModConfigRec *mc = myModConfig(s); + struct context *ctx = context; apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; @@ -203,7 +219,7 @@ static BOOL ssl_scache_dbm_retrieve(void *context, server_rec *s, const UCHAR *i apr_status_t rc; /* allow the regular expiring to occur */ - ssl_scache_dbm_expire(context, s); + ssl_scache_dbm_expire(ctx, s); /* create DBM key and values */ dbmkey.dptr = (char *)id; @@ -214,12 +230,13 @@ static BOOL ssl_scache_dbm_retrieve(void *context, server_rec *s, const UCHAR *i * do the apr_dbm_close? This would make the code a bit cleaner. */ ssl_mutex_on(s); - if ((rc = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, - APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, p)) != APR_SUCCESS) { + 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) { ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, "Cannot open SSLSessionCache DBM file `%s' for reading " "(fetch)", - mc->szSessionCacheDataFile); + ctx->data_file); ssl_mutex_off(s); return FALSE; } @@ -263,7 +280,7 @@ static BOOL ssl_scache_dbm_retrieve(void *context, server_rec *s, const UCHAR *i static void ssl_scache_dbm_remove(void *context, server_rec *s, UCHAR *id, int idlen, apr_pool_t *p) { - SSLModConfigRec *mc = myModConfig(s); + struct context *ctx = context; apr_dbm_t *dbm; apr_datum_t dbmkey; apr_status_t rv; @@ -274,12 +291,12 @@ static void ssl_scache_dbm_remove(void *context, server_rec *s, UCHAR *id, int i /* and delete it from the DBM file */ ssl_mutex_on(s); - if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, + if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, p)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot open SSLSessionCache DBM file `%s' for writing " "(delete)", - mc->szSessionCacheDataFile); + ctx->data_file); ssl_mutex_off(s); return; } @@ -290,15 +307,12 @@ static void ssl_scache_dbm_remove(void *context, server_rec *s, UCHAR *id, int i return; } -static void ssl_scache_dbm_expire(void *context, server_rec *s) +static void ssl_scache_dbm_expire(struct context *ctx, server_rec *s) { - SSLModConfigRec *mc = myModConfig(s); SSLSrvConfigRec *sc = mySrvConfig(s); - static time_t tLast = 0; apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; - apr_pool_t *p; time_t tExpiresAt; int nElements = 0; int nDeleted = 0; @@ -314,9 +328,15 @@ static void ssl_scache_dbm_expire(void *context, server_rec *s) * cache entries is done only from time to time */ tNow = time(NULL); - if (tNow < tLast+sc->session_cache_timeout) + + ssl_mutex_on(s); + + if (tNow < ctx->last_expiry + sc->session_cache_timeout) { + ssl_mutex_off(s); return; - tLast = tNow; + } + + ctx->last_expiry = tNow; /* * Here we have to be very carefully: Not all DBM libraries are @@ -331,27 +351,22 @@ static void ssl_scache_dbm_expire(void *context, server_rec *s) #define KEYMAX 1024 - ssl_mutex_on(s); for (;;) { /* allocate the key array in a memory sub pool */ - apr_pool_create_ex(&p, mc->pPool, NULL, NULL); - if (p == NULL) - break; - if ((keylist = apr_palloc(p, sizeof(dbmkey)*KEYMAX)) == NULL) { - apr_pool_destroy(p); + apr_pool_clear(ctx->pool); + + if ((keylist = apr_palloc(ctx->pool, sizeof(dbmkey)*KEYMAX)) == NULL) { break; } /* pass 1: scan DBM database */ keyidx = 0; - if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, - APR_DBM_RWCREATE,SSL_DBM_FILE_MODE, - p)) != APR_SUCCESS) { + if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE, + SSL_DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot open SSLSessionCache DBM file `%s' for " "scanning", - mc->szSessionCacheDataFile); - apr_pool_destroy(p); + ctx->data_file); break; } apr_dbm_firstkey(dbm, &dbmkey); @@ -367,7 +382,7 @@ static void ssl_scache_dbm_expire(void *context, server_rec *s) bDelete = TRUE; } if (bDelete) { - if ((keylist[keyidx].dptr = apr_pmemdup(p, dbmkey.dptr, dbmkey.dsize)) != NULL) { + if ((keylist[keyidx].dptr = apr_pmemdup(ctx->pool, dbmkey.dptr, dbmkey.dsize)) != NULL) { keylist[keyidx].dsize = dbmkey.dsize; keyidx++; if (keyidx == KEYMAX) @@ -379,13 +394,12 @@ static void ssl_scache_dbm_expire(void *context, server_rec *s) apr_dbm_close(dbm); /* pass 2: delete expired elements */ - if (apr_dbm_open(&dbm, mc->szSessionCacheDataFile, - APR_DBM_RWCREATE,SSL_DBM_FILE_MODE, p) != APR_SUCCESS) { + if (apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE, + SSL_DBM_FILE_MODE, ctx->pool) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot re-open SSLSessionCache DBM file `%s' for " "expiring", - mc->szSessionCacheDataFile); - apr_pool_destroy(p); + ctx->data_file); break; } for (i = 0; i < keyidx; i++) { @@ -394,9 +408,6 @@ static void ssl_scache_dbm_expire(void *context, server_rec *s) } apr_dbm_close(dbm); - /* destroy temporary pool */ - apr_pool_destroy(p); - if (keyidx < KEYMAX) break; } @@ -406,13 +417,12 @@ static void ssl_scache_dbm_expire(void *context, server_rec *s) "Inter-Process Session Cache (DBM) Expiry: " "old: %d, new: %d, removed: %d", nElements, nElements-nDeleted, nDeleted); - return; } static void ssl_scache_dbm_status(void *context, request_rec *r, int flags, apr_pool_t *p) { - SSLModConfigRec *mc = myModConfig(r->server); + struct context *ctx = context; apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; @@ -424,16 +434,14 @@ static void ssl_scache_dbm_status(void *context, request_rec *r, nElem = 0; nSize = 0; ssl_mutex_on(r->server); - /* - * XXX - Check what pool is to be used - TBD - */ - if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, - APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, - mc->pPool)) != APR_SUCCESS) { + + apr_pool_clear(ctx->pool); + if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE, + SSL_DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "Cannot open SSLSessionCache DBM file `%s' for status " "retrival", - mc->szSessionCacheDataFile); + ctx->data_file); ssl_mutex_off(r->server); return; } @@ -461,6 +469,7 @@ static void ssl_scache_dbm_status(void *context, request_rec *r, } const modssl_sesscache_provider modssl_sesscache_dbm = { + ssl_scache_dbm_create, ssl_scache_dbm_init, ssl_scache_dbm_kill, ssl_scache_dbm_store, diff --git a/modules/ssl/ssl_scache_dc.c b/modules/ssl/ssl_scache_dc.c index 3330096787..fa0ff5393c 100644 --- a/modules/ssl/ssl_scache_dc.c +++ b/modules/ssl/ssl_scache_dc.c @@ -49,22 +49,28 @@ */ struct context { + /* Configured target server: */ + const char *target; + /* distcache client context: */ DC_CTX *dc; }; -static apr_status_t ssl_scache_dc_init(server_rec *s, void **context, apr_pool_t *p) +static const char *ssl_scache_dc_create(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p) { - DC_CTX *dc; - SSLModConfigRec *mc = myModConfig(s); struct context *ctx; - /* - * Create a session context - */ - if (mc->szSessionCacheDataFile == NULL) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); - return APR_EINVAL; - } + ctx = *context = apr_palloc(p, sizeof *ctx); + + ctx->target = apr_pstrdup(p, arg); + + return NULL; +} + +static apr_status_t ssl_scache_dc_init(void *context, server_rec *s, apr_pool_t *p) +{ + struct context *ctx = ctx; + #if 0 /* If a "persistent connection" mode of operation is preferred, you *must* * also use the PIDCHECK flag to ensure fork()'d processes don't interlace @@ -81,17 +87,12 @@ static apr_status_t ssl_scache_dc_init(server_rec *s, void **context, apr_pool_t * performance/stability danger of file-descriptor bloatage. */ #define SESSION_CTX_FLAGS 0 #endif - dc = DC_CTX_new(mc->szSessionCacheDataFile, SESSION_CTX_FLAGS); - if (!dc) { + ctx->dc = DC_CTX_new(ctx->target, SESSION_CTX_FLAGS); + if (!ctx->dc) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache failed to obtain context"); return APR_EGENERAL; } ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "distributed scache context initialised"); - /* - * Success ... - */ - ctx = *context = apr_palloc(p, sizeof *ctx); - ctx->dc = dc; return APR_SUCCESS; } @@ -161,15 +162,16 @@ static void ssl_scache_dc_remove(void *context, server_rec *s, static void ssl_scache_dc_status(void *context, request_rec *r, int flags, apr_pool_t *pool) { - SSLModConfigRec *mc = myModConfig(r->server); + struct context *ctx = context; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "distributed scache 'ssl_scache_dc_status'"); ap_rprintf(r, "cache type: <b>DC (Distributed Cache)</b>, " - " target: <b>%s</b><br>", mc->szSessionCacheDataFile); + " target: <b>%s</b><br>", ctx->target); } const modssl_sesscache_provider modssl_sesscache_dc = { + ssl_scache_dc_create, ssl_scache_dc_init, ssl_scache_dc_kill, ssl_scache_dc_store, diff --git a/modules/ssl/ssl_scache_memcache.c b/modules/ssl/ssl_scache_memcache.c index 964125e1c8..ed7a5c5260 100644 --- a/modules/ssl/ssl_scache_memcache.c +++ b/modules/ssl/ssl_scache_memcache.c @@ -68,10 +68,23 @@ #endif struct context { + const char *servers; apr_memcache_t *mc; }; -static apr_status_t ssl_scache_mc_init(server_rec *s, void **context, apr_pool_t *p) +static const char *ssl_scache_mc_create(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p) +{ + struct context *ctx; + + *context = ctx = apr_palloc(p, sizeof *ctx); + + ctx->servers = apr_pstrdup(p, arg); + + return NULL; +} + +static apr_status_t ssl_scache_mc_init(void *context, server_rec *s, apr_pool_t *p) { apr_status_t rv; int thread_limit = 0; @@ -79,18 +92,12 @@ static apr_status_t ssl_scache_mc_init(server_rec *s, void **context, apr_pool_t char *cache_config; char *split; char *tok; - SSLModConfigRec *mc = myModConfig(s); - struct context *ctx = apr_palloc(p, sizeof *ctx); + struct context *ctx = context; ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); - if (mc->szSessionCacheDataFile == NULL) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); - return APR_EINVAL; - } - /* Find all the servers in the first run to get a total count */ - cache_config = apr_pstrdup(p, mc->szSessionCacheDataFile); + cache_config = apr_pstrdup(p, ctx->servers); split = apr_strtok(cache_config, ",", &tok); while (split) { nservers++; @@ -106,7 +113,7 @@ static apr_status_t ssl_scache_mc_init(server_rec *s, void **context, apr_pool_t } /* Now add each server to the memcache */ - cache_config = apr_pstrdup(p, mc->szSessionCacheDataFile); + cache_config = apr_pstrdup(p, ctx->servers); split = apr_strtok(cache_config, ",", &tok); while (split) { apr_memcache_server_t *st; @@ -157,8 +164,6 @@ static apr_status_t ssl_scache_mc_init(server_rec *s, void **context, apr_pool_t split = apr_strtok(NULL,",", &tok); } - *context = ctx; - return APR_SUCCESS; } @@ -287,6 +292,7 @@ static void ssl_scache_mc_status(void *context, request_rec *r, } const modssl_sesscache_provider modssl_sesscache_mc = { + ssl_scache_mc_create, ssl_scache_mc_init, ssl_scache_mc_kill, ssl_scache_mc_store, diff --git a/modules/ssl/ssl_scache_shmcb.c b/modules/ssl/ssl_scache_shmcb.c index 7c2d633a8a..d7f5d9c980 100644 --- a/modules/ssl/ssl_scache_shmcb.c +++ b/modules/ssl/ssl_scache_shmcb.c @@ -87,6 +87,8 @@ typedef struct { } SHMCBIndex; struct context { + const char *data_file; + apr_size_t shm_size; apr_shm_t *shm; SHMCBHeader *header; }; @@ -250,42 +252,71 @@ static BOOL shmcb_subcache_remove(server_rec *, SHMCBHeader *, SHMCBSubcache *, * subcache internals are deferred to shmcb_subcache_*** functions lower down */ -static apr_status_t ssl_scache_shmcb_init(server_rec *s, void **context, - apr_pool_t *p) +static const char *ssl_scache_shmcb_create(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p) +{ + struct context *ctx; + char *path, *cp, *cp2; + + /* Allocate the context. */ + *context = ctx = apr_pcalloc(p, sizeof *ctx); + + ctx->data_file = path = ap_server_root_relative(p, arg); + ctx->shm_size = 1024*512; /* 512KB */ + + cp = strchr(path, '('); + if (cp) { + *cp++ = NUL; + + if (!(cp2 = strchr(cp, ')'))) { + return "Invalid argument: no closing parenthesis"; + } + + *cp2 = NUL; + + ctx->shm_size = atoi(cp); + + if (ctx->shm_size < 8192) { + return "Invalid argument: size has to be >= 8192 bytes"; + + } + + if (ctx->shm_size >= APR_SHM_MAXSIZE) { + return apr_psprintf(tmp, + "Invalid argument: size has " + "to be < %d bytes on this platform", + APR_SHM_MAXSIZE); + + } + } + + return NULL; +} + +static apr_status_t ssl_scache_shmcb_init(void *context, server_rec *s, apr_pool_t *p) { - SSLModConfigRec *mc = myModConfig(s); void *shm_segment; apr_size_t shm_segsize; apr_status_t rv; SHMCBHeader *header; unsigned int num_subcache, num_idx, loop; - struct context *ctx; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "POOL %p %p", mc->pPool, p); - - /* Allocate the context. */ - *context = ctx = apr_pcalloc(p, sizeof *ctx); + struct context *ctx = context; /* Create shared memory segment */ - if (mc->szSessionCacheDataFile == NULL) { + if (ctx->data_file == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); return APR_EINVAL; } /* Use anonymous shm by default, fall back on name-based. */ - rv = apr_shm_create(&ctx->shm, mc->nSessionCacheDataSize, - NULL, mc->pPool); + rv = apr_shm_create(&ctx->shm, ctx->shm_size, NULL, p); if (APR_STATUS_IS_ENOTIMPL(rv)) { /* For a name-based segment, remove it first in case of a * previous unclean shutdown. */ - apr_shm_remove(mc->szSessionCacheDataFile, mc->pPool); + apr_shm_remove(ctx->data_file, p); - rv = apr_shm_create(&ctx->shm, - mc->nSessionCacheDataSize, - mc->szSessionCacheDataFile, - mc->pPool); + rv = apr_shm_create(&ctx->shm, ctx->shm_size, ctx->data_file, p); } if (rv != APR_SUCCESS) { @@ -487,7 +518,6 @@ static void ssl_scache_shmcb_status(void *context, request_rec *r, int flags, apr_pool_t *p) { server_rec *s = r->server; - SSLModConfigRec *mc = myModConfig(s); struct context *ctx = context; SHMCBHeader *header = ctx->header; unsigned int loop, total = 0, cache_total = 0, non_empty_subcaches = 0; @@ -525,9 +555,9 @@ static void ssl_scache_shmcb_status(void *context, request_rec *r, cache_pct = (100 * cache_total) / (header->subcache_data_size * header->subcache_num); /* Generate HTML */ - ap_rprintf(r, "cache type: <b>SHMCB</b>, shared memory: <b>%d</b> " + ap_rprintf(r, "cache type: <b>SHMCB</b>, shared memory: <b>%" APR_SIZE_T_FMT "</b> " "bytes, current sessions: <b>%d</b><br>", - mc->nSessionCacheDataSize, total); + ctx->shm_size, total); ap_rprintf(r, "subcaches: <b>%d</b>, indexes per subcache: <b>%d</b><br>", header->subcache_num, header->index_num); if (non_empty_subcaches) { @@ -802,6 +832,7 @@ static BOOL shmcb_subcache_remove(server_rec *s, SHMCBHeader *header, } const modssl_sesscache_provider modssl_sesscache_shmcb = { + ssl_scache_shmcb_create, ssl_scache_shmcb_init, ssl_scache_shmcb_kill, ssl_scache_shmcb_store, |