typdef gaurd / error out on bad mutex init / handle no maxHa or maxIO set

This commit is contained in:
Jacob Barthelmeh
2016-06-10 14:13:27 -06:00
parent 2bda6c6449
commit 3d3591a227
6 changed files with 53 additions and 46 deletions

View File

@@ -1022,6 +1022,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
err_sys("static memory was not used with ssl"); err_sys("static memory was not used with ssl");
fprintf(stderr, "\nprint off SSL memory stats\n"); fprintf(stderr, "\nprint off SSL memory stats\n");
fprintf(stderr, "*** This is memory state before wolfSSL_free is called\n");
fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem); fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem);
fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem); fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem);
fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc); fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc);

View File

@@ -3132,13 +3132,15 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
WOLFSSL_MSG("Bad memory_mutex lock"); WOLFSSL_MSG("Bad memory_mutex lock");
return BAD_MUTEX_E; return BAD_MUTEX_E;
} }
if (ctx_hint->memory->maxHa <= ctx_hint->memory->curHa) { if (ctx_hint->memory->maxHa > 0 &&
ctx_hint->memory->maxHa <= ctx_hint->memory->curHa) {
WOLFSSL_MSG("At max number of handshakes for static memory"); WOLFSSL_MSG("At max number of handshakes for static memory");
return MEMORY_E; return MEMORY_E;
} }
ctx_hint->memory->curHa++; ctx_hint->memory->curHa++;
if (ctx_hint->memory->maxIO <= ctx_hint->memory->curIO) { if (ctx_hint->memory->maxIO > 0 &&
ctx_hint->memory->maxIO <= ctx_hint->memory->curIO) {
WOLFSSL_MSG("At max number of IO allowed for static memory"); WOLFSSL_MSG("At max number of IO allowed for static memory");
return MEMORY_E; return MEMORY_E;
} }
@@ -3566,7 +3568,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
if (ctx_heap->flag & WOLFMEM_TRACK_STATS) { if (ctx_heap->flag & WOLFMEM_TRACK_STATS) {
XFREE(ssl_hint->stats, ssl->ctx->heap, DYNAMIC_TYPE_SSL); XFREE(ssl_hint->stats, ssl->ctx->heap, DYNAMIC_TYPE_SSL);
} }
XFREE(ssl->heap, ssl_hint, DYNAMIC_TYPE_SSL); XFREE(ssl->heap, ssl->ctx->heap, DYNAMIC_TYPE_SSL);
#ifdef WOLFSSL_HEAP_TEST #ifdef WOLFSSL_HEAP_TEST
} }
#endif #endif
@@ -6429,7 +6431,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
keyRet = MEMORY_E; keyRet = MEMORY_E;
} else { } else {
keyRet = wc_InitRsaKey(ssl->peerRsaKey, keyRet = wc_InitRsaKey(ssl->peerRsaKey,
ssl->ctx->heap); ssl->heap);
} }
} else if (ssl->peerRsaKeyPresent) { } else if (ssl->peerRsaKeyPresent) {
/* don't leak on reuse */ /* don't leak on reuse */
@@ -6494,17 +6496,17 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
if (ssl->peerEccDsaKey == NULL) { if (ssl->peerEccDsaKey == NULL) {
/* alloc/init on demand */ /* alloc/init on demand */
ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->ctx->heap, DYNAMIC_TYPE_ECC); ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccDsaKey == NULL) { if (ssl->peerEccDsaKey == NULL) {
WOLFSSL_MSG("PeerEccDsaKey Memory error"); WOLFSSL_MSG("PeerEccDsaKey Memory error");
return MEMORY_E; return MEMORY_E;
} }
wc_ecc_init_h(ssl->peerEccDsaKey, ssl->ctx->heap); wc_ecc_init_h(ssl->peerEccDsaKey, ssl->heap);
} else if (ssl->peerEccDsaKeyPresent) { } else if (ssl->peerEccDsaKeyPresent) {
/* don't leak on reuse */ /* don't leak on reuse */
wc_ecc_free(ssl->peerEccDsaKey); wc_ecc_free(ssl->peerEccDsaKey);
ssl->peerEccDsaKeyPresent = 0; ssl->peerEccDsaKeyPresent = 0;
wc_ecc_init_h(ssl->peerEccDsaKey, ssl->ctx->heap); wc_ecc_init_h(ssl->peerEccDsaKey, ssl->heap);
} }
if (wc_ecc_import_x963(dCert->publicKey, dCert->pubKeySize, if (wc_ecc_import_x963(dCert->publicKey, dCert->pubKeySize,
ssl->peerEccDsaKey) != 0) { ssl->peerEccDsaKey) != 0) {
@@ -13231,16 +13233,16 @@ static void PickHashSigAlgo(WOLFSSL* ssl,
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
/* alloc/init on demand */ /* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->ctx->heap, DYNAMIC_TYPE_ECC); ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error"); WOLFSSL_MSG("PeerEccKey Memory error");
return MEMORY_E; return MEMORY_E;
} }
wc_ecc_init_h(ssl->peerEccKey, ssl->ctx->heap); wc_ecc_init_h(ssl->peerEccKey, ssl->heap);
} else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
wc_ecc_free(ssl->peerEccKey); wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKeyPresent = 0; ssl->peerEccKeyPresent = 0;
wc_ecc_init_h(ssl->peerEccKey, ssl->ctx->heap); wc_ecc_init_h(ssl->peerEccKey, ssl->heap);
} }
if (wc_ecc_import_x963(input + *inOutIdx, length, if (wc_ecc_import_x963(input + *inOutIdx, length,
@@ -13412,16 +13414,16 @@ static void PickHashSigAlgo(WOLFSSL* ssl,
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
/* alloc/init on demand */ /* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->ctx->heap, DYNAMIC_TYPE_ECC); ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error"); WOLFSSL_MSG("PeerEccKey Memory error");
return MEMORY_E; return MEMORY_E;
} }
wc_ecc_init_h(ssl->peerEccKey, ssl->ctx->heap); wc_ecc_init_h(ssl->peerEccKey, ssl->heap);
} else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
wc_ecc_free(ssl->peerEccKey); wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKeyPresent = 0; ssl->peerEccKeyPresent = 0;
wc_ecc_init_h(ssl->peerEccKey, ssl->ctx->heap); wc_ecc_init_h(ssl->peerEccKey, ssl->heap);
} }
if (wc_ecc_import_x963(input + *inOutIdx, length, if (wc_ecc_import_x963(input + *inOutIdx, length,
@@ -15718,7 +15720,7 @@ int DoSessionTicket(WOLFSSL* ssl,
if (ssl->buffers.serverDH_Pub.buffer == NULL) { if (ssl->buffers.serverDH_Pub.buffer == NULL) {
/* Free'd in SSL_ResourceFree and FreeHandshakeResources */ /* Free'd in SSL_ResourceFree and FreeHandshakeResources */
ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC( ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap, ssl->buffers.serverDH_P.length + 2, ssl->heap,
DYNAMIC_TYPE_DH); DYNAMIC_TYPE_DH);
if (ssl->buffers.serverDH_Pub.buffer == NULL) { if (ssl->buffers.serverDH_Pub.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske); ERROR_OUT(MEMORY_E, exit_sske);
@@ -15728,7 +15730,7 @@ int DoSessionTicket(WOLFSSL* ssl,
if (ssl->buffers.serverDH_Priv.buffer == NULL) { if (ssl->buffers.serverDH_Priv.buffer == NULL) {
/* Free'd in SSL_ResourceFree and FreeHandshakeResources */ /* Free'd in SSL_ResourceFree and FreeHandshakeResources */
ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC( ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap, ssl->buffers.serverDH_P.length + 2, ssl->heap,
DYNAMIC_TYPE_DH); DYNAMIC_TYPE_DH);
if (ssl->buffers.serverDH_Priv.buffer == NULL) { if (ssl->buffers.serverDH_Priv.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske); ERROR_OUT(MEMORY_E, exit_sske);
@@ -15758,7 +15760,7 @@ int DoSessionTicket(WOLFSSL* ssl,
if (ssl->eccTempKey == NULL) { if (ssl->eccTempKey == NULL) {
/* alloc/init on demand */ /* alloc/init on demand */
ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->ctx->heap, DYNAMIC_TYPE_ECC); ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->eccTempKey == NULL) { if (ssl->eccTempKey == NULL) {
WOLFSSL_MSG("EccTempKey Memory error"); WOLFSSL_MSG("EccTempKey Memory error");
ERROR_OUT(MEMORY_E, exit_sske); ERROR_OUT(MEMORY_E, exit_sske);
@@ -18323,7 +18325,7 @@ int DoSessionTicket(WOLFSSL* ssl,
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
/* alloc/init on demand */ /* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->ctx->heap, DYNAMIC_TYPE_ECC); ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error"); WOLFSSL_MSG("PeerEccKey Memory error");
ERROR_OUT(MEMORY_E, exit_dcke); ERROR_OUT(MEMORY_E, exit_dcke);
@@ -18533,7 +18535,7 @@ int DoSessionTicket(WOLFSSL* ssl,
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
/* alloc/init on demand */ /* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->ctx->heap, DYNAMIC_TYPE_ECC); ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error"); WOLFSSL_MSG("PeerEccKey Memory error");
ERROR_OUT(MEMORY_E, exit_dcke); ERROR_OUT(MEMORY_E, exit_dcke);

View File

@@ -658,6 +658,7 @@ int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap)
if (InitMutex(&(heap->memory_mutex)) != 0) { if (InitMutex(&(heap->memory_mutex)) != 0) {
WOLFSSL_MSG("Error creating heap memory mutex"); WOLFSSL_MSG("Error creating heap memory mutex");
return BAD_MUTEX_E;
} }
return SSL_SUCCESS; return SSL_SUCCESS;
@@ -854,9 +855,9 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
return SIDE_ERROR; return SIDE_ERROR;
if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH); XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH); XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
ssl->buffers.weOwnDH = 1; /* SSL owns now */ ssl->buffers.weOwnDH = 1; /* SSL owns now */
ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap, ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap,

View File

@@ -145,11 +145,11 @@ void* wolfSSL_Realloc(void *ptr, size_t size)
#ifdef WOLFSSL_STATIC_MEMORY #ifdef WOLFSSL_STATIC_MEMORY
typedef struct wc_Memory { struct wc_Memory {
word32 sz;
byte* buffer; byte* buffer;
struct wc_Memory* next; struct wc_Memory* next;
} wc_Memory; word32 sz;
};
/* returns amount of memory used on success. On error returns negative value /* returns amount of memory used on success. On error returns negative value
@@ -160,7 +160,7 @@ static int create_memory_buckets(byte* buffer, word32 bufSz,
word32 i; word32 i;
byte* pt = buffer; byte* pt = buffer;
int ret = 0; int ret = 0;
word32 memSz = sizeof(wc_Memory); word32 memSz = (word32)sizeof(wc_Memory);
word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
/* if not enough space available for bucket size then do not try */ /* if not enough space available for bucket size then do not try */
@@ -203,7 +203,7 @@ int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag,
word32 ava = sz; word32 ava = sz;
byte* pt = buffer; byte* pt = buffer;
int ret = 0; int ret = 0;
word32 memSz = sizeof(wc_Memory); word32 memSz = (word32)sizeof(wc_Memory);
word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
WOLFSSL_ENTER("wolfSSL_load_static_memory"); WOLFSSL_ENTER("wolfSSL_load_static_memory");
@@ -216,11 +216,7 @@ int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag,
while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) { while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
*pt = 0x00; *pt = 0x00;
pt++; pt++;
} ava--;
if (InitMutex(&(heap->memory_mutex)) != 0) {
WOLFSSL_MSG("Bad mutex init");
return BAD_MUTEX_E;
} }
/* devide into chunks of memory and add them to available list */ /* devide into chunks of memory and add them to available list */

View File

@@ -256,17 +256,19 @@ WOLFSSL_API int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf,
#endif /* WOLFSSL_SESSION_EXPORT */ #endif /* WOLFSSL_SESSION_EXPORT */
#ifdef WOLFSSL_STATIC_MEMORY #ifdef WOLFSSL_STATIC_MEMORY
/* use underscore to avoid possible redefinition of typdef from memory.h */ #ifndef WOLFSSL_MEM_GUARD
typedef struct WOLFSSL_MEM_STATS _WOLFSSL_MEM_STATS; #define WOLFSSL_MEM_GUARD
typedef struct WOLFSSL_MEM_CONN_STATS _WOLFSSL_MEM_CONN_STATS; typedef struct WOLFSSL_MEM_STATS WOLFSSL_MEM_STATS;
typedef struct WOLFSSL_MEM_CONN_STATS WOLFSSL_MEM_CONN_STATS;
#endif
WOLFSSL_API int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, WOLFSSL_API int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx,
wolfSSL_method_func method, wolfSSL_method_func method,
unsigned char* buf, unsigned int sz, unsigned char* buf, unsigned int sz,
int flag, int max); int flag, int max);
WOLFSSL_API int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_API int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx,
_WOLFSSL_MEM_STATS* mem_stats); WOLFSSL_MEM_STATS* mem_stats);
WOLFSSL_API int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_API int wolfSSL_is_static_memory(WOLFSSL* ssl,
_WOLFSSL_MEM_CONN_STATS* mem_stats); WOLFSSL_MEM_CONN_STATS* mem_stats);
#endif #endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)

View File

@@ -82,17 +82,22 @@ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function,
#define WOLFMEM_IO_POOL_FIXED 0x04 #define WOLFMEM_IO_POOL_FIXED 0x04
#define WOLFMEM_TRACK_STATS 0x08 #define WOLFMEM_TRACK_STATS 0x08
#ifndef WOLFSSL_MEM_GUARD
#define WOLFSSL_MEM_GUARD
typedef struct WOLFSSL_MEM_STATS WOLFSSL_MEM_STATS;
typedef struct WOLFSSL_MEM_CONN_STATS WOLFSSL_MEM_CONN_STATS;
#endif
typedef struct WOLFSSL_MEM_CONN_STATS { struct WOLFSSL_MEM_CONN_STATS {
word32 peakMem; /* peak memory usage */ word32 peakMem; /* peak memory usage */
word32 curMem; /* current memory usage */ word32 curMem; /* current memory usage */
word32 peakAlloc; /* peak memory allocations */ word32 peakAlloc; /* peak memory allocations */
word32 curAlloc; /* current memory allocations */ word32 curAlloc; /* current memory allocations */
word32 totalAlloc;/* total memory allocations for lifetime */ word32 totalAlloc;/* total memory allocations for lifetime */
word32 totalFr; /* total frees for lifetime */ word32 totalFr; /* total frees for lifetime */
} WOLFSSL_MEM_CONN_STATS; };
typedef struct WOLFSSL_MEM_STATS { struct WOLFSSL_MEM_STATS {
word32 curAlloc; /* current memory allocations */ word32 curAlloc; /* current memory allocations */
word32 totalAlloc;/* total memory allocations for lifetime */ word32 totalAlloc;/* total memory allocations for lifetime */
word32 totalFr; /* total frees for lifetime */ word32 totalFr; /* total frees for lifetime */
@@ -104,12 +109,12 @@ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function,
word32 avaBlock[WOLFMEM_MAX_BUCKETS];/* ava block sizes */ word32 avaBlock[WOLFMEM_MAX_BUCKETS];/* ava block sizes */
word32 usedBlock[WOLFMEM_MAX_BUCKETS]; word32 usedBlock[WOLFMEM_MAX_BUCKETS];
int flag; /* flag used */ int flag; /* flag used */
} WOLFSSL_MEM_STATS; };
typedef struct wc_Memory _wc_Memory; /* internal structure for mem bucket */ typedef struct wc_Memory wc_Memory; /* internal structure for mem bucket */
typedef struct WOLFSSL_HEAP { typedef struct WOLFSSL_HEAP {
_wc_Memory* ava[WOLFMEM_MAX_BUCKETS]; wc_Memory* ava[WOLFMEM_MAX_BUCKETS];
_wc_Memory* io; /* list of buffers to use for IO */ wc_Memory* io; /* list of buffers to use for IO */
word32 maxHa; /* max concurent handshakes */ word32 maxHa; /* max concurent handshakes */
word32 curHa; word32 curHa;
word32 maxIO; /* max concurrent IO connections */ word32 maxIO; /* max concurrent IO connections */
@@ -130,8 +135,8 @@ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function,
typedef struct WOLFSSL_HEAP_HINT { typedef struct WOLFSSL_HEAP_HINT {
WOLFSSL_HEAP* memory; WOLFSSL_HEAP* memory;
WOLFSSL_MEM_CONN_STATS* stats; /* hold individual connection stats */ WOLFSSL_MEM_CONN_STATS* stats; /* hold individual connection stats */
_wc_Memory* outBuf; /* set if using fixed io buffers */ wc_Memory* outBuf; /* set if using fixed io buffers */
_wc_Memory* inBuf; wc_Memory* inBuf;
} WOLFSSL_HEAP_HINT; } WOLFSSL_HEAP_HINT;
@@ -139,8 +144,8 @@ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function,
int flag, WOLFSSL_HEAP* heap); int flag, WOLFSSL_HEAP* heap);
WOLFSSL_LOCAL int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_LOCAL int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap,
WOLFSSL_MEM_STATS* stats); WOLFSSL_MEM_STATS* stats);
WOLFSSL_LOCAL int SetFixedIO(WOLFSSL_HEAP* heap, _wc_Memory** io); WOLFSSL_LOCAL int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io);
WOLFSSL_LOCAL int FreeFixedIO(WOLFSSL_HEAP* heap, _wc_Memory** io); WOLFSSL_LOCAL int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io);
#endif /* WOLFSSL_STATIC_MEMORY */ #endif /* WOLFSSL_STATIC_MEMORY */
#ifdef __cplusplus #ifdef __cplusplus