⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_scache_shmht.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
字号:
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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_shmht.c *  Session Cache via Shared Memory (Hash Table Variant) */#include "mod_ssl.h"/* *  Wrapper functions for table library which resemble malloc(3) & Co  *  but use the variants from the MM shared memory library. */static void *ssl_scache_shmht_malloc(void *opt_param, size_t size){    SSLModConfigRec *mc = myModConfig((server_rec *)opt_param);    apr_rmm_off_t off = apr_rmm_calloc(mc->pSessionCacheDataRMM, size);    return apr_rmm_addr_get(mc->pSessionCacheDataRMM, off);}static void *ssl_scache_shmht_calloc(void *opt_param,                                     size_t number, size_t size){    SSLModConfigRec *mc = myModConfig((server_rec *)opt_param);    apr_rmm_off_t off = apr_rmm_calloc(mc->pSessionCacheDataRMM, (number*size));    return apr_rmm_addr_get(mc->pSessionCacheDataRMM, off);}static void *ssl_scache_shmht_realloc(void *opt_param, void *ptr, size_t size){    SSLModConfigRec *mc = myModConfig((server_rec *)opt_param);    apr_rmm_off_t off = apr_rmm_realloc(mc->pSessionCacheDataRMM, ptr, size);    return apr_rmm_addr_get(mc->pSessionCacheDataRMM, off);}static void ssl_scache_shmht_free(void *opt_param, void *ptr){    SSLModConfigRec *mc = myModConfig((server_rec *)opt_param);    apr_rmm_off_t off = apr_rmm_offset_get(mc->pSessionCacheDataRMM, ptr);    apr_rmm_free(mc->pSessionCacheDataRMM, off);    return;}/* * Now the actual session cache implementation * based on a hash table inside a shared memory segment. */void ssl_scache_shmht_init(server_rec *s, apr_pool_t *p){    SSLModConfigRec *mc = myModConfig(s);    table_t *ta;    int ta_errno;    apr_size_t avail;    int n;    apr_status_t rv;    /*     * Create shared memory segment     */    if (mc->szSessionCacheDataFile == NULL) {        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                     "SSLSessionCache required");        ssl_die();    }    if ((rv = apr_shm_create(&(mc->pSessionCacheDataMM),                    mc->nSessionCacheDataSize,                    mc->szSessionCacheDataFile, mc->pPool)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,                     "Cannot allocate shared memory");        ssl_die();    }    if ((rv = apr_rmm_init(&(mc->pSessionCacheDataRMM), NULL,                   apr_shm_baseaddr_get(mc->pSessionCacheDataMM),                   mc->nSessionCacheDataSize, mc->pPool)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,                     "Cannot initialize rmm");        ssl_die();    }    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                 "initialize MM %pp RMM %pp",                 mc->pSessionCacheDataMM, mc->pSessionCacheDataRMM);    /*     * Create hash table in shared memory segment     */    avail = mc->nSessionCacheDataSize;    n = (avail/2) / 1024;    n = n < 10 ? 10 : n;    /*     * Passing server_rec as opt_param to table_alloc so that we can do     * logging if required ssl_util_table. Otherwise, mc is sufficient.     */     if ((ta = table_alloc(n, &ta_errno,                           ssl_scache_shmht_malloc,                            ssl_scache_shmht_calloc,                           ssl_scache_shmht_realloc,                           ssl_scache_shmht_free, s )) == NULL) {        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                     "Cannot allocate hash table in shared memory: %s",                     table_strerror(ta_errno));        ssl_die();    }    table_attr(ta, TABLE_FLAG_AUTO_ADJUST|TABLE_FLAG_ADJUST_DOWN);    table_set_data_alignment(ta, sizeof(char *));    table_clear(ta);    mc->tSessionCacheDataTable = ta;    /*     * Log the done work     */    ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,                  "Init: Created hash-table (%d buckets) "                 "in shared memory (%" APR_SIZE_T_FMT                  " bytes) for SSL session cache",                 n, avail);    return;}void ssl_scache_shmht_kill(server_rec *s){    SSLModConfigRec *mc = myModConfig(s);    if (mc->pSessionCacheDataRMM != NULL) {        apr_rmm_destroy(mc->pSessionCacheDataRMM);        mc->pSessionCacheDataRMM = NULL;    }    if (mc->pSessionCacheDataMM != NULL) {        apr_shm_destroy(mc->pSessionCacheDataMM);        mc->pSessionCacheDataMM = NULL;    }    return;}BOOL ssl_scache_shmht_store(server_rec *s, UCHAR *id, int idlen, time_t expiry, SSL_SESSION *sess){    SSLModConfigRec *mc = myModConfig(s);    void *vp;    UCHAR ucaData[SSL_SESSION_MAX_DER];    int nData;    UCHAR *ucp;    /* streamline session data */    if ((nData = i2d_SSL_SESSION(sess, NULL)) > sizeof(ucaData))        return FALSE;    ucp = ucaData;    i2d_SSL_SESSION(sess, &ucp);    ssl_mutex_on(s);    if (table_insert_kd(mc->tSessionCacheDataTable,                         id, idlen, NULL, sizeof(time_t)+nData,                        NULL, &vp, 1) != TABLE_ERROR_NONE) {        ssl_mutex_off(s);        return FALSE;    }    memcpy(vp, &expiry, sizeof(time_t));    memcpy((char *)vp+sizeof(time_t), ucaData, nData);    ssl_mutex_off(s);    /* allow the regular expiring to occur */    ssl_scache_shmht_expire(s);    return TRUE;}SSL_SESSION *ssl_scache_shmht_retrieve(server_rec *s, UCHAR *id, int idlen){    SSLModConfigRec *mc = myModConfig(s);    void *vp;    SSL_SESSION *sess = NULL;    UCHAR *ucpData;    int nData;    time_t expiry;    time_t now;    int n;    /* allow the regular expiring to occur */    ssl_scache_shmht_expire(s);    /* lookup key in table */    ssl_mutex_on(s);    if (table_retrieve(mc->tSessionCacheDataTable,                       id, idlen, &vp, &n) != TABLE_ERROR_NONE) {        ssl_mutex_off(s);        return NULL;    }    /* copy over the information to the SCI */    nData = n-sizeof(time_t);    ucpData = (UCHAR *)malloc(nData);    if (ucpData == NULL) {        ssl_mutex_off(s);        return NULL;    }    memcpy(&expiry, vp, sizeof(time_t));    memcpy(ucpData, (char *)vp+sizeof(time_t), nData);    ssl_mutex_off(s);    /* make sure the stuff is still not expired */    now = time(NULL);    if (expiry <= now) {        ssl_scache_shmht_remove(s, id, idlen);        return NULL;    }    /* unstreamed SSL_SESSION */    sess = d2i_SSL_SESSION(NULL, &ucpData, nData);    return sess;}void ssl_scache_shmht_remove(server_rec *s, UCHAR *id, int idlen){    SSLModConfigRec *mc = myModConfig(s);    /* remove value under key in table */    ssl_mutex_on(s);    table_delete(mc->tSessionCacheDataTable, id, idlen, NULL, NULL);    ssl_mutex_off(s);    return;}void ssl_scache_shmht_expire(server_rec *s){    SSLModConfigRec *mc = myModConfig(s);    SSLSrvConfigRec *sc = mySrvConfig(s);    static time_t tLast = 0;    table_linear_t iterator;    time_t tExpiresAt;    void *vpKey;    void *vpKeyThis;    void *vpData;    int nKey;    int nKeyThis;    int nData;    int nElements = 0;    int nDeleted = 0;    int bDelete;    int rc;    time_t tNow;    /*     * make sure the expiration for still not-accessed session     * cache entries is done only from time to time     */    tNow = time(NULL);    if (tNow < tLast+sc->session_cache_timeout)        return;    tLast = tNow;    ssl_mutex_on(s);    if (table_first_r(mc->tSessionCacheDataTable, &iterator,                      &vpKey, &nKey, &vpData, &nData) == TABLE_ERROR_NONE) {        do {            bDelete = FALSE;            nElements++;            if (nData < sizeof(time_t) || vpData == NULL)                bDelete = TRUE;            else {                memcpy(&tExpiresAt, vpData, sizeof(time_t));                /*                  * XXX : Force the record to be cleaned up. TBD (Madhu)                 * tExpiresAt = tNow;                 */                if (tExpiresAt <= tNow)                   bDelete = TRUE;            }            vpKeyThis = vpKey;            nKeyThis  = nKey;            rc = table_next_r(mc->tSessionCacheDataTable, &iterator,                              &vpKey, &nKey, &vpData, &nData);            if (bDelete) {                table_delete(mc->tSessionCacheDataTable,                             vpKeyThis, nKeyThis, NULL, NULL);                nDeleted++;            }        } while (rc == TABLE_ERROR_NONE);         /* (vpKeyThis != vpKey) && (nKeyThis != nKey) */    }    ssl_mutex_off(s);    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                 "Inter-Process Session Cache (SHMHT) Expiry: "                 "old: %d, new: %d, removed: %d",                 nElements, nElements-nDeleted, nDeleted);    return;}void ssl_scache_shmht_status(server_rec *s, apr_pool_t *p, void (*func)(char *, void *), void *arg){    SSLModConfigRec *mc = myModConfig(s);    void *vpKey;    void *vpData;    int nKey;    int nData;    int nElem;    int nSize;    int nAverage;    nElem = 0;    nSize = 0;    ssl_mutex_on(s);    if (table_first(mc->tSessionCacheDataTable,                    &vpKey, &nKey, &vpData, &nData) == TABLE_ERROR_NONE) {        do {            if (vpKey == NULL || vpData == NULL)                continue;            nElem += 1;            nSize += nData;        } while (table_next(mc->tSessionCacheDataTable,                        &vpKey, &nKey, &vpData, &nData) == TABLE_ERROR_NONE);    }    ssl_mutex_off(s);    if (nSize > 0 && nElem > 0)        nAverage = nSize / nElem;    else        nAverage = 0;    func(apr_psprintf(p, "cache type: <b>SHMHT</b>, maximum size: <b>%d</b> bytes<br>", mc->nSessionCacheDataSize), arg);    func(apr_psprintf(p, "current sessions: <b>%d</b>, current size: <b>%d</b> bytes<br>", nElem, nSize), arg);    func(apr_psprintf(p, "average session size: <b>%d</b> bytes<br>", nAverage), arg);    return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -