From e8469fd02a2aabfededff93e944571f583279264 Mon Sep 17 00:00:00 2001 From: Sergei Shirokov Date: Wed, 27 Nov 2024 17:49:56 +0200 Subject: [PATCH] Eliminate private TxItem --- libudpard/udpard.c | 89 +++++------ libudpard/udpard.h | 3 + tests/src/test_intrusive_tx.c | 286 +++++++++++++++------------------- 3 files changed, 171 insertions(+), 207 deletions(-) diff --git a/libudpard/udpard.c b/libudpard/udpard.c index ce2c132..80e0bbb 100644 --- a/libudpard/udpard.c +++ b/libudpard/udpard.c @@ -272,23 +272,12 @@ static inline uint32_t transferCRCCompute(const size_t size, const void* const d // ================================================= TX PIPELINE ================================================= // ===================================================================================================================== -/// This is a subclass of UdpardTxItem. A pointer to this type can be cast to UdpardTxItem safely. -/// This is compliant with the C99 standard; paragraph 6.7.2.1.15 says: -/// A pointer to a structure object, suitably converted, points to its initial member (or if that member is a -/// bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a -/// structure object, but not at its beginning. -typedef struct -{ - struct UdpardTxItem base; - enum UdpardPriority priority; ///< Do we need this exposed in the public structure? We already have DSCP there. -} TxItem; - /// Chain of TX frames prepared for insertion into a TX queue. typedef struct { - TxItem* head; - TxItem* tail; - size_t count; + struct UdpardTxItem* head; + struct UdpardTxItem* tail; + size_t count; } TxChain; static inline bool txValidateMemoryResources(const struct UdpardTxMemoryResources memory) @@ -297,40 +286,40 @@ static inline bool txValidateMemoryResources(const struct UdpardTxMemoryResource (memory.payload.allocate != NULL) && (memory.payload.deallocate != NULL); } -static inline TxItem* txNewItem(const struct UdpardTxMemoryResources memory, - const uint_least8_t dscp_value_per_priority[UDPARD_PRIORITY_MAX + 1U], - const UdpardMicrosecond deadline_usec, - const enum UdpardPriority priority, - const struct UdpardUDPIPEndpoint endpoint, - const size_t datagram_payload_size, - void* const user_transfer_reference) +static inline struct UdpardTxItem* txNewItem(const struct UdpardTxMemoryResources memory, + const uint_least8_t dscp_value_per_priority[UDPARD_PRIORITY_MAX + 1U], + const UdpardMicrosecond deadline_usec, + const enum UdpardPriority priority, + const struct UdpardUDPIPEndpoint endpoint, + const size_t datagram_payload_size, + void* const user_transfer_reference) { - TxItem* out = memAlloc(memory.fragment, sizeof(TxItem)); + struct UdpardTxItem* out = memAlloc(memory.fragment, sizeof(struct UdpardTxItem)); if (out != NULL) { // No tree linkage by default. - out->base.base.up = NULL; - out->base.base.lr[0] = NULL; - out->base.base.lr[1] = NULL; - out->base.base.bf = 0; + out->base.up = NULL; + out->base.lr[0] = NULL; + out->base.lr[1] = NULL; + out->base.bf = 0; // Init metadata. - out->priority = priority; - out->base.next_in_transfer = NULL; // Last by default. - out->base.deadline_usec = deadline_usec; + out->priority = priority; + out->next_in_transfer = NULL; // Last by default. + out->deadline_usec = deadline_usec; UDPARD_ASSERT(priority <= UDPARD_PRIORITY_MAX); - out->base.dscp = dscp_value_per_priority[priority]; - out->base.destination = endpoint; - out->base.user_transfer_reference = user_transfer_reference; + out->dscp = dscp_value_per_priority[priority]; + out->destination = endpoint; + out->user_transfer_reference = user_transfer_reference; void* const payload_data = memAlloc(memory.payload, datagram_payload_size); if (NULL != payload_data) { - out->base.datagram_payload.data = payload_data; - out->base.datagram_payload.size = datagram_payload_size; + out->datagram_payload.data = payload_data; + out->datagram_payload.size = datagram_payload_size; } else { - memFree(memory.fragment, sizeof(TxItem), out); + memFree(memory.fragment, sizeof(struct UdpardTxItem), out); out = NULL; } } @@ -342,8 +331,8 @@ static inline TxItem* txNewItem(const struct UdpardTxMemoryResources memory, static inline int_fast8_t txAVLPredicate(void* const user_reference, // NOSONAR Cavl API requires pointer to non-const. const struct UdpardTreeNode* const node) { - const TxItem* const target = (const TxItem*) user_reference; - const TxItem* const other = (const TxItem*) (const void*) node; + const struct UdpardTxItem* const target = (const struct UdpardTxItem*) user_reference; + const struct UdpardTxItem* const other = (const struct UdpardTxItem*) (const void*) node; UDPARD_ASSERT((target != NULL) && (other != NULL)); return (target->priority >= other->priority) ? +1 : -1; } @@ -421,13 +410,13 @@ static inline TxChain txMakeChain(const struct UdpardTxMemoryResources memory, size_t offset = 0U; while (offset < payload_size_with_crc) { - TxItem* const item = txNewItem(memory, - dscp_value_per_priority, - deadline_usec, - meta.priority, - endpoint, - smaller(payload_size_with_crc - offset, mtu) + HEADER_SIZE_BYTES, - user_transfer_reference); + struct UdpardTxItem* const item = txNewItem(memory, + dscp_value_per_priority, + deadline_usec, + meta.priority, + endpoint, + smaller(payload_size_with_crc - offset, mtu) + HEADER_SIZE_BYTES, + user_transfer_reference); if (NULL == out.head) { out.head = item; @@ -436,7 +425,7 @@ static inline TxChain txMakeChain(const struct UdpardTxMemoryResources memory, { // C std, 6.7.2.1.15: A pointer to a structure object <...> points to its initial member, and vice versa. // Can't just read tqi->base because tqi may be NULL; https://github.com/OpenCyphal/libcanard/issues/203. - out.tail->base.next_in_transfer = (struct UdpardTxItem*) item; + out.tail->next_in_transfer = item; } out.tail = item; if (NULL == out.tail) @@ -444,7 +433,7 @@ static inline TxChain txMakeChain(const struct UdpardTxMemoryResources memory, break; } const bool last = (payload_size_with_crc - offset) <= mtu; - byte_t* const dst_buffer = item->base.datagram_payload.data; + byte_t* const dst_buffer = item->datagram_payload.data; byte_t* write_ptr = txSerializeHeader(dst_buffer, meta, (uint32_t) out.count, last); if (offset < payload.size) { @@ -460,7 +449,7 @@ static inline TxChain txMakeChain(const struct UdpardTxMemoryResources memory, { const size_t crc_offset = offset - payload.size; UDPARD_ASSERT(crc_offset < TRANSFER_CRC_SIZE_BYTES); - const size_t available = item->base.datagram_payload.size - (size_t) (write_ptr - dst_buffer); + const size_t available = item->datagram_payload.size - (size_t) (write_ptr - dst_buffer); UDPARD_ASSERT(available <= TRANSFER_CRC_SIZE_BYTES); const size_t write_size = smaller(TRANSFER_CRC_SIZE_BYTES - crc_offset, available); // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) @@ -509,7 +498,7 @@ static inline int32_t txPush(struct UdpardTx* const tx, if (chain.tail != NULL) { UDPARD_ASSERT(frame_count == chain.count); - struct UdpardTxItem* next = &chain.head->base; + struct UdpardTxItem* next = chain.head; do { const struct UdpardTreeNode* const res = @@ -527,7 +516,7 @@ static inline int32_t txPush(struct UdpardTx* const tx, else // The queue is large enough but we ran out of heap memory, so we have to unwind the chain. { out = -UDPARD_ERROR_MEMORY; - struct UdpardTxItem* head = &chain.head->base; + struct UdpardTxItem* head = chain.head; while (head != NULL) { struct UdpardTxItem* const next = head->next_in_transfer; @@ -694,7 +683,7 @@ void udpardTxFree(const struct UdpardTxMemoryResources memory, struct UdpardTxIt memFree(memory.payload, item->datagram_payload.size, item->datagram_payload.data); } - memFree(memory.fragment, sizeof(TxItem), item); + memFree(memory.fragment, sizeof(struct UdpardTxItem), item); } } diff --git a/libudpard/udpard.h b/libudpard/udpard.h index 3223d32..88fcde9 100644 --- a/libudpard/udpard.h +++ b/libudpard/udpard.h @@ -482,6 +482,9 @@ struct UdpardTxItem /// LibUDPard selects the DSCP value based on the transfer priority level and the configured DSCP mapping. uint_least8_t dscp; + /// Holds original transfer priority level (before DSCP mapping, see above `dscp`). + enum UdpardPriority priority; + /// This UDP/IP datagram compiled by libudpard should be sent to this endpoint. /// The endpoint is always at a multicast address. struct UdpardUDPIPEndpoint destination; diff --git a/tests/src/test_intrusive_tx.c b/tests/src/test_intrusive_tx.c index 7aee571..ec78f07 100644 --- a/tests/src/test_intrusive_tx.c +++ b/tests/src/test_intrusive_tx.c @@ -115,25 +115,22 @@ static void testMakeChainEmpty(void) (UdpardPayload){.size = 0, .data = ""}, &user_transfer_referent); TEST_ASSERT_EQUAL(1 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(sizeof(TxItem) + HEADER_SIZE_BYTES + 4, alloc.allocated_bytes); + TEST_ASSERT_EQUAL(sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES + 4, alloc.allocated_bytes); TEST_ASSERT_EQUAL(1, chain.count); TEST_ASSERT_EQUAL(chain.head, chain.tail); - TEST_ASSERT_EQUAL(NULL, chain.head->base.next_in_transfer); - TEST_ASSERT_EQUAL(1234567890, chain.head->base.deadline_usec); - TEST_ASSERT_EQUAL(33, chain.head->base.dscp); - TEST_ASSERT_EQUAL(0x0A0B0C0DU, chain.head->base.destination.ip_address); - TEST_ASSERT_EQUAL(0x1234, chain.head->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 4, chain.head->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 0, true).data, - chain.head->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(NULL, chain.head->next_in_transfer); + TEST_ASSERT_EQUAL(1234567890, chain.head->deadline_usec); + TEST_ASSERT_EQUAL(33, chain.head->dscp); + TEST_ASSERT_EQUAL(0x0A0B0C0DU, chain.head->destination.ip_address); + TEST_ASSERT_EQUAL(0x1234, chain.head->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 4, chain.head->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 0, true).data, chain.head->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp("\x00\x00\x00\x00", // CRC of the empty transfer. - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES, 4)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->base.user_transfer_reference); - udpardTxFree(mem, &chain.head->base); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->user_transfer_reference); + udpardTxFree(mem, chain.head); TEST_ASSERT_EQUAL(0, alloc.allocated_fragments); } @@ -162,32 +159,28 @@ static void testMakeChainSingleMaxMTU(void) (UdpardPayload){.size = DetailOfTheCosmosSize, .data = DetailOfTheCosmos}, &user_transfer_referent); TEST_ASSERT_EQUAL(1 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(sizeof(TxItem) + HEADER_SIZE_BYTES + DetailOfTheCosmosSize + TRANSFER_CRC_SIZE_BYTES, + TEST_ASSERT_EQUAL(sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES + DetailOfTheCosmosSize + TRANSFER_CRC_SIZE_BYTES, alloc.allocated_bytes); TEST_ASSERT_EQUAL(1, chain.count); TEST_ASSERT_EQUAL(chain.head, chain.tail); - TEST_ASSERT_EQUAL(NULL, chain.head->base.next_in_transfer); - TEST_ASSERT_EQUAL(1234567890, chain.head->base.deadline_usec); - TEST_ASSERT_EQUAL(77, chain.head->base.dscp); - TEST_ASSERT_EQUAL(0x0A0B0C00U, chain.head->base.destination.ip_address); - TEST_ASSERT_EQUAL(7474, chain.head->base.destination.udp_port); + TEST_ASSERT_EQUAL(NULL, chain.head->next_in_transfer); + TEST_ASSERT_EQUAL(1234567890, chain.head->deadline_usec); + TEST_ASSERT_EQUAL(77, chain.head->dscp); + TEST_ASSERT_EQUAL(0x0A0B0C00U, chain.head->destination.ip_address); + TEST_ASSERT_EQUAL(7474, chain.head->destination.udp_port); TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + DetailOfTheCosmosSize + TRANSFER_CRC_SIZE_BYTES, - chain.head->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 0, true).data, - chain.head->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + chain.head->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 0, true).data, chain.head->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(DetailOfTheCosmos, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES, DetailOfTheCosmosSize)); TEST_ASSERT_EQUAL(0, memcmp(DetailOfTheCosmosCRC, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES + - DetailOfTheCosmosSize, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES + DetailOfTheCosmosSize, TRANSFER_CRC_SIZE_BYTES)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->base.user_transfer_reference); - udpardTxFree(mem, &chain.head->base); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->user_transfer_reference); + udpardTxFree(mem, chain.head); TEST_ASSERT_EQUAL(0, alloc.allocated_fragments); } @@ -214,13 +207,13 @@ static void testMakeChainSingleFrameDefaultMTU(void) (UdpardPayload){.size = UDPARD_MTU_DEFAULT_MAX_SINGLE_FRAME, .data = payload}, NULL); TEST_ASSERT_EQUAL(1 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(sizeof(TxItem) + HEADER_SIZE_BYTES + UDPARD_MTU_DEFAULT_MAX_SINGLE_FRAME + + TEST_ASSERT_EQUAL(sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES + UDPARD_MTU_DEFAULT_MAX_SINGLE_FRAME + TRANSFER_CRC_SIZE_BYTES, alloc.allocated_bytes); TEST_ASSERT_EQUAL(1, chain.count); TEST_ASSERT_EQUAL(chain.head, chain.tail); - TEST_ASSERT_EQUAL(NULL, chain.head->base.next_in_transfer); - udpardTxFree(mem, &chain.head->base); + TEST_ASSERT_EQUAL(NULL, chain.head->next_in_transfer); + udpardTxFree(mem, chain.head); TEST_ASSERT_EQUAL(0, alloc.allocated_fragments); } { // Increase the payload by 1 byte and ensure it spills over. @@ -238,15 +231,15 @@ static void testMakeChainSingleFrameDefaultMTU(void) (UdpardPayload){.size = UDPARD_MTU_DEFAULT_MAX_SINGLE_FRAME + 1, .data = payload}, NULL); TEST_ASSERT_EQUAL(2 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL((sizeof(TxItem) + HEADER_SIZE_BYTES) * 2 + UDPARD_MTU_DEFAULT_MAX_SINGLE_FRAME + 1 + - TRANSFER_CRC_SIZE_BYTES, + TEST_ASSERT_EQUAL((sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES) * 2 + UDPARD_MTU_DEFAULT_MAX_SINGLE_FRAME + + 1 + TRANSFER_CRC_SIZE_BYTES, alloc.allocated_bytes); TEST_ASSERT_EQUAL(2, chain.count); TEST_ASSERT_NOT_EQUAL(chain.head, chain.tail); - TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->base.next_in_transfer); - TEST_ASSERT_EQUAL(NULL, chain.tail->base.next_in_transfer); - udpardTxFree(mem, &chain.head->base); - udpardTxFree(mem, &chain.tail->base); + TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->next_in_transfer); + TEST_ASSERT_EQUAL(NULL, chain.tail->next_in_transfer); + udpardTxFree(mem, chain.head); + udpardTxFree(mem, chain.tail); TEST_ASSERT_EQUAL(0, alloc.allocated_fragments); } } @@ -277,9 +270,10 @@ static void testMakeChainThreeFrames(void) (UdpardPayload){.size = EtherealStrengthSize, .data = EtherealStrength}, &user_transfer_referent); TEST_ASSERT_EQUAL(3 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(3 * (sizeof(TxItem) + HEADER_SIZE_BYTES) + EtherealStrengthSize + 4U, alloc.allocated_bytes); + TEST_ASSERT_EQUAL(3 * (sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES) + EtherealStrengthSize + 4U, + alloc.allocated_bytes); TEST_ASSERT_EQUAL(3, chain.count); - UdpardTxItem* const first = &chain.head->base; + UdpardTxItem* const first = chain.head; TEST_ASSERT_NOT_EQUAL(NULL, first); UdpardTxItem* const second = first->next_in_transfer; TEST_ASSERT_NOT_EQUAL(NULL, second); @@ -362,52 +356,46 @@ static void testMakeChainCRCSpill1(void) (UdpardPayload){.size = InterstellarWarSize, .data = InterstellarWar}, &user_transfer_referent); TEST_ASSERT_EQUAL(2 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(2 * (sizeof(TxItem) + HEADER_SIZE_BYTES) + InterstellarWarSize + 4U, alloc.allocated_bytes); + TEST_ASSERT_EQUAL(2 * (sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES) + InterstellarWarSize + 4U, + alloc.allocated_bytes); TEST_ASSERT_EQUAL(2, chain.count); TEST_ASSERT_NOT_EQUAL(chain.head, chain.tail); - TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->base.next_in_transfer); - TEST_ASSERT_EQUAL(NULL, chain.tail->base.next_in_transfer); + TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->next_in_transfer); + TEST_ASSERT_EQUAL(NULL, chain.tail->next_in_transfer); // FIRST FRAME -- contains the payload and the first three bytes of the CRC. - TEST_ASSERT_EQUAL(223574680, chain.head->base.deadline_usec); - TEST_ASSERT_EQUAL(55, chain.head->base.dscp); - TEST_ASSERT_EQUAL(0xBABADEDAU, chain.head->base.destination.ip_address); - TEST_ASSERT_EQUAL(0xD0ED, chain.head->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + mtu, chain.head->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 0, false).data, - chain.head->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(223574680, chain.head->deadline_usec); + TEST_ASSERT_EQUAL(55, chain.head->dscp); + TEST_ASSERT_EQUAL(0xBABADEDAU, chain.head->destination.ip_address); + TEST_ASSERT_EQUAL(0xD0ED, chain.head->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + mtu, chain.head->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 0, false).data, chain.head->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWar, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES, InterstellarWarSize)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWarCRC, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES + - InterstellarWarSize, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES + InterstellarWarSize, 3U)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->base.user_transfer_reference); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->user_transfer_reference); // SECOND FRAME -- contains the last byte of the CRC. - TEST_ASSERT_EQUAL(223574680, chain.tail->base.deadline_usec); - TEST_ASSERT_EQUAL(55, chain.tail->base.dscp); - TEST_ASSERT_EQUAL(0xBABADEDAU, chain.tail->base.destination.ip_address); - TEST_ASSERT_EQUAL(0xD0ED, chain.tail->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 1U, chain.tail->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 1, true).data, - chain.tail->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(223574680, chain.tail->deadline_usec); + TEST_ASSERT_EQUAL(55, chain.tail->dscp); + TEST_ASSERT_EQUAL(0xBABADEDAU, chain.tail->destination.ip_address); + TEST_ASSERT_EQUAL(0xD0ED, chain.tail->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 1U, chain.tail->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 1, true).data, chain.tail->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWarCRC + 3U, - (byte_t*) (chain.tail->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.tail->datagram_payload.data) + HEADER_SIZE_BYTES, 1U)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.tail->base.user_transfer_reference); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.tail->user_transfer_reference); // Clean up. - udpardTxFree(mem, &chain.head->base); - udpardTxFree(mem, &chain.tail->base); + udpardTxFree(mem, chain.head); + udpardTxFree(mem, chain.tail); TEST_ASSERT_EQUAL(0, alloc.allocated_fragments); } @@ -437,52 +425,46 @@ static void testMakeChainCRCSpill2(void) (UdpardPayload){.size = InterstellarWarSize, .data = InterstellarWar}, &user_transfer_referent); TEST_ASSERT_EQUAL(2 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(2 * (sizeof(TxItem) + HEADER_SIZE_BYTES) + InterstellarWarSize + 4U, alloc.allocated_bytes); + TEST_ASSERT_EQUAL(2 * (sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES) + InterstellarWarSize + 4U, + alloc.allocated_bytes); TEST_ASSERT_EQUAL(2, chain.count); TEST_ASSERT_NOT_EQUAL(chain.head, chain.tail); - TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->base.next_in_transfer); - TEST_ASSERT_EQUAL(NULL, chain.tail->base.next_in_transfer); + TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->next_in_transfer); + TEST_ASSERT_EQUAL(NULL, chain.tail->next_in_transfer); // FIRST FRAME -- contains the payload and the first two bytes of the CRC. - TEST_ASSERT_EQUAL(223574680, chain.head->base.deadline_usec); - TEST_ASSERT_EQUAL(55, chain.head->base.dscp); - TEST_ASSERT_EQUAL(0xBABADEDAU, chain.head->base.destination.ip_address); - TEST_ASSERT_EQUAL(0xD0ED, chain.head->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + mtu, chain.head->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 0, false).data, - chain.head->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(223574680, chain.head->deadline_usec); + TEST_ASSERT_EQUAL(55, chain.head->dscp); + TEST_ASSERT_EQUAL(0xBABADEDAU, chain.head->destination.ip_address); + TEST_ASSERT_EQUAL(0xD0ED, chain.head->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + mtu, chain.head->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 0, false).data, chain.head->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWar, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES, InterstellarWarSize)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWarCRC, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES + - InterstellarWarSize, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES + InterstellarWarSize, 2U)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->base.user_transfer_reference); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->user_transfer_reference); // SECOND FRAME -- contains the last two bytes of the CRC. - TEST_ASSERT_EQUAL(223574680, chain.tail->base.deadline_usec); - TEST_ASSERT_EQUAL(55, chain.tail->base.dscp); - TEST_ASSERT_EQUAL(0xBABADEDAU, chain.tail->base.destination.ip_address); - TEST_ASSERT_EQUAL(0xD0ED, chain.tail->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 2U, chain.tail->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 1, true).data, - chain.tail->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(223574680, chain.tail->deadline_usec); + TEST_ASSERT_EQUAL(55, chain.tail->dscp); + TEST_ASSERT_EQUAL(0xBABADEDAU, chain.tail->destination.ip_address); + TEST_ASSERT_EQUAL(0xD0ED, chain.tail->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 2U, chain.tail->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 1, true).data, chain.tail->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWarCRC + 2U, - (byte_t*) (chain.tail->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.tail->datagram_payload.data) + HEADER_SIZE_BYTES, 2U)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.tail->base.user_transfer_reference); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.tail->user_transfer_reference); // Clean up. - udpardTxFree(mem, &chain.head->base); - udpardTxFree(mem, &chain.tail->base); + udpardTxFree(mem, chain.head); + udpardTxFree(mem, chain.tail); TEST_ASSERT_EQUAL(0, alloc.allocated_fragments); } @@ -512,52 +494,46 @@ static void testMakeChainCRCSpill3(void) (UdpardPayload){.size = InterstellarWarSize, .data = InterstellarWar}, &user_transfer_referent); TEST_ASSERT_EQUAL(2 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(2 * (sizeof(TxItem) + HEADER_SIZE_BYTES) + InterstellarWarSize + 4U, alloc.allocated_bytes); + TEST_ASSERT_EQUAL(2 * (sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES) + InterstellarWarSize + 4U, + alloc.allocated_bytes); TEST_ASSERT_EQUAL(2, chain.count); TEST_ASSERT_NOT_EQUAL(chain.head, chain.tail); - TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->base.next_in_transfer); - TEST_ASSERT_EQUAL(NULL, chain.tail->base.next_in_transfer); + TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->next_in_transfer); + TEST_ASSERT_EQUAL(NULL, chain.tail->next_in_transfer); // FIRST FRAME -- contains the payload and the first byte of the CRC. - TEST_ASSERT_EQUAL(223574680, chain.head->base.deadline_usec); - TEST_ASSERT_EQUAL(55, chain.head->base.dscp); - TEST_ASSERT_EQUAL(0xBABADEDAU, chain.head->base.destination.ip_address); - TEST_ASSERT_EQUAL(0xD0ED, chain.head->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + mtu, chain.head->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 0, false).data, - chain.head->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(223574680, chain.head->deadline_usec); + TEST_ASSERT_EQUAL(55, chain.head->dscp); + TEST_ASSERT_EQUAL(0xBABADEDAU, chain.head->destination.ip_address); + TEST_ASSERT_EQUAL(0xD0ED, chain.head->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + mtu, chain.head->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 0, false).data, chain.head->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWar, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES, InterstellarWarSize)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWarCRC, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES + - InterstellarWarSize, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES + InterstellarWarSize, 1U)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->base.user_transfer_reference); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->user_transfer_reference); // SECOND FRAME -- contains the last three bytes of the CRC. - TEST_ASSERT_EQUAL(223574680, chain.tail->base.deadline_usec); - TEST_ASSERT_EQUAL(55, chain.tail->base.dscp); - TEST_ASSERT_EQUAL(0xBABADEDAU, chain.tail->base.destination.ip_address); - TEST_ASSERT_EQUAL(0xD0ED, chain.tail->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 3U, chain.tail->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 1, true).data, - chain.tail->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(223574680, chain.tail->deadline_usec); + TEST_ASSERT_EQUAL(55, chain.tail->dscp); + TEST_ASSERT_EQUAL(0xBABADEDAU, chain.tail->destination.ip_address); + TEST_ASSERT_EQUAL(0xD0ED, chain.tail->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 3U, chain.tail->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 1, true).data, chain.tail->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWarCRC + 1U, - (byte_t*) (chain.tail->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.tail->datagram_payload.data) + HEADER_SIZE_BYTES, 3U)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.tail->base.user_transfer_reference); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.tail->user_transfer_reference); // Clean up. - udpardTxFree(mem, &chain.head->base); - udpardTxFree(mem, &chain.tail->base); + udpardTxFree(mem, chain.head); + udpardTxFree(mem, chain.tail); TEST_ASSERT_EQUAL(0, alloc.allocated_fragments); } @@ -587,48 +563,43 @@ static void testMakeChainCRCSpillFull(void) (UdpardPayload){.size = InterstellarWarSize, .data = InterstellarWar}, &user_transfer_referent); TEST_ASSERT_EQUAL(2 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(2 * (sizeof(TxItem) + HEADER_SIZE_BYTES) + InterstellarWarSize + 4U, alloc.allocated_bytes); + TEST_ASSERT_EQUAL(2 * (sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES) + InterstellarWarSize + 4U, + alloc.allocated_bytes); TEST_ASSERT_EQUAL(2, chain.count); TEST_ASSERT_NOT_EQUAL(chain.head, chain.tail); - TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->base.next_in_transfer); - TEST_ASSERT_EQUAL(NULL, chain.tail->base.next_in_transfer); + TEST_ASSERT_EQUAL((UdpardTxItem*) chain.tail, chain.head->next_in_transfer); + TEST_ASSERT_EQUAL(NULL, chain.tail->next_in_transfer); // FIRST FRAME -- contains the payload only. - TEST_ASSERT_EQUAL(223574680, chain.head->base.deadline_usec); - TEST_ASSERT_EQUAL(55, chain.head->base.dscp); - TEST_ASSERT_EQUAL(0xBABADEDAU, chain.head->base.destination.ip_address); - TEST_ASSERT_EQUAL(0xD0ED, chain.head->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + mtu, chain.head->base.datagram_payload.size); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + InterstellarWarSize, chain.head->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 0, false).data, - chain.head->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(223574680, chain.head->deadline_usec); + TEST_ASSERT_EQUAL(55, chain.head->dscp); + TEST_ASSERT_EQUAL(0xBABADEDAU, chain.head->destination.ip_address); + TEST_ASSERT_EQUAL(0xD0ED, chain.head->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + mtu, chain.head->datagram_payload.size); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + InterstellarWarSize, chain.head->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 0, false).data, chain.head->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWar, - (byte_t*) (chain.head->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.head->datagram_payload.data) + HEADER_SIZE_BYTES, InterstellarWarSize)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->base.user_transfer_reference); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.head->user_transfer_reference); // SECOND FRAME -- contains the last byte of the CRC. - TEST_ASSERT_EQUAL(223574680, chain.tail->base.deadline_usec); - TEST_ASSERT_EQUAL(55, chain.tail->base.dscp); - TEST_ASSERT_EQUAL(0xBABADEDAU, chain.tail->base.destination.ip_address); - TEST_ASSERT_EQUAL(0xD0ED, chain.tail->base.destination.udp_port); - TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 4U, chain.tail->base.datagram_payload.size); - TEST_ASSERT_EQUAL(0, - memcmp(makeHeader(meta, 1, true).data, - chain.tail->base.datagram_payload.data, - HEADER_SIZE_BYTES)); + TEST_ASSERT_EQUAL(223574680, chain.tail->deadline_usec); + TEST_ASSERT_EQUAL(55, chain.tail->dscp); + TEST_ASSERT_EQUAL(0xBABADEDAU, chain.tail->destination.ip_address); + TEST_ASSERT_EQUAL(0xD0ED, chain.tail->destination.udp_port); + TEST_ASSERT_EQUAL(HEADER_SIZE_BYTES + 4U, chain.tail->datagram_payload.size); + TEST_ASSERT_EQUAL(0, memcmp(makeHeader(meta, 1, true).data, chain.tail->datagram_payload.data, HEADER_SIZE_BYTES)); TEST_ASSERT_EQUAL(0, memcmp(InterstellarWarCRC, - (byte_t*) (chain.tail->base.datagram_payload.data) + HEADER_SIZE_BYTES, + (byte_t*) (chain.tail->datagram_payload.data) + HEADER_SIZE_BYTES, 4U)); - TEST_ASSERT_EQUAL(&user_transfer_referent, chain.tail->base.user_transfer_reference); + TEST_ASSERT_EQUAL(&user_transfer_referent, chain.tail->user_transfer_reference); // Clean up. - udpardTxFree(mem, &chain.head->base); - udpardTxFree(mem, &chain.tail->base); + udpardTxFree(mem, chain.head); + udpardTxFree(mem, chain.tail); TEST_ASSERT_EQUAL(0, alloc.allocated_fragments); } @@ -667,7 +638,8 @@ static void testPushPeekPopFree(void) (UdpardPayload){.size = EtherealStrengthSize, .data = EtherealStrength}, &user_transfer_referent)); TEST_ASSERT_EQUAL(3 * 2ULL, alloc.allocated_fragments); - TEST_ASSERT_EQUAL(3 * (sizeof(TxItem) + HEADER_SIZE_BYTES) + EtherealStrengthSize + 4U, alloc.allocated_bytes); + TEST_ASSERT_EQUAL(3 * (sizeof(struct UdpardTxItem) + HEADER_SIZE_BYTES) + EtherealStrengthSize + 4U, + alloc.allocated_bytes); TEST_ASSERT_EQUAL(3, tx.queue_size); const UdpardTxItem* frame = udpardTxPeek(&tx);