📄 ssl_scache_dbm.c
字号:
ssl_mutex_off(s); return NULL; } /* parse resulting data */ nData = dbmval.dsize-sizeof(time_t); ucpData = malloc(nData); if (ucpData == NULL) { apr_dbm_close(dbm); ssl_mutex_off(s); return NULL; } /* Cast needed, ucpData may be const */ memcpy((unsigned char *)ucpData, (char *)dbmval.dptr + sizeof(time_t), nData); memcpy(&expiry, dbmval.dptr, sizeof(time_t)); apr_dbm_close(dbm); ssl_mutex_off(s); /* make sure the stuff is still not expired */ now = time(NULL); if (expiry <= now) { ssl_scache_dbm_remove(s, id, idlen); return NULL; } /* unstreamed SSL_SESSION */ sess = d2i_SSL_SESSION(NULL, &ucpData, nData); return sess;}void ssl_scache_dbm_remove(server_rec *s, UCHAR *id, int idlen){ SSLModConfigRec *mc = myModConfig(s); apr_dbm_t *dbm; apr_datum_t dbmkey; apr_status_t rv; /* create DBM key and values */ dbmkey.dptr = (char *)id; dbmkey.dsize = idlen; /* and delete it from the DBM file */ ssl_mutex_on(s); if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot open SSLSessionCache DBM file `%s' for writing " "(delete)", mc->szSessionCacheDataFile); ssl_mutex_off(s); return; } apr_dbm_delete(dbm, dbmkey); apr_dbm_close(dbm); ssl_mutex_off(s); return;}static void ssl_scache_dbm_expire(server_rec *s){ SSLModConfigRec *mc = myModConfig(s); SSLSrvConfigRec *sc = mySrvConfig(s); static time_t tLast = 0; apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; apr_pool_t *p; time_t tExpiresAt; int nElements = 0; int nDeleted = 0; int bDelete; apr_datum_t *keylist; int keyidx; int i; time_t tNow; apr_status_t rv; /* * 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; /* * Here we have to be very carefully: Not all DBM libraries are * smart enough to allow one to iterate over the elements and at the * same time delete expired ones. Some of them get totally crazy * while others have no problems. So we have to do it the slower but * more safe way: we first iterate over all elements and remember * those which have to be expired. Then in a second pass we delete * all those expired elements. Additionally we reopen the DBM file * to be really safe in state. */#define KEYMAX 1024 ssl_mutex_on(s); for (;;) { /* allocate the key array in a memory sub pool */ apr_pool_create_ex(&p, mc->pPool, NULL, NULL); if (p == NULL) break; if ((keylist = apr_palloc(p, sizeof(dbmkey)*KEYMAX)) == NULL) { apr_pool_destroy(p); break; } /* pass 1: scan DBM database */ keyidx = 0; if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, APR_DBM_RWCREATE,SSL_DBM_FILE_MODE, p)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot open SSLSessionCache DBM file `%s' for " "scanning", mc->szSessionCacheDataFile); apr_pool_destroy(p); break; } apr_dbm_firstkey(dbm, &dbmkey); while (dbmkey.dptr != NULL) { nElements++; bDelete = FALSE; apr_dbm_fetch(dbm, dbmkey, &dbmval); if (dbmval.dsize <= sizeof(time_t) || dbmval.dptr == NULL) bDelete = TRUE; else { memcpy(&tExpiresAt, dbmval.dptr, sizeof(time_t)); if (tExpiresAt <= tNow) bDelete = TRUE; } if (bDelete) { if ((keylist[keyidx].dptr = apr_pmemdup(p, dbmkey.dptr, dbmkey.dsize)) != NULL) { keylist[keyidx].dsize = dbmkey.dsize; keyidx++; if (keyidx == KEYMAX) break; } } apr_dbm_nextkey(dbm, &dbmkey); } apr_dbm_close(dbm); /* pass 2: delete expired elements */ if (apr_dbm_open(&dbm, mc->szSessionCacheDataFile, APR_DBM_RWCREATE,SSL_DBM_FILE_MODE, p) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot re-open SSLSessionCache DBM file `%s' for " "expiring", mc->szSessionCacheDataFile); apr_pool_destroy(p); break; } for (i = 0; i < keyidx; i++) { apr_dbm_delete(dbm, keylist[i]); nDeleted++; } apr_dbm_close(dbm); /* destroy temporary pool */ apr_pool_destroy(p); if (keyidx < KEYMAX) break; } ssl_mutex_off(s); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Inter-Process Session Cache (DBM) Expiry: " "old: %d, new: %d, removed: %d", nElements, nElements-nDeleted, nDeleted); return;}void ssl_scache_dbm_status(request_rec *r, int flags, apr_pool_t *p){ SSLModConfigRec *mc = myModConfig(r->server); apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; int nElem; int nSize; int nAverage; apr_status_t rv; nElem = 0; nSize = 0; ssl_mutex_on(r->server); /* * XXX - Check what pool is to be used - TBD */ if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "Cannot open SSLSessionCache DBM file `%s' for status " "retrival", mc->szSessionCacheDataFile); ssl_mutex_off(r->server); return; } /* * XXX - Check the return value of apr_dbm_firstkey, apr_dbm_fetch - TBD */ apr_dbm_firstkey(dbm, &dbmkey); for ( ; dbmkey.dptr != NULL; apr_dbm_nextkey(dbm, &dbmkey)) { apr_dbm_fetch(dbm, dbmkey, &dbmval); if (dbmval.dptr == NULL) continue; nElem += 1; nSize += dbmval.dsize; } apr_dbm_close(dbm); ssl_mutex_off(r->server); if (nSize > 0 && nElem > 0) nAverage = nSize / nElem; else nAverage = 0; ap_rprintf(r, "cache type: <b>DBM</b>, maximum size: <b>unlimited</b><br>"); ap_rprintf(r, "current sessions: <b>%d</b>, current size: <b>%d</b> bytes<br>", nElem, nSize); ap_rprintf(r, "average session size: <b>%d</b> bytes<br>", nAverage); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -