@@ -1201,36 +1201,59 @@ fd_quic_conn_set_rx_max_data( fd_quic_conn_t * conn, ulong rx_max_data ) {
12011201/* packet processing */
12021202
12031203/* fd_quic_conn_free_pkt_meta frees all pkt_meta associated with
1204- encryption levels less or equal to enc_level. Returns the number
1205- of freed pkt_meta. */
1204+ enc_level. Returns the number of freed pkt_meta. */
12061205static ulong
12071206fd_quic_conn_free_pkt_meta ( fd_quic_conn_t * conn ,
12081207 uint enc_level ) {
1209- ulong freed = 0UL ;
12101208 fd_quic_pkt_meta_tracker_t * tracker = & conn -> pkt_meta_tracker ;
12111209 fd_quic_pkt_meta_t * pool = tracker -> pool ;
1210+ fd_quic_pkt_meta_ds_t * sent = & tracker -> sent_pkt_metas [enc_level ];
12121211
1213- for ( uint j = 0 ; j <=enc_level ; ++ j ) {
1214- fd_quic_pkt_meta_ds_t * sent = & tracker -> sent_pkt_metas [j ];
1215- fd_quic_pkt_meta_t * prev = NULL ;
1216- for ( fd_quic_pkt_meta_ds_fwd_iter_t iter = fd_quic_pkt_meta_ds_fwd_iter_init ( sent , pool );
1217- !fd_quic_pkt_meta_ds_fwd_iter_done ( iter );
1218- iter = fd_quic_pkt_meta_ds_fwd_iter_next ( iter , pool ) ) {
1219- fd_quic_pkt_meta_t * e = fd_quic_pkt_meta_ds_fwd_iter_ele ( iter , pool );
1220- if ( FD_LIKELY ( prev ) ) {
1221- fd_quic_pkt_meta_pool_ele_release ( pool , prev );
1222- }
1223- prev = e ;
1224- }
1212+ fd_quic_pkt_meta_t * prev = NULL ;
1213+ for ( fd_quic_pkt_meta_ds_fwd_iter_t iter = fd_quic_pkt_meta_ds_fwd_iter_init ( sent , pool );
1214+ !fd_quic_pkt_meta_ds_fwd_iter_done ( iter );
1215+ iter = fd_quic_pkt_meta_ds_fwd_iter_next ( iter , pool ) ) {
1216+ fd_quic_pkt_meta_t * e = fd_quic_pkt_meta_ds_fwd_iter_ele ( iter , pool );
12251217 if ( FD_LIKELY ( prev ) ) {
12261218 fd_quic_pkt_meta_pool_ele_release ( pool , prev );
12271219 }
1220+ prev = e ;
1221+ }
1222+ if ( FD_LIKELY ( prev ) ) {
1223+ fd_quic_pkt_meta_pool_ele_release ( pool , prev );
1224+ }
1225+
12281226
1229- conn -> used_pkt_meta -= fd_quic_pkt_meta_ds_ele_cnt ( sent );
1230- freed += fd_quic_pkt_meta_ds_ele_cnt ( sent );
1231- fd_quic_pkt_meta_ds_clear ( tracker , j );
1227+ /* Instead of paying log(n) to maintain the treap structure during ele_remove
1228+ on each iteration, we've returned all pkt_meta to the pool, but left them
1229+ in the treap. Then, we reinitialize the treap, in constant time deleting
1230+ all elements that were in the 'old treap'. This function now runs in linear
1231+ time, instead of O(n*lg(n)). */
1232+
1233+ ulong pre_ele_cnt = fd_quic_pkt_meta_ds_ele_cnt ( sent );
1234+
1235+ fd_quic_pkt_meta_ds_clear ( tracker , enc_level );
1236+ conn -> used_pkt_meta -= pre_ele_cnt ;
1237+
1238+ return pre_ele_cnt ;
1239+ }
1240+
1241+ /* reclaim and free all pkt_meta for a given encryption level,
1242+ and return the number affected. */
1243+ static ulong
1244+ fd_quic_reclaim_pkt_meta_level ( fd_quic_conn_t * conn , uint enc_level ) {
1245+ fd_quic_pkt_meta_tracker_t * tracker = & conn -> pkt_meta_tracker ;
1246+ fd_quic_pkt_meta_t * pool = tracker -> pool ;
1247+ fd_quic_pkt_meta_ds_t * sent = & tracker -> sent_pkt_metas [enc_level ];
1248+
1249+ for ( fd_quic_pkt_meta_ds_fwd_iter_t iter = fd_quic_pkt_meta_ds_fwd_iter_init ( sent , pool );
1250+ !fd_quic_pkt_meta_ds_fwd_iter_done ( iter );
1251+ iter = fd_quic_pkt_meta_ds_fwd_iter_next ( iter , pool ) ) {
1252+ fd_quic_pkt_meta_t * e = fd_quic_pkt_meta_ds_fwd_iter_ele ( iter , pool );
1253+ fd_quic_reclaim_pkt_meta ( conn , e , enc_level );
12321254 }
1233- return freed ;
1255+
1256+ return fd_quic_conn_free_pkt_meta ( conn , enc_level );
12341257}
12351258
12361259
@@ -1246,23 +1269,14 @@ fd_quic_abandon_enc_level( fd_quic_conn_t * conn,
12461269
12471270 fd_quic_ack_gen_abandon_enc_level ( conn -> ack_gen , enc_level );
12481271
1249- fd_quic_pkt_meta_tracker_t * tracker = & conn -> pkt_meta_tracker ;
1250- fd_quic_pkt_meta_t * pool = tracker -> pool ;
1251-
1272+ ulong freed = 0UL ;
12521273 for ( uint j = 0 ; j <= enc_level ; ++ j ) {
12531274 conn -> keys_avail = fd_uint_clear_bit ( conn -> keys_avail , (int )j );
12541275 /* treat all packets as ACKed (freeing handshake data, etc.) */
1255- fd_quic_pkt_meta_ds_t * sent = & tracker -> sent_pkt_metas [j ];
1256-
1257- for ( fd_quic_pkt_meta_ds_fwd_iter_t iter = fd_quic_pkt_meta_ds_fwd_iter_init ( sent , pool );
1258- !fd_quic_pkt_meta_ds_fwd_iter_done ( iter );
1259- iter = fd_quic_pkt_meta_ds_fwd_iter_next ( iter , pool ) ) {
1260- fd_quic_pkt_meta_t * e = fd_quic_pkt_meta_ds_fwd_iter_ele ( iter , pool );
1261- fd_quic_reclaim_pkt_meta ( conn , e , j );
1262- }
1276+ freed += fd_quic_reclaim_pkt_meta_level ( conn , j );
12631277 }
12641278
1265- return fd_quic_conn_free_pkt_meta ( conn , enc_level ) ;
1279+ return freed ;
12661280}
12671281
12681282static void
@@ -3968,7 +3982,7 @@ fd_quic_conn_free( fd_quic_t * quic,
39683982 enqueued once */
39693983
39703984 /* free pkt_meta */
3971- fd_quic_conn_free_pkt_meta ( conn , fd_quic_enc_level_appdata_id );
3985+ for ( uint j = 0 ; j <= fd_quic_enc_level_appdata_id ; ++ j ) fd_quic_conn_free_pkt_meta ( conn , j );
39723986
39733987 /* remove all stream ids from map, and free stream */
39743988
@@ -4427,7 +4441,7 @@ fd_quic_pkt_meta_retry( fd_quic_t * quic,
44274441
44284442 /* already moved to another enc_level */
44294443 if ( enc_level < peer_enc_level ) {
4430- cnt_freed += fd_quic_abandon_enc_level ( conn , peer_enc_level );
4444+ cnt_freed += fd_quic_reclaim_pkt_meta_level ( conn , enc_level );
44314445 continue ;
44324446 }
44334447
@@ -4529,10 +4543,9 @@ fd_quic_pkt_meta_retry( fd_quic_t * quic,
45294543 fd_quic_svc_prep_schedule_now ( conn );
45304544
45314545 /* free pkt_meta */
4532- fd_quic_pkt_meta_remove_range ( & tracker -> sent_pkt_metas [enc_level ],
4533- pool ,
4534- pkt_meta -> key .pkt_num ,
4535- pkt_meta -> key .pkt_num );
4546+ fd_quic_pkt_meta_remove ( & tracker -> sent_pkt_metas [enc_level ],
4547+ pool ,
4548+ pkt_meta );
45364549
45374550 conn -> used_pkt_meta -= 1 ;
45384551 cnt_freed ++ ;
@@ -4776,6 +4789,7 @@ fd_quic_reclaim_pkt_meta( fd_quic_conn_t * conn,
47764789 break ;
47774790 }
47784791}
4792+
47794793/* process lost packets
47804794 * These packets will be declared lost and relevant data potentially resent */
47814795void
0 commit comments