Don't over-allocate memory for DTLS fragments

Don't reserve the full message length of memory. Instead we only allocate memory for the fragments that we have already received. We also dynamically combine memory fragments when we receive overlap.
This commit is contained in:
Juliusz Sosinowicz
2022-09-02 18:07:57 +02:00
parent a33368f314
commit 8bf3e0829e
4 changed files with 475 additions and 165 deletions

View File

@@ -57640,6 +57640,139 @@ static int test_wolfSSL_DtlsUpdateWindow(void)
}
#endif /* WOLFSSL_DTLS */
#ifdef WOLFSSL_DTLS
static int DFB_TEST(WOLFSSL* ssl, word32 seq, word32 len, word32 f_offset,
word32 f_len, word32 f_count, byte ready, word32 bytesReceived)
{
DtlsMsg* cur;
static byte msg[100];
static byte msgInit = 0;
if (!msgInit) {
int i;
for (i = 0; i < 100; i++)
msg[i] = i + 1;
msgInit = 1;
}
/* Sanitize test parameters */
if (len > sizeof(msg))
return -1;
if (f_offset + f_len > sizeof(msg))
return -1;
DtlsMsgStore(ssl, 0, seq, msg + f_offset, len, certificate, f_offset, f_len, NULL);
if (ssl->dtls_rx_msg_list == NULL)
return -100;
if ((cur = DtlsMsgFind(ssl->dtls_rx_msg_list, 0, seq)) == NULL)
return -200;
if (cur->fragBucketListCount != f_count)
return -300;
if (cur->ready != ready)
return -400;
if (cur->bytesReceived != bytesReceived)
return -500;
if (ready) {
if (cur->fragBucketList != NULL)
return -600;
if (XMEMCMP(cur->fullMsg, msg, cur->sz) != 0)
return -700;
}
else {
DtlsFragBucket* fb;
if (cur->fragBucketList == NULL)
return -800;
for (fb = cur->fragBucketList; fb != NULL; fb = fb->next) {
if (XMEMCMP(fb->buf, msg + fb->offset, fb->sz) != 0)
return -900;
}
}
return 0;
}
static void DFB_TEST_RESET(WOLFSSL* ssl)
{
DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
ssl->dtls_rx_msg_list = NULL;
ssl->dtls_rx_msg_list_sz = 0;
}
static int test_wolfSSL_DTLS_fragment_buckets(void)
{
WOLFSSL ssl[1];
printf(testingFmt, "wolfSSL_DTLS_fragment_buckets()");
XMEMSET(ssl, 0, sizeof(*ssl));
AssertIntEQ(DFB_TEST(ssl, 0, 100, 0, 100, 0, 1, 100), 0); /* 0-100 */
AssertIntEQ(DFB_TEST(ssl, 1, 100, 0, 20, 1, 0, 20), 0); /* 0-20 */
AssertIntEQ(DFB_TEST(ssl, 1, 100, 20, 20, 1, 0, 40), 0); /* 20-40 */
AssertIntEQ(DFB_TEST(ssl, 1, 100, 40, 20, 1, 0, 60), 0); /* 40-60 */
AssertIntEQ(DFB_TEST(ssl, 1, 100, 60, 20, 1, 0, 80), 0); /* 60-80 */
AssertIntEQ(DFB_TEST(ssl, 1, 100, 80, 20, 0, 1, 100), 0); /* 80-100 */
/* Test all permutations of 3 regions */
/* 1 2 3 */
AssertIntEQ(DFB_TEST(ssl, 2, 100, 0, 30, 1, 0, 30), 0); /* 0-30 */
AssertIntEQ(DFB_TEST(ssl, 2, 100, 30, 30, 1, 0, 60), 0); /* 30-60 */
AssertIntEQ(DFB_TEST(ssl, 2, 100, 60, 40, 0, 1, 100), 0); /* 60-100 */
/* 1 3 2 */
AssertIntEQ(DFB_TEST(ssl, 3, 100, 0, 30, 1, 0, 30), 0); /* 0-30 */
AssertIntEQ(DFB_TEST(ssl, 3, 100, 60, 40, 2, 0, 70), 0); /* 60-100 */
AssertIntEQ(DFB_TEST(ssl, 3, 100, 30, 30, 0, 1, 100), 0); /* 30-60 */
/* 2 1 3 */
AssertIntEQ(DFB_TEST(ssl, 4, 100, 30, 30, 1, 0, 30), 0); /* 30-60 */
AssertIntEQ(DFB_TEST(ssl, 4, 100, 0, 30, 1, 0, 60), 0); /* 0-30 */
AssertIntEQ(DFB_TEST(ssl, 4, 100, 60, 40, 0, 1, 100), 0); /* 60-100 */
/* 2 3 1 */
AssertIntEQ(DFB_TEST(ssl, 5, 100, 30, 30, 1, 0, 30), 0); /* 30-60 */
AssertIntEQ(DFB_TEST(ssl, 5, 100, 60, 40, 1, 0, 70), 0); /* 60-100 */
AssertIntEQ(DFB_TEST(ssl, 5, 100, 0, 30, 0, 1, 100), 0); /* 0-30 */
/* 3 1 2 */
AssertIntEQ(DFB_TEST(ssl, 6, 100, 60, 40, 1, 0, 40), 0); /* 60-100 */
AssertIntEQ(DFB_TEST(ssl, 6, 100, 0, 30, 2, 0, 70), 0); /* 0-30 */
AssertIntEQ(DFB_TEST(ssl, 6, 100, 30, 30, 0, 1, 100), 0); /* 30-60 */
/* 3 2 1 */
AssertIntEQ(DFB_TEST(ssl, 7, 100, 60, 40, 1, 0, 40), 0); /* 60-100 */
AssertIntEQ(DFB_TEST(ssl, 7, 100, 30, 30, 1, 0, 70), 0); /* 30-60 */
AssertIntEQ(DFB_TEST(ssl, 7, 100, 0, 30, 0, 1, 100), 0); /* 0-30 */
/* Test overlapping regions */
AssertIntEQ(DFB_TEST(ssl, 8, 100, 0, 30, 1, 0, 30), 0); /* 0-30 */
AssertIntEQ(DFB_TEST(ssl, 8, 100, 20, 10, 1, 0, 30), 0); /* 20-30 */
AssertIntEQ(DFB_TEST(ssl, 8, 100, 70, 10, 2, 0, 40), 0); /* 70-80 */
AssertIntEQ(DFB_TEST(ssl, 8, 100, 20, 30, 2, 0, 60), 0); /* 20-50 */
AssertIntEQ(DFB_TEST(ssl, 8, 100, 40, 60, 0, 1, 100), 0); /* 40-100 */
/* Test overlapping multiple regions */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 0, 20, 1, 0, 20), 0); /* 0-20 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 30, 5, 2, 0, 25), 0); /* 30-35 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 40, 5, 3, 0, 30), 0); /* 40-45 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 50, 5, 4, 0, 35), 0); /* 50-55 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 60, 5, 5, 0, 40), 0); /* 60-65 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 70, 5, 6, 0, 45), 0); /* 70-75 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 30, 25, 4, 0, 55), 0); /* 30-55 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 55, 15, 2, 0, 65), 0); /* 55-70 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 75, 25, 2, 0, 90), 0); /* 75-100 */
AssertIntEQ(DFB_TEST(ssl, 9, 100, 10, 25, 0, 1, 100), 0); /* 10-35 */
AssertIntEQ(DFB_TEST(ssl, 10, 100, 0, 20, 1, 0, 20), 0); /* 0-20 */
AssertIntEQ(DFB_TEST(ssl, 10, 100, 30, 20, 2, 0, 40), 0); /* 30-50 */
AssertIntEQ(DFB_TEST(ssl, 10, 100, 0, 40, 1, 0, 50), 0); /* 0-40 */
AssertIntEQ(DFB_TEST(ssl, 10, 100, 50, 50, 0, 1, 100), 0); /* 10-35 */
DFB_TEST_RESET(ssl);
printf(resultFmt, passed);
return 0;
}
#endif
/*----------------------------------------------------------------------------*
| Main
*----------------------------------------------------------------------------*/
@@ -58535,6 +58668,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_FIPS_mode),
#ifdef WOLFSSL_DTLS
TEST_DECL(test_wolfSSL_DtlsUpdateWindow),
TEST_DECL(test_wolfSSL_DTLS_fragment_buckets),
#endif
TEST_DECL(test_ForceZero),