mirror of
https://github.com/apache/httpd.git
synced 2025-08-01 16:41:19 +00:00
Adjust socache init interface to take sizing hints, and namespace tag
for memcache: * modules/cache/ap_socache.h (struct ap_socache_hints): New structure. Change init callback to take namespace string and hints structure pointer. * modules/cache/mod_socache_dc.c (socache_dc_init): Adjust accordingly. * modules/cache/mod_socache_dbm.c (struct ap_socache_instance_t): Rename timeout field to expiry_interval. (socache_dbm_init, socache_dbm_create): Take expiry interval from hints rather than hard-code to 30. (socache_dbm_expire): Update for timeout field rename. * modules/cache/mod_socache_shmcb.c (socache_shmcb_init): Adjust for hints and namespace; adjust subcache index sizing heuristics to use passed-in hints. * modules/cache/mod_socache_memcache.c (struct ap_socache_instance_t): Add tag, taglen fields. (socache_mc_init): Store the passed-in namespace in instance structure. (mc_session_id2sz): Adjust to not take context, use configured tag as string prefix, and not use a return value. (socache_mc_store, socache_mc_retrieve, socache_mc_remove): Adjust for mc_session_id2sz interface changes. * modules/ssl/ssl_scache.c (ssl_scache_init): Pass namespace and hints to socache provider init function. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@645978 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
19
modules/cache/ap_socache.h
vendored
19
modules/cache/ap_socache.h
vendored
@ -39,6 +39,18 @@
|
||||
/* A cache instance. */
|
||||
typedef struct ap_socache_instance_t ap_socache_instance_t;
|
||||
|
||||
/* Hints which may be passed to the init function; providers may
|
||||
* ignore some or all of these hints. */
|
||||
struct ap_socache_hints {
|
||||
/* Approximate average length of IDs: */
|
||||
apr_size_t avg_id_len;
|
||||
/* Approximate average size of objects: */
|
||||
apr_size_t avg_obj_size;
|
||||
/* Interval (in seconds) after which an expiry run is
|
||||
* necessary. */
|
||||
time_t expiry_interval;
|
||||
};
|
||||
|
||||
typedef struct ap_socache_provider_t {
|
||||
/* Canonical provider name: */
|
||||
const char *name;
|
||||
@ -56,8 +68,11 @@ typedef struct ap_socache_provider_t {
|
||||
* first argument to subsequent invocations. */
|
||||
const char *(*create)(ap_socache_instance_t **instance, const char *arg,
|
||||
apr_pool_t *tmp, apr_pool_t *p);
|
||||
/* Initialize the cache. Return APR error code. */
|
||||
apr_status_t (*init)(ap_socache_instance_t *instance, /* hints, namespace */
|
||||
/* Initialize the cache. NAMESPACE must given a unique string
|
||||
* prefix for use with memcached; if hints is non-NULL, it gives a
|
||||
* set of hints for the provider. Return APR error code. */
|
||||
apr_status_t (*init)(ap_socache_instance_t *instance, const char *namespace,
|
||||
const struct ap_socache_hints *hints,
|
||||
server_rec *s, apr_pool_t *pool);
|
||||
/* Destroy a given cache context. */
|
||||
void (*destroy)(ap_socache_instance_t *instance, server_rec *s);
|
||||
|
11
modules/cache/mod_socache_dbm.c
vendored
11
modules/cache/mod_socache_dbm.c
vendored
@ -41,7 +41,7 @@ struct ap_socache_instance_t {
|
||||
/* Pool must only be used with the mutex held. */
|
||||
apr_pool_t *pool;
|
||||
time_t last_expiry;
|
||||
time_t timeout;
|
||||
time_t expiry_interval;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -81,13 +81,15 @@ static const char *socache_dbm_create(ap_socache_instance_t **context,
|
||||
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 socache_dbm_init(ap_socache_instance_t *ctx,
|
||||
const char *namespace,
|
||||
const struct ap_socache_hints *hints,
|
||||
server_rec *s, apr_pool_t *p)
|
||||
{
|
||||
apr_dbm_t *dbm;
|
||||
@ -112,6 +114,9 @@ static apr_status_t socache_dbm_init(ap_socache_instance_t *ctx,
|
||||
}
|
||||
apr_dbm_close(dbm);
|
||||
|
||||
ctx->expiry_interval = (hints && hints->expiry_interval
|
||||
? hints->expiry_interval : 30);
|
||||
|
||||
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
|
||||
/*
|
||||
* We have to make sure the Apache child processes have access to
|
||||
@ -345,7 +350,7 @@ static void socache_dbm_expire(ap_socache_instance_t *ctx, server_rec *s)
|
||||
*/
|
||||
tNow = time(NULL);
|
||||
|
||||
if (tNow < ctx->last_expiry + ctx->timeout) {
|
||||
if (tNow < ctx->last_expiry + ctx->expiry_interval) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
5
modules/cache/mod_socache_dc.c
vendored
5
modules/cache/mod_socache_dc.c
vendored
@ -51,7 +51,10 @@ static const char *socache_dc_create(ap_socache_instance_t **context,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static apr_status_t socache_dc_init(ap_socache_instance_t *ctx, server_rec *s, apr_pool_t *p)
|
||||
static apr_status_t socache_dc_init(ap_socache_instance_t *ctx,
|
||||
const char *namespace,
|
||||
const struct ap_socache_hints *hints,
|
||||
server_rec *s, apr_pool_t *p)
|
||||
{
|
||||
#if 0
|
||||
/* If a "persistent connection" mode of operation is preferred, you *must*
|
||||
|
55
modules/cache/mod_socache_memcache.c
vendored
55
modules/cache/mod_socache_memcache.c
vendored
@ -35,10 +35,6 @@
|
||||
#include "apr_memcache.h"
|
||||
|
||||
/* 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
|
||||
@ -61,6 +57,8 @@
|
||||
struct ap_socache_instance_t {
|
||||
const char *servers;
|
||||
apr_memcache_t *mc;
|
||||
const char *tag;
|
||||
apr_size_t taglen;
|
||||
};
|
||||
|
||||
static const char *socache_mc_create(ap_socache_instance_t **context,
|
||||
@ -77,6 +75,8 @@ static const char *socache_mc_create(ap_socache_instance_t **context,
|
||||
}
|
||||
|
||||
static apr_status_t socache_mc_init(ap_socache_instance_t *ctx,
|
||||
const char *namespace,
|
||||
const struct ap_socache_hints *hints,
|
||||
server_rec *s, apr_pool_t *p)
|
||||
{
|
||||
apr_status_t rv;
|
||||
@ -156,6 +156,9 @@ static apr_status_t socache_mc_init(ap_socache_instance_t *ctx,
|
||||
split = apr_strtok(NULL,",", &tok);
|
||||
}
|
||||
|
||||
ctx->tag = apr_pstrcat(p, namespace, ":", NULL);
|
||||
ctx->taglen = strlen(ctx->tag);
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -164,22 +167,21 @@ static void socache_mc_kill(ap_socache_instance_t *context, server_rec *s)
|
||||
/* noop. */
|
||||
}
|
||||
|
||||
static char *mc_session_id2sz(const unsigned char *id, unsigned int idlen,
|
||||
char *str, int strsize)
|
||||
static void mc_session_id2sz(ap_socache_instance_t *ctx,
|
||||
const unsigned char *id, unsigned int idlen,
|
||||
char *buf, apr_size_t buflen)
|
||||
{
|
||||
apr_size_t maxlen = (buflen - ctx->taglen) / 2;
|
||||
char *cp;
|
||||
int n;
|
||||
int maxlen = (strsize - MC_TAG_LEN)/2;
|
||||
|
||||
cp = apr_cpystrn(str, MC_TAG, MC_TAG_LEN);
|
||||
cp = apr_cpystrn(buf, ctx->tag, ctx->taglen);
|
||||
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 socache_mc_store(ap_socache_instance_t *ctx, server_rec *s,
|
||||
@ -188,21 +190,16 @@ static apr_status_t socache_mc_store(ap_socache_instance_t *ctx, server_rec *s,
|
||||
unsigned char *ucaData, unsigned int nData)
|
||||
{
|
||||
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;
|
||||
}
|
||||
mc_session_id2sz(ctx, id, idlen, buf, sizeof(buf));
|
||||
|
||||
rv = apr_memcache_set(ctx->mc, strkey, (char*)ucaData, nData, timeout, 0);
|
||||
rv = apr_memcache_set(ctx->mc, buf, (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);
|
||||
"with %d bytes of data", buf, nData);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -217,21 +214,14 @@ static apr_status_t socache_mc_retrieve(ap_socache_instance_t *ctx,
|
||||
{
|
||||
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;
|
||||
}
|
||||
mc_session_id2sz(ctx, id, idlen, buf, sizeof(buf));
|
||||
|
||||
/* ### 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,
|
||||
rv = apr_memcache_getp(ctx->mc, p, buf,
|
||||
&der, &der_len, NULL);
|
||||
if (rv) {
|
||||
if (rv != APR_NOTFOUND) {
|
||||
@ -257,21 +247,16 @@ static void socache_mc_remove(ap_socache_instance_t *ctx, server_rec *s,
|
||||
apr_pool_t *p)
|
||||
{
|
||||
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;
|
||||
}
|
||||
mc_session_id2sz(ctx, id, idlen, buf, sizeof(buf));
|
||||
|
||||
rv = apr_memcache_delete(ctx->mc, strkey, 0);
|
||||
rv = apr_memcache_delete(ctx->mc, buf, 0);
|
||||
|
||||
if (rv != APR_SUCCESS) {
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
|
||||
"scache_mc: error deleting key '%s' ",
|
||||
strkey);
|
||||
buf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
17
modules/cache/mod_socache_shmcb.c
vendored
17
modules/cache/mod_socache_shmcb.c
vendored
@ -302,6 +302,8 @@ static const char *socache_shmcb_create(ap_socache_instance_t **context,
|
||||
}
|
||||
|
||||
static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
|
||||
const char *namespace,
|
||||
const struct ap_socache_hints *hints,
|
||||
server_rec *s, apr_pool_t *p)
|
||||
{
|
||||
void *shm_segment;
|
||||
@ -309,6 +311,7 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
|
||||
apr_status_t rv;
|
||||
SHMCBHeader *header;
|
||||
unsigned int num_subcache, num_idx, loop;
|
||||
apr_size_t avg_obj_size, avg_id_len;
|
||||
|
||||
/* Create shared memory segment */
|
||||
if (ctx->data_file == NULL) {
|
||||
@ -348,16 +351,10 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
|
||||
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;
|
||||
/* Select index size based on average object size hints, if given. */
|
||||
avg_obj_size = hints && hints->avg_obj_size ? hints->avg_obj_size : 150;
|
||||
avg_id_len = hints && hints->avg_id_len ? hints->avg_id_len : 30;
|
||||
num_idx = (shm_segsize) / (avg_obj_size + avg_id_len);
|
||||
num_subcache = 256;
|
||||
while ((num_idx / num_subcache) < (2 * num_subcache))
|
||||
num_subcache /= 2;
|
||||
|
@ -43,6 +43,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p)
|
||||
apr_status_t rv;
|
||||
void *data;
|
||||
const char *userdata_key = "ssl_scache_init";
|
||||
struct ap_socache_hints hints;
|
||||
|
||||
/* The very first invocation of this function will be the
|
||||
* post_config invocation during server startup; do nothing for
|
||||
@ -67,7 +68,12 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p)
|
||||
return;
|
||||
}
|
||||
|
||||
rv = mc->sesscache->init(mc->sesscache_context, s, p);
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.avg_obj_size = 150;
|
||||
hints.avg_id_len = 30;
|
||||
hints.expiry_interval = 30;
|
||||
|
||||
rv = mc->sesscache->init(mc->sesscache_context, "mod_ssl", &hints, s, p);
|
||||
if (rv) {
|
||||
/* ABORT ABORT etc. */
|
||||
ssl_die();
|
||||
|
Reference in New Issue
Block a user