📄 ssl_scache_shmcb.c
字号:
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 150 bytes, so erring to division by 120 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) / 120; 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, "for %" APR_SIZE_T_FMT " bytes (%" APR_SIZE_T_FMT " including header), recommending %u subcaches, " "%u indexes each", shm_segsize, shm_segsize + sizeof(SHMCBHeader), num_subcache, num_idx); if (num_idx < 5) { /* we're still too small, bail out */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "shared memory segment too small"); ssl_die(); } /* OK, we're sorted */ header = shm_segment; header->stat_stores = 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. * This assumes that sizeof(unsigned long) provides an appropriate * alignment unit. */ header->subcache_size = ((size_t)(shm_segsize / num_subcache) & ~(size_t)(sizeof(unsigned long) - 1)); header->subcache_data_offset = sizeof(SHMCBSubcache) + num_idx * sizeof(SHMCBIndex); 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, "shmcb_init_memory choices follow"); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "subcache_num = %u", header->subcache_num); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "subcache_size = %u", header->subcache_size); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "subcache_data_offset = %u", header->subcache_data_offset); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "subcache_data_size = %u", header->subcache_data_size); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "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, "Shared memory session cache initialised"); /* Success ... */ mc->tSessionCacheDataTable = shm_segment;}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; unsigned char encoded[SSL_SESSION_MAX_DER]; unsigned char *ptr_encoded; unsigned int len_encoded; SHMCBHeader *header = mc->tSessionCacheDataTable; SHMCBSubcache *subcache = SHMCB_MASK(header, id); ssl_mutex_on(s); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "ssl_scache_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 " "(%u bytes)", idlen); goto done; } /* Serialise the session. */ len_encoded = i2d_SSL_SESSION(pSession, NULL); if (len_encoded > SSL_SESSION_MAX_DER) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "session is too big (%u bytes)", len_encoded); goto done; } ptr_encoded = encoded; len_encoded = i2d_SSL_SESSION(pSession, &ptr_encoded); if (!shmcb_subcache_store(s, header, subcache, encoded, len_encoded, id, timeout)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "can't store a session!"); goto done; } header->stat_stores++; to_return = TRUE; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "leaving ssl_scache_shmcb_store successfully");done: 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 = NULL; SHMCBHeader *header = mc->tSessionCacheDataTable; SHMCBSubcache *subcache = SHMCB_MASK(header, id); ssl_mutex_on(s); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "ssl_scache_shmcb_retrieve (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 " "(%u bytes)", idlen); goto done; } /* Get the session corresponding to the session_id or NULL if it doesn't * exist (or is flagged as "removed"). */ pSession = shmcb_subcache_retrieve(s, header, subcache, id, idlen); if (pSession) header->stat_retrieves_hit++; else header->stat_retrieves_miss++; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "leaving ssl_scache_shmcb_retrieve successfully");done: ssl_mutex_off(s); return pSession;}void ssl_scache_shmcb_remove(server_rec *s, UCHAR *id, int idlen){ SSLModConfigRec *mc = myModConfig(s); SHMCBHeader *header = mc->tSessionCacheDataTable; SHMCBSubcache *subcache = SHMCB_MASK(header, id); ssl_mutex_on(s); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "ssl_scache_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 " "(%u bytes)", idlen); goto done; } if (shmcb_subcache_remove(s, header, subcache, id, idlen)) header->stat_removes_hit++; else header->stat_removes_miss++; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "leaving ssl_scache_shmcb_remove successfully");done: ssl_mutex_off(s);}void ssl_scache_shmcb_status(request_rec *r, int flags, apr_pool_t *p){ server_rec *s = r->server; SSLModConfigRec *mc = myModConfig(s); void *shm_segment = apr_shm_baseaddr_get(mc->pSessionCacheDataMM); SHMCBHeader *header = shm_segment; unsigned int loop, total = 0, cache_total = 0, non_empty_subcaches = 0; time_t idx_expiry, min_expiry = 0, max_expiry = 0, average_expiry = 0; time_t now = time(NULL); double expiry_total = 0; int index_pct, cache_pct; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "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. */ ssl_mutex_on(s); /* Iterate over the subcaches */ for (loop = 0; loop < header->subcache_num; loop++) { SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop); shmcb_subcache_expire(s, header, subcache); 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); } } ssl_mutex_off(s); index_pct = (100 * total) / (header->index_num * header->subcache_num); cache_pct = (100 * cache_total) / (header->subcache_data_size * header->subcache_num); /* Generate HTML */ 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, "subcaches: <b>%d</b>, indexes per subcache: <b>%d</b><br>", header->subcache_num, header->index_num); if (non_empty_subcaches) { average_expiry = (time_t)(expiry_total / (double)non_empty_subcaches); 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->stat_stores); ap_rprintf(r, "total sessions expired since starting: <b>%lu</b><br>", header->stat_expiries); ap_rprintf(r, "total (pre-expiry) sessions 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); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "leaving shmcb_status");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -