@@ -5871,18 +5871,37 @@ int picoquic_process_ack_of_paths_blocked_frame(picoquic_cnx_t* cnx, const uint8
5871
5871
5872
5872
/* PATH CID BLOCKED frame */
5873
5873
uint8_t * picoquic_format_path_cid_blocked_frame (
5874
- uint8_t * bytes , const uint8_t * bytes_max , uint64_t path_id , int * more_data )
5874
+ uint8_t * bytes , const uint8_t * bytes_max , uint64_t path_id , uint64_t next_sequence_number , int * more_data )
5875
5875
{
5876
5876
/* This code assumes that the frame type is already skipped */
5877
5877
uint8_t * bytes0 = bytes ;
5878
5878
if ((bytes = picoquic_frames_varint_encode (bytes , bytes_max , picoquic_frame_type_path_cid_blocked )) == NULL ||
5879
- (bytes = picoquic_frames_varint_encode (bytes , bytes_max , path_id )) == NULL ) {
5879
+ (bytes = picoquic_frames_varint_encode (bytes , bytes_max , path_id )) == NULL ||
5880
+ (bytes = picoquic_frames_varint_encode (bytes , bytes_max , next_sequence_number )) == NULL ) {
5880
5881
bytes = bytes0 ;
5881
5882
* more_data = 1 ;
5882
5883
}
5883
5884
return bytes ;
5884
5885
}
5885
5886
5887
+ uint64_t picoquic_path_cid_next_sequence_number (picoquic_path_t * path_x )
5888
+ {
5889
+ picoquic_remote_cnxid_stash_t * stash = picoquic_find_or_create_remote_cnxid_stash (path_x -> cnx , path_x -> unique_path_id , 0 );
5890
+ uint64_t next_sequence_number = 0 ;
5891
+
5892
+ if (stash != NULL ) {
5893
+ picoquic_remote_cnxid_t * remote_cnxid = stash -> cnxid_stash_first ;
5894
+
5895
+ while (remote_cnxid != NULL ) {
5896
+ if (remote_cnxid -> sequence >= next_sequence_number ) {
5897
+ next_sequence_number = remote_cnxid -> sequence + 1 ;
5898
+ }
5899
+ remote_cnxid = remote_cnxid -> next ;
5900
+ }
5901
+ }
5902
+ return next_sequence_number ;
5903
+ }
5904
+
5886
5905
int picoquic_queue_path_cid_blocked_frame (
5887
5906
picoquic_path_t * path_x )
5888
5907
{
@@ -5891,8 +5910,10 @@ int picoquic_queue_path_cid_blocked_frame(
5891
5910
uint8_t frame_buffer [256 ];
5892
5911
int is_pure_ack = 0 ;
5893
5912
int more_data = 0 ;
5913
+ uint64_t next_sequence_number = picoquic_path_cid_next_sequence_number (path_x );
5894
5914
uint8_t * bytes_next = picoquic_format_path_cid_blocked_frame (
5895
- frame_buffer , frame_buffer + sizeof (frame_buffer ), path_x -> unique_path_id , & more_data );
5915
+ frame_buffer , frame_buffer + sizeof (frame_buffer ), path_x -> unique_path_id ,
5916
+ next_sequence_number , & more_data );
5896
5917
size_t consumed = bytes_next - frame_buffer ;
5897
5918
ret = picoquic_queue_misc_frame (path_x -> cnx , frame_buffer , consumed , is_pure_ack ,
5898
5919
picoquic_packet_context_application );
@@ -5905,21 +5926,26 @@ int picoquic_queue_path_cid_blocked_frame(
5905
5926
const uint8_t * picoquic_skip_path_cid_blocked_frame (const uint8_t * bytes , const uint8_t * bytes_max )
5906
5927
{
5907
5928
/* This code assumes that the frame type is already skipped */
5908
- bytes = picoquic_frames_varint_skip (bytes , bytes_max );
5929
+ if ((bytes = picoquic_frames_varint_skip (bytes , bytes_max )) != NULL ) {
5930
+ bytes = picoquic_frames_varint_skip (bytes , bytes_max );
5931
+ }
5909
5932
return bytes ;
5910
5933
}
5911
5934
5912
5935
const uint8_t * picoquic_parse_path_cid_blocked_frame (const uint8_t * bytes , const uint8_t * bytes_max ,
5913
- uint64_t * max_path_id )
5936
+ uint64_t * unique_path_id , uint64_t * next_sequence_number )
5914
5937
{
5915
- bytes = picoquic_frames_varint_decode (bytes , bytes_max , max_path_id );
5938
+ if ((bytes = picoquic_frames_varint_decode (bytes , bytes_max , unique_path_id )) != NULL ) {
5939
+ bytes = picoquic_frames_varint_decode (bytes , bytes_max , next_sequence_number );
5940
+ }
5916
5941
return bytes ;
5917
5942
}
5918
5943
5919
5944
const uint8_t * picoquic_decode_path_cid_blocked_frame (const uint8_t * bytes , const uint8_t * bytes_max ,
5920
5945
picoquic_cnx_t * cnx )
5921
5946
{
5922
- uint64_t path_id ;
5947
+ uint64_t unique_path_id = 0 ;
5948
+ uint64_t next_sequence_number = 0 ;
5923
5949
5924
5950
/* This code assumes that the frame type is already skipped */
5925
5951
@@ -5928,7 +5954,7 @@ const uint8_t* picoquic_decode_path_cid_blocked_frame(const uint8_t* bytes, cons
5928
5954
picoquic_connection_error_ex (cnx , PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR ,
5929
5955
picoquic_frame_type_path_cid_blocked , "multipath extension not negotiated" );
5930
5956
}
5931
- else if ((bytes = picoquic_parse_path_cid_blocked_frame (bytes , bytes_max , & path_id )) == NULL ) {
5957
+ else if ((bytes = picoquic_parse_path_cid_blocked_frame (bytes , bytes_max , & unique_path_id , & next_sequence_number )) == NULL ) {
5932
5958
/* Bad frame encoding */
5933
5959
picoquic_connection_error_ex (cnx , PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR ,
5934
5960
picoquic_frame_type_path_cid_blocked , "bad path blocked frame" );
@@ -5941,10 +5967,11 @@ int picoquic_path_cid_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint
5941
5967
{
5942
5968
int ret = 0 ;
5943
5969
uint64_t unique_path_id = 0 ;
5970
+ uint64_t next_sequence_number = 0 ;
5944
5971
5945
5972
* no_need_to_repeat = 0 ;
5946
5973
5947
- if ((bytes = picoquic_parse_path_cid_blocked_frame (bytes , bytes_max , & unique_path_id )) == NULL ) {
5974
+ if ((bytes = picoquic_parse_path_cid_blocked_frame (bytes , bytes_max , & unique_path_id , & next_sequence_number )) == NULL ) {
5948
5975
/* Malformed frame, do not retransmit */
5949
5976
* no_need_to_repeat = 1 ;
5950
5977
}
@@ -5960,6 +5987,15 @@ int picoquic_path_cid_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint
5960
5987
/* the blocked frame was already acknowledged */
5961
5988
* no_need_to_repeat = 1 ;
5962
5989
}
5990
+ else {
5991
+ uint64_t current_next_number = picoquic_path_cid_next_sequence_number (cnx -> path [path_index ]);
5992
+
5993
+ if (current_next_number > next_sequence_number )
5994
+ {
5995
+ /* New CID is now available */
5996
+ * no_need_to_repeat = 1 ;
5997
+ }
5998
+ }
5963
5999
}
5964
6000
return ret ;
5965
6001
}
@@ -5969,8 +6005,9 @@ int picoquic_process_ack_of_path_cid_blocked_frame(picoquic_cnx_t* cnx, const ui
5969
6005
{
5970
6006
int ret = 0 ;
5971
6007
uint64_t unique_path_id = 0 ;
6008
+ uint64_t next_sequence_number = 0 ;
5972
6009
5973
- const uint8_t * bytes_next = picoquic_parse_path_cid_blocked_frame (bytes , bytes + bytes_max , & unique_path_id );
6010
+ const uint8_t * bytes_next = picoquic_parse_path_cid_blocked_frame (bytes , bytes + bytes_max , & unique_path_id , & next_sequence_number );
5974
6011
5975
6012
if (bytes_next != NULL ) {
5976
6013
/* Find the path context for the path ID */
@@ -6864,7 +6901,7 @@ int picoquic_skip_frame(const uint8_t* bytes, size_t bytes_maxsize, size_t* cons
6864
6901
* pure_ack = 0 ;
6865
6902
break ;
6866
6903
case picoquic_frame_type_path_cid_blocked :
6867
- bytes = picoquic_skip_paths_blocked_frame (bytes , bytes_max );
6904
+ bytes = picoquic_skip_path_cid_blocked_frame (bytes , bytes_max );
6868
6905
* pure_ack = 0 ;
6869
6906
break ;
6870
6907
case picoquic_frame_type_bdp :
0 commit comments