Skip to content

Commit

Permalink
Factor out helper structure for path validation responses
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralith authored and djc committed Jan 25, 2024
1 parent bfd1b24 commit d95c65e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 20 deletions.
26 changes: 9 additions & 17 deletions quinn-proto/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use packet_crypto::{PrevCrypto, ZeroRttCrypto};

mod paths;
pub use paths::RttEstimator;
use paths::{PathData, PathResponse};
use paths::{PathData, PathResponses};

mod send_buffer;

Expand Down Expand Up @@ -197,7 +197,8 @@ pub struct Connection {
//
// Queued non-retransmittable 1-RTT data
//
path_response: Option<PathResponse>,
/// Responses to PATH_CHALLENGE frames
path_responses: PathResponses,
close: bool,

//
Expand Down Expand Up @@ -336,7 +337,7 @@ impl Connection {
#[cfg(not(test))]
packet_number_filter: PacketNumberFilter::new(&mut rng),

path_response: None,
path_responses: PathResponses::default(),
close: false,

ack_frequency: AckFrequencyState::new(get_max_ack_delay(
Expand Down Expand Up @@ -2582,16 +2583,7 @@ impl Connection {
close = Some(reason);
}
Frame::PathChallenge(token) => {
if self
.path_response
.as_ref()
.map_or(true, |x| x.packet <= number)
{
self.path_response = Some(PathResponse {
packet: number,
token,
});
}
self.path_responses.push(number, token);
if remote == self.path.remote {
// PATH_CHALLENGE on active path, possible off-path packet forwarding
// attack. Send a non-probing packet to recover the active path.
Expand Down Expand Up @@ -3011,12 +3003,12 @@ impl Connection {

// PATH_RESPONSE
if buf.len() + 9 < max_size && space_id == SpaceId::Data {
if let Some(response) = self.path_response.take() {
if let Some(token) = self.path_responses.pop() {
sent.non_retransmits = true;
sent.requires_padding = true;
trace!("PATH_RESPONSE {:08x}", response.token);
trace!("PATH_RESPONSE {:08x}", token);
buf.write(frame::Type::PATH_RESPONSE);
buf.write(response.token);
buf.write(token);
self.stats.frame_tx.path_response += 1;
}
}
Expand Down Expand Up @@ -3414,7 +3406,7 @@ impl Connection {
.prev_path
.as_ref()
.map_or(false, |x| x.challenge_pending)
|| self.path_response.is_some()
|| !self.path_responses.is_empty()
|| !self.datagrams.outgoing.is_empty()
}

Expand Down
27 changes: 24 additions & 3 deletions quinn-proto/src/connection/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,29 @@ impl RttEstimator {
}
}

pub(crate) struct PathResponse {
#[derive(Default)]
pub(crate) struct PathResponses {
pending: Option<PathResponse>,
}

impl PathResponses {
pub(crate) fn push(&mut self, packet: u64, token: u64) {
if self.pending.as_ref().map_or(true, |x| x.packet <= packet) {
self.pending = Some(PathResponse { packet, token });
}
}

pub(crate) fn pop(&mut self) -> Option<u64> {
Some(self.pending.take()?.token)
}

pub(crate) fn is_empty(&self) -> bool {
self.pending.is_none()
}
}

struct PathResponse {
/// The packet number the corresponding PATH_CHALLENGE was received in
pub(crate) packet: u64,
pub(crate) token: u64,
packet: u64,
token: u64,
}

0 comments on commit d95c65e

Please sign in to comment.