/* 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.
 */

#include "httpd.h"
#include "http_log.h"
#include "http_request.h"
#include "http_protocol.h"
#include "http_config.h"
#include "mod_status.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 "apr_general.h"

#if APR_HAVE_LIMITS_H
#include <limits.h>
#endif

#include "ap_socache.h"

/* XXX Unfortunately, there are still many unsigned ints in use here, so we
 * XXX cannot allow more than UINT_MAX. Since some of the ints are exposed in
 * XXX public interfaces, a simple search and replace is not enough.
 * XXX It should be possible to extend that so that the total cache size can
 * XXX be APR_SIZE_MAX and only the object size needs to be smaller than
 * XXX UINT_MAX.
 */
#define SHMCB_MAX_SIZE (UINT_MAX<APR_SIZE_MAX ? UINT_MAX : APR_SIZE_MAX)

#define DEFAULT_SHMCB_PREFIX "socache-shmcb-"

#define DEFAULT_SHMCB_SUFFIX ".cache"

#define ALIGNED_HEADER_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBHeader))
#define ALIGNED_SUBCACHE_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBSubcache))
#define ALIGNED_INDEX_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBIndex))

/*
 * Header structure - the start of the shared-mem segment
 */
typedef struct {
    /* Stats for cache operations */
    unsigned long stat_stores;
    unsigned long stat_replaced;
    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 */
    apr_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 socache entries */
    unsigned char removed;
} SHMCBIndex;

struct ap_socache_instance_t {
    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 cached object.
 * 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)) + \
                        ALIGNED_HEADER_SIZE + \
                        (num) * ((pHeader)->subcache_size))

/* This macro takes a pointer to the header and an 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) + \
                        ALIGNED_SUBCACHE_SIZE + \
                        (num) * ALIGNED_INDEX_SIZE)

/* 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 *,
                                  apr_time_t);
/* 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,
                                apr_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);

/* Returns result of the (iterator)() call, zero is success (continue) */
static apr_status_t shmcb_subcache_iterate(ap_socache_instance_t *instance,
                                           server_rec *s,
                                           void *userctx,
                                           SHMCBHeader *header,
                                           SHMCBSubcache *subcache,
                                           ap_socache_iterator_t *iterator,
                                           unsigned char **buf,
                                           apr_size_t *buf_len,
                                           apr_pool_t *pool,
                                           apr_time_t now);

/*
 * High-Level "handlers" as per ssl_scache.c
 * subcache internals are deferred to shmcb_subcache_*** functions lower down
 */

static const char *socache_shmcb_create(ap_socache_instance_t **context,
                                        const char *arg,
                                        apr_pool_t *tmp, apr_pool_t *p)
{
    ap_socache_instance_t *ctx;
    char *path, *cp, *cp2;

    /* Allocate the context. */
    *context = ctx = apr_pcalloc(p, sizeof *ctx);

    ctx->shm_size  = 1024*512; /* 512KB */

    if (!arg || *arg == '\0') {
        /* Use defaults. */
        return NULL;
    }

    ctx->data_file = path = ap_runtime_dir_relative(p, arg);

    cp = strrchr(path, '(');
    cp2 = path + strlen(path) - 1;
    if (cp) {
        char *endptr;
        if (*cp2 != ')') {
            return "Invalid argument: no closing parenthesis or cache size "
                   "missing after pathname with parenthesis";
        }
        *cp++ = '\0';
        *cp2  = '\0';


        ctx->shm_size = strtol(cp, &endptr, 10);
        if (endptr != cp2) {
            return "Invalid argument: cache size not numerical";
        }

        if (ctx->shm_size < 8192) {
            return "Invalid argument: size has to be >= 8192 bytes";

        }

        if (ctx->shm_size >= SHMCB_MAX_SIZE) {
            return apr_psprintf(tmp, "Invalid argument: size has "
                    "to be < %" APR_SIZE_T_FMT " bytes on this platform",
                    SHMCB_MAX_SIZE);
        }
    }
    else if (cp2 >= path && *cp2 == ')') {
        return "Invalid argument: no opening parenthesis";
    }

    return NULL;
}

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;
    apr_size_t shm_segsize;
    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) {
        const char *path = apr_pstrcat(p, DEFAULT_SHMCB_PREFIX, namespace,
                                       DEFAULT_SHMCB_SUFFIX, NULL);

        ctx->data_file = ap_runtime_dir_relative(p, path);
    }

    /* 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)) {
        /* If anon shm isn't supported, fail if no named file was
         * configured successfully; the ap_runtime_dir_relative call
         * above will return NULL for invalid paths. */
        if (ctx->data_file == NULL) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00818)
                         "Could not use default path '%s' for shmcb socache",
                         ctx->data_file);
            return APR_EINVAL;
        }

        /* 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, APLOGNO(00819)
                     "Could not allocate shared memory segment for shmcb "
                     "socache");
        return rv;
    }

    shm_segment = apr_shm_baseaddr_get(ctx->shm);
    shm_segsize = apr_shm_size_get(ctx->shm);
    if (shm_segsize < (5 * ALIGNED_HEADER_SIZE)) {
        /* the segment is ridiculously small, bail out */
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00820)
                     "shared memory segment too small");
        return APR_ENOSPC;
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00821)
                 "shmcb_init allocated %" APR_SIZE_T_FMT
                 " bytes of shared memory",
                 shm_segsize);
    /* Discount the header */
    shm_segsize -= ALIGNED_HEADER_SIZE;
    /* 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;
    num_idx /= num_subcache;
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00822)
                 "for %" APR_SIZE_T_FMT " bytes (%" APR_SIZE_T_FMT
                 " including header), recommending %u subcaches, "
                 "%u indexes each", shm_segsize,
                 shm_segsize + ALIGNED_HEADER_SIZE,
                 num_subcache, num_idx);
    if (num_idx < 5) {
        /* we're still too small, bail out */
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00823)
                     "shared memory segment too small");
        return APR_ENOSPC;
    }
    /* OK, we're sorted */
    ctx->header = header = shm_segment;
    header->stat_stores = 0;
    header->stat_replaced = 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. */
    header->subcache_size = (size_t)(shm_segsize / num_subcache);
    if (header->subcache_size != APR_ALIGN_DEFAULT(header->subcache_size)) {
        header->subcache_size = APR_ALIGN_DEFAULT(header->subcache_size) -
                                APR_ALIGN_DEFAULT(1);
    }
    header->subcache_data_offset = ALIGNED_SUBCACHE_SIZE +
                                   num_idx * ALIGNED_INDEX_SIZE;
    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, APLOGNO(00824)
                 "shmcb_init_memory choices follow");
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00825)
                 "subcache_num = %u", header->subcache_num);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00826)
                 "subcache_size = %u", header->subcache_size);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00827)
                 "subcache_data_offset = %u", header->subcache_data_offset);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00828)
                 "subcache_data_size = %u", header->subcache_data_size);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00829)
                 "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, APLOGNO(00830)
                 "Shared memory socache initialised");
    /* Success ... */

    return APR_SUCCESS;
}

static void socache_shmcb_destroy(ap_socache_instance_t *ctx, server_rec *s)
{
    if (ctx && ctx->shm) {
        apr_shm_destroy(ctx->shm);
        ctx->shm = NULL;
    }
}

static apr_status_t socache_shmcb_store(ap_socache_instance_t *ctx,
                                        server_rec *s, const unsigned char *id,
                                        unsigned int idlen, apr_time_t expiry,
                                        unsigned char *encoded,
                                        unsigned int len_encoded,
                                        apr_pool_t *p)
{
    SHMCBHeader *header = ctx->header;
    SHMCBSubcache *subcache = SHMCB_MASK(header, id);
    int tryreplace;

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00831)
                 "socache_shmcb_store (0x%02x -> subcache %d)",
                 SHMCB_MASK_DBG(header, id));
    /* XXX: Says who?  Why shouldn't this be acceptable, or padded if not? */
    if (idlen < 4) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00832) "unusably short id provided "
                "(%u bytes)", idlen);
        return APR_EINVAL;
    }
    tryreplace = shmcb_subcache_remove(s, header, subcache, id, idlen);
    if (shmcb_subcache_store(s, header, subcache, encoded,
                             len_encoded, id, idlen, expiry)) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00833)
                     "can't store an socache entry!");
        return APR_ENOSPC;
    }
    if (tryreplace == 0) {
        header->stat_replaced++;
    }
    else {
        header->stat_stores++;
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00834)
                 "leaving socache_shmcb_store successfully");
    return APR_SUCCESS;
}

static apr_status_t socache_shmcb_retrieve(ap_socache_instance_t *ctx,
                                           server_rec *s,
                                           const unsigned char *id, unsigned int idlen,
                                           unsigned char *dest, unsigned int *destlen,
                                           apr_pool_t *p)
{
    SHMCBHeader *header = ctx->header;
    SHMCBSubcache *subcache = SHMCB_MASK(header, id);
    int rv;

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00835)
                 "socache_shmcb_retrieve (0x%02x -> subcache %d)",
                 SHMCB_MASK_DBG(header, id));

    /* Get the entry corresponding to the 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, APLOGNO(00836)
                 "leaving socache_shmcb_retrieve successfully");

    return rv == 0 ? APR_SUCCESS : APR_NOTFOUND;
}

static apr_status_t socache_shmcb_remove(ap_socache_instance_t *ctx,
                                         server_rec *s, const unsigned char *id,
                                         unsigned int idlen, apr_pool_t *p)
{
    SHMCBHeader *header = ctx->header;
    SHMCBSubcache *subcache = SHMCB_MASK(header, id);
    apr_status_t rv;

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00837)
                 "socache_shmcb_remove (0x%02x -> subcache %d)",
                 SHMCB_MASK_DBG(header, id));
    if (idlen < 4) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00838) "unusably short id provided "
                "(%u bytes)", idlen);
        return APR_EINVAL;
    }
    if (shmcb_subcache_remove(s, header, subcache, id, idlen) == 0) {
        header->stat_removes_hit++;
        rv = APR_SUCCESS;
    } else {
        header->stat_removes_miss++;
        rv = APR_NOTFOUND;
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00839)
                 "leaving socache_shmcb_remove successfully");

    return rv;
}

static void socache_shmcb_status(ap_socache_instance_t *ctx,
                                 request_rec *r, int flags)
{
    server_rec *s = r->server;
    SHMCBHeader *header = ctx->header;
    unsigned int loop, total = 0, cache_total = 0, non_empty_subcaches = 0;
    apr_time_t idx_expiry, min_expiry = 0, max_expiry = 0;
    apr_time_t now = apr_time_now();
    double expiry_total = 0;
    int index_pct, cache_pct;

    AP_DEBUG_ASSERT(header->subcache_num > 0);
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00840) "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, now);
        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 Output */
    if (!(flags & AP_STATUS_SHORT)) {
        ap_rprintf(r, "cache type: <b>SHMCB</b>, shared memory: <b>%" APR_SIZE_T_FMT "</b> "
                   "bytes, current entries: <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) {
            apr_time_t average_expiry = (apr_time_t)(expiry_total / (double)non_empty_subcaches);
            ap_rprintf(r, "time left on oldest entries' objects: ");
            if (now < average_expiry)
                ap_rprintf(r, "avg: <b>%d</b> seconds, (range: %d...%d)<br>",
                           (int)apr_time_sec(average_expiry - now),
                           (int)apr_time_sec(min_expiry - now),
                           (int)apr_time_sec(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 entries stored since starting: <b>%lu</b><br>",
                   header->stat_stores);
        ap_rprintf(r, "total entries replaced since starting: <b>%lu</b><br>",
                   header->stat_replaced);
        ap_rprintf(r, "total entries expired since starting: <b>%lu</b><br>",
                   header->stat_expiries);
        ap_rprintf(r, "total (pre-expiry) entries 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);
    }
    else {
        ap_rputs("CacheType: SHMCB\n", r);
        ap_rprintf(r, "CacheSharedMemory: %" APR_SIZE_T_FMT "\n",
                   ctx->shm_size);
        ap_rprintf(r, "CacheCurrentEntries: %d\n", total);
        ap_rprintf(r, "CacheSubcaches: %d\n", header->subcache_num);
        ap_rprintf(r, "CacheIndexesPerSubcaches: %d\n", header->index_num);
        if (non_empty_subcaches) {
            apr_time_t average_expiry = (apr_time_t)(expiry_total / (double)non_empty_subcaches);
            if (now < average_expiry) {
                ap_rprintf(r, "CacheTimeLeftOldestAvg: %d\n", (int)apr_time_sec(average_expiry - now));
                ap_rprintf(r, "CacheTimeLeftOldestMin: %d\n", (int)apr_time_sec(min_expiry - now));
                ap_rprintf(r, "CacheTimeLeftOldestMax: %d\n", (int)apr_time_sec(max_expiry - now));
            }
        }

        ap_rprintf(r, "CacheIndexUsage: %d%%\n", index_pct);
        ap_rprintf(r, "CacheUsage: %d%%\n", cache_pct);
        ap_rprintf(r, "CacheStoreCount: %lu\n", header->stat_stores);
        ap_rprintf(r, "CacheReplaceCount: %lu\n", header->stat_replaced);
        ap_rprintf(r, "CacheExpireCount: %lu\n", header->stat_expiries);
        ap_rprintf(r, "CacheDiscardCount: %lu\n", header->stat_scrolled);
        ap_rprintf(r, "CacheRetrieveHitCount: %lu\n", header->stat_retrieves_hit);
        ap_rprintf(r, "CacheRetrieveMissCount: %lu\n", header->stat_retrieves_miss);
        ap_rprintf(r, "CacheRemoveHitCount: %lu\n", header->stat_removes_hit);
        ap_rprintf(r, "CacheRemoveMissCount: %lu\n", header->stat_removes_miss);
    }
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00841) "leaving shmcb_status");
}

static apr_status_t socache_shmcb_iterate(ap_socache_instance_t *instance,
                                          server_rec *s, void *userctx,
                                          ap_socache_iterator_t *iterator,
                                          apr_pool_t *pool)
{
    SHMCBHeader *header = instance->header;
    unsigned int loop;
    apr_time_t now = apr_time_now();
    apr_status_t rv = APR_SUCCESS;
    apr_size_t buflen = 0;
    unsigned char *buf = NULL;

    /* 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 && rv == APR_SUCCESS; loop++) {
        SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
        rv = shmcb_subcache_iterate(instance, s, userctx, header, subcache,
                                    iterator, &buf, &buflen, pool, now);
    }
    return rv;
}

/*
 * Subcache-level cache operations
 */

static void shmcb_subcache_expire(server_rec *s, SHMCBHeader *header,
                                  SHMCBSubcache *subcache, apr_time_t now)
{
    unsigned int loop = 0, freed = 0, expired = 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->removed)
            freed++;
        else if (idx->expires <= now)
            expired++;
        else
            /* not removed and not 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, APLOGNO(00842)
                 "expiring %u and reclaiming %u removed socache entries",
                 expired, freed);
    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 += expired;
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00843)
                 "we now have %u socache entries", 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,
                                apr_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, APLOGNO(00844)
                     "inserting socache entry larger (%d) than subcache data area (%d)",
                     total_len, header->subcache_data_size);
        return -1;
    }

    /* First reclaim space from removed and expired records. */
    shmcb_subcache_expire(s, header, subcache, apr_time_now());

    /* Loop until there is enough space to insert
     * XXX: This should first compress out-of-order expiries and
     * removed records, and then force-remove oldest-first
     */
    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, APLOGNO(00845)
                     "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, APLOGNO(00846)
                     "finished force-expire, subcache: idx_used=%d, "
                     "data_used=%d", subcache->idx_used, subcache->data_used);
    }

    /* HERE WE ASSUME THAT THE NEW ENTRY SHOULD GO ON THE END! I'M NOT
     * CHECKING WHETHER IT SHOULD BE GENUINELY "INSERTED" SOMEWHERE.
     *
     * We aught to fix that.  httpd (never mind third party modules)
     * does not promise to perform any processing in date order
     * (c.f. FAQ "My log entries are not in date order!")
     */
    /* 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, APLOGNO(00847)
                 "insert happened at idx=%d, data=(%u:%u)", new_idx,
                 id_offset, data_offset);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00848)
                 "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;
    apr_time_t now = apr_time_now();

    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, and the record is not expired.
         * 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) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00849)
                         "match at idx=%d, data=%d", pos, idx->data_pos);
            if (idx->expires > now) {
                unsigned int data_offset;

                /* 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;
            }
            else {
                /* Already stale, quietly remove and treat as not-found */
                idx->removed = 1;
                header->stat_expiries++;
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00850)
                             "shmcb_subcache_retrieve discarding expired entry");
                return -1;
            }
        }
        /* Increment */
        loop++;
        pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
    }

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00851)
                 "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;

    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, APLOGNO(00852)
                         "possible match at idx=%d, data=%d", pos, idx->data_pos);

            /* Found the matching entry, remove it quietly. */
            idx->removed = 1;
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00853)
                         "shmcb_subcache_remove removing matching entry");
            return 0;
        }
        /* Increment */
        loop++;
        pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
    }

    return -1; /* failure */
}


static apr_status_t shmcb_subcache_iterate(ap_socache_instance_t *instance,
                                           server_rec *s,
                                           void *userctx,
                                           SHMCBHeader *header,
                                           SHMCBSubcache *subcache,
                                           ap_socache_iterator_t *iterator,
                                           unsigned char **buf,
                                           apr_size_t *buf_len,
                                           apr_pool_t *pool,
                                           apr_time_t now)
{
    unsigned int pos;
    unsigned int loop = 0;
    apr_status_t rv;

    pos = subcache->idx_pos;
    while (loop < subcache->idx_used) {
        SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);

        /* Only consider 'idx' if the "removed" flag isn't set. */
        if (!idx->removed) {

            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00854)
                         "iterating idx=%d, data=%d", pos, idx->data_pos);
            if (idx->expires > now) {
                unsigned char *id = *buf;
                unsigned char *dest;
                unsigned int data_offset, dest_len;
                apr_size_t buf_req;

                /* 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);

                dest_len = idx->data_used - idx->id_len;

                buf_req = APR_ALIGN_DEFAULT(idx->id_len + 1)
                        + APR_ALIGN_DEFAULT(dest_len + 1);

                if (buf_req > *buf_len) {
                     /* Grow to ~150% of this buffer requirement on resize
                      * always using APR_ALIGN_DEFAULT sized pages
                      */
                     *buf_len = buf_req + APR_ALIGN_DEFAULT(buf_req / 2);
                     *buf = apr_palloc(pool, *buf_len);
                     id = *buf;
                }

                dest = *buf + APR_ALIGN_DEFAULT(idx->id_len + 1);

                /* Copy out the data, because it's potentially cyclic */
                shmcb_cyclic_cton_memcpy(header->subcache_data_size, id,
                                         SHMCB_DATA(header, subcache),
                                         idx->data_pos, idx->id_len);
                id[idx->id_len] = '\0';

                shmcb_cyclic_cton_memcpy(header->subcache_data_size, dest,
                                         SHMCB_DATA(header, subcache),
                                         data_offset, dest_len);
                dest[dest_len] = '\0';

                rv = iterator(instance, s, userctx, id, idx->id_len,
                              dest, dest_len, pool);
                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00855)
                             "shmcb entry iterated");
                if (rv != APR_SUCCESS)
                    return rv;
            }
            else {
                /* Already stale, quietly remove and treat as not-found */
                idx->removed = 1;
                header->stat_expiries++;
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00856)
                             "shmcb_subcache_iterate discarding expired entry");
            }
        }
        /* Increment */
        loop++;
        pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
    }

    return APR_SUCCESS;
}

static const ap_socache_provider_t socache_shmcb = {
    "shmcb",
    AP_SOCACHE_FLAG_NOTMPSAFE,
    socache_shmcb_create,
    socache_shmcb_init,
    socache_shmcb_destroy,
    socache_shmcb_store,
    socache_shmcb_retrieve,
    socache_shmcb_remove,
    socache_shmcb_status,
    socache_shmcb_iterate
};

static void register_hooks(apr_pool_t *p)
{
    ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "shmcb",
                         AP_SOCACHE_PROVIDER_VERSION,
                         &socache_shmcb);

    /* Also register shmcb under the default provider name. */
    ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP,
                         AP_SOCACHE_DEFAULT_PROVIDER,
                         AP_SOCACHE_PROVIDER_VERSION,
                         &socache_shmcb);
}

AP_DECLARE_MODULE(socache_shmcb) = {
    STANDARD20_MODULE_STUFF,
    NULL, NULL, NULL, NULL, NULL,
    register_hooks
};
