mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-21 02:33:23 +00:00
feat(proto): Implement TransportConfig::set_rtt_hint
This commit is contained in:
@@ -8,7 +8,7 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ConnectionId, Duration, INITIAL_MTU, Instant, MAX_UDP_PAYLOAD, Side, VarInt,
|
||||
ConnectionId, Duration, FourTuple, INITIAL_MTU, Instant, MAX_UDP_PAYLOAD, Side, VarInt,
|
||||
VarIntBoundsExceeded, address_discovery, congestion, connection::qlog::QlogSink,
|
||||
};
|
||||
#[cfg(feature = "qlog")]
|
||||
@@ -83,6 +83,8 @@ pub struct TransportConfig {
|
||||
|
||||
pub(crate) max_remote_nat_traversal_addresses: Option<NonZeroU8>,
|
||||
|
||||
pub(crate) rtt_hint: Arc<dyn Fn(FourTuple) -> Option<Duration> + Send + Sync>,
|
||||
|
||||
#[cfg(feature = "qlog")]
|
||||
pub(crate) qlog_factory: Option<Arc<dyn QlogFactory>>,
|
||||
}
|
||||
@@ -467,6 +469,27 @@ impl TransportConfig {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the rtt hint function.
|
||||
///
|
||||
/// This function is consulted any time a new path is opened on a 4-tuple that we don't
|
||||
/// yet have a good rtt estimate for yet.
|
||||
///
|
||||
/// If the function returns some RTT, then this RTT is used as the initial RTT in the path's
|
||||
/// rtt estimator.
|
||||
/// If the function returns None, then we use the default rtt estimator's initial RTT value
|
||||
/// (see also [`Self::initial_rtt`]).
|
||||
///
|
||||
/// Be sure to always use conservative estimates of RTT, as the initial RTT value is used
|
||||
/// for setting the path's timeout. If the RTT estimate is about 9x lower than the actual
|
||||
/// RTT, then the path will be abandoned before a response could even be processed.
|
||||
pub fn set_rtt_hint(
|
||||
&mut self,
|
||||
rtt_hint: impl Fn(FourTuple) -> Option<Duration> + Send + Sync + 'static,
|
||||
) -> &mut Self {
|
||||
self.rtt_hint = Arc::new(rtt_hint);
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures qlog capturing by setting a [`QlogFactory`].
|
||||
///
|
||||
/// This assigns a [`QlogFactory`] that produces qlog capture configurations for
|
||||
@@ -582,6 +605,8 @@ impl Default for TransportConfig {
|
||||
// nat traversal disabled by default
|
||||
max_remote_nat_traversal_addresses: None,
|
||||
|
||||
rtt_hint: Arc::new(|_| None),
|
||||
|
||||
#[cfg(feature = "qlog")]
|
||||
qlog_factory: None,
|
||||
}
|
||||
@@ -621,6 +646,7 @@ impl fmt::Debug for TransportConfig {
|
||||
default_path_max_idle_timeout,
|
||||
default_path_keep_alive_interval,
|
||||
max_remote_nat_traversal_addresses,
|
||||
rtt_hint: _,
|
||||
#[cfg(feature = "qlog")]
|
||||
qlog_factory,
|
||||
} = self;
|
||||
|
||||
@@ -818,15 +818,6 @@ impl Connection {
|
||||
&mut self.paths.get_mut(&path_id).expect("known path").data
|
||||
}
|
||||
|
||||
/// Check if the 4-tuple path (as in RFC9000 Path, not multipath path) had already been validated.
|
||||
fn is_path_validated(&self, addresses: FourTuple) -> bool {
|
||||
self.paths
|
||||
.values()
|
||||
.any(|path_state| path_state.data.validated && path_state.data.addresses == addresses)
|
||||
// TODO(@divma): we might want to ensure the path has been recently active to consider the
|
||||
// address validated
|
||||
}
|
||||
|
||||
fn ensure_path(
|
||||
&mut self,
|
||||
path_id: PathId,
|
||||
@@ -834,7 +825,17 @@ impl Connection {
|
||||
now: Instant,
|
||||
pn: Option<u64>,
|
||||
) -> &mut PathData {
|
||||
let validated = self.is_path_validated(addresses);
|
||||
let path_on_same_address = self
|
||||
.paths
|
||||
.iter()
|
||||
.find(|(path_id, state)| {
|
||||
addresses.is_probably_same_path(&state.data.addresses)
|
||||
&& state.data.validated
|
||||
&& !self.abandoned_paths.contains(path_id)
|
||||
})
|
||||
.clone();
|
||||
let validated = path_on_same_address.is_some();
|
||||
let initial_rtt = path_on_same_address.map(|(_, state)| state.data.rtt.conservative());
|
||||
let vacant_entry = match self.paths.entry(path_id) {
|
||||
btree_map::Entry::Vacant(vacant_entry) => vacant_entry,
|
||||
btree_map::Entry::Occupied(occupied_entry) => {
|
||||
@@ -856,6 +857,9 @@ impl Connection {
|
||||
);
|
||||
|
||||
data.validated = validated;
|
||||
if let Some(rtt_hint) = initial_rtt.or_else(|| (self.config.rtt_hint)(addresses)) {
|
||||
data.rtt.reset_initial_rtt(rtt_hint);
|
||||
}
|
||||
|
||||
let pto = self.ack_frequency.max_ack_delay_for_pto() + data.rtt.pto_base();
|
||||
self.timers.set(
|
||||
|
||||
Reference in New Issue
Block a user