@@ -4054,10 +4054,14 @@ picoquic_tuple_t* picoquic_check_path_control_needed(picoquic_cnx_t* cnx, picoqu
4054
4054
/* Find available paths:
4055
4055
* Check that there is at least one available path. If not, promote one of the candidates.
4056
4056
*/
4057
- int picoquic_verify_path_available (picoquic_cnx_t * cnx , picoquic_path_t * * next_path , uint64_t current_time )
4057
+ int picoquic_verify_path_available (picoquic_cnx_t * cnx , picoquic_path_t * * next_path , uint64_t * min_retransmit , uint64_t current_time )
4058
4058
{
4059
4059
int backup_index = -1 ;
4060
4060
int nb_available = 0 ;
4061
+ uint64_t best_available_retransmit = UINT64_MAX ;
4062
+ uint64_t best_backup_retransmit = UINT64_MAX ;
4063
+
4064
+ * min_retransmit = 0 ;
4061
4065
4062
4066
for (int path_index = 0 ; path_index < cnx -> nb_paths ; path_index ++ ) {
4063
4067
picoquic_path_t * path_x = cnx -> path [path_index ];
@@ -4068,24 +4072,33 @@ int picoquic_verify_path_available(picoquic_cnx_t * cnx, picoquic_path_t** next_
4068
4072
cnx -> congestion_alg -> alg_init (cnx , path_x , cnx -> congestion_alg_option_string , current_time );
4069
4073
}
4070
4074
/* track the available paths */
4071
- /* TODO: handle number of retransmissions? */
4072
4075
if (path_x -> path_is_backup ) {
4073
- if (backup_index < 0 ) {
4076
+ if (backup_index < 0 || path_x -> nb_retransmit < best_backup_retransmit ) {
4077
+ best_backup_retransmit = path_x -> nb_retransmit ;
4074
4078
backup_index = path_index ;
4075
4079
}
4076
4080
}
4077
4081
else
4078
4082
{
4079
- * next_path = path_x ;
4083
+ if (path_x -> nb_retransmit < best_available_retransmit ) {
4084
+ best_available_retransmit = path_x -> nb_retransmit ;
4085
+ * next_path = path_x ;
4086
+ nb_available = 0 ;
4087
+ }
4080
4088
nb_available ++ ;
4081
4089
}
4082
4090
}
4083
4091
}
4084
- if (nb_available == 0 && backup_index >= 0 ) {
4092
+ if (best_available_retransmit > 0 && best_backup_retransmit < best_available_retransmit ) {
4085
4093
cnx -> path [backup_index ]-> path_is_backup = 0 ;
4086
4094
* next_path = cnx -> path [backup_index ];
4087
- nb_available += 1 ;
4088
- /* TODO: some logging. Queue PATH_AVAILABLE frame. */
4095
+ nb_available = 1 ;
4096
+ * min_retransmit = best_backup_retransmit ;
4097
+ /* TODO: some logging. Queue PATH_AVAILABLE frame? */
4098
+ }
4099
+ else
4100
+ {
4101
+ * min_retransmit = best_available_retransmit ;
4089
4102
}
4090
4103
return nb_available ;
4091
4104
}
@@ -4095,7 +4108,7 @@ int picoquic_verify_path_available(picoquic_cnx_t * cnx, picoquic_path_t** next_
4095
4108
*/
4096
4109
4097
4110
void picoquic_sort_available_paths (picoquic_cnx_t * cnx , uint64_t current_time , uint64_t * next_wake_time ,
4098
- picoquic_path_t * * next_path , picoquic_tuple_t * * next_tuple )
4111
+ picoquic_path_t * * next_path , uint64_t min_retransmit , picoquic_tuple_t * * next_tuple )
4099
4112
{
4100
4113
int data_path_cwin = -1 ;
4101
4114
int data_path_pacing = -1 ;
@@ -4115,7 +4128,7 @@ void picoquic_sort_available_paths(picoquic_cnx_t * cnx, uint64_t current_time,
4115
4128
/* Clear the nominal ack path flag from all path -- it will be reset to the low RTT path later */
4116
4129
path_x -> is_nominal_ack_path = 0 ;
4117
4130
/* Only continue processing if the path is available */
4118
- if (path_x -> path_is_backup || !path_x -> first_tuple -> challenge_verified || path_x -> path_is_demoted ) {
4131
+ if (path_x -> path_is_backup || !path_x -> first_tuple -> challenge_verified || path_x -> path_is_demoted || path_x -> nb_retransmit > min_retransmit ) {
4119
4132
continue ;
4120
4133
}
4121
4134
/* This path is a candidate for min rtt */
@@ -4221,6 +4234,7 @@ void picoquic_select_next_path_tuple(picoquic_cnx_t* cnx, uint64_t current_time,
4221
4234
picoquic_path_t * * next_path , picoquic_tuple_t * * next_tuple )
4222
4235
{
4223
4236
int nb_available = 0 ;
4237
+ uint64_t min_retransmit = 0 ;
4224
4238
4225
4239
* next_path = NULL ;
4226
4240
* next_tuple = NULL ;
@@ -4236,24 +4250,24 @@ void picoquic_select_next_path_tuple(picoquic_cnx_t* cnx, uint64_t current_time,
4236
4250
(* next_path )-> challenger ++ ;
4237
4251
break ;
4238
4252
}
4239
- else if (cnx -> path [path_index ]-> first_tuple -> challenge_verified && cnx -> path [path_index ]-> nb_retransmit > 0 &&
4253
+ else if (cnx -> nb_paths > 0 && cnx -> path [path_index ]-> first_tuple -> challenge_verified && cnx -> path [path_index ]-> nb_retransmit > 0 &&
4240
4254
cnx -> cnx_state == picoquic_state_ready && cnx -> path [path_index ]-> bytes_in_transit == 0 ) {
4241
4255
cnx -> path [path_index ]-> is_multipath_probe_needed = 1 ;
4242
4256
* next_path = cnx -> path [path_index ];
4257
+ * next_tuple = (* next_path )-> first_tuple ;
4243
4258
(* next_path )-> challenger ++ ;
4244
4259
break ;
4245
4260
}
4246
4261
}
4247
4262
if (* next_path != NULL ) {
4248
- * next_tuple = (* next_path )-> first_tuple ;
4249
4263
/* we are done */
4250
4264
}
4251
4265
else if (cnx -> nb_paths == 1 ) {
4252
4266
/* No choice, just use this path -- this is the default if multipath is not selected. */
4253
4267
* next_path = cnx -> path [0 ];
4254
4268
* next_tuple = (* next_path )-> first_tuple ;
4255
4269
}
4256
- else if ((nb_available = picoquic_verify_path_available (cnx , next_path , current_time )) < 2 ) {
4270
+ else if ((nb_available = picoquic_verify_path_available (cnx , next_path , & min_retransmit , current_time )) < 2 ) {
4257
4271
/* Only 0 or 1 path to chose from. Just select that. */
4258
4272
if (* next_path == NULL ) {
4259
4273
* next_path = cnx -> path [0 ];
@@ -4265,7 +4279,7 @@ void picoquic_select_next_path_tuple(picoquic_cnx_t* cnx, uint64_t current_time,
4265
4279
* available path that can send ACK, or paced data, or congestion
4266
4280
* controlled data.
4267
4281
*/
4268
- picoquic_sort_available_paths (cnx , current_time , next_wake_time , next_path , next_tuple );
4282
+ picoquic_sort_available_paths (cnx , current_time , next_wake_time , next_path , min_retransmit , next_tuple );
4269
4283
}
4270
4284
}
4271
4285
@@ -4285,8 +4299,6 @@ static void picoquic_set_path_addresses_from_tuple(picoquic_tuple_t* tuple,
4285
4299
}
4286
4300
}
4287
4301
4288
-
4289
-
4290
4302
/* manage the CC timer, if any */
4291
4303
static int picoquic_check_cc_feedback_timer (picoquic_cnx_t * cnx , uint64_t * next_wake_time , uint64_t current_time )
4292
4304
{
0 commit comments