The cleanest and simplest way to extract the session cache providers from mod_ssl seems to be like this:
1) define the provider vtable structure in a header, ap_socache.h 2) implement all the provider backends in separate modules, mod_socache_* There's no central registration of new backends required like this; a new provider can be added simply by loading a new module. I have a mild preference for the name "socache" over the suggested alternatives; "mod_small_cache_blah" would be too long, "mod_gicache" for "generic internal" is a slight misnomer since the cache is not necessarily "internal" i.e. memcache/distcache. Still to do: * pass a "hints" structure to the ->init to define expected object sizes so shmcb caches can be sized correctly, along with a namespace string which can be used by memcache as a key prefix * doxygenify the comments in ap_socache.h * update comments through to be less mod_ssl-centric * test more ;) [Patch shows diffs relative to original ssl_scache_* for the providers] Index: modules/cache/ap_socache.h =================================================================== --- modules/cache/ap_socache.h (revision 0) +++ modules/cache/ap_socache.h (revision 0) @@ -0,0 +1,89 @@ +/* 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. + */ + +/** + * @file ap_socache.h + * @brief Small object cache provider interface. + * + * @defgroup AP_SOCACHE ap_socache + * @ingroup APACHE_MODS + * @{ + */ + +#ifndef AP_SOCACHE_H +#define AP_SOCACHE_H + +#include "httpd.h" +#include "ap_provider.h" +#include "apr_pools.h" + +/* 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 AP_SOCACHE_FLAG_NOTMPSAFE (0x0001) + +typedef struct ap_socache_provider_t { + /* Canonical provider name: */ + const char *name; + + /* Bitmask of AP_SOCACHE_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 *INSTANCE will be passed as the + * first argument to subsequent invocations. */ + const char *(*create)(void **instance, const char *arg, + apr_pool_t *tmp, apr_pool_t *p); + /* Initialize the cache. Return APR error code. */ + apr_status_t (*init)(void *instance, /* hints, namespace */ + server_rec *s, apr_pool_t *pool); + /* Destroy a given cache context. */ + void (*destroy)(void *instance, server_rec *s); + /* Store an object in the cache. */ + apr_status_t (*store)(void *instance, 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 *instance, 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 *instance, server_rec *s, + const unsigned char *id, unsigned int idlen, + apr_pool_t *pool); + /* Dump cache status for mod_status output. */ + void (*status)(void *instance, request_rec *r, int flags); +} ap_socache_provider_t; + +/* Cache providers are registered using the ap_provider_* interface, + * with the following group and version: */ +#define AP_SOCACHE_PROVIDER_GROUP "socache" +#define AP_SOCACHE_PROVIDER_VERSION "0" + +#endif /* AP_SOCACHE_H */ +/** @} */ Property changes on: modules/cache/ap_socache.h ___________________________________________________________________ Name: svn:eol-style + native Index: modules/cache/config.m4 =================================================================== --- modules/cache/config.m4 (revision 633418) +++ modules/cache/config.m4 (working copy) @@ -24,4 +24,86 @@ APACHE_MODULE(disk_cache, disk caching module, , , most) APACHE_MODULE(mem_cache, memory caching module, $mem_cache_objs, , ) +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,Enable distcache support), + 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_SOCACHE_LDADD, [-ldistcache -lnal]) + AC_DEFINE(HAVE_DISTCACHE, 1, [Define if distcache support is enabled]) + fi + fi +]) + +APACHE_MODULE(socache_shmcb, shmcb small object cache provider, , most) +APACHE_MODULE(socache_dbm, dbm small object cache provider, , most) +APACHE_MODULE(socache_memcache, memcache small object cache provider, , most) +APACHE_MODULE(socache_dc, distcache small object cache provider, , , no, [ + CHECK_DISTCACHE +]) + +APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) + APACHE_MODPATH_FINISH Index: modules/cache/mod_socache_dbm.c =================================================================== --- modules/cache/mod_socache_dbm.c (revision 633418) +++ modules/cache/mod_socache_dbm.c (working copy) @@ -14,18 +14,26 @@ * limitations under the License. */ -/* _ _ - * _ __ ___ ___ __| | ___ ___| | mod_ssl - * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL - * | | | | | | (_) | (_| | \__ \__ \ | - * |_| |_| |_|\___/ \__,_|___|___/___/_| - * |_____| - * ssl_scache_dbm.c - * Session Cache via DBM - */ +#include "httpd.h" +#include "http_log.h" +#include "http_request.h" +#include "http_protocol.h" +#include "http_config.h" +#include "mpm_common.h" -#include "ssl_private.h" +#include "apr.h" +#include "apr_strings.h" +#include "apr_time.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "apr_dbm.h" +#if APR_HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "ap_socache.h" + /* Use of the context structure must be thread-safe after the initial * create/init; callers must hold the mutex. */ struct context { @@ -33,16 +41,38 @@ /* Pool must only be used with the mutex held. */ apr_pool_t *pool; time_t last_expiry; + time_t timeout; }; -static void ssl_scache_dbm_expire(struct context *ctx, server_rec *s); +/** + * Support for DBM library + */ +#define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) -static void ssl_scache_dbm_remove(void *context, server_rec *s, - const unsigned char *id, unsigned int idlen, - apr_pool_t *p); +/* ### this should use apr_dbm_usednames. */ +#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 -static const char *ssl_scache_dbm_create(void **context, const char *arg, - apr_pool_t *tmp, apr_pool_t *p) + + +static void socache_dbm_expire(struct context *ctx, server_rec *s); + +static void socache_dbm_remove(void *context, server_rec *s, + const unsigned char *id, unsigned int idlen, + apr_pool_t *p); + +static const char *socache_dbm_create(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p) { struct context *ctx; @@ -52,13 +82,13 @@ if (!ctx->data_file) { return apr_psprintf(tmp, "Invalid cache file path %s", arg); } - + ctx->timeout = 30; /* ### take as hint in _init */ 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) +static apr_status_t socache_dbm_init(void *context, server_rec *s, apr_pool_t *p) { struct context *ctx = context; apr_dbm_t *dbm; @@ -107,12 +137,12 @@ } } #endif - ssl_scache_dbm_expire(ctx, s); + socache_dbm_expire(ctx, s); return APR_SUCCESS; } -static void ssl_scache_dbm_kill(void *context, server_rec *s) +static void socache_dbm_kill(void *context, server_rec *s) { struct context *ctx = context; @@ -128,10 +158,10 @@ 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) +static apr_status_t socache_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; @@ -197,15 +227,15 @@ free(dbmval.dptr); /* allow the regular expiring to occur */ - ssl_scache_dbm_expire(ctx, s); + socache_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) +static apr_status_t socache_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; @@ -217,7 +247,7 @@ apr_status_t rc; /* allow the regular expiring to occur */ - ssl_scache_dbm_expire(ctx, s); + socache_dbm_expire(ctx, s); /* create DBM key and values */ dbmkey.dptr = (char *)id; @@ -243,7 +273,7 @@ } if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(time_t)) { apr_dbm_close(dbm); - return rc; + return APR_EGENERAL; } /* parse resulting data */ @@ -262,16 +292,16 @@ /* 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; + socache_dbm_remove(ctx, s, id, idlen, p); + return APR_NOTFOUND; } 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) +static void socache_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; @@ -299,9 +329,8 @@ return; } -static void ssl_scache_dbm_expire(struct context *ctx, server_rec *s) +static void socache_dbm_expire(struct context *ctx, server_rec *s) { - SSLSrvConfigRec *sc = mySrvConfig(s); apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; @@ -321,7 +350,7 @@ */ tNow = time(NULL); - if (tNow < ctx->last_expiry + sc->session_cache_timeout) { + if (tNow < ctx->last_expiry + ctx->timeout) { return; } @@ -407,7 +436,7 @@ nElements, nElements-nDeleted, nDeleted); } -static void ssl_scache_dbm_status(void *context, request_rec *r, int flags) +static void socache_dbm_status(void *context, request_rec *r, int flags) { struct context *ctx = context; apr_dbm_t *dbm; @@ -452,14 +481,27 @@ return; } -const modssl_sesscache_provider modssl_sesscache_dbm = { +static const ap_socache_provider_t socache_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 + AP_SOCACHE_FLAG_NOTMPSAFE, + socache_dbm_create, + socache_dbm_init, + socache_dbm_kill, + socache_dbm_store, + socache_dbm_retrieve, + socache_dbm_remove, + socache_dbm_status }; + +static void register_hooks(apr_pool_t *p) +{ + ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "dbm", + AP_SOCACHE_PROVIDER_VERSION, + &socache_dbm); +} + +const module AP_MODULE_DECLARE_DATA socache_dbm_module = { + STANDARD20_MODULE_STUFF, + NULL, NULL, NULL, NULL, NULL, + register_hooks +}; Index: modules/cache/mod_socache_dc.c =================================================================== --- modules/cache/mod_socache_dc.c (revision 633418) +++ modules/cache/mod_socache_dc.c (working copy) @@ -14,20 +14,16 @@ * limitations under the License. */ -/* _ _ - * _ __ ___ ___ __| | ___ ___| | mod_ssl - * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL - * | | | | | | (_) | (_| | \__ \__ \ | - * |_| |_| |_|\___/ \__,_|___|___/___/_| - * |_____| - * ssl_scache_dc.c - * Distributed Session Cache (client support) - */ +#include "httpd.h" +#include "http_log.h" +#include "http_request.h" +#include "http_config.h" +#include "http_protocol.h" -#include "ssl_private.h" +#include "apr_strings.h" +#include "apr_time.h" -/* Only build this code if it's enabled at configure-time. */ -#ifdef HAVE_DISTCACHE +#include "ap_socache.h" #include "distcache/dc_client.h" @@ -35,19 +31,6 @@ #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; @@ -55,8 +38,8 @@ DC_CTX *dc; }; -static const char *ssl_scache_dc_create(void **context, const char *arg, - apr_pool_t *tmp, apr_pool_t *p) +static const char *socache_dc_create(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p) { struct context *ctx; @@ -67,7 +50,7 @@ return NULL; } -static apr_status_t ssl_scache_dc_init(void *context, server_rec *s, apr_pool_t *p) +static apr_status_t socache_dc_init(void *context, server_rec *s, apr_pool_t *p) { struct context *ctx = ctx; @@ -97,7 +80,7 @@ return APR_SUCCESS; } -static void ssl_scache_dc_kill(void *context, server_rec *s) +static void socache_dc_kill(void *context, server_rec *s) { struct context *ctx = context; @@ -107,10 +90,10 @@ } } -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) +static apr_status_t socache_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; @@ -126,10 +109,10 @@ 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) +static apr_status_t socache_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; @@ -148,9 +131,9 @@ 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) +static void socache_dc_remove(void *context, server_rec *s, + const unsigned char *id, unsigned int idlen, + apr_pool_t *p) { struct context *ctx = context; @@ -162,27 +145,38 @@ } } -static void ssl_scache_dc_status(void *context, request_rec *r, int flags) +static void socache_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'"); + "distributed scache 'socache_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 = { +static const ap_socache_provider_t socache_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 + socache_dc_create, + socache_dc_init, + socache_dc_kill, + socache_dc_store, + socache_dc_retrieve, + socache_dc_remove, + socache_dc_status }; -#endif +static void register_hooks(apr_pool_t *p) +{ + ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "dc", + AP_SOCACHE_PROVIDER_VERSION, + &socache_dc); +} +const module AP_MODULE_DECLARE_DATA socache_dc_module = { + STANDARD20_MODULE_STUFF, + NULL, NULL, NULL, NULL, NULL, + register_hooks +}; + Index: modules/cache/mod_socache_memcache.c =================================================================== --- modules/cache/mod_socache_memcache.c (revision 633418) +++ modules/cache/mod_socache_memcache.c (working copy) @@ -15,34 +15,25 @@ */ -/* _ _ - * _ __ ___ ___ __| | ___ ___| | mod_ssl - * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL - * | | | | | | (_) | (_| | \__ \__ \ | - * |_| |_| |_|\___/ \__,_|___|___/___/_| - * |_____| - * ssl_scache_memcache.c - * Distributed Session Cache on top of memcached - */ +#include "httpd.h" +#include "http_config.h" -#include "ssl_private.h" +#include "apr.h" +#include "apu_version.h" -#ifdef HAVE_SSL_CACHE_MEMCACHE +/* apr_memcache support requires >= 1.3 */ +#if APU_MAJOR_VERSION > 1 || \ + (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION > 2) +#define HAVE_APU_MEMCACHE 1 +#endif +#ifdef HAVE_APU_MEMCACHE + +#include "ap_socache.h" +#include "ap_mpm.h" +#include "http_log.h" #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 \ @@ -72,8 +63,8 @@ apr_memcache_t *mc; }; -static const char *ssl_scache_mc_create(void **context, const char *arg, - apr_pool_t *tmp, apr_pool_t *p) +static const char *socache_mc_create(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p) { struct context *ctx; @@ -84,7 +75,7 @@ return NULL; } -static apr_status_t ssl_scache_mc_init(void *context, server_rec *s, apr_pool_t *p) +static apr_status_t socache_mc_init(void *context, server_rec *s, apr_pool_t *p) { apr_status_t rv; int thread_limit = 0; @@ -167,7 +158,7 @@ return APR_SUCCESS; } -static void ssl_scache_mc_kill(void *context, server_rec *s) +static void socache_mc_kill(void *context, server_rec *s) { /* noop. */ } @@ -190,10 +181,10 @@ 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) +static apr_status_t socache_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]; @@ -218,10 +209,10 @@ 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) +static apr_status_t socache_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; @@ -261,9 +252,9 @@ 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) +static void socache_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]; @@ -286,21 +277,37 @@ } } -static void ssl_scache_mc_status(void *context, request_rec *r, int flags) +static void socache_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 = { +static const ap_socache_provider_t socache_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 + socache_mc_create, + socache_mc_init, + socache_mc_kill, + socache_mc_store, + socache_mc_retrieve, + socache_mc_remove, + socache_mc_status }; + +#endif /* HAVE_APU_MEMCACHE */ + +static void register_hooks(apr_pool_t *p) +{ +#ifdef HAVE_APU_MEMCACHE + ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "mc", + AP_SOCACHE_PROVIDER_VERSION, + &socache_mc); #endif +} + +const module AP_MODULE_DECLARE_DATA socache_memcache_module = { + STANDARD20_MODULE_STUFF, + NULL, NULL, NULL, NULL, NULL, + register_hooks +}; Index: modules/cache/mod_socache_shmcb.c =================================================================== --- modules/cache/mod_socache_shmcb.c (revision 633418) +++ modules/cache/mod_socache_shmcb.c (working copy) @@ -14,18 +14,23 @@ * limitations under the License. */ -/* _ _ - * _ __ ___ ___ __| | ___ ___| | mod_ssl - * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL - * | | | | | | (_) | (_| | \__ \__ \ | - * |_| |_| |_|\___/ \__,_|___|___/___/_| - * |_____| - * ssl_scache_shmcb.c - * Session Cache via Shared Memory (Cyclic Buffer Variant) - */ +#include "httpd.h" +#include "http_log.h" +#include "http_request.h" +#include "http_protocol.h" +#include "http_config.h" -#include "ssl_private.h" +#include "apr.h" +#include "apr_strings.h" +#include "apr_time.h" +#include "apr_shm.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "ap_socache.h" + +#define SHMCB_MAX_SIZE (64 * 1024 * 1024) + /* * This shared memory based SSL session cache implementation was * originally written by Geoff Thorpe <geoff geoffthorpe.net> for C2Net @@ -254,8 +259,8 @@ * 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) +static const char *socache_shmcb_create(void **context, const char *arg, + apr_pool_t *tmp, apr_pool_t *p) { struct context *ctx; char *path, *cp, *cp2; @@ -268,13 +273,13 @@ cp = strchr(path, '('); if (cp) { - *cp++ = NUL; + *cp++ = '\0'; if (!(cp2 = strchr(cp, ')'))) { return "Invalid argument: no closing parenthesis"; } - *cp2 = NUL; + *cp2 = '\0'; ctx->shm_size = atoi(cp); @@ -283,11 +288,11 @@ } - if (ctx->shm_size >= APR_SHM_MAXSIZE) { + if (ctx->shm_size >= SHMCB_MAX_SIZE) { return apr_psprintf(tmp, "Invalid argument: size has " "to be < %d bytes on this platform", - APR_SHM_MAXSIZE); + SHMCB_MAX_SIZE); } } @@ -295,7 +300,7 @@ return NULL; } -static apr_status_t ssl_scache_shmcb_init(void *context, server_rec *s, apr_pool_t *p) +static apr_status_t socache_shmcb_init(void *context, server_rec *s, apr_pool_t *p) { void *shm_segment; apr_size_t shm_segsize; @@ -415,7 +420,7 @@ return APR_SUCCESS; } -static void ssl_scache_shmcb_kill(void *context, server_rec *s) +static void socache_shmcb_kill(void *context, server_rec *s) { struct context *ctx = context; @@ -425,18 +430,18 @@ } } -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) +static apr_status_t socache_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)", + "socache_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 " @@ -451,11 +456,11 @@ } header->stat_stores++; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "leaving ssl_scache_shmcb_store successfully"); + "leaving socache_shmcb_store successfully"); return APR_SUCCESS; } -static apr_status_t ssl_scache_shmcb_retrieve(void *context, server_rec *s, +static apr_status_t socache_shmcb_retrieve(void *context, server_rec *s, const unsigned char *id, unsigned int idlen, unsigned char *dest, unsigned int *destlen, apr_pool_t *p) @@ -466,7 +471,7 @@ int rv; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "ssl_scache_shmcb_retrieve (0x%02x -> subcache %d)", + "socache_shmcb_retrieve (0x%02x -> subcache %d)", SHMCB_MASK_DBG(header, id)); /* Get the session corresponding to the session_id, if it exists. */ @@ -477,12 +482,12 @@ else header->stat_retrieves_miss++; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "leaving ssl_scache_shmcb_retrieve successfully"); + "leaving socache_shmcb_retrieve successfully"); return rv == 0 ? APR_SUCCESS : APR_EGENERAL; } -static void ssl_scache_shmcb_remove(void *context, server_rec *s, +static void socache_shmcb_remove(void *context, server_rec *s, const unsigned char *id, unsigned int idlen, apr_pool_t *p) { @@ -491,7 +496,7 @@ SHMCBSubcache *subcache = SHMCB_MASK(header, id); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "ssl_scache_shmcb_remove (0x%02x -> subcache %d)", + "socache_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 " @@ -503,10 +508,10 @@ else header->stat_removes_miss++; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "leaving ssl_scache_shmcb_remove successfully"); + "leaving socache_shmcb_remove successfully"); } -static void ssl_scache_shmcb_status(void *context, request_rec *r, int flags) +static void socache_shmcb_status(void *context, request_rec *r, int flags) { server_rec *s = r->server; struct context *ctx = context; @@ -820,14 +825,27 @@ return -1; /* failure */ } -const modssl_sesscache_provider modssl_sesscache_shmcb = { +static const ap_socache_provider_t socache_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 + AP_SOCACHE_FLAG_NOTMPSAFE, + socache_shmcb_create, + socache_shmcb_init, + socache_shmcb_kill, + socache_shmcb_store, + socache_shmcb_retrieve, + socache_shmcb_remove, + socache_shmcb_status }; + +static void register_hooks(apr_pool_t *p) +{ + ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "shmcb", + AP_SOCACHE_PROVIDER_VERSION, + &socache_shmcb); +} + +const module AP_MODULE_DECLARE_DATA socache_shmcb_module = { + STANDARD20_MODULE_STUFF, + NULL, NULL, NULL, NULL, NULL, + register_hooks +};