forked from wolfSSL/wolfssl
Merge pull request #5840 from kareem-wolfssl/dynSessCache2
Add dynamic session cache which allocates sessions from the heap.
This commit is contained in:
137
src/ssl.c
137
src/ssl.c
@ -191,6 +191,12 @@
|
||||
* ClientCache by default for backwards compatibility. This define will
|
||||
* make wolfSSL_get_session return a reference to ssl->session. The returned
|
||||
* pointer will be freed with the related WOLFSSL object.
|
||||
* SESSION_CACHE_DYNAMIC_MEM:
|
||||
* Dynamically allocate sessions for the session cache from the heap, as
|
||||
* opposed to the default which allocates from the stack. Allocates
|
||||
* memory only when a session is added to the cache, frees memory after the
|
||||
* session is no longer being used. Recommended for memory-constrained
|
||||
* systems.
|
||||
* WOLFSSL_SYS_CA_CERTS
|
||||
* Enables ability to load system CA certs from the OS via
|
||||
* wolfSSL_CTX_load_system_CA_certs.
|
||||
@ -6196,7 +6202,12 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
|
||||
typedef struct SessionRow {
|
||||
int nextIdx; /* where to place next one */
|
||||
int totalCount; /* sessions ever on this row */
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
WOLFSSL_SESSION* Sessions[SESSIONS_PER_ROW];
|
||||
void* heap;
|
||||
#else
|
||||
WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
|
||||
/* not included in import/export */
|
||||
@ -11475,7 +11486,13 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
|
||||
|
||||
#endif /* !NO_CLIENT_CACHE */
|
||||
|
||||
#if defined(PERSIST_SESSION_CACHE)
|
||||
/* TODO: Add SESSION_CACHE_DYNAMIC_MEM support for PERSIST_SESSION_CACHE.
|
||||
* Need a count of current sessions to get an accurate memsize (totalCount is
|
||||
* not decremented when sessions are removed).
|
||||
* Need to determine ideal layout for mem/filesave.
|
||||
* Also need mem/filesave checking to ensure not restoring non DYNAMIC_MEM cache.
|
||||
*/
|
||||
#if defined(PERSIST_SESSION_CACHE) && !defined(SESSION_CACHE_DYNAMIC_MEM)
|
||||
|
||||
/* for persistence, if changes to layout need to increment and modify
|
||||
save_session_cache() and restore_session_cache and memory versions too */
|
||||
@ -11499,7 +11516,6 @@ typedef struct {
|
||||
PERSISTENT_SESSION_CACHE functions
|
||||
*/
|
||||
|
||||
|
||||
/* get how big the the session cache save buffer needs to be */
|
||||
int wolfSSL_get_session_cache_memsize(void)
|
||||
{
|
||||
@ -11804,7 +11820,7 @@ int wolfSSL_restore_session_cache(const char *fname)
|
||||
}
|
||||
|
||||
#endif /* !NO_FILESYSTEM */
|
||||
#endif /* PERSIST_SESSION_CACHE */
|
||||
#endif /* PERSIST_SESSION_CACHE && !SESSION_CACHE_DYNAMIC_MEM */
|
||||
#endif /* NO_SESSION_CACHE */
|
||||
|
||||
|
||||
@ -14128,8 +14144,12 @@ int wolfSSL_Cleanup(void)
|
||||
{
|
||||
int ret = WOLFSSL_SUCCESS; /* Only the first error will be returned */
|
||||
int release = 0;
|
||||
#if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
|
||||
#if !defined(NO_SESSION_CACHE) && (defined(ENABLE_SESSION_CACHE_ROW_LOCK) || \
|
||||
defined(SESSION_CACHE_DYNAMIC_MEM))
|
||||
int i;
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
int j;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_Cleanup");
|
||||
@ -14177,6 +14197,17 @@ int wolfSSL_Cleanup(void)
|
||||
}
|
||||
session_lock_valid = 0;
|
||||
#endif
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
for (i = 0; i < SESSION_ROWS; i++) {
|
||||
for (j = 0; j < SESSIONS_PER_ROW; j++) {
|
||||
if (SessionCache[i].Sessions[j]) {
|
||||
XFREE(SessionCache[i].Sessions[j], SessionCache[i].heap,
|
||||
DYNAMIC_TYPE_SESSION);
|
||||
SessionCache[i].Sessions[j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_CLIENT_CACHE
|
||||
if ((clisession_mutex_valid == 1) &&
|
||||
(wc_FreeMutex(&clisession_mutex) != 0)) {
|
||||
@ -14401,8 +14432,12 @@ WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
current = sessRow->Sessions[clSess[idx].serverIdx];
|
||||
#else
|
||||
current = &sessRow->Sessions[clSess[idx].serverIdx];
|
||||
if (XMEMCMP(current->serverID, id, len) == 0) {
|
||||
#endif
|
||||
if (current && XMEMCMP(current->serverID, id, len) == 0) {
|
||||
WOLFSSL_MSG("Found a serverid match for client");
|
||||
if (LowResTimer() < (current->bornOn + current->timeout)) {
|
||||
WOLFSSL_MSG("Session valid");
|
||||
@ -14513,8 +14548,12 @@ int TlsSessionCacheGetAndLock(const byte *id, WOLFSSL_SESSION **sess,
|
||||
idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
|
||||
}
|
||||
for (; count > 0; --count) {
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
s = sessRow->Sessions[idx];
|
||||
#else
|
||||
s = &sessRow->Sessions[idx];
|
||||
if (XMEMCMP(s->sessionID, id, ID_LEN) == 0) {
|
||||
#endif
|
||||
if (s && XMEMCMP(s->sessionID, id, ID_LEN) == 0) {
|
||||
*sess = s;
|
||||
break;
|
||||
}
|
||||
@ -15086,8 +15125,12 @@ WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session)
|
||||
}
|
||||
}
|
||||
if (error == 0) {
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
cacheSession = sessRow->Sessions[clientSession->serverIdx];
|
||||
#else
|
||||
cacheSession = &sessRow->Sessions[clientSession->serverIdx];
|
||||
if (cacheSession->sessionIDSz == 0) {
|
||||
#endif
|
||||
if (cacheSession && cacheSession->sessionIDSz == 0) {
|
||||
cacheSession = NULL;
|
||||
WOLFSSL_MSG("Session cache entry not set");
|
||||
error = -1;
|
||||
@ -15227,9 +15270,14 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
||||
}
|
||||
|
||||
for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
|
||||
if (XMEMCMP(id,
|
||||
sessRow->Sessions[i].sessionID, ID_LEN) == 0 &&
|
||||
sessRow->Sessions[i].side == side) {
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
cacheSession = sessRow->Sessions[i];
|
||||
#else
|
||||
cacheSession = &sessRow->Sessions[i];
|
||||
#endif
|
||||
if (cacheSession && XMEMCMP(id,
|
||||
cacheSession->sessionID, ID_LEN) == 0 &&
|
||||
cacheSession->side == side) {
|
||||
WOLFSSL_MSG("Session already exists. Overwriting.");
|
||||
overwrite = 1;
|
||||
idx = i;
|
||||
@ -15243,7 +15291,23 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
||||
if (sessionIndex != NULL)
|
||||
*sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
|
||||
#endif
|
||||
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
cacheSession = sessRow->Sessions[idx];
|
||||
if (cacheSession) {
|
||||
XFREE(cacheSession, sessRow->heap, DYNAMIC_TYPE_SESSION);
|
||||
cacheSession = NULL;
|
||||
}
|
||||
cacheSession = (WOLFSSL_SESSION*) XMALLOC(sizeof(WOLFSSL_SESSION), sessRow->heap,
|
||||
DYNAMIC_TYPE_SESSION);
|
||||
if (cacheSession == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(cacheSession, 0, sizeof(WOLFSSL_SESSION));
|
||||
sessRow->Sessions[idx] = cacheSession;
|
||||
#else
|
||||
cacheSession = &sessRow->Sessions[idx];
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EX_DATA
|
||||
if (cacheSession->ownExData) {
|
||||
@ -15561,6 +15625,7 @@ int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
|
||||
{
|
||||
int row, col, result = WOLFSSL_FAILURE;
|
||||
SessionRow* sessRow;
|
||||
WOLFSSL_SESSION* cacheSession;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
|
||||
|
||||
@ -15579,8 +15644,18 @@ int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
XMEMCPY(session, &sessRow->Sessions[col], sizeof(WOLFSSL_SESSION));
|
||||
result = WOLFSSL_SUCCESS;
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
cacheSession = sessRow->Sessions[col];
|
||||
#else
|
||||
cacheSession = &sessRow->Sessions[col];
|
||||
#endif
|
||||
if (cacheSession) {
|
||||
XMEMCPY(session, cacheSession, sizeof(WOLFSSL_SESSION));
|
||||
result = WOLFSSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
result = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
SESSION_ROW_UNLOCK(sessRow);
|
||||
|
||||
@ -15679,8 +15754,15 @@ static int get_locked_session_stats(word32* active, word32* total, word32* peak)
|
||||
|
||||
for (; count > 0; --count) {
|
||||
/* if not expired then good */
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
if (row->Sessions[idx] &&
|
||||
ticks < (row->Sessions[idx]->bornOn +
|
||||
row->Sessions[idx]->timeout) )
|
||||
#else
|
||||
if (ticks < (row->Sessions[idx].bornOn +
|
||||
row->Sessions[idx].timeout) ) {
|
||||
row->Sessions[idx].timeout) )
|
||||
#endif
|
||||
{
|
||||
now++;
|
||||
}
|
||||
|
||||
@ -32510,6 +32592,7 @@ static void SESSION_ex_data_cache_update(WOLFSSL_SESSION* session, int idx,
|
||||
int i;
|
||||
int error = 0;
|
||||
SessionRow* sessRow = NULL;
|
||||
WOLFSSL_SESSION* cacheSession = NULL;
|
||||
const byte* id;
|
||||
byte foundCache = 0;
|
||||
|
||||
@ -32539,20 +32622,26 @@ static void SESSION_ex_data_cache_update(WOLFSSL_SESSION* session, int idx,
|
||||
}
|
||||
|
||||
for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
|
||||
if (XMEMCMP(id, sessRow->Sessions[i].sessionID, ID_LEN) == 0
|
||||
&& session->side == sessRow->Sessions[i].side
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
cacheSession = sessRow->Sessions[i];
|
||||
#else
|
||||
cacheSession = &sessRow->Sessions[i];
|
||||
#endif
|
||||
if (cacheSession &&
|
||||
XMEMCMP(id, cacheSession->sessionID, ID_LEN) == 0
|
||||
&& session->side == cacheSession->side
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
|
||||
&& (IsAtLeastTLSv1_3(session->version) ==
|
||||
IsAtLeastTLSv1_3(sessRow->Sessions[i].version))
|
||||
IsAtLeastTLSv1_3(cacheSession->version))
|
||||
#endif
|
||||
) {
|
||||
if (get) {
|
||||
*getRet = wolfSSL_CRYPTO_get_ex_data(
|
||||
&sessRow->Sessions[i].ex_data, idx);
|
||||
&cacheSession->ex_data, idx);
|
||||
}
|
||||
else {
|
||||
*setRet = wolfSSL_CRYPTO_set_ex_data(
|
||||
&sessRow->Sessions[i].ex_data, idx, data);
|
||||
&cacheSession->ex_data, idx, data);
|
||||
}
|
||||
foundCache = 1;
|
||||
break;
|
||||
@ -34390,8 +34479,13 @@ int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
|
||||
}
|
||||
|
||||
for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
cacheSession = sessRow->Sessions[i];
|
||||
#else
|
||||
cacheSession = &sessRow->Sessions[i];
|
||||
if (XMEMCMP(id, cacheSession->sessionID, ID_LEN) == 0) {
|
||||
#endif
|
||||
if (cacheSession &&
|
||||
XMEMCMP(id, cacheSession->sessionID, ID_LEN) == 0) {
|
||||
if (ctx->method->side != cacheSession->side)
|
||||
continue;
|
||||
cacheSession->timeout = 0;
|
||||
@ -34405,6 +34499,11 @@ int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
|
||||
cacheSession->ownExData = 0; /* We clear below */
|
||||
s->ownExData = 1;
|
||||
#endif
|
||||
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
XFREE(cacheSession, sessRow->heap, DYNAMIC_TYPE_SESSION);
|
||||
sessRow->Sessions[i] = NULL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2940,6 +2940,10 @@ extern void uITRON4_free(void *p) ;
|
||||
#endif
|
||||
#endif /* WOLFSSL_SYS_CA_CERTS */
|
||||
|
||||
#if defined(SESSION_CACHE_DYNAMIC_MEM) && defined(PERSIST_SESSION_CACHE)
|
||||
#error "Dynamic session cache currently does not support persistent session cache."
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user