static OSStatus SessionCacheLookupEntry( SessionCache *cache, const SSLBuffer *sessionKey, SSLBuffer *sessionData) { SessionCacheEntry *entry = NULL; SessionCacheEntry **current; for (current = &(cache->head); *current; current = &((*current)->next)) { entry = *current; if (SessionCacheEntryMatchKey(entry, sessionKey)) break; } if (*current == NULL) return errSSLSessionNotFound; if (SessionCacheEntryIsStaleNow(entry)) { sslLogSessCacheDebug("SessionCache::lookupEntry %p: STALE " "entry, deleting; current %p, entry->next %p", entry, current, entry->next); cachePrint(entry, sessionKey, &entry->mSessionData); *current = entry->next; SessionCacheEntryDelete(entry); return errSSLSessionNotFound; } /* alloc/copy sessionData from existing entry (caller must free) */ return SSLCopyBuffer(&entry->mSessionData, sessionData); }
/* these three correspond to the C functions exported by this file */ static OSStatus SessionCacheAddEntry( SessionCache *cache, const SSLBuffer *sessionKey, const SSLBuffer *sessionData, uint32 timeToLive) /* optional time-to-live in seconds; 0 ==> default */ { SessionCacheEntry *entry = NULL; SessionCacheEntry **current; CFTimeInterval expireTime; for (current = &(cache->head); *current; current = &((*current)->next)) { entry = *current; if (SessionCacheEntryMatchKey(entry, sessionKey)) { /* cache hit - just update this entry's sessionData if necessary */ /* Note we leave expiration time and position in queue unchanged - OK? */ /* What if the entry has already expired? */ if((entry->mSessionData.length == sessionData->length) && (memcmp(entry->mSessionData.data, sessionData->data, sessionData->length) == 0)) { /* * These usually match, and a memcmp is a lot cheaper than * a malloc and a free, hence this quick optimization..... */ sslLogSessCacheDebug("SessionCache::addEntry CACHE HIT " "entry = %p", entry); return noErr; } else { sslLogSessCacheDebug("SessionCache::addEntry CACHE REPLACE " "entry = %p", entry); return SessionCacheEntrySetSessionData(entry, sessionData); } } } expireTime = CFAbsoluteTimeGetCurrent(); if(timeToLive) { /* caller-specified */ expireTime += (CFTimeInterval)timeToLive; } else { /* default */ expireTime += cache->mTimeToLive; } /* this allocs new copy of incoming sessionKey and sessionData */ entry = SessionCacheEntryCreate(sessionKey, sessionData, expireTime); sslLogSessCacheDebug("SessionCache::addEntry %p", entry); cachePrint(entry, sessionKey, sessionData); dumpAllCache(); /* add to head of queue for LIFO caching */ entry->next = cache->head; cache->head = entry; return noErr; }
static OSStatus SessionCacheDeleteEntry( SessionCache *cache, const SSLBuffer *sessionKey) { SessionCacheEntry **current; for (current = &(cache->head); *current; current = &((*current)->next)) { SessionCacheEntry *entry = *current; if (SessionCacheEntryMatchKey(entry, sessionKey)) { #ifndef DEBUG sslLogSessCacheDebug("...SessionCacheDeleteEntry: deleting " "cached session (%p)", entry); cachePrint(entry, &entry->mKey, &entry->mSessionData); #endif *current = entry->next; SessionCacheEntryDelete(entry); return noErr; } } return noErr; }
static OSStatus SessionCacheLookupEntry( SessionCache *cache, const tls_buffer *sessionKey, tls_buffer *sessionData) { SessionCacheEntry *entry = NULL; SessionCacheEntry **current; for (current = &(cache->head); *current; current = &((*current)->next)) { entry = *current; if (SessionCacheEntryMatchKey(entry, sessionKey)) break; } if (*current == NULL) return -9804; //errSSLSessionNotFound; if (SessionCacheEntryIsStaleNow(entry)) { sslLogSessCacheDebug("SessionCache::lookupEntry %p: STALE " "entry, deleting; current %p, entry->next %p", entry, current, entry->next); cachePrint(entry, sessionKey, &entry->mSessionData); *current = entry->next; SessionCacheEntryDelete(entry); return -9804; //errSSLSessionNotFound; } #if 1 // "get" not "copy", see: <rdar://problem/16277298> coreTLS: session cache callbacks can lead to leaks or crashes sessionData->data = entry->mSessionData.data; sessionData->length = entry->mSessionData.length; return 0; #else /* alloc/copy sessionData from existing entry (caller must free) */ return SSLCopyBuffer(&entry->mSessionData, sessionData); #endif }