@@ -2530,45 +2530,72 @@ static int decrypt_packet(ptls_cipher_context_t *header_protection,
25302530 return 0 ;
25312531}
25322532
2533- static int on_ack_ack (quicly_sentmap_t * map , const quicly_sent_packet_t * packet , int acked , quicly_sent_t * sent )
2533+ static int do_on_ack_ack (quicly_conn_t * conn , const quicly_sent_packet_t * packet , uint64_t start , uint64_t start_length ,
2534+ struct st_quicly_sent_ack_additional_t * additional , size_t additional_capacity )
25342535{
2535- quicly_conn_t * conn = (quicly_conn_t * )((char * )map - offsetof(quicly_conn_t , egress .loss .sentmap ));
2536-
2537- /* TODO log */
2536+ /* find the pn space */
2537+ struct st_quicly_pn_space_t * space ;
2538+ switch (packet -> ack_epoch ) {
2539+ case QUICLY_EPOCH_INITIAL :
2540+ space = & conn -> initial -> super ;
2541+ break ;
2542+ case QUICLY_EPOCH_HANDSHAKE :
2543+ space = & conn -> handshake -> super ;
2544+ break ;
2545+ case QUICLY_EPOCH_1RTT :
2546+ space = & conn -> application -> super ;
2547+ break ;
2548+ default :
2549+ assert (!"FIXME" );
2550+ return QUICLY_TRANSPORT_ERROR_INTERNAL ;
2551+ }
25382552
2539- if (acked ) {
2540- /* find the pn space */
2541- struct st_quicly_pn_space_t * space ;
2542- switch (packet -> ack_epoch ) {
2543- case QUICLY_EPOCH_INITIAL :
2544- space = & conn -> initial -> super ;
2545- break ;
2546- case QUICLY_EPOCH_HANDSHAKE :
2547- space = & conn -> handshake -> super ;
2548- break ;
2549- case QUICLY_EPOCH_1RTT :
2550- space = & conn -> application -> super ;
2551- break ;
2552- default :
2553- assert (!"FIXME" );
2554- return QUICLY_TRANSPORT_ERROR_INTERNAL ;
2555- }
2556- /* subtract given ACK range, then make adjustments */
2557- int ret ;
2558- if ((ret = quicly_ranges_subtract (& space -> ack_queue , sent -> data .ack .range .start , sent -> data .ack .range .end )) != 0 )
2553+ /* subtract given ACK ranges */
2554+ int ret ;
2555+ uint64_t end = start + start_length ;
2556+ if ((ret = quicly_ranges_subtract (& space -> ack_queue , start , end )) != 0 )
2557+ return ret ;
2558+ for (size_t i = 0 ; i < additional_capacity && additional [i ].gap != 0 ; ++ i ) {
2559+ start = end + additional [i ].gap ;
2560+ end = start + additional [i ].length ;
2561+ if ((ret = quicly_ranges_subtract (& space -> ack_queue , start , end )) != 0 )
25592562 return ret ;
2560- if (space -> ack_queue .num_ranges == 0 ) {
2561- space -> largest_pn_received_at = INT64_MAX ;
2562- space -> unacked_count = 0 ;
2563- } else if (space -> ack_queue .num_ranges > QUICLY_MAX_ACK_BLOCKS ) {
2564- quicly_ranges_drop_by_range_indices (& space -> ack_queue , space -> ack_queue .num_ranges - QUICLY_MAX_ACK_BLOCKS ,
2565- space -> ack_queue .num_ranges );
2566- }
2563+ }
2564+
2565+ /* make adjustments */
2566+ if (space -> ack_queue .num_ranges == 0 ) {
2567+ space -> largest_pn_received_at = INT64_MAX ;
2568+ space -> unacked_count = 0 ;
2569+ } else if (space -> ack_queue .num_ranges > QUICLY_MAX_ACK_BLOCKS ) {
2570+ quicly_ranges_drop_by_range_indices (& space -> ack_queue , space -> ack_queue .num_ranges - QUICLY_MAX_ACK_BLOCKS ,
2571+ space -> ack_queue .num_ranges );
25672572 }
25682573
25692574 return 0 ;
25702575}
25712576
2577+ static int on_ack_ack_ranges64 (quicly_sentmap_t * map , const quicly_sent_packet_t * packet , int acked , quicly_sent_t * sent )
2578+ {
2579+ quicly_conn_t * conn = (quicly_conn_t * )((char * )map - offsetof(quicly_conn_t , egress .loss .sentmap ));
2580+
2581+ /* TODO log */
2582+
2583+ return acked ? do_on_ack_ack (conn , packet , sent -> data .ack .start , sent -> data .ack .ranges64 .start_length ,
2584+ sent -> data .ack .ranges64 .additional , PTLS_ELEMENTSOF (sent -> data .ack .ranges64 .additional ))
2585+ : 0 ;
2586+ }
2587+
2588+ static int on_ack_ack_ranges8 (quicly_sentmap_t * map , const quicly_sent_packet_t * packet , int acked , quicly_sent_t * sent )
2589+ {
2590+ quicly_conn_t * conn = (quicly_conn_t * )((char * )map - offsetof(quicly_conn_t , egress .loss .sentmap ));
2591+
2592+ /* TODO log */
2593+
2594+ return acked ? do_on_ack_ack (conn , packet , sent -> data .ack .start , sent -> data .ack .ranges8 .start_length ,
2595+ sent -> data .ack .ranges8 .additional , PTLS_ELEMENTSOF (sent -> data .ack .ranges8 .additional ))
2596+ : 0 ;
2597+ }
2598+
25722599static int on_ack_stream_ack_one (quicly_conn_t * conn , quicly_stream_id_t stream_id , quicly_sendstate_sent_t * sent )
25732600{
25742601 quicly_stream_t * stream ;
@@ -3313,12 +3340,39 @@ static int send_ack(quicly_conn_t *conn, struct st_quicly_pn_space_t *space, qui
33133340 s -> dst = dst ;
33143341
33153342 { /* save what's inflight */
3316- size_t i ;
3317- for ( i = 0 ; i != space -> ack_queue .num_ranges ; ++ i ) {
3343+ size_t range_index = 0 ;
3344+ while ( range_index < space -> ack_queue .num_ranges ) {
33183345 quicly_sent_t * sent ;
3319- if ((sent = quicly_sentmap_allocate (& conn -> egress .loss .sentmap , on_ack_ack )) == NULL )
3346+ struct st_quicly_sent_ack_additional_t * additional , * additional_end ;
3347+ /* allocate */
3348+ if ((sent = quicly_sentmap_allocate (& conn -> egress .loss .sentmap , on_ack_ack_ranges8 )) == NULL )
33203349 return PTLS_ERROR_NO_MEMORY ;
3321- sent -> data .ack .range = space -> ack_queue .ranges [i ];
3350+ /* store the first range, as well as preparing references to the additional slots */
3351+ sent -> data .ack .start = space -> ack_queue .ranges [range_index ].start ;
3352+ uint64_t length = space -> ack_queue .ranges [range_index ].end - space -> ack_queue .ranges [range_index ].start ;
3353+ if (length <= UINT8_MAX ) {
3354+ sent -> data .ack .ranges8 .start_length = length ;
3355+ additional = sent -> data .ack .ranges8 .additional ;
3356+ additional_end = additional + PTLS_ELEMENTSOF (sent -> data .ack .ranges8 .additional );
3357+ } else {
3358+ sent -> acked = on_ack_ack_ranges64 ;
3359+ sent -> data .ack .ranges64 .start_length = length ;
3360+ additional = sent -> data .ack .ranges64 .additional ;
3361+ additional_end = additional + PTLS_ELEMENTSOF (sent -> data .ack .ranges64 .additional );
3362+ }
3363+ /* store additional ranges, if possible */
3364+ for (++ range_index ; range_index < space -> ack_queue .num_ranges && additional < additional_end ;
3365+ ++ range_index , ++ additional ) {
3366+ uint64_t gap = space -> ack_queue .ranges [range_index ].start - space -> ack_queue .ranges [range_index - 1 ].end ;
3367+ uint64_t length = space -> ack_queue .ranges [range_index ].end - space -> ack_queue .ranges [range_index ].start ;
3368+ if (gap > UINT8_MAX || length > UINT8_MAX )
3369+ break ;
3370+ additional -> gap = gap ;
3371+ additional -> length = length ;
3372+ }
3373+ /* additional list is zero-terminated, if not full */
3374+ if (additional < additional_end )
3375+ additional -> gap = 0 ;
33223376 }
33233377 }
33243378
0 commit comments