add CTX reference count, can free by CTX or SSL

This commit is contained in:
toddouska 2011-12-07 16:32:18 -08:00
parent 247d5b5609
commit 2bc14ce69d
3 changed files with 71 additions and 31 deletions

View File

@ -563,9 +563,33 @@ struct CYASSL_CIPHER {
};
#ifdef SINGLE_THREADED
typedef int CyaSSL_Mutex;
#else /* MULTI_THREADED */
#ifdef USE_WINDOWS_API
typedef CRITICAL_SECTION CyaSSL_Mutex;
#elif defined(CYASSL_PTHREADS)
typedef pthread_mutex_t CyaSSL_Mutex;
#elif defined(THREADX)
typedef TX_MUTEX CyaSSL_Mutex;
#elif defined(MICRIUM)
typedef OS_MUTEX CyaSSL_Mutex;
#else
#error Need a mutex type in multithreaded mode
#endif /* USE_WINDOWS_API */
#endif /* SINGLE_THREADED */
CYASSL_LOCAL int InitMutex(CyaSSL_Mutex*);
CYASSL_LOCAL int FreeMutex(CyaSSL_Mutex*);
CYASSL_LOCAL int LockMutex(CyaSSL_Mutex*);
CYASSL_LOCAL int UnLockMutex(CyaSSL_Mutex*);
/* CyaSSL context type */
struct CYASSL_CTX {
CYASSL_METHOD* method;
CyaSSL_Mutex countMutex; /* reference count mutex */
int refCount; /* reference count */
buffer certificate;
buffer certChain;
/* chain after self, in DER, with leading size for each cert */
@ -603,7 +627,7 @@ struct CYASSL_CTX {
CYASSL_LOCAL
void InitSSL_Ctx(CYASSL_CTX*, CYASSL_METHOD*);
int InitSSL_Ctx(CYASSL_CTX*, CYASSL_METHOD*);
CYASSL_LOCAL
void FreeSSL_Ctx(CYASSL_CTX*);
CYASSL_LOCAL
@ -1218,29 +1242,6 @@ CYASSL_LOCAL timer_d Timer(void);
CYASSL_LOCAL word32 LowResTimer(void);
#ifdef SINGLE_THREADED
typedef int CyaSSL_Mutex;
#else /* MULTI_THREADED */
#ifdef USE_WINDOWS_API
typedef CRITICAL_SECTION CyaSSL_Mutex;
#elif defined(CYASSL_PTHREADS)
typedef pthread_mutex_t CyaSSL_Mutex;
#elif defined(THREADX)
typedef TX_MUTEX CyaSSL_Mutex;
#elif defined(MICRIUM)
typedef OS_MUTEX CyaSSL_Mutex;
#else
#error Need a mutex type in multithreaded mode
#endif /* USE_WINDOWS_API */
#endif /* SINGLE_THREADED */
CYASSL_LOCAL int InitMutex(CyaSSL_Mutex*);
CYASSL_LOCAL int FreeMutex(CyaSSL_Mutex*);
CYASSL_LOCAL int LockMutex(CyaSSL_Mutex*);
CYASSL_LOCAL int UnLockMutex(CyaSSL_Mutex*);
#ifdef __cplusplus
} /* extern "C" */

View File

@ -322,9 +322,11 @@ void InitSSL_Method(CYASSL_METHOD* method, ProtocolVersion pv)
}
void InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
/* Initialze SSL context, return 0 on success */
int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
{
ctx->method = method;
ctx->refCount = 1; /* so either CTX_free or SSL_free can release */
ctx->certificate.buffer = 0;
ctx->certChain.buffer = 0;
ctx->privateKey.buffer = 0;
@ -380,6 +382,11 @@ void InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
ctx->sendVerify = 0;
ctx->quietShutdown = 0;
if (InitMutex(&ctx->countMutex) < 0) {
CYASSL_MSG("Mutex error on CTX init");
return BAD_MUTEX_ERROR;
}
return 0;
}
@ -399,12 +406,29 @@ void SSL_CtxResourceFree(CYASSL_CTX* ctx)
void FreeSSL_Ctx(CYASSL_CTX* ctx)
{
SSL_CtxResourceFree(ctx);
XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
int doFree = 0;
if (LockMutex(&ctx->countMutex) != 0) {
CYASSL_MSG("Couldn't lock count mutex");
return;
}
ctx->refCount--;
if (ctx->refCount == 0)
doFree = 1;
UnLockMutex(&ctx->countMutex);
if (doFree) {
CYASSL_MSG("CTX ref count down to 0, doing full free");
SSL_CtxResourceFree(ctx);
XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
}
else {
(void)ctx;
CYASSL_MSG("CTX ref count not 0 yet, no free");
}
}
void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
byte haveNTRU, byte haveECDSA, int side)
{
@ -638,6 +662,15 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->version = ctx->method->version;
ssl->suites = ctx->suites;
/* increment CTX reference count */
if (LockMutex(&ctx->countMutex) != 0) {
CYASSL_MSG("Couldn't lock CTX count mutex");
return BAD_MUTEX_ERROR;
}
ctx->refCount++;
UnLockMutex(&ctx->countMutex);
#ifdef HAVE_LIBZ
ssl->didStreamInit = 0;
#endif
@ -859,6 +892,7 @@ void SSL_ResourceFree(CYASSL* ssl)
void FreeSSL(CYASSL* ssl)
{
FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */
SSL_ResourceFree(ssl);
XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
}

View File

@ -74,8 +74,13 @@ CYASSL_CTX* CyaSSL_CTX_new(CYASSL_METHOD* method)
return ctx;
ctx = (CYASSL_CTX*) XMALLOC(sizeof(CYASSL_CTX), 0, DYNAMIC_TYPE_CTX);
if (ctx)
InitSSL_Ctx(ctx, method);
if (ctx) {
if (InitSSL_Ctx(ctx, method) < 0) {
CYASSL_MSG("Init CTX failed");
CyaSSL_CTX_free(ctx);
ctx = NULL;
}
}
CYASSL_LEAVE("CYASSL_CTX_new", 0);
return ctx;
@ -453,7 +458,7 @@ int AddCA(CYASSL_CTX* ctx, buffer der, int force)
}
else {
CYASSL_MSG(" CA Mutex Lock failed");
ret = -1;
ret = BAD_MUTEX_ERROR;
FreeSigners(signer, ctx->heap);
}
}