* 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;
{
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))) {
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)) ||
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;
}
#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;
/* 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;
}
* 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;
}
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
/* 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;
}
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;
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;
* 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;
}
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;
/* 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;
}
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;
* 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
#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);
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)
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++) {
}
apr_dbm_close(dbm);
- /* destroy temporary pool */
- apr_pool_destroy(p);
-
if (keyidx < KEYMAX)
break;
}
"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;
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;
}
}
const modssl_sesscache_provider modssl_sesscache_dbm = {
+ ssl_scache_dbm_create,
ssl_scache_dbm_init,
ssl_scache_dbm_kill,
ssl_scache_dbm_store,
} SHMCBIndex;
struct context {
+ const char *data_file;
+ apr_size_t shm_size;
apr_shm_t *shm;
SHMCBHeader *header;
};
* 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) {
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;
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) {
}
const modssl_sesscache_provider modssl_sesscache_shmcb = {
+ ssl_scache_shmcb_create,
ssl_scache_shmcb_init,
ssl_scache_shmcb_kill,
ssl_scache_shmcb_store,