@@ -287,7 +287,8 @@ static byte_t* header_serialize(byte_t* const buffer,
287287 const meta_t meta ,
288288 const bool flag_eot ,
289289 const uint32_t frame_index ,
290- const uint32_t frame_payload_offset )
290+ const uint32_t frame_payload_offset ,
291+ const uint32_t prefix_crc )
291292{
292293 byte_t * ptr = buffer ;
293294 byte_t flags = 0 ;
@@ -307,7 +308,7 @@ static byte_t* header_serialize(byte_t* const buffer,
307308 ptr = serialize_u64 (ptr , meta .transfer_id );
308309 ptr = serialize_u64 (ptr , meta .sender_uid );
309310 ptr = serialize_u64 (ptr , meta .topic_hash );
310- ptr = serialize_u32 (ptr , 0 );
311+ ptr = serialize_u32 (ptr , prefix_crc );
311312 ptr = serialize_u32 (ptr , crc_full (HEADER_SIZE_BYTES - CRC_SIZE_BYTES , buffer ));
312313 UDPARD_ASSERT ((size_t )(ptr - buffer ) == HEADER_SIZE_BYTES );
313314 return ptr ;
@@ -318,6 +319,7 @@ static bool header_deserialize(const udpard_bytes_mut_t dgram_payload,
318319 bool * const flag_eot ,
319320 uint32_t * const frame_index ,
320321 uint32_t * const frame_payload_offset ,
322+ uint32_t * const prefix_crc ,
321323 udpard_bytes_mut_t * const out_payload )
322324{
323325 UDPARD_ASSERT (out_payload != NULL );
@@ -339,6 +341,7 @@ static bool header_deserialize(const udpard_bytes_mut_t dgram_payload,
339341 ptr = deserialize_u64 (ptr , & out_meta -> transfer_id );
340342 ptr = deserialize_u64 (ptr , & out_meta -> sender_uid );
341343 ptr = deserialize_u64 (ptr , & out_meta -> topic_hash );
344+ ptr = deserialize_u32 (ptr , prefix_crc );
342345 (void )ptr ;
343346 // Set up the output payload view.
344347 out_payload -> size = dgram_payload .size - HEADER_SIZE_BYTES ;
@@ -467,17 +470,16 @@ static tx_chain_t tx_spool(const udpard_tx_mem_resources_t memory,
467470{
468471 UDPARD_ASSERT (mtu > 0 );
469472 UDPARD_ASSERT ((payload .data != NULL ) || (payload .size == 0U ));
470- const size_t payload_size_with_crc = payload .size + CRC_SIZE_BYTES ;
471- byte_t crc_bytes [CRC_SIZE_BYTES ];
472- serialize_u32 (crc_bytes , crc_full (payload .size , payload .data ));
473- tx_chain_t out = { NULL , NULL , 0 };
474- size_t offset = 0U ;
475- while (offset < payload_size_with_crc ) {
476- udpard_tx_item_t * const item = tx_item_new (memory ,
473+ uint32_t prefix_crc = CRC_INITIAL ;
474+ tx_chain_t out = { NULL , NULL , 0 };
475+ size_t offset = 0U ;
476+ while (offset < payload .size ) {
477+ const size_t progress = smaller (payload .size - offset , mtu );
478+ udpard_tx_item_t * const item = tx_item_new (memory , //
477479 deadline ,
478480 meta .priority ,
479481 endpoint ,
480- smaller ( payload_size_with_crc - offset , mtu ) + HEADER_SIZE_BYTES ,
482+ progress + HEADER_SIZE_BYTES ,
481483 user_transfer_reference );
482484 if (NULL == out .head ) {
483485 out .head = item ;
@@ -488,31 +490,22 @@ static tx_chain_t tx_spool(const udpard_tx_mem_resources_t memory,
488490 if (NULL == out .tail ) {
489491 break ;
490492 }
491- const bool last = (payload_size_with_crc - offset ) <= mtu ;
492- byte_t * const dst_buffer = item -> datagram_payload .data ;
493- byte_t * write_ptr = header_serialize (dst_buffer , meta , last , (uint32_t )out .count , (uint32_t )offset );
494- if (offset < payload .size ) {
495- const size_t progress = smaller (payload .size - offset , mtu );
496- // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
497- (void )memcpy (write_ptr , ((const byte_t * )payload .data ) + offset , progress );
498- offset += progress ;
499- write_ptr += progress ;
500- UDPARD_ASSERT (offset <= payload .size );
501- UDPARD_ASSERT ((!last ) || (offset == payload .size ));
502- }
503- if (offset >= payload .size ) {
504- const size_t crc_offset = offset - payload .size ;
505- UDPARD_ASSERT (crc_offset < CRC_SIZE_BYTES );
506- const size_t available = item -> datagram_payload .size - (size_t )(write_ptr - dst_buffer );
507- UDPARD_ASSERT (available <= CRC_SIZE_BYTES );
508- const size_t write_size = smaller (CRC_SIZE_BYTES - crc_offset , available );
509- // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
510- (void )memcpy (write_ptr , & crc_bytes [crc_offset ], write_size );
511- offset += write_size ;
512- }
493+ const bool last = (payload .size - offset ) <= mtu ;
494+ const byte_t * const read_ptr = ((const byte_t * )payload .data ) + offset ;
495+ prefix_crc = crc_add (prefix_crc , progress , read_ptr );
496+ byte_t * const write_ptr = header_serialize (item -> datagram_payload .data , //
497+ meta ,
498+ last ,
499+ (uint32_t )out .count ,
500+ (uint32_t )offset ,
501+ prefix_crc ^ CRC_OUTPUT_XOR );
502+ (void )memcpy (write_ptr , read_ptr , progress ); // NOLINT(*DeprecatedOrUnsafeBufferHandling)
503+ offset += progress ;
504+ UDPARD_ASSERT (offset <= payload .size );
505+ UDPARD_ASSERT ((!last ) || (offset == payload .size ));
513506 out .count ++ ;
514507 }
515- UDPARD_ASSERT ((offset == payload_size_with_crc ) || (out .tail == NULL ));
508+ UDPARD_ASSERT ((offset == payload . size ) || (out .tail == NULL ));
516509 return out ;
517510}
518511
@@ -526,7 +519,7 @@ static uint32_t tx_push(udpard_tx_t* const tx,
526519 UDPARD_ASSERT (tx != NULL );
527520 uint32_t out = 0 ; // The number of frames enqueued; zero on error (error counters incremented).
528521 const size_t mtu = larger (tx -> mtu , UDPARD_MTU_MIN );
529- const size_t frame_count = (( payload .size + CRC_SIZE_BYTES + mtu ) - 1U ) / mtu ;
522+ const size_t frame_count = (payload .size + mtu - 1U ) / mtu ;
530523 if ((tx -> queue_size + frame_count ) > tx -> queue_capacity ) {
531524 tx -> errors_capacity ++ ;
532525 } else {
@@ -724,7 +717,7 @@ typedef struct
724717/// given a linked list of these objects represented as a list of udpard_fragment_t.
725718typedef struct rx_fragment_t
726719{
727- udpard_fragment_t base ;
720+ udpard_fragment_t base ; ///< Must be the first member; do not move!
728721 udpard_tree_t tree ;
729722} rx_fragment_t ;
730723
@@ -735,7 +728,7 @@ typedef struct
735728 bool eot_discovered ;
736729 uint32_t accepted_frames ; ///< Number of frames accepted so far.
737730 size_t payload_size_stored ; ///< Grows with each accepted fragment (out of order).
738- uint32_t crc ; ///< Out-of-order CRC reconstruction state.
731+ uint32_t crc ; ///< CRC reconstruction state.
739732 udpard_tree_t * fragments ;
740733} rx_slot_iface_t ;
741734
0 commit comments