- Cache now only allows a maximum of entries in cache for preventing memory overrun

This commit is contained in:
Paul Bakker 2012-10-23 22:18:28 +00:00
parent 0fd018efb2
commit ba26e9ebfd
2 changed files with 53 additions and 14 deletions

View file

@ -29,7 +29,8 @@
#include "ssl.h" #include "ssl.h"
#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */ #define SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */
#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -53,8 +54,9 @@ struct _ssl_cache_entry
*/ */
struct _ssl_cache_context struct _ssl_cache_context
{ {
ssl_cache_entry *chain; /*!< start of the chain */ ssl_cache_entry *chain; /*!< start of the chain */
int timeout; /*!< cache timeout */ int timeout; /*!< cache entry timeout */
int max_entries; /*!< maximum entries */
}; };
/** /**
@ -91,6 +93,15 @@ int ssl_cache_set( void *data, const ssl_session *session );
*/ */
void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout ); void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout );
/**
* \brief Set the cache timeout
* (Default: SSL_CACHE_DEFAULT_MAX_ENTRIES (50))
*
* \param cache SSL cache context
* \param max cache entry maximum
*/
void ssl_cache_set_max_entries( ssl_cache_context *cache, int max );
/** /**
* \brief Free referenced items in a cache context and clear memory * \brief Free referenced items in a cache context and clear memory
* *

View file

@ -40,6 +40,7 @@ void ssl_cache_init( ssl_cache_context *cache )
memset( cache, 0, sizeof( ssl_cache_context ) ); memset( cache, 0, sizeof( ssl_cache_context ) );
cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT; cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT;
cache->max_entries = SSL_CACHE_DEFAULT_MAX_ENTRIES;
} }
int ssl_cache_get( void *data, ssl_session *session ) int ssl_cache_get( void *data, ssl_session *session )
@ -78,15 +79,18 @@ int ssl_cache_get( void *data, ssl_session *session )
int ssl_cache_set( void *data, const ssl_session *session ) int ssl_cache_set( void *data, const ssl_session *session )
{ {
time_t t = time( NULL ); time_t t = time( NULL ), oldest = 0;
ssl_cache_context *cache = (ssl_cache_context *) data; ssl_cache_context *cache = (ssl_cache_context *) data;
ssl_cache_entry *cur, *prv; ssl_cache_entry *cur, *prv, *old = NULL;
int count = 0;
cur = cache->chain; cur = cache->chain;
prv = NULL; prv = NULL;
while( cur != NULL ) while( cur != NULL )
{ {
count++;
if( cache->timeout != 0 && if( cache->timeout != 0 &&
(int) ( t - cur->timestamp ) > cache->timeout ) (int) ( t - cur->timestamp ) > cache->timeout )
{ {
@ -97,22 +101,39 @@ int ssl_cache_set( void *data, const ssl_session *session )
if( memcmp( session->id, cur->session.id, cur->session.length ) == 0 ) if( memcmp( session->id, cur->session.id, cur->session.length ) == 0 )
break; /* client reconnected, keep timestamp for session id */ break; /* client reconnected, keep timestamp for session id */
if( oldest == 0 || cur->timestamp < oldest )
{
oldest = cur->timestamp;
old = cur;
}
prv = cur; prv = cur;
cur = cur->next; cur = cur->next;
} }
if( cur == NULL ) if( cur == NULL )
{ {
cur = (ssl_cache_entry *) malloc( sizeof( ssl_cache_entry ) ); /*
if( cur == NULL ) * Reuse oldest entry if max_entries reached
return( 1 ); */
if( old != NULL && count >= cache->max_entries )
memset( cur, 0, sizeof( ssl_cache_entry ) ); {
cur = old;
if( prv == NULL ) memset( &cur->session, 0, sizeof( ssl_session ) );
cache->chain = cur; }
else else
prv->next = cur; {
cur = (ssl_cache_entry *) malloc( sizeof( ssl_cache_entry ) );
if( cur == NULL )
return( 1 );
memset( cur, 0, sizeof( ssl_cache_entry ) );
if( prv == NULL )
cache->chain = cur;
else
prv->next = cur;
}
cur->timestamp = t; cur->timestamp = t;
} }
@ -133,6 +154,13 @@ void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout )
cache->timeout = timeout; cache->timeout = timeout;
} }
void ssl_cache_set_max_entries( ssl_cache_context *cache, int max )
{
if( max < 0 ) max = 0;
cache->max_entries = max;
}
void ssl_cache_free( ssl_cache_context *cache ) void ssl_cache_free( ssl_cache_context *cache )
{ {
ssl_cache_entry *cur, *prv; ssl_cache_entry *cur, *prv;