Skip to content

Commit 9a4f6f0

Browse files
committed
Handle preferred address migration properly
1 parent d0b7fb0 commit 9a4f6f0

File tree

5 files changed

+25
-53
lines changed

5 files changed

+25
-53
lines changed

picoquic/frames.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4650,7 +4650,6 @@ const uint8_t* picoquic_decode_path_challenge_frame(picoquic_cnx_t* cnx, const u
46504650
* source (addr_from) matches the peer address if known. */
46514651
picoquic_tuple_t* tuple = path_x->first_tuple;
46524652
while (tuple != NULL) {
4653-
46544653
if (addr_from == NULL ||
46554654
picoquic_compare_addr(addr_from, (struct sockaddr*)&tuple->peer_addr) == 0) {
46564655
/* If the source address matches, we must verify that the destination
@@ -4682,6 +4681,19 @@ const uint8_t* picoquic_decode_path_challenge_frame(picoquic_cnx_t* cnx, const u
46824681
picoquic_addr_text((struct sockaddr*)&path_x->first_tuple->local_addr, buf4, sizeof(buf4))
46834682
);
46844683
}
4684+
else if (!cnx->client_mode && cnx->local_parameters.migration_disabled) {
4685+
/* We do not expect path challenges, unless they are on the default path
4686+
* and match the preferred address.
4687+
*/
4688+
if (cnx->local_parameters.prefered_address.is_defined) {
4689+
/* TODO: verify that this is going to the preferred address. */
4690+
cnx->local_parameters.migration_disabled = 0;
4691+
picoquic_log_app_message(cnx, "Enabling migration after preferred address validation on path %" PRIu64, path_x->unique_path_id);
4692+
}
4693+
else {
4694+
picoquic_connection_error_ex(cnx, PICOQUIC_TRANSPORT_PROTOCOL_VIOLATION, picoquic_frame_type_path_challenge, "Migration is disabled");
4695+
}
4696+
}
46854697
}
46864698
}
46874699

@@ -4744,6 +4756,10 @@ const uint8_t* picoquic_decode_path_response_frame(picoquic_cnx_t* cnx, const ui
47444756
previous_tuple->next_tuple = tuple->next_tuple;
47454757
tuple->next_tuple = path_x->first_tuple;
47464758
path_x->first_tuple = tuple;
4759+
if (tuple->to_preferred_address) {
4760+
cnx->remote_parameters.migration_disabled = 0;
4761+
picoquic_log_app_message(cnx, "Migration to server preferred address successful on path %" PRIu64, path_x->unique_path_id);
4762+
}
47474763
picoquic_reset_path_mtu(path_x);
47484764
if (cnx->are_path_callbacks_enabled &&
47494765
cnx->callback_fn(cnx, path_x->unique_path_id, NULL, 0, picoquic_callback_path_available,

picoquic/picoquic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,8 @@ int picoquic_probe_new_path(picoquic_cnx_t* cnx, const struct sockaddr* addr_pee
959959
const struct sockaddr* addr_local, uint64_t current_time);
960960
int picoquic_probe_new_path_ex(picoquic_cnx_t* cnx, const struct sockaddr* addr_peer,
961961
const struct sockaddr* addr_local, int if_index, uint64_t current_time, int to_preferred_address);
962+
int picoquic_probe_new_tuple(picoquic_cnx_t* cnx, picoquic_path_t* path_x, struct sockaddr const* addr_peer,
963+
struct sockaddr const* addr_local, int if_index, uint64_t current_time, int to_preferred_address);
962964
void picoquic_enable_path_callbacks(picoquic_cnx_t* cnx, int are_enabled);
963965
void picoquic_enable_path_callbacks_default(picoquic_quic_t* quic, int are_enabled);
964966
int picoquic_set_app_path_ctx(picoquic_cnx_t* cnx, uint64_t unique_path_id, void * app_path_ctx);

picoquic/picoquic_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,7 @@ typedef struct st_picoquic_tuple_t {
10591059
unsigned int challenge_verified : 1;
10601060
unsigned int challenge_failed : 1;
10611061
unsigned int response_required : 1;
1062+
unsigned int to_preferred_address : 1;
10621063
} picoquic_tuple_t;
10631064

10641065
/*
@@ -1115,7 +1116,6 @@ typedef struct st_picoquic_path_t {
11151116
unsigned int current_spin : 1;
11161117
unsigned int last_bw_estimate_path_limited : 1;
11171118
unsigned int path_cid_rotated : 1;
1118-
unsigned int path_is_preferred_path : 1;
11191119
unsigned int is_nat_challenge : 1;
11201120
unsigned int is_cc_data_updated : 1;
11211121
unsigned int is_multipath_probe_needed : 1;

picoquic/quicctx.c

Lines changed: 4 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1951,51 +1951,7 @@ void picoquic_demote_path(picoquic_cnx_t* cnx, int path_index, uint64_t current_
19511951
}
19521952
}
19531953

1954-
/* Promote path to default. This happens when a new path is verified, at the end
1955-
* of a migration, and becomes the new default path.
1956-
*/
1957-
1958-
void picoquic_promote_path_to_default(picoquic_cnx_t* cnx, int path_index, uint64_t current_time)
1959-
{
1960-
if (path_index > 0 && path_index < cnx->nb_paths) {
1961-
picoquic_path_t * path_x = cnx->path[path_index];
1962-
1963-
if (cnx->path[path_index]->path_is_preferred_path) {
1964-
/* this is a migration to the preferred path requested by the server */
1965-
if (cnx->client_mode) {
1966-
cnx->remote_parameters.migration_disabled = 0;
1967-
}
1968-
else {
1969-
cnx->local_parameters.migration_disabled = 0;
1970-
}
1971-
}
19721954

1973-
if (cnx->quic->F_log != NULL || cnx->f_binlog != NULL) {
1974-
char src_ip[128];
1975-
char dst_ip[128];
1976-
1977-
picoquic_log_app_message(cnx, "Path %d promoted to default at T=%fs, Local: %s, Remote: %s",
1978-
path_index, (double)(current_time - cnx->start_time) / 1000000.0,
1979-
picoquic_addr_text((struct sockaddr*) & cnx->path[path_index]->first_tuple->local_addr, src_ip, sizeof(src_ip)),
1980-
picoquic_addr_text((struct sockaddr*) & cnx->path[path_index]->first_tuple->peer_addr, dst_ip, sizeof(dst_ip)));
1981-
}
1982-
1983-
/* Set the congestion algorithm for the new path */
1984-
if (cnx->congestion_alg != NULL) {
1985-
cnx->congestion_alg->alg_init(cnx, path_x, cnx->congestion_alg_option_string, current_time);
1986-
}
1987-
1988-
/* Mark old path as demoted */
1989-
picoquic_demote_path(cnx, 0, current_time, 0, NULL);
1990-
1991-
/* Swap */
1992-
cnx->path[path_index] = cnx->path[0];
1993-
cnx->path[0] = path_x;
1994-
1995-
/* Update the secret */
1996-
(void)picoquic_register_net_secret(cnx);
1997-
}
1998-
}
19991955

20001956
/* set the challenge used for a tuple */
20011957
void picoquic_set_tuple_challenge(picoquic_tuple_t * tuple, uint64_t current_time, int use_constant_challenges)
@@ -2331,6 +2287,7 @@ int picoquic_probe_new_tuple(picoquic_cnx_t* cnx, picoquic_path_t* path_x, struc
23312287
/* There was no NAT ongoing NAT rebinding, we created one, we need to initiate path challenges. */
23322288
picoquic_set_tuple_challenge(tuple, current_time, cnx->quic->use_constant_challenges);
23332289
tuple->challenge_required = 1;
2290+
tuple->to_preferred_address = to_preferred_address;
23342291
}
23352292
}
23362293
}
@@ -2343,7 +2300,7 @@ int picoquic_probe_new_path_ex(picoquic_cnx_t* cnx, const struct sockaddr* addr_
23432300
{
23442301
int path_id = -1;
23452302

2346-
if (!cnx->is_multipath_enabled) {
2303+
if (!cnx->is_multipath_enabled || to_preferred_address) {
23472304
return picoquic_probe_new_tuple(cnx, cnx->path[0], addr_peer, addr_local, if_index, current_time, to_preferred_address);
23482305
}
23492306

@@ -2368,7 +2325,6 @@ int picoquic_probe_new_path_ex(picoquic_cnx_t* cnx, const struct sockaddr* addr_
23682325
path_x->path_is_published = 1;
23692326
picoquic_register_path(cnx, path_x);
23702327
picoquic_set_path_challenge(cnx, path_id, current_time);
2371-
path_x->path_is_preferred_path = to_preferred_address;
23722328
path_x->is_nat_challenge = 0;
23732329
// path_x->first_tuple->if_index = if_index;
23742330
}
@@ -3954,9 +3910,8 @@ picoquic_cnx_t* picoquic_create_cnx(picoquic_quic_t* quic,
39543910
memcpy(&cnx->local_parameters, &quic->default_tp, sizeof(picoquic_tp_t));
39553911
/* If the default parameters include preferred address, document it */
39563912
if (cnx->local_parameters.prefered_address.is_defined) {
3957-
/* Create an additional CID -- this depends on the multipath variant being already negotiated */
3958-
uint64_t unique_path_id = (cnx->is_multipath_enabled) ? 1 : 0;
3959-
picoquic_local_cnxid_t* cnxid1 = picoquic_create_local_cnxid(cnx, unique_path_id, NULL, start_time);
3913+
/* Create an additional CID -- always for path 0, even if multipath */
3914+
picoquic_local_cnxid_t* cnxid1 = picoquic_create_local_cnxid(cnx, 0, NULL, start_time);
39603915
if (cnxid1 != NULL){
39613916
/* copy the connection ID into the local parameter */
39623917
cnx->local_parameters.prefered_address.connection_id = cnxid1->cnx_id;

picoquic/sender.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,9 +1841,8 @@ int picoquic_prepare_server_address_migration(picoquic_cnx_t* cnx)
18411841
if (cnx->path[0]->first_tuple->local_addr.ss_family != 0 && cnx->path[0]->first_tuple->local_addr.ss_family == dest_addr.ss_family) {
18421842
local_addr = (struct sockaddr*) & cnx->path[0]->first_tuple->local_addr;
18431843
}
1844+
picoquic_probe_new_tuple(cnx, cnx->path[0], (struct sockaddr*)&dest_addr, local_addr, 0, picoquic_get_quic_time(cnx->quic),1);
18441845

1845-
ret = picoquic_probe_new_path_ex(cnx, (struct sockaddr *)&dest_addr, local_addr, 0,
1846-
picoquic_get_quic_time(cnx->quic), 1);
18471846
}
18481847
}
18491848
}

0 commit comments

Comments
 (0)