@@ -5508,9 +5508,9 @@ int picoquic_queue_path_abandon_frame(picoquic_cnx_t* cnx,
5508
5508
return ret ;
5509
5509
}
5510
5510
5511
- /* Multipath PATH STANDBY and AVAILABLE frames
5511
+ /* Multipath PATH BACKUP and AVAILABLE frames
5512
5512
*/
5513
- uint8_t * picoquic_format_path_available_or_standby_frame (
5513
+ uint8_t * picoquic_format_path_available_or_backup_frame (
5514
5514
uint8_t * bytes , const uint8_t * bytes_max , uint64_t frame_type ,
5515
5515
uint64_t path_id , uint64_t sequence , int * more_data )
5516
5516
{
@@ -5525,7 +5525,7 @@ uint8_t* picoquic_format_path_available_or_standby_frame(
5525
5525
return bytes ;
5526
5526
}
5527
5527
5528
- int picoquic_queue_path_available_or_standby_frame (
5528
+ int picoquic_queue_path_available_or_backup_frame (
5529
5529
picoquic_cnx_t * cnx , picoquic_path_t * path_x , picoquic_path_status_enum status )
5530
5530
{
5531
5531
int ret = 0 ;
@@ -5544,7 +5544,7 @@ int picoquic_queue_path_available_or_standby_frame(
5544
5544
path_x -> p_remote_cnxid -> sequence ;
5545
5545
int is_pure_ack = 0 ;
5546
5546
int more_data = 0 ;
5547
- uint8_t * bytes_next = picoquic_format_path_available_or_standby_frame (
5547
+ uint8_t * bytes_next = picoquic_format_path_available_or_backup_frame (
5548
5548
frame_buffer , frame_buffer + sizeof (frame_buffer ), frame_type , path_id , sequence , & more_data );
5549
5549
size_t consumed = bytes_next - frame_buffer ;
5550
5550
ret = picoquic_queue_misc_frame (cnx , frame_buffer , consumed , is_pure_ack ,
@@ -5557,7 +5557,7 @@ int picoquic_queue_path_available_or_standby_frame(
5557
5557
return ret ;
5558
5558
}
5559
5559
5560
- const uint8_t * picoquic_skip_path_available_or_standby_frame (const uint8_t * bytes , const uint8_t * bytes_max )
5560
+ const uint8_t * picoquic_skip_path_available_or_backup_frame (const uint8_t * bytes , const uint8_t * bytes_max )
5561
5561
{
5562
5562
/* This code assumes that the frame type is already skipped */
5563
5563
if ((bytes = picoquic_frames_varint_skip (bytes , bytes_max )) != NULL ){
@@ -5566,7 +5566,7 @@ const uint8_t* picoquic_skip_path_available_or_standby_frame(const uint8_t* byte
5566
5566
return bytes ;
5567
5567
}
5568
5568
5569
- const uint8_t * picoquic_parse_path_available_or_standby_frame (const uint8_t * bytes , const uint8_t * bytes_max ,
5569
+ const uint8_t * picoquic_parse_path_available_or_backup_frame (const uint8_t * bytes , const uint8_t * bytes_max ,
5570
5570
uint64_t * path_id , uint64_t * sequence )
5571
5571
{
5572
5572
if ((bytes = picoquic_frames_varint_decode (bytes , bytes_max , path_id )) != NULL ){
@@ -5575,7 +5575,7 @@ const uint8_t* picoquic_parse_path_available_or_standby_frame(const uint8_t* byt
5575
5575
return bytes ;
5576
5576
}
5577
5577
5578
- const uint8_t * picoquic_decode_path_available_or_standby_frame (const uint8_t * bytes , const uint8_t * bytes_max ,
5578
+ const uint8_t * picoquic_decode_path_available_or_backup_frame (const uint8_t * bytes , const uint8_t * bytes_max ,
5579
5579
uint64_t frame_id64 , picoquic_cnx_t * cnx , uint64_t current_time )
5580
5580
{
5581
5581
uint64_t path_id ;
@@ -5588,7 +5588,7 @@ const uint8_t* picoquic_decode_path_available_or_standby_frame(const uint8_t* by
5588
5588
picoquic_connection_error_ex (cnx , PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR ,
5589
5589
frame_id64 , "multipath not negotiated" );
5590
5590
}
5591
- else if ((bytes = picoquic_parse_path_available_or_standby_frame (bytes , bytes_max , & path_id , & sequence )) == NULL ) {
5591
+ else if ((bytes = picoquic_parse_path_available_or_backup_frame (bytes , bytes_max , & path_id , & sequence )) == NULL ) {
5592
5592
/* Bad frame encoding */
5593
5593
picoquic_connection_error_ex (cnx , PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR ,
5594
5594
frame_id64 , "bad status frame" );
@@ -5599,18 +5599,18 @@ const uint8_t* picoquic_decode_path_available_or_standby_frame(const uint8_t* by
5599
5599
if (path_number < 0 ) {
5600
5600
/* Invalid path ID. Just ignore this frame. Add line in log for debug */
5601
5601
picoquic_log_app_message (cnx , "Ignore path %s frame with invalid ID: %" PRIu64 ,
5602
- (frame_id64 == picoquic_frame_type_path_available )?"available" :"standby " , path_id );
5602
+ (frame_id64 == picoquic_frame_type_path_available )?"available" :"backup " , path_id );
5603
5603
}
5604
5604
else {
5605
5605
if (cnx -> path [path_number ]-> status_sequence_to_receive_next > sequence ) {
5606
5606
/* Old frame, ignore. */
5607
5607
}
5608
5608
else {
5609
- /* Status will be set to 1 for standby, 2 for available.
5610
- * Default status is 0?
5609
+ /* Status will be set to 1 for backup, 0 for available.
5610
+ * Default status is 0.
5611
5611
*/
5612
5612
cnx -> path [path_number ]-> status_sequence_to_receive_next = sequence + 1 ;
5613
- cnx -> path [path_number ]-> path_is_standby = (frame_id64 == picoquic_frame_type_path_available ) ? 0 :1 ;
5613
+ cnx -> path [path_number ]-> path_is_backup = (frame_id64 == picoquic_frame_type_path_available ) ? 0 :1 ;
5614
5614
}
5615
5615
}
5616
5616
}
@@ -5626,7 +5626,7 @@ int picoquic_path_available_or_backup_frame_need_repeat(picoquic_cnx_t* cnx, con
5626
5626
5627
5627
* no_need_to_repeat = 0 ;
5628
5628
5629
- if ((bytes = picoquic_parse_path_available_or_standby_frame (bytes , bytes_max , & path_id , & sequence )) == NULL ){
5629
+ if ((bytes = picoquic_parse_path_available_or_backup_frame (bytes , bytes_max , & path_id , & sequence )) == NULL ){
5630
5630
/* Malformed frame, do not retransmit */
5631
5631
* no_need_to_repeat = 1 ;
5632
5632
}
@@ -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 */
@@ -6504,7 +6541,7 @@ int picoquic_decode_frames(picoquic_cnx_t* cnx, picoquic_path_t * path_x, const
6504
6541
break ;
6505
6542
case picoquic_frame_type_path_backup :
6506
6543
case picoquic_frame_type_path_available :
6507
- bytes = picoquic_decode_path_available_or_standby_frame (bytes , bytes_max , frame_id64 , cnx , current_time );
6544
+ bytes = picoquic_decode_path_available_or_backup_frame (bytes , bytes_max , frame_id64 , cnx , current_time );
6508
6545
ack_needed = 1 ;
6509
6546
break ;
6510
6547
case picoquic_frame_type_max_path_id :
@@ -6852,7 +6889,7 @@ int picoquic_skip_frame(const uint8_t* bytes, size_t bytes_maxsize, size_t* cons
6852
6889
break ;
6853
6890
case picoquic_frame_type_path_backup :
6854
6891
case picoquic_frame_type_path_available :
6855
- bytes = picoquic_skip_path_available_or_standby_frame (bytes , bytes_max );
6892
+ bytes = picoquic_skip_path_available_or_backup_frame (bytes , bytes_max );
6856
6893
* pure_ack = 0 ;
6857
6894
break ;
6858
6895
case picoquic_frame_type_max_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