diff --git a/picoquic/frames.c b/picoquic/frames.c index e1184583b25556b755fd724f87aaaee5fe16f5da..b05641393d3241229c0008a7e19e79c0f44620a7 100644 --- a/picoquic/frames.c +++ b/picoquic/frames.c @@ -569,14 +569,20 @@ uint8_t* picoquic_decode_retire_connection_id_frame(picoquic_cnx_t* cnx, uint8_t } else { /* Go through the list of paths to find the connection ID */ + int nb_demoted = 0; for (int i = 0; i < cnx->nb_paths; i++) { - if (cnx->path[i]->path_sequence == sequence) { + if (cnx->path[i]->path_sequence == sequence && + cnx->path[i]->path_is_activated == 0){ /* Mark the corresponding path as demoted */ picoquic_demote_path(cnx, i, current_time); - break; + nb_demoted++; } } + + if (nb_demoted != 0 && cnx->nb_cnxid_published > 0) { + cnx->nb_cnxid_published--; + } } return bytes; diff --git a/picoquic/packet.c b/picoquic/packet.c index 2ca8703ea68bf3730180f908f3a3813c6a582438..ab235843e46ca8197724ce011288389f97c96af2 100644 --- a/picoquic/packet.c +++ b/picoquic/packet.c @@ -1206,21 +1206,23 @@ int picoquic_incoming_0rtt( /* * Find path of incoming encrypted packet. (This code is not used during the - * handshake, or if the conenction is closing.) + * handshake, or if the connection is closing.) * * Check whether this matches a path defined by Local & Remote Addr, Local CNXID: * - if local CID length > 0 and does not match: no match; * - if local addr defined and does not match: no match; * - if peer addr defined and does not match: no match. + * Keep the "best match", if local cid match and local addr match. * - * If no path matches: new path. Check whether the addresses match a pending probe. + * If no path matches: new path. Check pathological conditions, such as + * too many open paths. + * Check whether the addresses match a pending probe. * If they do, merge probe, retain probe's CID as dest CID. If they don't, get CID * from stash or use null CID if peer uses null CID; initiated required probing. If - * no CID available, accept packet but no not create a path. + * no CID available, reuse CID from best match. + * Ask verification of new path. * - * If path matched: existing path. If peer address changed: NAT rebinding. If - * source address changed: if undef, update; else NAT rebinding. If NAT rebinding: - * change the probe secret; mark probe as required. + * If there is a best match: ask verification on best match. */ int picoquic_find_incoming_path(picoquic_cnx_t* cnx, picoquic_packet_header * ph, diff --git a/picoquic/picoquic_internal.h b/picoquic/picoquic_internal.h index c994ab538110ac4b40f3ed3f3620c04e2166da24..ab175953b4713c2242046c9e80d1e85040eff07e 100644 --- a/picoquic/picoquic_internal.h +++ b/picoquic/picoquic_internal.h @@ -731,6 +731,7 @@ typedef struct st_picoquic_cnx_t { int nb_paths; int nb_path_alloc; int path_sequence_next; + int nb_cnxid_published; /* Management of the CNX-ID stash */ picoquic_cnxid_stash_t * cnxid_stash_first; /* Management of ongoing probes */ diff --git a/picoquic/quicctx.c b/picoquic/quicctx.c index 6e1ac741b31e2dfab870b679d4ad8e70cc346c37..daf56098c9eb12b938ce757dc15409ddc2b6d7c9 100644 --- a/picoquic/quicctx.c +++ b/picoquic/quicctx.c @@ -1493,6 +1493,8 @@ picoquic_cnx_t* picoquic_create_cnx(picoquic_quic_t* quic, picoquic_register_path(cnx, cnx->path[0]); picoquic_open_cc_dump(cnx); + + cnx->nb_cnxid_published = 1; } return cnx; diff --git a/picoquic/sender.c b/picoquic/sender.c index d6e891604a7f6f2f34c5a7c707ac88e3a53f0c99..68486f0386db5b3e91ca7ea043ac35b5eb424500 100644 --- a/picoquic/sender.c +++ b/picoquic/sender.c @@ -2003,6 +2003,10 @@ int picoquic_prepare_new_path_and_id(picoquic_cnx_t* cnx, uint8_t* bytes, size_t *consumed = 0; } + if (ret == 0) { + cnx->nb_cnxid_published++; + } + return ret; } @@ -2204,7 +2208,7 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t * path_x, /* If there are not enough paths, create and advertise */ while (ret == 0 && cnx->remote_parameters.migration_disabled == 0 && cnx->local_parameters.migration_disabled == 0 && - cnx->nb_paths < PICOQUIC_NB_PATH_TARGET) { + cnx->nb_cnxid_published < PICOQUIC_NB_PATH_TARGET) { ret = picoquic_prepare_new_path_and_id(cnx, &bytes[length], send_buffer_min_max - checksum_overhead - length, current_time, &data_bytes);