📄 ssl_scache_shmcb.c
字号:
/* * Create shared memory segment */ if (mc->szSessionCacheDataFile == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); ssl_die(); } /* Use anonymous shm by default, fall back on name-based. */ rv = apr_shm_create(&(mc->pSessionCacheDataMM), mc->nSessionCacheDataSize, NULL, mc->pPool); if (APR_STATUS_IS_ENOTIMPL(rv)) { /* For a name-based segment, remove it first in case of a * previous unclean shutdown. */ apr_shm_remove(mc->szSessionCacheDataFile, mc->pPool); rv = apr_shm_create(&(mc->pSessionCacheDataMM), mc->nSessionCacheDataSize, mc->szSessionCacheDataFile, mc->pPool); } if (rv != APR_SUCCESS) { char buf[100]; ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Cannot allocate shared memory: (%d)%s", rv, apr_strerror(rv, buf, sizeof(buf))); ssl_die(); } shm_segment = apr_shm_baseaddr_get(mc->pSessionCacheDataMM); shm_segsize = apr_shm_size_get(mc->pSessionCacheDataMM); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "shmcb_init allocated %" APR_SIZE_T_FMT " bytes of shared memory", shm_segsize); if (!shmcb_init_memory(s, shm_segment, shm_segsize)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Failure initialising 'shmcb' shared memory"); ssl_die(); } ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "Shared memory session cache initialised"); /* * Success ... */ mc->tSessionCacheDataTable = shm_segment; return;}void ssl_scache_shmcb_kill(server_rec *s){ SSLModConfigRec *mc = myModConfig(s); if (mc->pSessionCacheDataMM != NULL) { apr_shm_destroy(mc->pSessionCacheDataMM); mc->pSessionCacheDataMM = NULL; } return;}BOOL ssl_scache_shmcb_store(server_rec *s, UCHAR *id, int idlen, time_t timeout, SSL_SESSION * pSession){ SSLModConfigRec *mc = myModConfig(s); BOOL to_return = FALSE; ssl_mutex_on(s); if (!shmcb_store_session(s, mc->tSessionCacheDataTable, id, idlen, pSession, timeout)) /* in this cache engine, "stores" should never fail. */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "'shmcb' code was unable to store a " "session in the cache."); else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "shmcb_store successful"); to_return = TRUE; } ssl_mutex_off(s); return to_return;}SSL_SESSION *ssl_scache_shmcb_retrieve(server_rec *s, UCHAR *id, int idlen){ SSLModConfigRec *mc = myModConfig(s); SSL_SESSION *pSession; ssl_mutex_on(s); pSession = shmcb_retrieve_session(s, mc->tSessionCacheDataTable, id, idlen); ssl_mutex_off(s); if (pSession) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "shmcb_retrieve had a hit"); else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "shmcb_retrieve had a miss"); ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "Client requested a 'session-resume' but " "we have no such session."); } return pSession;}void ssl_scache_shmcb_remove(server_rec *s, UCHAR *id, int idlen){ SSLModConfigRec *mc = myModConfig(s); ssl_mutex_on(s); shmcb_remove_session(s, mc->tSessionCacheDataTable, id, idlen); ssl_mutex_off(s);}void ssl_scache_shmcb_status(request_rec *r, int flags, apr_pool_t *p){ SSLModConfigRec *mc = myModConfig(r->server); SHMCBHeader *header; SHMCBQueue queue; SHMCBCache cache; SHMCBIndex *idx; unsigned int loop, total, cache_total, non_empty_divisions; int index_pct, cache_pct; double expiry_total; time_t average_expiry, now, max_expiry, min_expiry, idxexpiry; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "inside shmcb_status"); /* Get the header structure. */ shmcb_get_header(mc->tSessionCacheDataTable, &header); total = cache_total = non_empty_divisions = 0; average_expiry = max_expiry = min_expiry = 0; expiry_total = 0; /* It may seem strange to grab "now" at this point, but in theory * we should never have a negative threshold but grabbing "now" after * the loop (which performs expiries) could allow that chance. */ now = time(NULL); for (loop = 0; loop <= header->division_mask; loop++) { if (shmcb_get_division(header, &queue, &cache, loop)) { shmcb_expire_division(r->server, &queue, &cache); total += shmcb_get_safe_uint(queue.pos_count); cache_total += shmcb_get_safe_uint(cache.pos_count); if (shmcb_get_safe_uint(queue.pos_count) > 0) { idx = shmcb_get_index(&queue, shmcb_get_safe_uint(queue.first_pos)); non_empty_divisions++; idxexpiry = shmcb_get_safe_time(&(idx->expires)); expiry_total += (double) idxexpiry; max_expiry = (idxexpiry > max_expiry ? idxexpiry : max_expiry); if (min_expiry == 0) min_expiry = idxexpiry; else min_expiry = (idxexpiry < min_expiry ? idxexpiry : min_expiry); } } } index_pct = (100 * total) / (header->index_num * (header->division_mask + 1)); cache_pct = (100 * cache_total) / (header->cache_data_size * (header->division_mask + 1)); ap_rprintf(r, "cache type: <b>SHMCB</b>, shared memory: <b>%d</b> " "bytes, current sessions: <b>%d</b><br>", mc->nSessionCacheDataSize, total); ap_rprintf(r, "sub-caches: <b>%d</b>, indexes per sub-cache: " "<b>%d</b><br>", (int) header->division_mask + 1, (int) header->index_num); if (non_empty_divisions != 0) { average_expiry = (time_t)(expiry_total / (double)non_empty_divisions); ap_rprintf(r, "time left on oldest entries' SSL sessions: "); if (now < average_expiry) ap_rprintf(r, "avg: <b>%d</b> seconds, (range: %d...%d)<br>", (int)(average_expiry - now), (int) (min_expiry - now), (int)(max_expiry - now)); else ap_rprintf(r, "expiry threshold: <b>Calculation Error!</b>" "<br>"); } ap_rprintf(r, "index usage: <b>%d%%</b>, cache usage: <b>%d%%</b>" "<br>", index_pct, cache_pct); ap_rprintf(r, "total sessions stored since starting: <b>%lu</b><br>", header->num_stores); ap_rprintf(r, "total sessions expired since starting: <b>%lu</b><br>", header->num_expiries); ap_rprintf(r, "total (pre-expiry) sessions scrolled out of the " "cache: <b>%lu</b><br>", header->num_scrolled); ap_rprintf(r, "total retrieves since starting: <b>%lu</b> hit, " "<b>%lu</b> miss<br>", header->num_retrieves_hit, header->num_retrieves_miss); ap_rprintf(r, "total removes since starting: <b>%lu</b> hit, " "<b>%lu</b> miss<br>", header->num_removes_hit, header->num_removes_miss); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "leaving shmcb_status"); return;}/***** Memory manipulation and low-level cache operations***/static BOOL shmcb_init_memory( server_rec *s, void *shm_mem, unsigned int shm_mem_size){ SHMCBHeader *header; SHMCBQueue queue; SHMCBCache cache; unsigned int temp, loop, granularity; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "entered shmcb_init_memory()"); /* Calculate some sizes... */ temp = sizeof(SHMCBHeader); /* If the segment is ridiculously too small, bail out */ if (shm_mem_size < (2*temp)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "shared memory segment too small"); return FALSE; } /* Make temp the amount of memory without the header */ temp = shm_mem_size - temp; /* Work on the basis that you need 10 bytes index for each session * (approx 150 bytes), which is to divide temp by 160 - and then * make sure we err on having too index space to burn even when * the cache is full, which is a lot less stupid than having * having not enough index space to utilise the whole cache!. */ temp /= 120; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "for %u bytes, recommending %u indexes", shm_mem_size, temp); /* We should divide these indexes evenly amongst the queues. Try * to get it so that there are roughly half the number of divisions * as there are indexes in each division. */ granularity = 256; while ((temp / granularity) < (2 * granularity)) granularity /= 2; /* So we have 'granularity' divisions, set 'temp' equal to the * number of indexes in each division. */ temp /= granularity; /* Too small? Bail ... */ if (temp < 5) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "shared memory segment too small"); return FALSE; } /* OK, we're sorted - from here on in, the return should be TRUE */ header = (SHMCBHeader *)shm_mem; header->division_mask = (unsigned char)(granularity - 1); header->division_offset = sizeof(SHMCBHeader); header->index_num = temp; header->index_offset = (2 * sizeof(unsigned int)); header->index_size = sizeof(SHMCBIndex); header->queue_size = header->index_offset + (header->index_num * header->index_size); /* Now calculate the space for each division */ temp = shm_mem_size - header->division_offset; header->division_size = temp / granularity; /* Calculate the space left in each division for the cache */ temp -= header->queue_size; header->cache_data_offset = (2 * sizeof(unsigned int)); header->cache_data_size = header->division_size - header->queue_size - header->cache_data_offset; /* Output trace info */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "shmcb_init_memory choices follow"); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "division_mask = 0x%02X", header->division_mask); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "division_offset = %u", header->division_offset); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "division_size = %u", header->division_size); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "queue_size = %u", header->queue_size); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "index_num = %u", header->index_num); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "index_offset = %u", header->index_offset); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "index_size = %u", header->index_size); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "cache_data_offset = %u", header->cache_data_offset); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "cache_data_size = %u", header->cache_data_size); /* The header is done, make the caches empty */ for (loop = 0; loop < granularity; loop++) { if (!shmcb_get_division(header, &queue, &cache, loop)) ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "shmcb_init_memory, " "internal error"); shmcb_set_safe_uint(cache.first_pos, 0); shmcb_set_safe_uint(cache.pos_count, 0); shmcb_set_safe_uint(queue.first_pos, 0); shmcb_set_safe_uint(queue.pos_count, 0); } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "leaving shmcb_init_memory()"); return TRUE;}static BOOL shmcb_store_session( server_rec *s, void *shm_segment, UCHAR *id, int idlen, SSL_SESSION * pSession, time_t timeout){ SHMCBHeader *header; SHMCBQueue queue; SHMCBCache cache; unsigned char masked_index; unsigned char encoded[SSL_SESSION_MAX_DER]; unsigned char *ptr_encoded; unsigned int len_encoded; time_t expiry_time; unsigned char *session_id = SSL_SESSION_get_session_id(pSession); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "inside shmcb_store_session"); /* Get the header structure, which division this session will fall into etc. */ shmcb_get_header(shm_segment, &header); masked_index = session_id[0] & header->division_mask; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -