Skip to content

Commit ab03f16

Browse files
authored
fix: Expect missing CIDs when migrating (#362)
With multipath there is no guarantee that CIDs exist. Since this previous PathData is currently only used to send a single fire-and-forget PATH_CHALLENGE there is no value to store it as the previous path, since it would not be able to be sent. And this path would still have to be path-validated from scratch if it is the valid one. Additionally fix a bug that only stored this path if the previous path was *currently* validating. This was a bug introduced due to refactors. The intention is to store the path only if it was path-validated. Not to store it only if it was currently not being validated. Fixes #310
1 parent cd7a9d8 commit ab03f16

File tree

1 file changed

+22
-14
lines changed
  • quinn-proto/src/connection

1 file changed

+22
-14
lines changed

quinn-proto/src/connection/mod.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4955,12 +4955,11 @@ impl Connection {
49554955
// Note that the congestion window will not grow until validation terminates. Helps mitigate
49564956
// amplification attacks performed by spoofing source addresses.
49574957
let prev_pto = self.pto(SpaceId::Data, path_id);
4958-
let known_path = self.paths.get_mut(&path_id).expect("known path");
4959-
let path = &mut known_path.data;
4960-
let mut new_path = if network_path.remote.is_ipv4()
4961-
&& network_path.remote.ip() == path.network_path.remote.ip()
4958+
let path = self.paths.get_mut(&path_id).expect("known path");
4959+
let mut new_path_data = if network_path.remote.is_ipv4()
4960+
&& network_path.remote.ip() == path.data.network_path.remote.ip()
49624961
{
4963-
PathData::from_previous(network_path, path, self.path_generation_counter, now)
4962+
PathData::from_previous(network_path, &path.data, self.path_generation_counter, now)
49644963
} else {
49654964
let peer_max_udp_payload_size =
49664965
u16::try_from(self.peer_params.max_udp_payload_size.into_inner())
@@ -4974,26 +4973,35 @@ impl Connection {
49744973
&self.config,
49754974
)
49764975
};
4977-
new_path.last_observed_addr_report = path.last_observed_addr_report.clone();
4976+
new_path_data.last_observed_addr_report = path.data.last_observed_addr_report.clone();
49784977
if let Some(report) = observed_addr
4979-
&& let Some(updated) = new_path.update_observed_addr_report(report)
4978+
&& let Some(updated) = new_path_data.update_observed_addr_report(report)
49804979
{
49814980
tracing::info!("adding observed addr event from migration");
49824981
self.events.push_back(Event::Path(PathEvent::ObservedAddr {
49834982
id: path_id,
49844983
addr: updated,
49854984
}));
49864985
}
4987-
new_path.send_new_challenge = true;
4986+
new_path_data.send_new_challenge = true;
49884987

4989-
let mut prev = mem::replace(path, new_path);
4990-
// Don't clobber the original path if the previous one hasn't been validated yet
4991-
if !prev.is_validating_path() {
4992-
prev.send_new_challenge = true;
4988+
let mut prev_path_data = mem::replace(&mut path.data, new_path_data);
4989+
4990+
// Only store this as previous path if it was validated. For all we know there could
4991+
// already be a previous path stored which might have been validated in the past,
4992+
// which is more valuable than one that's not yet validated.
4993+
//
4994+
// With multipath it is possible that there are no remote CIDs for the path ID
4995+
// yet. In this case we would never have sent on this path yet and would not be able
4996+
// to send a PATH_CHALLENGE either, which is currently a fire-and-forget affair
4997+
// anyway. So don't store such a path either.
4998+
if !prev_path_data.validated
4999+
&& let Some(cid) = self.remote_cids.get(&path_id).map(CidQueue::active)
5000+
{
5001+
prev_path_data.send_new_challenge = true;
49935002
// We haven't updated the remote CID yet, this captures the remote CID we were using on
49945003
// the previous path.
4995-
4996-
known_path.prev = Some((self.remote_cids.get(&path_id).unwrap().active(), prev));
5004+
path.prev = Some((cid, prev_path_data));
49975005
}
49985006

49995007
// We need to re-assign the correct remote to this path in qlog

0 commit comments

Comments
 (0)