]> granicus.if.org Git - apache/commitdiff
Session cache interface redesign, Part 4:
authorJoe Orton <jorton@apache.org>
Mon, 25 Feb 2008 20:09:38 +0000 (20:09 +0000)
committerJoe Orton <jorton@apache.org>
Mon, 25 Feb 2008 20:09:38 +0000 (20:09 +0000)
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

modules/ssl/ssl_engine_config.c
modules/ssl/ssl_private.h
modules/ssl/ssl_scache.c
modules/ssl/ssl_scache_dbm.c
modules/ssl/ssl_scache_dc.c
modules/ssl/ssl_scache_memcache.c
modules/ssl/ssl_scache_shmcb.c

index 95a4663c6faacfb10ecc044372b54411c24c792e..5194e454a7048f547509b1d4afaba8f0ee3b6e4d 100644 (file)
@@ -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;
 }
 
index c913075647d68fc615aab4e92e3ccbd471621636..62fb206731f64ce174f627dff3825fe5538045c2 100644 (file)
@@ -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. */
index ea944942a2eebee4bb015462a4528552f6f7ac50..948078d124e706fd25b1e5c505e692fd5d491df9 100644 (file)
@@ -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();
index 5723d84752b9ff427439aaf665b5dbb8f2914269..50b5660b0983e9f495e876540d645c7505d642e6 100644 (file)
 
 #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,
index 3330096787166058596645d017b3ae7b83ce85c5..fa0ff5393c380fae66d720f3af6836d705ff58fc 100644 (file)
 */
 
 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,
index 964125e1c8b1b95dce24a228cd1c5cca2c96145a..ed7a5c5260da99e69daacb5ad1ae5394f7339462 100644 (file)
 #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,
index 7c2d633a8a3da2d8c6e474f5932dee927ba53282..d7f5d9c9805fa9cfe8de057ed728f9300134e800 100644 (file)
@@ -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,