diff --git a/src/dtls13.c b/src/dtls13.c index e2c3518d4..b9df18b92 100644 --- a/src/dtls13.c +++ b/src/dtls13.c @@ -679,11 +679,11 @@ static int Dtls13DetectDisruption(WOLFSSL* ssl, word32 fragOffset) peer retransmission) */ if (ssl->dtls_rx_msg_list != NULL) { DtlsFragBucket* last = ssl->dtls_rx_msg_list->fragBucketList; - while (last != NULL && last->next != NULL) - last = last->next; + while (last != NULL && last->m.m.next != NULL) + last = last->m.m.next; /* Does this fragment start right after the last fragment we * have stored? */ - if (last != NULL && (last->offset + last->sz) != fragOffset) + if (last != NULL && (last->m.m.offset + last->m.m.sz) != fragOffset) return 1; } else { diff --git a/src/internal.c b/src/internal.c index 6b1c437ca..6aa2cf751 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8143,7 +8143,7 @@ void DtlsMsgDelete(DtlsMsg* item, void* heap) if (item != NULL) { while (item->fragBucketList != NULL) { - DtlsFragBucket* next = item->fragBucketList->next; + DtlsFragBucket* next = item->fragBucketList->m.m.next; DtlsMsgDestroyFragBucket(item->fragBucketList, heap); item->fragBucketList = next; } @@ -8195,9 +8195,9 @@ static DtlsFragBucket* DtlsMsgCreateFragBucket(word32 offset, const byte* data, DYNAMIC_TYPE_DTLS_FRAG); if (bucket != NULL) { XMEMSET(bucket, 0, sizeof(*bucket)); - bucket->next = NULL; - bucket->offset = offset; - bucket->sz = dataSz; + bucket->m.m.next = NULL; + bucket->m.m.offset = offset; + bucket->m.m.sz = dataSz; if (data != NULL) XMEMCPY(bucket->buf, data, dataSz); } @@ -8219,27 +8219,27 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg, const byte* data, word32 dataSz, void* heap) { word32 offsetEnd = offset + dataSz; - word32 newOffset = min(cur->offset, offset); + word32 newOffset = min(cur->m.m.offset, offset); word32 newOffsetEnd; word32 newSz; - word32 overlapSz = cur->sz; + word32 overlapSz = cur->m.m.sz; DtlsFragBucket** chosenBucket; DtlsFragBucket* newBucket; DtlsFragBucket* otherBucket; byte combineNext = FALSE; - if (next != NULL && offsetEnd >= next->offset) + if (next != NULL && offsetEnd >= next->m.m.offset) combineNext = TRUE; if (combineNext) - newOffsetEnd = next->offset + next->sz; + newOffsetEnd = next->m.m.offset + next->m.m.sz; else - newOffsetEnd = max(cur->offset + cur->sz, offsetEnd); + newOffsetEnd = max(cur->m.m.offset + cur->m.m.sz, offsetEnd); newSz = newOffsetEnd - newOffset; /* Expand the larger bucket if data bridges the gap between cur and next */ - if (!combineNext || cur->sz >= next->sz) { + if (!combineNext || cur->m.m.sz >= next->m.m.sz) { chosenBucket = &cur; otherBucket = next; } @@ -8256,9 +8256,9 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg, if (chosenBucket == &next) { /* Update the link */ DtlsFragBucket* beforeNext = cur; - while (beforeNext->next != next) - beforeNext = beforeNext->next; - beforeNext->next = tmp; + while (beforeNext->m.m.next != next) + beforeNext = beforeNext->m.m.next; + beforeNext->m.m.next = tmp; } newBucket = *chosenBucket = tmp; } @@ -8266,10 +8266,10 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg, if (combineNext) { /* Put next first since it will always be at the end. Use memmove since * newBucket may be next. */ - XMEMMOVE(newBucket->buf + (next->offset - newOffset), next->buf, - next->sz); + XMEMMOVE(newBucket->buf + (next->m.m.offset - newOffset), next->buf, + next->m.m.sz); /* memory after newOffsetEnd is already copied. Don't do extra work. */ - newOffsetEnd = next->offset; + newOffsetEnd = next->m.m.offset; } if (newOffset == offset) { @@ -8282,16 +8282,16 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg, else { /* data -> cur. memcpy as much possible as its faster. */ XMEMMOVE(newBucket->buf + dataSz, cur->buf, - cur->sz - (offsetEnd - cur->offset)); + cur->m.m.sz - (offsetEnd - cur->m.m.offset)); XMEMCPY(newBucket->buf, data, dataSz); } } else { /* cur -> data */ - word32 curOffsetEnd = cur->offset + cur->sz; + word32 curOffsetEnd = cur->m.m.offset + cur->m.m.sz; if (newBucket != cur) - XMEMCPY(newBucket->buf, cur->buf, cur->sz); - XMEMCPY(newBucket->buf + cur->sz, + XMEMCPY(newBucket->buf, cur->buf, cur->m.m.sz); + XMEMCPY(newBucket->buf + cur->m.m.sz, data + (curOffsetEnd - offset), newOffsetEnd - curOffsetEnd); } @@ -8299,36 +8299,36 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg, /* All buckets up to and including next (if combining) have to be free'd */ { - DtlsFragBucket* toFree = cur->next; + DtlsFragBucket* toFree = cur->m.m.next; while (toFree != next) { - DtlsFragBucket* n = toFree->next; - overlapSz += toFree->sz; + DtlsFragBucket* n = toFree->m.m.next; + overlapSz += toFree->m.m.sz; DtlsMsgDestroyFragBucket(toFree, heap); msg->fragBucketListCount--; toFree = n; } if (combineNext) { - newBucket->next = next->next; - overlapSz += next->sz; + newBucket->m.m.next = next->m.m.next; + overlapSz += next->m.m.sz; DtlsMsgDestroyFragBucket(otherBucket, heap); msg->fragBucketListCount--; } else { - newBucket->next = next; + newBucket->m.m.next = next; } } /* Adjust size in msg */ msg->bytesReceived += newSz - overlapSz; - newBucket->offset = newOffset; - newBucket->sz = newSz; + newBucket->m.m.offset = newOffset; + newBucket->m.m.sz = newSz; return newBucket; } static void DtlsMsgAssembleCompleteMessage(DtlsMsg* msg) { /* We have received all necessary fragments. Reconstruct the header. */ - if (msg->fragBucketListCount != 1 || msg->fragBucketList->offset != 0 || - msg->fragBucketList->sz != msg->sz) { + if (msg->fragBucketListCount != 1 || msg->fragBucketList->m.m.offset != 0 || + msg->fragBucketList->m.m.sz != msg->sz) { WOLFSSL_MSG("Major error in fragment assembly logic"); return; } @@ -8395,9 +8395,9 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty DtlsFragBucket* prev = NULL; DtlsFragBucket* cur = msg->fragBucketList; byte done = 0; - for (; cur != NULL; prev = cur, cur = cur->next) { - word32 curOffset = cur->offset; - word32 curEnd = cur->offset + cur->sz; + for (; cur != NULL; prev = cur, cur = cur->m.m.next) { + word32 curOffset = cur->m.m.offset; + word32 curEnd = cur->m.m.offset + cur->m.m.sz; if (fragOffset >= curOffset && fragOffsetEnd <= curEnd) { /* We already have this fragment */ @@ -8417,13 +8417,14 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty WOLFSSL_ERROR_VERBOSE(DTLS_TOO_MANY_FRAGMENTS_E); return DTLS_TOO_MANY_FRAGMENTS_E; } - prev->next = DtlsMsgCreateFragBucket(fragOffset, data, fragSz, heap); - if (prev->next != NULL) { + prev->m.m.next = + DtlsMsgCreateFragBucket(fragOffset, data, fragSz, heap); + if (prev->m.m.next != NULL) { msg->bytesReceived += fragSz; msg->fragBucketListCount++; } } - else if (prev == NULL && fragOffsetEnd < cur->offset) { + else if (prev == NULL && fragOffsetEnd < cur->m.m.offset) { /* This is the new first fragment we have received */ if (msg->fragBucketListCount >= DTLS_FRAG_POOL_SZ) { WOLFSSL_ERROR_VERBOSE(DTLS_TOO_MANY_FRAGMENTS_E); @@ -8432,7 +8433,7 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty msg->fragBucketList = DtlsMsgCreateFragBucket(fragOffset, data, fragSz, heap); if (msg->fragBucketList != NULL) { - msg->fragBucketList->next = cur; + msg->fragBucketList->m.m.next = cur; msg->bytesReceived += fragSz; msg->fragBucketListCount++; } @@ -8443,12 +8444,12 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty } else { /* Find if this fragment overlaps with any more */ - DtlsFragBucket* next = cur->next; + DtlsFragBucket* next = cur->m.m.next; DtlsFragBucket** prev_next = prev != NULL - ? &prev->next : &msg->fragBucketList; + ? &prev->m.m.next : &msg->fragBucketList; while (next != NULL && - (next->offset + next->sz) <= fragOffsetEnd) - next = next->next; + (next->m.m.offset + next->m.m.sz) <= fragOffsetEnd) + next = next->m.m.next; /* We can combine the buckets */ *prev_next = DtlsMsgCombineFragBuckets(msg, cur, next, fragOffset, data, fragSz, heap); diff --git a/tests/api.c b/tests/api.c index 415323970..0ae5591e1 100644 --- a/tests/api.c +++ b/tests/api.c @@ -57684,8 +57684,8 @@ static int DFB_TEST(WOLFSSL* ssl, word32 seq, word32 len, word32 f_offset, 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) + for (fb = cur->fragBucketList; fb != NULL; fb = fb->m.m.next) { + if (XMEMCMP(fb->buf, msg + fb->m.m.offset, fb->m.m.sz) != 0) return -900; } } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ed9bc5eae..92693cc55 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4439,20 +4439,19 @@ typedef struct DtlsRecordLayerHeader { byte length[2]; } DtlsRecordLayerHeader; - -/* Padding necessary to fit DTLS_HANDSHAKE_HEADER_SZ bytes before the buf member - * of the DtlsFragBucket struct. */ -#define WOLFSSL_DTLS_FRAG_BUCKET_PADDING \ - ((DTLS_HANDSHAKE_HEADER_SZ > (sizeof(struct DtlsFragBucket*) + \ - sizeof(word32) + sizeof(word32))) ? \ - (DTLS_HANDSHAKE_HEADER_SZ - sizeof(struct DtlsFragBucket*) - \ - sizeof(word32) - sizeof(word32)) : 0) - typedef struct DtlsFragBucket { - struct DtlsFragBucket* next; - word32 offset; - word32 sz; - byte padding[WOLFSSL_DTLS_FRAG_BUCKET_PADDING]; + /* m stands for meta */ + union { + struct { + struct DtlsFragBucket* next; + word32 offset; + word32 sz; + } m; + /* Make sure we have at least DTLS_HANDSHAKE_HEADER_SZ bytes before the + * buf so that we can reconstruct the header in the allocated + * DtlsFragBucket buffer. */ + byte padding[DTLS_HANDSHAKE_HEADER_SZ]; + } m; byte buf[]; /* Add new member initialization to CreateFragBucket */ } DtlsFragBucket;