Commit 2dea113f authored by johan's avatar johan

Thread safe cache access API.

Add a mutex on database access
API with direct cache access is deprecated

+fix memory leaks in tests
parent 920b70eb
Pipeline #539 passed with stage
in 0 seconds
This diff is collapsed.
......@@ -48,10 +48,12 @@
typedef struct bzrtpChannelContext_struct bzrtpChannelContext_t;
#include <bctoolbox/crypto.h>
#include <bctoolbox/port.h>
#include "packetParser.h"
#include "stateMachine.h"
/* logging */
/* log domain is defined in CMakeList */
#include "bctoolbox/logging.h"
#ifdef _WIN32
......@@ -237,6 +239,7 @@ struct bzrtpContext_struct {
#else
void *zidCache; /**< an empty pointer always set to NULL when cache is disabled **/
#endif /* ZIDCACHE_ENABLED */
bctbx_mutex_t *zidCacheMutex; /**< lock access to the cache if provided **/
int zuid; /**< internal id used to address zid cache SIP/ZID pair binding **/
char *selfURI; /**< a null terminated string storing the local user URI **/
uint8_t selfZID[12]; /**< The ZRTP Identifier of this ZRTP end point - a random if running cache less */
......
......@@ -55,12 +55,13 @@ BZRTP_EXPORT int bzrtp_getPeerAssociatedSecrets(bzrtpContext_t *context, uint8_t
* - BZRTP_ZIDCACHE_INSERT_ZUID : if not found, insert a new row in ziduri table and return newly inserted zuid
* @param[out] zuid the internal db reference to the data row matching this particular pair of correspondant
* if identity binding is not found and insertFlag set to 0, this value is set to 0
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access, ignored if NULL
*
* @return 0 on success, BZRTP_ERROR_CACHE_PEERNOTFOUND if peer was not in and the insert flag is not set to BZRTP_ZIDCACHE_INSERT_ZUID, error code otherwise
*/
#define BZRTP_ZIDCACHE_DONT_INSERT_ZUID 0
#define BZRTP_ZIDCACHE_INSERT_ZUID 1
BZRTP_EXPORT int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const char *peerURI, const uint8_t peerZID[12], const uint8_t insertFlag, int *zuid);
BZRTP_EXPORT int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const char *peerURI, const uint8_t peerZID[12], const uint8_t insertFlag, int *zuid, bctbx_mutex_t *zidCacheMutex);
/**
* @brief This is a convenience wrapper to the bzrtp_cache_write function which will also take care of
......@@ -71,8 +72,7 @@ BZRTP_EXPORT int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const
* All three arrays must be the same lenght: columnsCount
* If the row isn't present in the given table, it will be inserted
*
* @param[in/out] dbPointer Pointer to an already opened sqlite db
* @param[in] zuid The DB internal id to adress the correct row(binding between local uri and peer ZID+URI)
* @param[in/out] context the current context, used to get the cache db pointer, zuid and cache mutex
* @param[in] tableName The name of the table to write in the db, must already exists. Null terminated string
* @param[in] columns An array of null terminated strings containing the name of the columns to update
* @param[in] values An array of buffers containing the values to insert/update matching the order of columns array
......@@ -81,6 +81,6 @@ BZRTP_EXPORT int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_cache_write_active(void *dbPointer, int zuid, const char *tableName, const char **columns, uint8_t **values, size_t *lengths, uint8_t columnsCount);
BZRTP_EXPORT int bzrtp_cache_write_active(bzrtpContext_t *context, const char *tableName, const char **columns, uint8_t **values, size_t *lengths, uint8_t columnsCount);
#endif /* ZIDCACHE_H */
......@@ -87,6 +87,7 @@ bzrtpContext_t *bzrtp_createBzrtpContext(void) {
/* initialise cached secret buffer to null */
context->zidCache = NULL; /* a pointer to the sqlite3 db accessor, can be NULL if running cacheless */
context->zidCacheMutex = NULL; /* a pointer to a mutex provided by the environment to lock database during access, ignored if NULL */
context->zuid = 0;
context->peerBzrtpVersion = 0;
context->selfURI = NULL;
......@@ -118,6 +119,8 @@ bzrtpContext_t *bzrtp_createBzrtpContext(void) {
* @brief Set the pointer allowing cache access
*
* @param[in] zidCachePointer Used by internal function to access cache: turn into a sqlite3 pointer if cache is enabled
* @param[in] selfURI Local URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] peerURI Peer URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
*
* @return 0 or BZRTP_CACHE_SETUP(if cache is populated by this call) on success, error code otherwise
*/
......@@ -141,7 +144,36 @@ int bzrtp_setZIDCache(bzrtpContext_t *context, void *zidCache, const char *selfU
context->peerURI = strdup(peerURI);
/* and init the cache(create needed tables if they don't exist) */
return bzrtp_initCache(context->zidCache);
return bzrtp_initCache_lock(context->zidCache, context->zidCacheMutex);
#else /* ZIDCACHE_ENABLED */
return BZRTP_ERROR_CACHEDISABLED;
#endif /* ZIDCACHE_ENABLED */
}
/**
* @brief Set the pointer allowing cache access, this version of the function get a mutex to lock the cache when accessing it
*
* Note: bzrtp does not manage the given mutex pointer, it has to be already initialized
* and shall be destroyed by environment after the BZRTP session is completed.
*
* @param[in] zidCachePointer Used by internal function to access cache: turn into a sqlite3 pointer if cache is enabled
* @param[in] selfURI Local URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] peerURI Peer URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access. Can be NULL, the zidcache is then non locked.
*
* @return 0 or BZRTP_CACHE_SETUP(if cache is populated by this call) on success, error code otherwise
*/
int bzrtp_setZIDCache_lock(bzrtpContext_t *context, void *zidCache, const char *selfURI, const char *peerURI, bctbx_mutex_t *zidCacheMutex) {
#ifdef ZIDCACHE_ENABLED
/* is zrtp context valid */
if (context==NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
context->zidCacheMutex = zidCacheMutex;
/* have the non lockable function finish the job */
return bzrtp_setZIDCache(context, zidCache, selfURI, peerURI);
#else /* ZIDCACHE_ENABLED */
return BZRTP_ERROR_CACHEDISABLED;
#endif /* ZIDCACHE_ENABLED */
......@@ -166,7 +198,7 @@ int bzrtp_initBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) {
}
/* initialise self ZID. Randomly generated if no ZID is found in cache or no cache found */
bzrtp_getSelfZID(context->zidCache, context->selfURI, context->selfZID, context->RNGContext);
bzrtp_getSelfZID_lock(context->zidCache, context->selfURI, context->selfZID, context->RNGContext, context->zidCacheMutex);
context->isInitialised = 1;
/* allocate 1 channel context, set all the others pointers to NULL */
......@@ -548,7 +580,7 @@ void bzrtp_SASVerified(bzrtpContext_t *zrtpContext) {
zrtpContext->cacheMismatchFlag = 0;
bzrtp_updateCachedSecrets(zrtpContext, zrtpContext->channelContext[0]); /* channel[0] is the only one in DHM mode, so the only one able to have a cache mismatch */
}
bzrtp_cache_write(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 1);
bzrtp_cache_write_lock(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 1, zrtpContext->zidCacheMutex);
}
}
......@@ -564,7 +596,7 @@ void bzrtp_resetSASVerified(bzrtpContext_t *zrtpContext) {
const char *colNames[] = {"pvs"};
uint8_t *colValues[] = {&pvsFlag};
size_t colLength[] = {1};
bzrtp_cache_write(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 1);
bzrtp_cache_write_lock(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 1, zrtpContext->zidCacheMutex);
}
}
......
......@@ -423,7 +423,6 @@ int bzrtp_packetParser(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpC
/* allocate a DHPart message structure and pv */
messageData = (bzrtpDHPartMessage_t *)malloc(sizeof(bzrtpDHPartMessage_t));
messageData->pv = (uint8_t *)malloc(pvLength*sizeof(uint8_t));
/* fill the structure */
memcpy(messageData->H1, messageContent, 32);
......@@ -509,6 +508,9 @@ int bzrtp_packetParser(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpC
}
/* alloc pv once all check are passed */
messageData->pv = (uint8_t *)malloc(pvLength*sizeof(uint8_t));
memcpy(messageData->rs1ID, messageContent, 8);
messageContent +=8;
memcpy(messageData->rs2ID, messageContent, 8);
......
......@@ -558,7 +558,7 @@ int state_keyAgreement_sendingCommit(bzrtpEvent_t event) {
size_t colLength[] = {1};
zrtpContext->cachedSecret.previouslyVerifiedSas = 0;
bzrtp_cache_write_active(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 1);
bzrtp_cache_write_active(zrtpContext, "zrtp", colNames, colValues, colLength, 1);
/* if we have a statusMessage callback, use it to warn user */
if (zrtpContext->zrtpCallbacks.bzrtp_statusMessage!=NULL && zrtpContext->zrtpCallbacks.bzrtp_messageLevel>=BZRTP_MESSAGE_ERROR) { /* use error level as this one MUST (RFC section 4.3.2) be warned */
......@@ -863,7 +863,7 @@ int state_keyAgreement_responderSendingDHPart1(bzrtpEvent_t event) {
size_t colLength[] = {1};
zrtpContext->cachedSecret.previouslyVerifiedSas = 0;
bzrtp_cache_write_active(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 1);
bzrtp_cache_write_active(zrtpContext, "zrtp", colNames, colValues, colLength, 1);
/* if we have a statusMessage callback, use it to warn user */
if (zrtpContext->zrtpCallbacks.bzrtp_statusMessage!=NULL && zrtpContext->zrtpCallbacks.bzrtp_messageLevel>=BZRTP_MESSAGE_ERROR) { /* use error level as this one MUST (RFC section 4.3.2) be warned */
......@@ -2253,10 +2253,10 @@ int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t
/* before writing into cache, we must check we have the zuid correctly set, if not (it's our first successfull exchange with peer), insert it*/
if (zrtpContext->zuid==0) {
bzrtp_cache_getZuid((void *)zrtpContext->zidCache, zrtpContext->selfURI, zrtpContext->peerURI, zrtpContext->peerZID, BZRTP_ZIDCACHE_INSERT_ZUID, &zrtpContext->zuid);
bzrtp_cache_getZuid((void *)zrtpContext->zidCache, zrtpContext->selfURI, zrtpContext->peerURI, zrtpContext->peerZID, BZRTP_ZIDCACHE_INSERT_ZUID, &zrtpContext->zuid, zrtpContext->zidCacheMutex);
}
bzrtp_cache_write_active(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 2);
bzrtp_cache_write_active(zrtpContext, "zrtp", colNames, colValues, colLength, 2);
/* if exist, call the callback function to perform custom cache operation that may use s0(writing exported key into cache) */
if (zrtpContext->zrtpCallbacks.bzrtp_contextReadyForExportedKeys != NULL) {
......
This diff is collapsed.
This diff is collapsed.
......@@ -196,9 +196,13 @@ void test_parser_param(uint8_t hvi_trick) {
/* Check also the zrtp hello hash */
if (zrtpPacket->messageType==MSGTYPE_HELLO) {
if (patternZRTPMetaData[i][2]==0x87654321) {
bzrtp_freeZrtpPacket(context12345678->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID]);
bzrtp_freeZrtpPacket(context87654321->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID]);
context12345678->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
context87654321->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
} else {
bzrtp_freeZrtpPacket(context87654321->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID]);
bzrtp_freeZrtpPacket(context12345678->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID]);
context87654321->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
context12345678->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
......@@ -648,6 +652,7 @@ static void test_parserComplete() {
memcpy(bob_DHPart1->auxsecretID, contextBob->channelContext[0]->responderAuxsecretID, 8);
memcpy(bob_DHPart1->pbxsecretID, contextBob->responderCachedSecretHash.pbxsecretID, 8);
free(contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->packetString);
retval +=bzrtp_packetBuild(contextBob, contextBob->channelContext[0], contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID],contextBob->channelContext[0]->selfSequenceNumber);
if (retval == 0) {
contextBob->channelContext[0]->selfSequenceNumber++;
......@@ -1239,11 +1244,13 @@ static void test_parserComplete() {
alice_Hello = bzrtp_createZrtpPacket(contextAlice, contextAlice->channelContext[1], MSGTYPE_HELLO, &retval);
if (bzrtp_packetBuild(contextAlice, contextAlice->channelContext[1], alice_Hello, contextAlice->channelContext[1]->selfSequenceNumber) ==0) {
contextAlice->channelContext[1]->selfSequenceNumber++;
bzrtp_freeZrtpPacket(contextAlice->channelContext[1]->selfPackets[HELLO_MESSAGE_STORE_ID]);
contextAlice->channelContext[1]->selfPackets[HELLO_MESSAGE_STORE_ID] = alice_Hello;
}
bob_Hello = bzrtp_createZrtpPacket(contextBob, contextBob->channelContext[1], MSGTYPE_HELLO, &retval);
if (bzrtp_packetBuild(contextBob, contextBob->channelContext[1], bob_Hello, contextBob->channelContext[1]->selfSequenceNumber) ==0) {
contextBob->channelContext[1]->selfSequenceNumber++;
bzrtp_freeZrtpPacket(contextBob->channelContext[1]->selfPackets[HELLO_MESSAGE_STORE_ID]);
contextBob->channelContext[1]->selfPackets[HELLO_MESSAGE_STORE_ID] = bob_Hello;
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment