Skip to content

Commit

Permalink
Merge pull request #682 from ejohnstown/static-memory
Browse files Browse the repository at this point in the history
Static Memory Pools
  • Loading branch information
JacobBarthelmeh authored May 8, 2024
2 parents 8839376 + 2e1ca68 commit 2c5e958
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 36 deletions.
8 changes: 4 additions & 4 deletions examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,20 +780,20 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
err_sys("If setting priv key, need pub key.");
}

ret = ClientSetPrivateKey(privKeyName, userEcc);
ret = ClientSetPrivateKey(privKeyName, userEcc, NULL);
if (ret != 0) {
err_sys("Error setting private key");
}

#ifdef WOLFSSH_CERTS
/* passed in certificate to use */
if (certName) {
ret = ClientUseCert(certName);
ret = ClientUseCert(certName, NULL);
}
else
#endif
if (pubKeyName) {
ret = ClientUsePubKey(pubKeyName, userEcc);
ret = ClientUsePubKey(pubKeyName, userEcc, NULL);
}
if (ret != 0) {
err_sys("Error setting public key");
Expand Down Expand Up @@ -1079,7 +1079,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
err_sys("Closing client stream failed");
}

ClientFreeBuffers(pubKeyName, privKeyName);
ClientFreeBuffers(pubKeyName, privKeyName, NULL);
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
Expand Down
37 changes: 20 additions & 17 deletions examples/client/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ static const unsigned int hanselPrivateEccSz = 223;

#if defined(WOLFSSH_CERTS)

static int load_der_file(const char* filename, byte** out, word32* outSz)
static int load_der_file(const char* filename, byte** out, word32* outSz,
void* heap)
{
WFILE* file;
byte* in;
Expand All @@ -267,7 +268,7 @@ static int load_der_file(const char* filename, byte** out, word32* outSz)
return -1;
}

in = (byte*)WMALLOC(inSz, NULL, 0);
in = (byte*)WMALLOC(inSz, heap, 0);
if (in == NULL) {
WFCLOSE(NULL, file);
return -1;
Expand All @@ -276,7 +277,7 @@ static int load_der_file(const char* filename, byte** out, word32* outSz)
ret = (int)WFREAD(NULL, in, 1, inSz, file);
if (ret <= 0 || (word32)ret != inSz) {
ret = -1;
WFREE(in, NULL, 0);
WFREE(in, heap, 0);
in = 0;
inSz = 0;
}
Expand Down Expand Up @@ -652,19 +653,20 @@ int ClientSetEcho(int type)

/* Set certificate to use and public key.
* returns 0 on success */
int ClientUseCert(const char* certName)
int ClientUseCert(const char* certName, void* heap)
{
int ret = 0;

if (certName != NULL) {
#ifdef WOLFSSH_CERTS
ret = load_der_file(certName, &userPublicKey, &userPublicKeySz);
ret = load_der_file(certName, &userPublicKey, &userPublicKeySz, heap);
if (ret == 0) {
userPublicKeyType = publicKeyType;
userPublicKeyTypeSz = (word32)WSTRLEN((const char*)publicKeyType);
pubKeyLoaded = 1;
}
#else
(void)heap;
fprintf(stderr, "Certificate support not compiled in");
ret = WS_NOT_COMPILED;
#endif
Expand All @@ -676,7 +678,7 @@ int ClientUseCert(const char* certName)

/* Reads the private key to use from file name privKeyName.
* returns 0 on success */
int ClientSetPrivateKey(const char* privKeyName, int userEcc)
int ClientSetPrivateKey(const char* privKeyName, int userEcc, void* heap)
{
int ret = 0;

Expand All @@ -685,14 +687,14 @@ int ClientSetPrivateKey(const char* privKeyName, int userEcc)
#ifndef WOLFSSH_NO_ECC
ret = wolfSSH_ReadKey_buffer(hanselPrivateEcc, hanselPrivateEccSz,
WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz,
&userPrivateKeyType, &userPrivateKeyTypeSz, NULL);
&userPrivateKeyType, &userPrivateKeyTypeSz, heap);
#endif
}
else {
#ifndef WOLFSSH_NO_RSA
ret = wolfSSH_ReadKey_buffer(hanselPrivateRsa, hanselPrivateRsaSz,
WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz,
&userPrivateKeyType, &userPrivateKeyTypeSz, NULL);
&userPrivateKeyType, &userPrivateKeyTypeSz, heap);
#endif
}
isPrivate = 1;
Expand All @@ -703,7 +705,7 @@ int ClientSetPrivateKey(const char* privKeyName, int userEcc)
ret = wolfSSH_ReadKey_file(privKeyName,
(byte**)&userPrivateKey, &userPrivateKeySz,
(const byte**)&userPrivateKeyType, &userPrivateKeyTypeSz,
&isPrivate, NULL);
&isPrivate, heap);
#else
printf("file system not compiled in!\n");
ret = NOT_COMPILED_IN;
Expand All @@ -716,7 +718,7 @@ int ClientSetPrivateKey(const char* privKeyName, int userEcc)

/* Set public key to use
* returns 0 on success */
int ClientUsePubKey(const char* pubKeyName, int userEcc)
int ClientUsePubKey(const char* pubKeyName, int userEcc, void* heap)
{
int ret = 0;

Expand All @@ -729,15 +731,15 @@ int ClientUsePubKey(const char* pubKeyName, int userEcc)
ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicEcc,
(word32)strlen(hanselPublicEcc), WOLFSSH_FORMAT_SSH,
&p, &userPublicKeySz,
&userPublicKeyType, &userPublicKeyTypeSz, NULL);
&userPublicKeyType, &userPublicKeyTypeSz, heap);
#endif
}
else {
#ifndef WOLFSSH_NO_RSA
ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicRsa,
(word32)strlen(hanselPublicRsa), WOLFSSH_FORMAT_SSH,
&p, &userPublicKeySz,
&userPublicKeyType, &userPublicKeyTypeSz, NULL);
&userPublicKeyType, &userPublicKeyTypeSz, heap);
#endif
}
isPrivate = 1;
Expand All @@ -748,7 +750,7 @@ int ClientUsePubKey(const char* pubKeyName, int userEcc)
ret = wolfSSH_ReadKey_file(pubKeyName,
&userPublicKey, &userPublicKeySz,
(const byte**)&userPublicKeyType, &userPublicKeyTypeSz,
&isPrivate, NULL);
&isPrivate, heap);
#else
printf("file system not compiled in!\n");
ret = -1;
Expand All @@ -771,7 +773,7 @@ int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert)
byte* der = NULL;
word32 derSz;

ret = load_der_file(caCert, &der, &derSz);
ret = load_der_file(caCert, &der, &derSz, ctx->heap);
if (ret == 0) {
if (wolfSSH_CTX_AddRootCert_buffer(ctx, der, derSz,
WOLFSSH_FORMAT_ASN1) != WS_SUCCESS) {
Expand All @@ -790,13 +792,14 @@ int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert)
}


void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName)
void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName,
void* heap)
{
if (pubKeyName != NULL && userPublicKey != NULL) {
WFREE(userPublicKey, NULL, DYNTYPE_PRIVKEY);
WFREE(userPublicKey, heap, DYNTYPE_PRIVKEY);
}

if (privKeyName != NULL && userPrivateKey != NULL) {
WFREE(userPrivateKey, NULL, DYNTYPE_PRIVKEY);
WFREE(userPrivateKey, heap, DYNTYPE_PRIVKEY);
}
}
9 changes: 5 additions & 4 deletions examples/client/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@
#ifndef WOLFSSH_COMMON_H
#define WOLFSSH_COMMON_H
int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert);
int ClientUsePubKey(const char* pubKeyName, int userEcc);
int ClientSetPrivateKey(const char* privKeyName, int userEcc);
int ClientUseCert(const char* certName);
int ClientUsePubKey(const char* pubKeyName, int userEcc, void* heap);
int ClientSetPrivateKey(const char* privKeyName, int userEcc, void* heap);
int ClientUseCert(const char* certName, void* heap);
int ClientSetEcho(int type);
int ClientUserAuth(byte authType,
WS_UserAuthData* authData,
void* ctx);
int ClientPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx);
void ClientIPOverride(int flag);
void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName);
void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName,
void* heap);

#endif /* WOLFSSH_COMMON_H */

110 changes: 109 additions & 1 deletion examples/echoserver/echoserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,87 @@ static int termios_show(int fd)
#endif /* SHELL_DEBUG */


#ifdef WOLFSSH_STATIC_MEMORY
#ifndef WOLFSSL_STATIC_MEMORY
#error Requires the static memory functions from wolfSSL
#endif
#if defined(WOLFSSH_SCP) || defined(WOLFSSH_SHELL) || defined(WOLFSSH_FWD)
#warning Static memory configuration for SFTP, results may vary.
#endif
typedef WOLFSSL_HEAP_HINT ES_HEAP_HINT;

/* This static buffer is tuned for building with SFTP only. The static
* buffer size is calulated by multiplying the pairs of sizeList items
* and distList items and summing (32*64 + 128*118 + ...) and adding
* the sum of the distList values times the sizeof wc_Memory (rounded up
* to a word, 24). This total was 288kb plus change, rounded up to 289. */
#ifndef ES_STATIC_SIZES
#define ES_STATIC_SIZES 32,128,384,800,3120,8400,17552,32846,131072
#endif
#ifndef ES_STATIC_DISTS
#define ES_STATIC_DISTS 64,118,3,4,6,2,2,2,1
#endif
#ifndef ES_STATIC_LISTSZ
#define ES_STATIC_LISTSZ 9
#endif
#ifndef ES_STATIC_BUFSZ
#define ES_STATIC_BUFSZ (289*1024)
#endif
static const word32 static_sizeList[] = {ES_STATIC_SIZES};
static const word32 static_distList[] = {ES_STATIC_DISTS};
static byte static_buffer[ES_STATIC_BUFSZ];

static void wolfSSH_MemoryPrintStats(ES_HEAP_HINT* hint)
{
if (hint != NULL) {
word16 i;
WOLFSSL_MEM_STATS stats;

wolfSSL_GetMemStats(hint->memory, &stats);

/* print to stderr so is on the same pipe as WOLFSSL_DEBUG */
fprintf(stderr, "Total mallocs = %d\n", stats.totalAlloc);
fprintf(stderr, "Total frees = %d\n", stats.totalFr);
fprintf(stderr, "Current mallocs = %d\n", stats.curAlloc);
fprintf(stderr, "Available IO = %d\n", stats.avaIO);
fprintf(stderr, "Max con. handshakes = %d\n", stats.maxHa);
fprintf(stderr, "Max con. IO = %d\n", stats.maxIO);
fprintf(stderr, "State of memory blocks: size : available\n");
for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
fprintf(stderr, " %8d : %d\n",
stats.blockSz[i], stats.avaBlock[i]);
}
}
}

static void wolfSSH_MemoryConnPrintStats(ES_HEAP_HINT* hint)
{
if (hint != NULL) {
WOLFSSL_MEM_CONN_STATS* stats = hint->stats;

/* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
if (hint->memory->flag & WOLFMEM_TRACK_STATS
&& hint->stats != NULL) {
fprintf(stderr, "peak connection memory = %d\n",
stats->peakMem);
fprintf(stderr, "current memory in use = %d\n",
stats->curMem);
fprintf(stderr, "peak connection allocs = %d\n",
stats->peakAlloc);
fprintf(stderr, "current connection allocs = %d\n",
stats->curAlloc);
fprintf(stderr, "total connection allocs = %d\n",
stats->totalAlloc);
fprintf(stderr, "total connection frees = %d\n\n",
stats->totalFr);
}
}
}
#else
typedef void ES_HEAP_HINT;
#endif


int ChildRunning = 0;

#ifdef WOLFSSH_SHELL
Expand Down Expand Up @@ -1419,6 +1500,11 @@ static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs)
threadCtx->fwdCbCtx.originName = NULL;
}
#endif

#ifdef WOLFSSH_STATIC_MEMORY
wolfSSH_MemoryConnPrintStats(threadCtx->ssh->ctx->heap);
#endif

wolfSSH_free(threadCtx->ssh);

if (ret != 0) {
Expand Down Expand Up @@ -2192,6 +2278,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
word32 threadCount = 0;
const char* keyList = NULL;
ES_HEAP_HINT* heap = NULL;
int multipleConnections = 1;
int userEcc = 0;
int peerEcc = 0;
Expand Down Expand Up @@ -2329,7 +2416,21 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
ES_ERROR("Couldn't initialize wolfSSH.\n");
}

ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL);
#ifdef WOLFSSH_STATIC_MEMORY
{
int ret;

ret = wc_LoadStaticMemory_ex(&heap,
ES_STATIC_LISTSZ, static_sizeList, static_distList,
static_buffer, sizeof(static_buffer),
WOLFMEM_GENERAL|WOLFMEM_TRACK_STATS, 0);
if (ret != 0) {
ES_ERROR("Couldn't set up static memory pool.\n");
}
}
#endif /* WOLFSSH_STATIC_MEMORY */

ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, heap);
if (ctx == NULL) {
ES_ERROR("Couldn't allocate SSH CTX data.\n");
}
Expand Down Expand Up @@ -2573,6 +2674,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
WFREE(threadCtx, NULL, 0);
ES_ERROR("Couldn't allocate SSH data.\n");
}
#ifdef WOLFSSH_STATIC_MEMORY
wolfSSH_MemoryConnPrintStats(heap);
#endif
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
/* Use the session object for its own highwater callback ctx */
if (defaultHighwater > 0) {
Expand Down Expand Up @@ -2649,6 +2753,10 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
wc_FreeMutex(&doneLock);
PwMapListDelete(&pwMapList);
wolfSSH_CTX_free(ctx);
#ifdef WOLFSSH_STATIC_MEMORY
wolfSSH_MemoryPrintStats(heap);
#endif

if (wolfSSH_Cleanup() != WS_SUCCESS) {
ES_ERROR("Couldn't clean up wolfSSH.\n");
}
Expand Down
8 changes: 4 additions & 4 deletions examples/scpclient/scpclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,20 +217,20 @@ THREAD_RETURN WOLFSSH_THREAD scp_client(void* args)
err_sys("Empty path values");
}

ret = ClientSetPrivateKey(privKeyName, 0);
ret = ClientSetPrivateKey(privKeyName, 0, NULL);
if (ret != 0) {
err_sys("Error setting private key");
}

#ifdef WOLFSSH_CERTS
/* passed in certificate to use */
if (certName) {
ret = ClientUseCert(certName);
ret = ClientUseCert(certName, NULL);
}
else
#endif
{
ret = ClientUsePubKey(pubKeyName, 0);
ret = ClientUsePubKey(pubKeyName, 0, NULL);
}
if (ret != 0) {
err_sys("Error setting public key");
Expand Down Expand Up @@ -327,7 +327,7 @@ THREAD_RETURN WOLFSSH_THREAD scp_client(void* args)
if (ret != WS_SUCCESS && ret != WS_SOCKET_ERROR_E)
err_sys("Closing scp stream failed. Connection could have been closed by peer");

ClientFreeBuffers(pubKeyName, privKeyName);
ClientFreeBuffers(pubKeyName, privKeyName, NULL);
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
Expand Down
Loading

0 comments on commit 2c5e958

Please sign in to comment.