summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/ssl/config.m4128
-rw-r--r--modules/ssl/mod_ssl.c30
-rw-r--r--modules/ssl/ssl_engine_config.c8
-rw-r--r--modules/ssl/ssl_engine_mutex.c4
-rw-r--r--modules/ssl/ssl_private.h93
-rw-r--r--modules/ssl/ssl_scache.c4
-rw-r--r--modules/ssl/ssl_scache_dbm.c465
-rw-r--r--modules/ssl/ssl_scache_dc.c188
-rw-r--r--modules/ssl/ssl_scache_memcache.c306
-rw-r--r--modules/ssl/ssl_scache_shmcb.c833
10 files changed, 11 insertions, 2048 deletions
diff --git a/modules/ssl/config.m4 b/modules/ssl/config.m4
index f95e1d4b27..841dbf1f61 100644
--- a/modules/ssl/config.m4
+++ b/modules/ssl/config.m4
@@ -13,128 +13,6 @@ dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dnl See the License for the specific language governing permissions and
dnl limitations under the License.
-AC_DEFUN([CHECK_DISTCACHE], [
- AC_MSG_CHECKING(whether Distcache is required)
- ap_ssltk_dc="no"
- tmp_nomessage=""
- tmp_forced="no"
- AC_ARG_ENABLE(distcache,
- APACHE_HELP_STRING(--enable-distcache,Select distcache support in mod_ssl),
- ap_ssltk_dc="$enableval"
- tmp_nomessage=""
- tmp_forced="yes"
- if test "x$ap_ssltk_dc" = "x"; then
- ap_ssltk_dc="yes"
- dnl our "error"s become "tests revealed that..."
- tmp_forced="no"
- fi
- if test "$ap_ssltk_dc" != "yes" -a "$ap_ssltk_dc" != "no"; then
- tmp_nomessage="--enable-distcache had illegal syntax - disabling"
- ap_ssltk_dc="no"
- fi)
- if test "$tmp_forced" = "no"; then
- AC_MSG_RESULT($ap_ssltk_dc (default))
- else
- AC_MSG_RESULT($ap_ssltk_dc (specified))
- fi
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno" -a "x$tmp_nomessage" != "x"; then
- AC_MSG_ERROR(distcache support failed: $tmp_nomessage)
- fi
- if test "$ap_ssltk_dc" = "yes"; then
- AC_CHECK_HEADER(
- [distcache/dc_client.h],
- [],
- [tmp_nomessage="can't include distcache headers"
- ap_ssltk_dc="no"])
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then
- AC_MSG_ERROR(distcache support failed: $tmp_nomessage)
- fi
- fi
- if test "$ap_ssltk_dc" = "yes"; then
- AC_MSG_CHECKING(for Distcache version)
- AC_TRY_COMPILE(
-[#include <distcache/dc_client.h>],
-[#if DISTCACHE_CLIENT_API != 0x0001
-#error "distcache API version is unrecognised"
-#endif],
-[],
-[tmp_nomessage="distcache has an unsupported API version"
-ap_ssltk_dc="no"])
- AC_MSG_RESULT($ap_ssltk_dc)
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then
- AC_MSG_ERROR(distcache support failed: $tmp_nomessage)
- fi
- fi
- if test "$ap_ssltk_dc" = "yes"; then
- AC_MSG_CHECKING(for Distcache libraries)
- save_libs=$LIBS
- LIBS="$LIBS -ldistcache -lnal"
- AC_TRY_LINK(
- [#include <distcache/dc_client.h>],
- [DC_CTX *foo = DC_CTX_new((const char *)0,0);],
- [],
- [tmp_no_message="failed to link with distcache libraries"
- ap_ssltk_dc="no"])
- LIBS=$save_libs
- AC_MSG_RESULT($ap_ssltk_dc)
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then
- AC_MSG_ERROR(distcache support failed: $tmp_nomessage)
- else
- APR_ADDTO(MOD_SSL_LDADD, [-ldistcache -lnal])
- AC_DEFINE(HAVE_DISTCACHE, 1, [Define if distcache support is enabled])
- fi
- fi
-])
-
-
-
-AC_DEFUN([CHECK_SSL_MEMCACHE], [
- AC_MSG_CHECKING(for ssl session caching in memcache)
- ap_ssltk_mc="no"
- tmp_nomessage=""
- tmp_forced="no"
- AC_ARG_ENABLE(ssl-memcache,
- APACHE_HELP_STRING(--enable-ssl-memcache,Select memcache support in mod_ssl),
- ap_ssltk_mc="$enableval"
- tmp_nomessage=""
- tmp_forced="yes"
- if test "x$ap_ssltk_mc" = "x"; then
- ap_ssltk_mc="yes"
- dnl our "error"s become "tests revealed that..."
- tmp_forced="no"
- fi
- if test "$ap_ssltk_mc" != "yes" -a "$ap_ssltk_mc" != "no"; then
- tmp_nomessage="--enable-ssl-cache-memcache had illegal syntax - disabling"
- ap_ssltk_mc="no"
- fi)
- if test "$tmp_forced" = "no"; then
- AC_MSG_RESULT($ap_ssltk_mc (default))
- else
- AC_MSG_RESULT($ap_ssltk_mc (specified))
- fi
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_mc" = "xno" -a "x$tmp_nomessage" != "x"; then
- AC_MSG_ERROR(ssl memcache support failed: $tmp_nomessage)
- fi
- if test "$ap_ssltk_mc" = "yes"; then
- save_cpp=$CPPFLAGS
- CPPFLAGS="$CPPFLAGS $APR_INCLUDES $APU_INCLUDES"
- AC_CHECK_HEADER(
- [apr_memcache.h],
- [],
- [tmp_nomessage="can't include apr_memcache headers"
- ap_ssltk_mc="no"])
-
- CPPFLAGS=$save_cpp
-
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_mc" = "xno"; then
- AC_MSG_ERROR(ssl memcache support failed: $tmp_nomessage)
- fi
- fi
- if test "$ap_ssltk_mc" = "yes"; then
- AC_DEFINE(HAVE_SSL_CACHE_MEMCACHE, 1, [Define if ssl-memcache support is enabled])
- fi
-])
-
AC_DEFUN([CHECK_OCSP], [
AC_CHECK_HEADERS(openssl/ocsp.h,
[AC_DEFINE([HAVE_OCSP], 1, [Define if OCSP is supported by OpenSSL])]
@@ -162,10 +40,6 @@ ssl_expr_eval.lo dnl
ssl_expr_parse.lo dnl
ssl_expr_scan.lo dnl
ssl_scache.lo dnl
-ssl_scache_dbm.lo dnl
-ssl_scache_shmcb.lo dnl
-ssl_scache_dc.lo dnl
-ssl_scache_memcache.lo dnl
ssl_util.lo dnl
ssl_util_ssl.lo dnl
ssl_engine_ocsp.lo dnl
@@ -175,8 +49,6 @@ dnl # hook module into the Autoconf mechanism (--enable-ssl option)
APACHE_MODULE(ssl, [SSL/TLS support (mod_ssl)], $ssl_objs, , no, [
APACHE_CHECK_SSL_TOOLKIT
APR_SETVAR(MOD_SSL_LDADD, [\$(SSL_LIBS)])
- CHECK_DISTCACHE
- CHECK_SSL_MEMCACHE
CHECK_OCSP
if test "x$enable_ssl" = "xshared"; then
# The only symbol which needs to be exported is the module
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index 379c827471..43d031d884 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -454,34 +454,6 @@ static int ssl_hook_pre_connection(conn_rec *c, void *csd)
return ssl_init_ssl_connection(c, NULL);
}
-/* Register all session cache providers. */
-static void modssl_register_scache(apr_pool_t *p)
-{
- /* shmcb is a cache of many names. */
- ap_register_provider(p, MODSSL_SESSCACHE_PROVIDER_GROUP, "shmcb",
- MODSSL_SESSCACHE_PROVIDER_VERSION,
- &modssl_sesscache_shmcb);
- ap_register_provider(p, MODSSL_SESSCACHE_PROVIDER_GROUP, "shmht",
- MODSSL_SESSCACHE_PROVIDER_VERSION,
- &modssl_sesscache_shmcb);
- ap_register_provider(p, MODSSL_SESSCACHE_PROVIDER_GROUP, "shm",
- MODSSL_SESSCACHE_PROVIDER_VERSION,
- &modssl_sesscache_shmcb);
- ap_register_provider(p, MODSSL_SESSCACHE_PROVIDER_GROUP, "dbm",
- MODSSL_SESSCACHE_PROVIDER_VERSION,
- &modssl_sesscache_dbm);
-#ifdef HAVE_DISTCACHE
- ap_register_provider(p, MODSSL_SESSCACHE_PROVIDER_GROUP, "dc",
- MODSSL_SESSCACHE_PROVIDER_VERSION,
- &modssl_sesscache_dc);
-#endif
-#ifdef HAVE_SSL_CACHE_MEMCACHE
- ap_register_provider(p, MODSSL_SESSCACHE_PROVIDER_GROUP, "mc",
- MODSSL_SESSCACHE_PROVIDER_VERSION,
- &modssl_sesscache_mc);
-#endif
-}
-
/*
* the module registration phase
*/
@@ -512,8 +484,6 @@ static void ssl_register_hooks(apr_pool_t *p)
ssl_var_register(p);
- modssl_register_scache(p);
-
APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
}
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index 18acb83c77..1a9ed212eb 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -985,9 +985,9 @@ const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
char *name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
/* Find the provider of given name. */
- mc->sesscache = ap_lookup_provider(MODSSL_SESSCACHE_PROVIDER_GROUP,
+ mc->sesscache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
name,
- MODSSL_SESSCACHE_PROVIDER_VERSION);
+ AP_SOCACHE_PROVIDER_VERSION);
if (mc->sesscache) {
/* Cache found; create it, passing anything beyond the colon. */
mc->sesscache_mode = enabled_flags;
@@ -1001,8 +1001,8 @@ const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
/* Build a comma-separated list of all registered provider
* names: */
name_list = ap_list_provider_names(cmd->pool,
- MODSSL_SESSCACHE_PROVIDER_GROUP,
- MODSSL_SESSCACHE_PROVIDER_VERSION);
+ AP_SOCACHE_PROVIDER_GROUP,
+ AP_SOCACHE_PROVIDER_VERSION);
all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
err = apr_psprintf(cmd->pool, "'%s' session cache not supported "
diff --git a/modules/ssl/ssl_engine_mutex.c b/modules/ssl/ssl_engine_mutex.c
index 649c324311..533a25289d 100644
--- a/modules/ssl/ssl_engine_mutex.c
+++ b/modules/ssl/ssl_engine_mutex.c
@@ -43,7 +43,7 @@ int ssl_mutex_init(server_rec *s, apr_pool_t *p)
* the provider used is not internally multi-process/thread
* safe. */
if (!mc->sesscache
- || (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) == 0) {
+ || (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) == 0) {
return TRUE;
}
@@ -88,7 +88,7 @@ int ssl_mutex_reinit(server_rec *s, apr_pool_t *p)
apr_status_t rv;
if (mc->nMutexMode == SSL_MUTEXMODE_NONE || !mc->sesscache
- || (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) == 0) {
+ || (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) == 0) {
return TRUE;
}
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index a28471403a..1bbbcb2ab9 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -48,11 +48,9 @@
#include "apr_lib.h"
#include "apr_fnmatch.h"
#include "apr_strings.h"
-#include "apr_dbm.h"
-#include "apr_rmm.h"
-#include "apr_shm.h"
#include "apr_global_mutex.h"
#include "apr_optional.h"
+#include "ap_socache.h"
#define MOD_SSL_VERSION AP_SERVER_BASEREVISION
@@ -159,25 +157,6 @@ typedef enum {
#define SSL_MM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
/**
- * Support for DBM library
- */
-#define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
-
-#if !defined(SSL_DBM_FILE_SUFFIX_DIR) && !defined(SSL_DBM_FILE_SUFFIX_PAG)
-#if defined(DBM_SUFFIX)
-#define SSL_DBM_FILE_SUFFIX_DIR DBM_SUFFIX
-#define SSL_DBM_FILE_SUFFIX_PAG DBM_SUFFIX
-#elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM))
-#define SSL_DBM_FILE_SUFFIX_DIR ".db"
-#define SSL_DBM_FILE_SUFFIX_PAG ".db"
-#else
-#define SSL_DBM_FILE_SUFFIX_DIR ".dir"
-#define SSL_DBM_FILE_SUFFIX_PAG ".pag"
-#endif
-#endif
-
-
-/**
* Define the certificate algorithm types
*/
@@ -351,59 +330,6 @@ typedef struct {
int non_ssl_request;
} SSLConnRec;
-#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
- * 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. */
- apr_status_t (*store)(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- time_t expiry,
- unsigned char *data, unsigned int datalen);
- /* Retrieve cached data with key ID of length IDLEN,
- * returning TRUE on success or FALSE otherwise. If
- * TRUE, the data must be placed in DEST, which has length
- * on entry of *DESTLEN. *DESTLEN must be updated to
- * equal the length of data written on exit. */
- apr_status_t (*retrieve)(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- unsigned char *dest, unsigned int *destlen,
- apr_pool_t *pool);
- /* Remove an object from the cache. */
- void (*delete)(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- apr_pool_t *pool);
- /* Dump cache status for mod_status output. */
- void (*status)(void *context, request_rec *r, int flags);
-} modssl_sesscache_provider;
-
typedef struct {
pid_t pid;
apr_pool_t *pPool;
@@ -414,8 +340,8 @@ typedef struct {
/* The configured provider, and associated private data
* structure. */
- const modssl_sesscache_provider *sesscache;
- void *sesscache_context;
+ const ap_socache_provider_t *sesscache;
+ ap_socache_instance_t *sesscache_context;
ssl_mutexmode_t nMutexMode;
apr_lockmech_e nMutexMech;
@@ -638,17 +564,6 @@ SSL_SESSION *ssl_scache_retrieve(server_rec *, UCHAR *, int, apr_pool_t *);
void ssl_scache_remove(server_rec *, UCHAR *, int,
apr_pool_t *);
-extern const modssl_sesscache_provider modssl_sesscache_shmcb;
-extern const modssl_sesscache_provider modssl_sesscache_dbm;
-
-#ifdef HAVE_DISTCACHE
-extern const modssl_sesscache_provider modssl_sesscache_dc;
-#endif
-
-#ifdef HAVE_SSL_CACHE_MEMCACHE
-extern const modssl_sesscache_provider modssl_sesscache_mc;
-#endif
-
/** Proxy Support */
int ssl_proxy_enable(conn_rec *c);
int ssl_engine_disable(conn_rec *c);
@@ -732,8 +647,6 @@ apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, const cha
void ssl_var_log_config_register(apr_pool_t *p);
-#define APR_SHM_MAXSIZE (64 * 1024 * 1024)
-
#ifdef HAVE_OCSP
/* Perform OCSP validation of the current cert in the given context.
* Returns non-zero on success or zero on failure. On failure, the
diff --git a/modules/ssl/ssl_scache.c b/modules/ssl/ssl_scache.c
index d096b7b929..120ef0a027 100644
--- a/modules/ssl/ssl_scache.c
+++ b/modules/ssl/ssl_scache.c
@@ -151,13 +151,13 @@ void ssl_scache_remove(server_rec *s, UCHAR *id, int idlen,
{
SSLModConfigRec *mc = myModConfig(s);
- if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
ssl_mutex_on(s);
}
mc->sesscache->delete(mc->sesscache_context, s, id, idlen, p);
- if (mc->sesscache->flags & MODSSL_SESSCACHE_FLAG_NOTMPSAFE) {
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
ssl_mutex_off(s);
}
}
diff --git a/modules/ssl/ssl_scache_dbm.c b/modules/ssl/ssl_scache_dbm.c
deleted file mode 100644
index bbed2fb89a..0000000000
--- a/modules/ssl/ssl_scache_dbm.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_scache_dbm.c
- * Session Cache via DBM
- */
-
-#include "ssl_private.h"
-
-/* 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,
- const unsigned char *id, unsigned int idlen,
- 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);
- }
-
- apr_pool_create(&ctx->pool, p);
-
- return NULL;
-}
-
-static apr_status_t ssl_scache_dbm_init(void *context, server_rec *s, apr_pool_t *p)
-{
- struct context *ctx = context;
- apr_dbm_t *dbm;
- apr_status_t rv;
-
- /* for the DBM we need the data file */
- 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 */
- 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'",
- ctx->data_file);
- return rv;
- }
- apr_dbm_close(dbm);
-
-#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
- /*
- * We have to make sure the Apache child processes have access to
- * the DBM file. But because there are brain-dead platforms where we
- * cannot exactly determine the suffixes we try all possibilities.
- */
- if (geteuid() == 0 /* is superuser */) {
- 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, ctx->data_file, ".db", NULL),
- unixd_config.user_id, -1) == -1)
- chown(apr_pstrcat(p, ctx->data_file, ".dir", NULL),
- unixd_config.user_id, -1);
- }
- 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, ctx->data_file, ".db", NULL),
- unixd_config.user_id, -1) == -1)
- chown(apr_pstrcat(p, ctx->data_file, ".pag", NULL),
- unixd_config.user_id, -1);
- }
- }
-#endif
- ssl_scache_dbm_expire(ctx, s);
-
- return APR_SUCCESS;
-}
-
-static void ssl_scache_dbm_kill(void *context, server_rec *s)
-{
- 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;
-}
-
-static apr_status_t ssl_scache_dbm_store(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- time_t expiry,
- unsigned char *ucaData, unsigned int nData)
-{
- struct context *ctx = context;
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- apr_status_t rv;
-
- /* be careful: do not try to store too much bytes in a DBM file! */
-#ifdef PAIRMAX
- if ((idlen + nData) >= PAIRMAX) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "data size too large for DBM session cache: %d >= %d",
- (idlen + nData), PAIRMAX);
- return APR_ENOSPC;
- }
-#else
- if ((idlen + nData) >= 950 /* at least less than approx. 1KB */) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "data size too large for DBM session cache: %d >= %d",
- (idlen + nData), 950);
- return APR_ENOSPC;
- }
-#endif
-
- /* create DBM key */
- dbmkey.dptr = (char *)id;
- dbmkey.dsize = idlen;
-
- /* create DBM value */
- dbmval.dsize = sizeof(time_t) + nData;
- dbmval.dptr = (char *)malloc(dbmval.dsize);
- if (dbmval.dptr == NULL) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "malloc error creating DBM value");
- return APR_ENOMEM;
- }
- memcpy((char *)dbmval.dptr, &expiry, sizeof(time_t));
- memcpy((char *)dbmval.dptr+sizeof(time_t), ucaData, nData);
-
- /* and store it to the DBM file */
- 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)",
- ctx->data_file);
- free(dbmval.dptr);
- return rv;
- }
- 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'",
- ctx->data_file);
- apr_dbm_close(dbm);
- free(dbmval.dptr);
- return rv;
- }
- apr_dbm_close(dbm);
-
- /* free temporary buffers */
- free(dbmval.dptr);
-
- /* allow the regular expiring to occur */
- ssl_scache_dbm_expire(ctx, s);
-
- return APR_SUCCESS;
-}
-
-static apr_status_t ssl_scache_dbm_retrieve(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- unsigned char *dest, unsigned int *destlen,
- apr_pool_t *p)
-{
- struct context *ctx = context;
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- unsigned int nData;
- time_t expiry;
- time_t now;
- apr_status_t rc;
-
- /* allow the regular expiring to occur */
- ssl_scache_dbm_expire(ctx, s);
-
- /* create DBM key and values */
- dbmkey.dptr = (char *)id;
- dbmkey.dsize = idlen;
-
- /* and fetch it from the DBM file
- * 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.
- */
- 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)",
- ctx->data_file);
- return rc;
- }
- rc = apr_dbm_fetch(dbm, dbmkey, &dbmval);
- if (rc != APR_SUCCESS) {
- apr_dbm_close(dbm);
- return rc;
- }
- if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(time_t)) {
- apr_dbm_close(dbm);
- return rc;
- }
-
- /* parse resulting data */
- nData = dbmval.dsize-sizeof(time_t);
- if (nData > *destlen) {
- apr_dbm_close(dbm);
- return APR_ENOSPC;
- }
-
- *destlen = nData;
- memcpy(&expiry, dbmval.dptr, sizeof(time_t));
- memcpy(dest, (char *)dbmval.dptr + sizeof(time_t), nData);
-
- apr_dbm_close(dbm);
-
- /* make sure the stuff is still not expired */
- now = time(NULL);
- if (expiry <= now) {
- ssl_scache_dbm_remove(context, s, id, idlen, p);
- return APR_EGENERAL;
- }
-
- return APR_SUCCESS;
-}
-
-static void ssl_scache_dbm_remove(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- apr_pool_t *p)
-{
- struct context *ctx = context;
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_status_t rv;
-
- /* create DBM key and values */
- dbmkey.dptr = (char *)id;
- dbmkey.dsize = idlen;
-
- /* and delete it from the DBM file */
- 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 "
- "(delete)",
- ctx->data_file);
- return;
- }
- apr_dbm_delete(dbm, dbmkey);
- apr_dbm_close(dbm);
-
- return;
-}
-
-static void ssl_scache_dbm_expire(struct context *ctx, server_rec *s)
-{
- SSLSrvConfigRec *sc = mySrvConfig(s);
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- time_t tExpiresAt;
- int nElements = 0;
- int nDeleted = 0;
- int bDelete;
- apr_datum_t *keylist;
- int keyidx;
- int i;
- time_t tNow;
- apr_status_t rv;
-
- /*
- * make sure the expiration for still not-accessed session
- * cache entries is done only from time to time
- */
- tNow = time(NULL);
-
- if (tNow < ctx->last_expiry + sc->session_cache_timeout) {
- return;
- }
-
- ctx->last_expiry = tNow;
-
- /*
- * Here we have to be very carefully: Not all DBM libraries are
- * smart enough to allow one to iterate over the elements and at the
- * same time delete expired ones. Some of them get totally crazy
- * while others have no problems. So we have to do it the slower but
- * more safe way: we first iterate over all elements and remember
- * those which have to be expired. Then in a second pass we delete
- * all those expired elements. Additionally we reopen the DBM file
- * to be really safe in state.
- */
-
-#define KEYMAX 1024
-
- for (;;) {
- /* allocate the key array in a memory sub pool */
- 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, 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",
- ctx->data_file);
- break;
- }
- apr_dbm_firstkey(dbm, &dbmkey);
- while (dbmkey.dptr != NULL) {
- nElements++;
- bDelete = FALSE;
- apr_dbm_fetch(dbm, dbmkey, &dbmval);
- if (dbmval.dsize <= sizeof(time_t) || dbmval.dptr == NULL)
- bDelete = TRUE;
- else {
- memcpy(&tExpiresAt, dbmval.dptr, sizeof(time_t));
- if (tExpiresAt <= tNow)
- bDelete = TRUE;
- }
- if (bDelete) {
- if ((keylist[keyidx].dptr = apr_pmemdup(ctx->pool, dbmkey.dptr, dbmkey.dsize)) != NULL) {
- keylist[keyidx].dsize = dbmkey.dsize;
- keyidx++;
- if (keyidx == KEYMAX)
- break;
- }
- }
- apr_dbm_nextkey(dbm, &dbmkey);
- }
- apr_dbm_close(dbm);
-
- /* pass 2: delete expired elements */
- 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",
- ctx->data_file);
- break;
- }
- for (i = 0; i < keyidx; i++) {
- apr_dbm_delete(dbm, keylist[i]);
- nDeleted++;
- }
- apr_dbm_close(dbm);
-
- if (keyidx < KEYMAX)
- break;
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "Inter-Process Session Cache (DBM) Expiry: "
- "old: %d, new: %d, removed: %d",
- nElements, nElements-nDeleted, nDeleted);
-}
-
-static void ssl_scache_dbm_status(void *context, request_rec *r, int flags)
-{
- struct context *ctx = context;
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- int nElem;
- int nSize;
- int nAverage;
- apr_status_t rv;
-
- nElem = 0;
- nSize = 0;
-
- 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",
- ctx->data_file);
- return;
- }
- /*
- * XXX - Check the return value of apr_dbm_firstkey, apr_dbm_fetch - TBD
- */
- apr_dbm_firstkey(dbm, &dbmkey);
- for ( ; dbmkey.dptr != NULL; apr_dbm_nextkey(dbm, &dbmkey)) {
- apr_dbm_fetch(dbm, dbmkey, &dbmval);
- if (dbmval.dptr == NULL)
- continue;
- nElem += 1;
- nSize += dbmval.dsize;
- }
- apr_dbm_close(dbm);
- if (nSize > 0 && nElem > 0)
- nAverage = nSize / nElem;
- else
- nAverage = 0;
- ap_rprintf(r, "cache type: <b>DBM</b>, maximum size: <b>unlimited</b><br>");
- ap_rprintf(r, "current sessions: <b>%d</b>, current size: <b>%d</b> bytes<br>", nElem, nSize);
- ap_rprintf(r, "average session size: <b>%d</b> bytes<br>", nAverage);
- return;
-}
-
-const modssl_sesscache_provider modssl_sesscache_dbm = {
- "dbm",
- MODSSL_SESSCACHE_FLAG_NOTMPSAFE,
- ssl_scache_dbm_create,
- ssl_scache_dbm_init,
- ssl_scache_dbm_kill,
- ssl_scache_dbm_store,
- ssl_scache_dbm_retrieve,
- ssl_scache_dbm_remove,
- ssl_scache_dbm_status
-};
diff --git a/modules/ssl/ssl_scache_dc.c b/modules/ssl/ssl_scache_dc.c
deleted file mode 100644
index 086fd41bb9..0000000000
--- a/modules/ssl/ssl_scache_dc.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_scache_dc.c
- * Distributed Session Cache (client support)
- */
-
-#include "ssl_private.h"
-
-/* Only build this code if it's enabled at configure-time. */
-#ifdef HAVE_DISTCACHE
-
-#include "distcache/dc_client.h"
-
-#if !defined(DISTCACHE_CLIENT_API) || (DISTCACHE_CLIENT_API < 0x0001)
-#error "You must compile with a more recent version of the distcache-base package"
-#endif
-
-/*
- * This cache implementation allows modssl to access 'distcache' servers (or
- * proxies) to facilitate distributed session caching. It is based on code
- * released as open source by Cryptographic Appliances Inc, and was developed by
- * Geoff Thorpe, Steve Robb, and Chris Zimmerman.
- */
-
-/*
-**
-** High-Level "handlers" as per ssl_scache.c
-**
-*/
-
-struct context {
- /* Configured target server: */
- const char *target;
- /* distcache client context: */
- DC_CTX *dc;
-};
-
-static const char *ssl_scache_dc_create(void **context, const char *arg,
- apr_pool_t *tmp, apr_pool_t *p)
-{
- struct context *ctx;
-
- 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
- * comms on the same connection as each other. */
-#define SESSION_CTX_FLAGS SESSION_CTX_FLAG_PERSISTENT | \
- SESSION_CTX_FLAG_PERSISTENT_PIDCHECK | \
- SESSION_CTX_FLAG_PERSISTENT_RETRY | \
- SESSION_CTX_FLAG_PERSISTENT_LATE
-#else
- /* This mode of operation will open a temporary connection to the 'target'
- * for each cache operation - this makes it safe against fork()
- * automatically. This mode is preferred when running a local proxy (over
- * unix domain sockets) because overhead is negligable and it reduces the
- * performance/stability danger of file-descriptor bloatage. */
-#define SESSION_CTX_FLAGS 0
-#endif
- 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");
-
- return APR_SUCCESS;
-}
-
-static void ssl_scache_dc_kill(void *context, server_rec *s)
-{
- struct context *ctx = context;
-
- if (ctx && ctx->dc) {
- DC_CTX_free(ctx->dc);
- ctx->dc = NULL;
- }
-}
-
-static apr_status_t ssl_scache_dc_store(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- time_t timeout,
- unsigned char *der, unsigned int der_len)
-{
- struct context *ctx = context;
-
- /* !@#$%^ - why do we deal with *absolute* time anyway??? */
- timeout -= time(NULL);
- /* Send the serialised session to the distributed cache context */
- if (!DC_CTX_add_session(ctx->dc, id, idlen, der, der_len,
- (unsigned long)timeout * 1000)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'add_session' failed");
- return APR_EGENERAL;
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'add_session' successful");
- return APR_SUCCESS;
-}
-
-static apr_status_t ssl_scache_dc_retrieve(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- unsigned char *dest, unsigned int *destlen,
- apr_pool_t *p)
-{
- unsigned int data_len;
- struct context *ctx = context;
-
- /* Retrieve any corresponding session from the distributed cache context */
- if (!DC_CTX_get_session(ctx->dc, id, idlen, dest, *destlen, &data_len)) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' MISS");
- return APR_EGENERAL;
- }
- if (data_len > *destlen) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' OVERFLOW");
- return APR_ENOSPC;
- }
- *destlen = data_len;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' HIT");
- return APR_SUCCESS;
-}
-
-static void ssl_scache_dc_remove(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- apr_pool_t *p)
-{
- struct context *ctx = context;
-
- /* Remove any corresponding session from the distributed cache context */
- if (!DC_CTX_remove_session(ctx->dc, id, idlen)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' MISS");
- } else {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' HIT");
- }
-}
-
-static void ssl_scache_dc_status(void *context, request_rec *r, int flags)
-{
- 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>", ctx->target);
-}
-
-const modssl_sesscache_provider modssl_sesscache_dc = {
- "distcache",
- 0,
- ssl_scache_dc_create,
- ssl_scache_dc_init,
- ssl_scache_dc_kill,
- ssl_scache_dc_store,
- ssl_scache_dc_retrieve,
- ssl_scache_dc_remove,
- ssl_scache_dc_status
-};
-
-#endif
-
diff --git a/modules/ssl/ssl_scache_memcache.c b/modules/ssl/ssl_scache_memcache.c
deleted file mode 100644
index f542e07bfa..0000000000
--- a/modules/ssl/ssl_scache_memcache.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_scache_memcache.c
- * Distributed Session Cache on top of memcached
- */
-
-#include "ssl_private.h"
-
-#ifdef HAVE_SSL_CACHE_MEMCACHE
-
-#include "apr_memcache.h"
-#include "ap_mpm.h"
-
-/*
- * SSL Session Caching using memcached as a backend.
- */
-
-/*
-**
-** High-Level "handlers" as per ssl_scache.c
-**
-*/
-
-
-/* The underlying apr_memcache system is thread safe.. */
-#define MC_TAG "mod_ssl:"
-#define MC_TAG_LEN \
- (sizeof(MC_TAG))
-
-#define MC_KEY_LEN 254
-
-#ifndef MC_DEFAULT_SERVER_PORT
-#define MC_DEFAULT_SERVER_PORT 11211
-#endif
-
-
-#ifndef MC_DEFAULT_SERVER_MIN
-#define MC_DEFAULT_SERVER_MIN 0
-#endif
-
-#ifndef MC_DEFAULT_SERVER_SMAX
-#define MC_DEFAULT_SERVER_SMAX 1
-#endif
-
-#ifndef MC_DEFAULT_SERVER_TTL
-#define MC_DEFAULT_SERVER_TTL 600
-#endif
-
-struct context {
- const char *servers;
- apr_memcache_t *mc;
-};
-
-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;
- int nservers = 0;
- char *cache_config;
- char *split;
- char *tok;
- struct context *ctx = context;
-
- ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
-
- /* Find all the servers in the first run to get a total count */
- cache_config = apr_pstrdup(p, ctx->servers);
- split = apr_strtok(cache_config, ",", &tok);
- while (split) {
- nservers++;
- split = apr_strtok(NULL,",", &tok);
- }
-
- rv = apr_memcache_create(p, nservers, 0, &ctx->mc);
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
- "SSLSessionCache: Failed to create Memcache Object of '%d' size.",
- nservers);
- return rv;
- }
-
- /* Now add each server to the memcache */
- cache_config = apr_pstrdup(p, ctx->servers);
- split = apr_strtok(cache_config, ",", &tok);
- while (split) {
- apr_memcache_server_t *st;
- char *host_str;
- char *scope_id;
- apr_port_t port;
-
- rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p);
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
- "SSLSessionCache: Failed to Parse Server: '%s'", split);
- return rv;
- }
-
- if (host_str == NULL) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
- "SSLSessionCache: Failed to Parse Server, "
- "no hostname specified: '%s'", split);
- return APR_EINVAL;
- }
-
- if (port == 0) {
- port = MC_DEFAULT_SERVER_PORT;
- }
-
- rv = apr_memcache_server_create(p,
- host_str, port,
- MC_DEFAULT_SERVER_MIN,
- MC_DEFAULT_SERVER_SMAX,
- thread_limit,
- MC_DEFAULT_SERVER_TTL,
- &st);
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
- "SSLSessionCache: Failed to Create Server: %s:%d",
- host_str, port);
- return rv;
- }
-
- rv = apr_memcache_add_server(ctx->mc, st);
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
- "SSLSessionCache: Failed to Add Server: %s:%d",
- host_str, port);
- return rv;
- }
-
- split = apr_strtok(NULL,",", &tok);
- }
-
- return APR_SUCCESS;
-}
-
-static void ssl_scache_mc_kill(void *context, server_rec *s)
-{
- /* noop. */
-}
-
-static char *mc_session_id2sz(const unsigned char *id, unsigned int idlen,
- char *str, int strsize)
-{
- char *cp;
- int n;
- int maxlen = (strsize - MC_TAG_LEN)/2;
-
- cp = apr_cpystrn(str, MC_TAG, MC_TAG_LEN);
- for (n = 0; n < idlen && n < maxlen; n++) {
- apr_snprintf(cp, 3, "%02X", (unsigned) id[n]);
- cp += 2;
- }
-
- *cp = '\0';
-
- return str;
-}
-
-static apr_status_t ssl_scache_mc_store(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- time_t timeout,
- unsigned char *ucaData, unsigned int nData)
-{
- struct context *ctx = context;
- char buf[MC_KEY_LEN];
- char *strkey = NULL;
- apr_status_t rv;
-
- strkey = mc_session_id2sz(id, idlen, buf, sizeof(buf));
- if(!strkey) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "scache_mc: Key generation borked.");
- return APR_EGENERAL;
- }
-
- rv = apr_memcache_set(ctx->mc, strkey, (char*)ucaData, nData, timeout, 0);
-
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
- "scache_mc: error setting key '%s' "
- "with %d bytes of data", strkey, nData);
- return rv;
- }
-
- return APR_SUCCESS;
-}
-
-static apr_status_t ssl_scache_mc_retrieve(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- unsigned char *dest, unsigned int *destlen,
- apr_pool_t *p)
-{
- struct context *ctx = context;
- apr_size_t der_len;
- char buf[MC_KEY_LEN], *der;
- char *strkey = NULL;
- apr_status_t rv;
-
- strkey = mc_session_id2sz(id, idlen, buf, sizeof(buf));
-
- if (!strkey) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "scache_mc: Key generation borked.");
- return APR_EGENERAL;
- }
-
- /* ### this could do with a subpool, but _getp looks like it will
- * eat memory like it's going out of fashion anyway. */
-
- rv = apr_memcache_getp(ctx->mc, p, strkey,
- &der, &der_len, NULL);
- if (rv) {
- if (rv != APR_NOTFOUND) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "scache_mc: 'get_session' FAIL");
- }
- return rv;
- }
- else if (der_len > *destlen) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "scache_mc: 'get_session' OVERFLOW");
- return rv;
- }
-
- memcpy(dest, der, der_len);
- *destlen = der_len;
-
- return APR_SUCCESS;
-}
-
-static void ssl_scache_mc_remove(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- apr_pool_t *p)
-{
- struct context *ctx = context;
- char buf[MC_KEY_LEN];
- char* strkey = NULL;
- apr_status_t rv;
-
- strkey = mc_session_id2sz(id, idlen, buf, sizeof(buf));
- if(!strkey) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "scache_mc: Key generation borked.");
- return;
- }
-
- rv = apr_memcache_delete(ctx->mc, strkey, 0);
-
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
- "scache_mc: error deleting key '%s' ",
- strkey);
- return;
- }
-}
-
-static void ssl_scache_mc_status(void *context, request_rec *r, int flags)
-{
- /* SSLModConfigRec *mc = myModConfig(r->server); */
- /* TODO: Make a mod_status handler. meh. */
-}
-
-const modssl_sesscache_provider modssl_sesscache_mc = {
- "memcache",
- 0,
- ssl_scache_mc_create,
- ssl_scache_mc_init,
- ssl_scache_mc_kill,
- ssl_scache_mc_store,
- ssl_scache_mc_retrieve,
- ssl_scache_mc_remove,
- ssl_scache_mc_status
-};
-#endif
diff --git a/modules/ssl/ssl_scache_shmcb.c b/modules/ssl/ssl_scache_shmcb.c
deleted file mode 100644
index 6cf5f3fc0f..0000000000
--- a/modules/ssl/ssl_scache_shmcb.c
+++ /dev/null
@@ -1,833 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_scache_shmcb.c
- * Session Cache via Shared Memory (Cyclic Buffer Variant)
- */
-
-#include "ssl_private.h"
-
-/*
- * This shared memory based SSL session cache implementation was
- * originally written by Geoff Thorpe <geoff geoffthorpe.net> for C2Net
- * Europe as a contribution to Ralf Engelschall's mod_ssl project.
- *
- * Since rewritten by GT to not use alignment-fudging memcpys and reduce
- * complexity.
- */
-
-/*
- * Header structure - the start of the shared-mem segment
- */
-typedef struct {
- /* Stats for cache operations */
- unsigned long stat_stores;
- unsigned long stat_expiries;
- unsigned long stat_scrolled;
- unsigned long stat_retrieves_hit;
- unsigned long stat_retrieves_miss;
- unsigned long stat_removes_hit;
- unsigned long stat_removes_miss;
- /* Number of subcaches */
- unsigned int subcache_num;
- /* How many indexes each subcache's queue has */
- unsigned int index_num;
- /* How large each subcache is, including the queue and data */
- unsigned int subcache_size;
- /* How far into each subcache the data area is (optimisation) */
- unsigned int subcache_data_offset;
- /* How large the data area in each subcache is (optimisation) */
- unsigned int subcache_data_size;
-} SHMCBHeader;
-
-/*
- * Subcache structure - the start of each subcache, followed by
- * indexes then data
- */
-typedef struct {
- /* The start position and length of the cyclic buffer of indexes */
- unsigned int idx_pos, idx_used;
- /* Same for the data area */
- unsigned int data_pos, data_used;
-} SHMCBSubcache;
-
-/*
- * Index structure - each subcache has an array of these
- */
-typedef struct {
- /* absolute time this entry expires */
- time_t expires;
- /* location within the subcache's data area */
- unsigned int data_pos;
- /* size (most logic ignores this, we keep it only to minimise memcpy) */
- unsigned int data_used;
- /* length of the used data which contains the id */
- unsigned int id_len;
- /* Used to mark explicitly-removed sessions */
- unsigned char removed;
-} SHMCBIndex;
-
-struct context {
- const char *data_file;
- apr_size_t shm_size;
- apr_shm_t *shm;
- SHMCBHeader *header;
-};
-
-/* The SHM data segment is of fixed size and stores data as follows.
- *
- * [ SHMCBHeader | Subcaches ]
- *
- * The SHMCBHeader header structure stores metadata concerning the
- * cache and the contained subcaches.
- *
- * Subcaches is a hash table of header->subcache_num SHMCBSubcache
- * structures. The hash table is indexed by SHMCB_MASK(id). Each
- * SHMCBSubcache structure has a fixed size (header->subcache_size),
- * which is determined at creation time, and looks like the following:
- *
- * [ SHMCBSubcache | Indexes | Data ]
- *
- * Each subcache is prefixed by the SHMCBSubcache structure.
- *
- * The subcache's "Data" segment is a single cyclic data buffer, of
- * total size header->subcache_data_size; data inside is referenced
- * using byte offsets. The offset marking the beginning of the cyclic
- * buffer is subcache->data_pos the buffer's length is
- * subcache->data_used.
- *
- * "Indexes" is an array of header->index_num SHMCBIndex structures,
- * which is used as a cyclic queue; subcache->idx_pos gives the array
- * index of the first in use, subcache->idx_used gives the number in
- * use. Both ->idx_* values have a range of [0, header->index_num)
- *
- * Each in-use SHMCBIndex structure represents a single SSL session.
- * The ID and data segment are stored consecutively in the subcache's
- * cyclic data buffer. The "Data" segment can thus be seen to
- * look like this, for example
- *
- * offset: [ 0 1 2 3 4 5 6 ...
- * contents:[ ID1 Data1 ID2 Data2 ID3 ...
- *
- * where the corresponding indices would look like:
- *
- * idx1 = { data_pos = 0, data_used = 3, id_len = 1, ...}
- * idx2 = { data_pos = 3, data_used = 3, id_len = 1, ...}
- * ...
- */
-
-/* This macro takes a pointer to the header and a zero-based index and returns
- * a pointer to the corresponding subcache. */
-#define SHMCB_SUBCACHE(pHeader, num) \
- (SHMCBSubcache *)(((unsigned char *)(pHeader)) + \
- sizeof(SHMCBHeader) + \
- (num) * ((pHeader)->subcache_size))
-
-/* This macro takes a pointer to the header and a session id and returns a
- * pointer to the corresponding subcache. */
-#define SHMCB_MASK(pHeader, id) \
- SHMCB_SUBCACHE((pHeader), *(id) & ((pHeader)->subcache_num - 1))
-
-/* This macro takes the same params as the last, generating two outputs for use
- * in ap_log_error(...). */
-#define SHMCB_MASK_DBG(pHeader, id) \
- *(id), (*(id) & ((pHeader)->subcache_num - 1))
-
-/* This macro takes a pointer to a subcache and a zero-based index and returns
- * a pointer to the corresponding SHMCBIndex. */
-#define SHMCB_INDEX(pSubcache, num) \
- ((SHMCBIndex *)(((unsigned char *)pSubcache) + \
- sizeof(SHMCBSubcache)) + num)
-
-/* This macro takes a pointer to the header and a subcache and returns a
- * pointer to the corresponding data area. */
-#define SHMCB_DATA(pHeader, pSubcache) \
- ((unsigned char *)(pSubcache) + (pHeader)->subcache_data_offset)
-
-/*
- * Cyclic functions - assists in "wrap-around"/modulo logic
- */
-
-/* Addition modulo 'mod' */
-#define SHMCB_CYCLIC_INCREMENT(val,inc,mod) \
- (((val) + (inc)) % (mod))
-
-/* Subtraction (or "distance between") modulo 'mod' */
-#define SHMCB_CYCLIC_SPACE(val1,val2,mod) \
- ((val2) >= (val1) ? ((val2) - (val1)) : \
- ((val2) + (mod) - (val1)))
-
-/* A "normal-to-cyclic" memcpy. */
-static void shmcb_cyclic_ntoc_memcpy(unsigned int buf_size, unsigned char *data,
- unsigned int dest_offset, const unsigned char *src,
- unsigned int src_len)
-{
- if (dest_offset + src_len < buf_size)
- /* It be copied all in one go */
- memcpy(data + dest_offset, src, src_len);
- else {
- /* Copy the two splits */
- memcpy(data + dest_offset, src, buf_size - dest_offset);
- memcpy(data, src + buf_size - dest_offset,
- src_len + dest_offset - buf_size);
- }
-}
-
-/* A "cyclic-to-normal" memcpy. */
-static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest,
- const unsigned char *data, unsigned int src_offset,
- unsigned int src_len)
-{
- if (src_offset + src_len < buf_size)
- /* It be copied all in one go */
- memcpy(dest, data + src_offset, src_len);
- else {
- /* Copy the two splits */
- memcpy(dest, data + src_offset, buf_size - src_offset);
- memcpy(dest + buf_size - src_offset, data,
- src_len + src_offset - buf_size);
- }
-}
-
-/* A memcmp against a cyclic data buffer. Compares SRC of length
- * SRC_LEN against the contents of cyclic buffer DATA (which is of
- * size BUF_SIZE), starting at offset DEST_OFFSET. Got that? Good. */
-static int shmcb_cyclic_memcmp(unsigned int buf_size, unsigned char *data,
- unsigned int dest_offset,
- const unsigned char *src,
- unsigned int src_len)
-{
- if (dest_offset + src_len < buf_size)
- /* It be compared all in one go */
- return memcmp(data + dest_offset, src, src_len);
- else {
- /* Compare the two splits */
- int diff;
-
- diff = memcmp(data + dest_offset, src, buf_size - dest_offset);
- if (diff) {
- return diff;
- }
- return memcmp(data, src + buf_size - dest_offset,
- src_len + dest_offset - buf_size);
- }
-}
-
-
-/* Prototypes for low-level subcache operations */
-static void shmcb_subcache_expire(server_rec *, SHMCBHeader *, SHMCBSubcache *);
-/* Returns zero on success, non-zero on failure. */
-static int shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache,
- unsigned char *data, unsigned int data_len,
- const unsigned char *id, unsigned int id_len,
- time_t expiry);
-/* Returns zero on success, non-zero on failure. */
-static int shmcb_subcache_retrieve(server_rec *, SHMCBHeader *, SHMCBSubcache *,
- const unsigned char *id, unsigned int idlen,
- unsigned char *data, unsigned int *datalen);
-/* Returns zero on success, non-zero on failure. */
-static int shmcb_subcache_remove(server_rec *, SHMCBHeader *, SHMCBSubcache *,
- const unsigned char *, unsigned int);
-
-/*
- * High-Level "handlers" as per ssl_scache.c
- * subcache internals are deferred to shmcb_subcache_*** functions lower down
- */
-
-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)
-{
- void *shm_segment;
- apr_size_t shm_segsize;
- apr_status_t rv;
- SHMCBHeader *header;
- unsigned int num_subcache, num_idx, loop;
- struct context *ctx = context;
-
- /* Create shared memory segment */
- 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, 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(ctx->data_file, p);
-
- rv = apr_shm_create(&ctx->shm, ctx->shm_size, ctx->data_file, p);
- }
-
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "could not allocate shared memory for shmcb "
- "session cache");
- return rv;
- }
-
- shm_segment = apr_shm_baseaddr_get(ctx->shm);
- shm_segsize = apr_shm_size_get(ctx->shm);
- if (shm_segsize < (5 * sizeof(SHMCBHeader))) {
- /* the segment is ridiculously small, bail out */
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "shared memory segment too small");
- return APR_ENOSPC;
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_init allocated %" APR_SIZE_T_FMT
- " bytes of shared memory",
- shm_segsize);
- /* Discount the header */
- shm_segsize -= sizeof(SHMCBHeader);
- /* Select the number of subcaches to create and how many indexes each
- * should contain based on the size of the memory (the header has already
- * been subtracted). Typical non-client-auth sslv3/tlsv1 sessions are
- * around 180 bytes (148 bytes data and 32 bytes for the id), so
- * erring to division by 150 helps ensure we would exhaust data
- * storage before index storage (except sslv2, where it's
- * *slightly* the other way). From there, we select the number of
- * subcaches to be a power of two, such that the number of indexes
- * per subcache at least twice the number of subcaches. */
- num_idx = (shm_segsize) / 150;
- num_subcache = 256;
- while ((num_idx / num_subcache) < (2 * num_subcache))
- num_subcache /= 2;
- num_idx /= num_subcache;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "for %" APR_SIZE_T_FMT " bytes (%" APR_SIZE_T_FMT
- " including header), recommending %u subcaches, "
- "%u indexes each", shm_segsize,
- shm_segsize + sizeof(SHMCBHeader), num_subcache, num_idx);
- if (num_idx < 5) {
- /* we're still too small, bail out */
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "shared memory segment too small");
- return APR_ENOSPC;
- }
- /* OK, we're sorted */
- ctx->header = header = shm_segment;
- header->stat_stores = 0;
- header->stat_expiries = 0;
- header->stat_scrolled = 0;
- header->stat_retrieves_hit = 0;
- header->stat_retrieves_miss = 0;
- header->stat_removes_hit = 0;
- header->stat_removes_miss = 0;
- header->subcache_num = num_subcache;
- /* Convert the subcache size (in bytes) to a value that is suitable for
- * structure alignment on the host platform, by rounding down if necessary.
- * This assumes that sizeof(unsigned long) provides an appropriate
- * alignment unit. */
- header->subcache_size = ((size_t)(shm_segsize / num_subcache) &
- ~(size_t)(sizeof(unsigned long) - 1));
- header->subcache_data_offset = sizeof(SHMCBSubcache) +
- num_idx * sizeof(SHMCBIndex);
- header->subcache_data_size = header->subcache_size -
- header->subcache_data_offset;
- header->index_num = num_idx;
-
- /* Output trace info */
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_init_memory choices follow");
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "subcache_num = %u", header->subcache_num);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "subcache_size = %u", header->subcache_size);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "subcache_data_offset = %u", header->subcache_data_offset);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "subcache_data_size = %u", header->subcache_data_size);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "index_num = %u", header->index_num);
- /* The header is done, make the caches empty */
- for (loop = 0; loop < header->subcache_num; loop++) {
- SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
- subcache->idx_pos = subcache->idx_used = 0;
- subcache->data_pos = subcache->data_used = 0;
- }
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Shared memory session cache initialised");
- /* Success ... */
-
- return APR_SUCCESS;
-}
-
-static void ssl_scache_shmcb_kill(void *context, server_rec *s)
-{
- struct context *ctx = context;
-
- if (ctx && ctx->shm) {
- apr_shm_destroy(ctx->shm);
- ctx->shm = NULL;
- }
-}
-
-static apr_status_t ssl_scache_shmcb_store(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- time_t timeout,
- unsigned char *encoded,
- unsigned int len_encoded)
-{
- struct context *ctx = context;
- SHMCBHeader *header = ctx->header;
- SHMCBSubcache *subcache = SHMCB_MASK(header, id);
-
- 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);
- return APR_EINVAL;
- }
- 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!");
- return APR_ENOSPC;
- }
- header->stat_stores++;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "leaving ssl_scache_shmcb_store successfully");
- return APR_SUCCESS;
-}
-
-static apr_status_t ssl_scache_shmcb_retrieve(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- unsigned char *dest, unsigned int *destlen,
- apr_pool_t *p)
-{
- struct context *ctx = context;
- SHMCBHeader *header = ctx->header;
- SHMCBSubcache *subcache = SHMCB_MASK(header, id);
- int rv;
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "ssl_scache_shmcb_retrieve (0x%02x -> subcache %d)",
- SHMCB_MASK_DBG(header, id));
-
- /* Get the session corresponding to the session_id, if it exists. */
- rv = shmcb_subcache_retrieve(s, header, subcache, id, idlen,
- dest, destlen);
- if (rv == 0)
- header->stat_retrieves_hit++;
- else
- header->stat_retrieves_miss++;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "leaving ssl_scache_shmcb_retrieve successfully");
-
- return rv == 0 ? APR_SUCCESS : APR_EGENERAL;
-}
-
-static void ssl_scache_shmcb_remove(void *context, server_rec *s,
- const unsigned char *id, unsigned int idlen,
- apr_pool_t *p)
-{
- struct context *ctx = context;
- SHMCBHeader *header = ctx->header;
- SHMCBSubcache *subcache = SHMCB_MASK(header, id);
-
- 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);
- return;
- }
- if (shmcb_subcache_remove(s, header, subcache, id, idlen))
- header->stat_removes_hit++;
- else
- header->stat_removes_miss++;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "leaving ssl_scache_shmcb_remove successfully");
-}
-
-static void ssl_scache_shmcb_status(void *context, request_rec *r, int flags)
-{
- server_rec *s = r->server;
- struct context *ctx = context;
- SHMCBHeader *header = ctx->header;
- unsigned int loop, total = 0, cache_total = 0, non_empty_subcaches = 0;
- time_t idx_expiry, min_expiry = 0, max_expiry = 0, average_expiry = 0;
- time_t now = time(NULL);
- double expiry_total = 0;
- int index_pct, cache_pct;
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "inside shmcb_status");
- /* 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. */
- /* Iterate over the subcaches */
- for (loop = 0; loop < header->subcache_num; loop++) {
- SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
- shmcb_subcache_expire(s, header, subcache);
- total += subcache->idx_used;
- cache_total += subcache->data_used;
- if (subcache->idx_used) {
- SHMCBIndex *idx = SHMCB_INDEX(subcache, subcache->idx_pos);
- non_empty_subcaches++;
- idx_expiry = idx->expires;
- expiry_total += (double)idx_expiry;
- max_expiry = ((idx_expiry > max_expiry) ? idx_expiry : max_expiry);
- if (!min_expiry)
- min_expiry = idx_expiry;
- else
- min_expiry = ((idx_expiry < min_expiry) ? idx_expiry : min_expiry);
- }
- }
- index_pct = (100 * total) / (header->index_num *
- header->subcache_num);
- 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>%" APR_SIZE_T_FMT "</b> "
- "bytes, current sessions: <b>%d</b><br>",
- 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) {
- average_expiry = (time_t)(expiry_total / (double)non_empty_subcaches);
- ap_rprintf(r, "time left on oldest entries' SSL sessions: ");
- if (now < average_expiry)
- ap_rprintf(r, "avg: <b>%d</b> seconds, (range: %d...%d)<br>",
- (int)(average_expiry - now),
- (int)(min_expiry - now),
- (int)(max_expiry - now));
- else
- ap_rprintf(r, "expiry_threshold: <b>Calculation error!</b><br>");
- }
-
- ap_rprintf(r, "index usage: <b>%d%%</b>, cache usage: <b>%d%%</b><br>",
- index_pct, cache_pct);
- ap_rprintf(r, "total sessions stored since starting: <b>%lu</b><br>",
- header->stat_stores);
- ap_rprintf(r, "total sessions expired since starting: <b>%lu</b><br>",
- header->stat_expiries);
- ap_rprintf(r, "total (pre-expiry) sessions scrolled out of the cache: "
- "<b>%lu</b><br>", header->stat_scrolled);
- ap_rprintf(r, "total retrieves since starting: <b>%lu</b> hit, "
- "<b>%lu</b> miss<br>", header->stat_retrieves_hit,
- header->stat_retrieves_miss);
- ap_rprintf(r, "total removes since starting: <b>%lu</b> hit, "
- "<b>%lu</b> miss<br>", header->stat_removes_hit,
- header->stat_removes_miss);
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "leaving shmcb_status");
-}
-
-/*
- * Subcache-level cache operations
- */
-
-static void shmcb_subcache_expire(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache)
-{
- time_t now = time(NULL);
- unsigned int loop = 0;
- unsigned int new_idx_pos = subcache->idx_pos;
- SHMCBIndex *idx = NULL;
-
- while (loop < subcache->idx_used) {
- idx = SHMCB_INDEX(subcache, new_idx_pos);
- if (idx->expires > now)
- /* it hasn't expired yet, we're done iterating */
- break;
- loop++;
- new_idx_pos = SHMCB_CYCLIC_INCREMENT(new_idx_pos, 1, header->index_num);
- }
- if (!loop)
- /* Nothing to do */
- return;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "will be expiring %u sessions", loop);
- if (loop == subcache->idx_used) {
- /* We're expiring everything, piece of cake */
- subcache->idx_used = 0;
- subcache->data_used = 0;
- } else {
- /* There remain other indexes, so we can use idx to adjust 'data' */
- unsigned int diff = SHMCB_CYCLIC_SPACE(subcache->data_pos,
- idx->data_pos,
- header->subcache_data_size);
- /* Adjust the indexes */
- subcache->idx_used -= loop;
- subcache->idx_pos = new_idx_pos;
- /* Adjust the data area */
- subcache->data_used -= diff;
- subcache->data_pos = idx->data_pos;
- }
- header->stat_expiries += loop;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "we now have %u sessions", subcache->idx_used);
-}
-
-static int shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache,
- unsigned char *data, unsigned int data_len,
- const unsigned char *id, unsigned int id_len,
- time_t expiry)
-{
- unsigned int data_offset, new_idx, id_offset;
- SHMCBIndex *idx;
- unsigned int total_len = id_len + data_len;
-
- /* Sanity check the input */
- if (total_len > header->subcache_data_size) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "inserting session larger (%d) than subcache data area (%d)",
- total_len, header->subcache_data_size);
- return -1;
- }
-
- /* If there are entries to expire, ditch them first. */
- shmcb_subcache_expire(s, header, subcache);
-
- /* Loop until there is enough space to insert */
- if (header->subcache_data_size - subcache->data_used < total_len
- || subcache->idx_used == header->index_num) {
- unsigned int loop = 0;
-
- idx = SHMCB_INDEX(subcache, subcache->idx_pos);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "about to force-expire, subcache: idx_used=%d, "
- "data_used=%d", subcache->idx_used, subcache->data_used);
- do {
- SHMCBIndex *idx2;
-
- /* Adjust the indexes by one */
- subcache->idx_pos = SHMCB_CYCLIC_INCREMENT(subcache->idx_pos, 1,
- header->index_num);
- subcache->idx_used--;
- if (!subcache->idx_used) {
- /* There's nothing left */
- subcache->data_used = 0;
- break;
- }
- /* Adjust the data */
- idx2 = SHMCB_INDEX(subcache, subcache->idx_pos);
- subcache->data_used -= SHMCB_CYCLIC_SPACE(idx->data_pos, idx2->data_pos,
- header->subcache_data_size);
- subcache->data_pos = idx2->data_pos;
- /* Stats */
- header->stat_scrolled++;
- /* Loop admin */
- idx = idx2;
- loop++;
- } while (header->subcache_data_size - subcache->data_used < total_len);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "finished force-expire, subcache: idx_used=%d, "
- "data_used=%d", subcache->idx_used, subcache->data_used);
- }
-
- /* HERE WE ASSUME THAT THE NEW SESSION SHOULD GO ON THE END! I'M NOT
- * CHECKING WHETHER IT SHOULD BE GENUINELY "INSERTED" SOMEWHERE.
- *
- * We either fix that, or find out at a "higher" (read "mod_ssl")
- * level whether it is possible to have distinct session caches for
- * any attempted tomfoolery to do with different session timeouts.
- * Knowing in advance that we can have a cache-wide constant timeout
- * would make this stuff *MUCH* more efficient. Mind you, it's very
- * efficient right now because I'm ignoring this problem!!!
- */
- /* Insert the id */
- id_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
- header->subcache_data_size);
- shmcb_cyclic_ntoc_memcpy(header->subcache_data_size,
- SHMCB_DATA(header, subcache), id_offset,
- id, id_len);
- subcache->data_used += id_len;
- /* Insert the data */
- data_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
- header->subcache_data_size);
- shmcb_cyclic_ntoc_memcpy(header->subcache_data_size,
- SHMCB_DATA(header, subcache), data_offset,
- data, data_len);
- subcache->data_used += data_len;
- /* Insert the index */
- new_idx = SHMCB_CYCLIC_INCREMENT(subcache->idx_pos, subcache->idx_used,
- header->index_num);
- idx = SHMCB_INDEX(subcache, new_idx);
- idx->expires = expiry;
- idx->data_pos = id_offset;
- idx->data_used = total_len;
- idx->id_len = id_len;
- idx->removed = 0;
- subcache->idx_used++;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "insert happened at idx=%d, data=(%u:%u)", new_idx,
- id_offset, data_offset);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "finished insert, subcache: idx_pos/idx_used=%d/%d, "
- "data_pos/data_used=%d/%d",
- subcache->idx_pos, subcache->idx_used,
- subcache->data_pos, subcache->data_used);
- return 0;
-}
-
-static int shmcb_subcache_retrieve(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache,
- const unsigned char *id, unsigned int idlen,
- unsigned char *dest, unsigned int *destlen)
-{
- unsigned int pos;
- unsigned int loop = 0;
-
- /* If there are entries to expire, ditch them first. */
- shmcb_subcache_expire(s, header, subcache);
- pos = subcache->idx_pos;
-
- while (loop < subcache->idx_used) {
- SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
-
- /* Only consider 'idx' if the id matches, and the "removed"
- * flag isn't set; check the data length too to avoid a buffer
- * overflow in case of corruption, which should be impossible,
- * but it's cheap to be safe. */
- if (!idx->removed
- && idx->id_len == idlen && (idx->data_used - idx->id_len) < *destlen
- && shmcb_cyclic_memcmp(header->subcache_data_size,
- SHMCB_DATA(header, subcache),
- idx->data_pos, id, idx->id_len) == 0) {
- unsigned int data_offset;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "match at idx=%d, data=%d", pos, idx->data_pos);
-
- /* Find the offset of the data segment, after the id */
- data_offset = SHMCB_CYCLIC_INCREMENT(idx->data_pos,
- idx->id_len,
- header->subcache_data_size);
-
- *destlen = idx->data_used - idx->id_len;
-
- /* Copy out the data */
- shmcb_cyclic_cton_memcpy(header->subcache_data_size,
- dest, SHMCB_DATA(header, subcache),
- data_offset, *destlen);
-
- return 0;
- }
- /* Increment */
- loop++;
- pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_subcache_retrieve found no match");
- return -1;
-
-}
-
-static int shmcb_subcache_remove(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache,
- const unsigned char *id, unsigned int idlen)
-{
- unsigned int pos;
- unsigned int loop = 0;
-
- /* Unlike the others, we don't do an expire-run first. This is to keep
- * consistent statistics where a "remove" operation may actually be the
- * higher layer spotting an expiry issue prior to us. Our caller is
- * handling stats, so a failure return would be inconsistent if the
- * intended session was in fact removed by an expiry run. */
-
- pos = subcache->idx_pos;
- while (loop < subcache->idx_used) {
- SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
-
- /* Only consider 'idx' if the id matches, and the "removed"
- * flag isn't set. */
- if (!idx->removed && idx->id_len == idlen
- && shmcb_cyclic_memcmp(header->subcache_data_size,
- SHMCB_DATA(header, subcache),
- idx->data_pos, id, idx->id_len) == 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "possible match at idx=%d, data=%d", pos, idx->data_pos);
- /* Found the matching session, remove it quietly. */
- idx->removed = 1;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_subcache_remove removing matching session");
- return 0;
- }
- /* Increment */
- loop++;
- pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
- }
-
- return -1; /* failure */
-}
-
-const modssl_sesscache_provider modssl_sesscache_shmcb = {
- "shmcb",
- MODSSL_SESSCACHE_FLAG_NOTMPSAFE,
- ssl_scache_shmcb_create,
- ssl_scache_shmcb_init,
- ssl_scache_shmcb_kill,
- ssl_scache_shmcb_store,
- ssl_scache_shmcb_retrieve,
- ssl_scache_shmcb_remove,
- ssl_scache_shmcb_status
-};