Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into refactor-futures
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed Apr 26, 2024
2 parents 0c3f2f2 + 2693ec5 commit a2cb330
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 50 deletions.
2 changes: 1 addition & 1 deletion iroh-gossip/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ iroh-base = { version = "0.14.0", path = "../iroh-base" }

# net dependencies (optional)
futures-lite = { version = "2.3", optional = true }
iroh-net = { path = "../iroh-net", version = "0.14.0", optional = true }
iroh-net = { path = "../iroh-net", version = "0.14.0", optional = true, default-features = false }
quinn = { version = "0.10", optional = true }
tokio = { version = "1", optional = true, features = ["io-util", "sync", "rt", "macros", "net", "fs"] }
tokio-util = { version = "0.7.8", optional = true, features = ["codec"] }
Expand Down
11 changes: 8 additions & 3 deletions iroh-net/src/magicsock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,19 +501,19 @@ impl Inner {
}

// order of polling is: UDPv4, UDPv6, relay
let msgs = match self.pconn4.poll_recv(cx, bufs, metas)? {
let (msgs, from_ipv4) = match self.pconn4.poll_recv(cx, bufs, metas)? {
Poll::Pending | Poll::Ready(0) => match &self.pconn6 {
Some(conn) => match conn.poll_recv(cx, bufs, metas)? {
Poll::Pending | Poll::Ready(0) => {
return self.poll_recv_relay(cx, bufs, metas);
}
Poll::Ready(n) => n,
Poll::Ready(n) => (n, false),
},
None => {
return self.poll_recv_relay(cx, bufs, metas);
}
},
Poll::Ready(n) => n,
Poll::Ready(n) => (n, true),
};

let dst_ip = self.normalized_local_addr().ok().map(|addr| addr.ip());
Expand Down Expand Up @@ -548,6 +548,11 @@ impl Inner {
false
} else {
trace!(src = %meta.addr, len = %meta.stride, "UDP recv: quic packet");
if from_ipv4 {
inc_by!(MagicsockMetrics, recv_data_ipv4, buf.len() as _);
} else {
inc_by!(MagicsockMetrics, recv_data_ipv6, buf.len() as _);
}
true
};

Expand Down
49 changes: 14 additions & 35 deletions iroh-net/src/magicsock/node_map/best_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ impl BestAddrInner {
.map(|trust_until| trust_until >= now)
.unwrap_or(false)
}

fn addr(&self) -> SocketAddr {
self.addr.addr
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -81,49 +85,24 @@ impl BestAddr {
self.0.is_none()
}

pub fn clear(&mut self, reason: ClearReason, has_relay: bool) -> bool {
if let Some(addr) = self.addr() {
self.0 = None;
info!(?reason, ?has_relay, old_addr = %addr, "clearing best_addr");
/// Unconditionally clears the best address.
pub fn clear(&mut self, reason: ClearReason, has_relay: bool) {
let old = self.0.take();
if let Some(old_addr) = old.as_ref().map(BestAddrInner::addr) {
info!(?reason, ?has_relay, %old_addr, "clearing best_addr");
// no longer relying on the direct connection
inc!(MagicsockMetrics, num_direct_conns_removed);
if has_relay {
// we are now relying on the relay connection, add a relay conn
inc!(MagicsockMetrics, num_relay_conns_added);
}
true
} else {
false
}
}

pub fn clear_if_equals(
&mut self,
addr: SocketAddr,
reason: ClearReason,
has_relay: bool,
) -> bool {
match &self.addr() {
Some(best_addr) if *best_addr == addr => self.clear(reason, has_relay),
_ => false,
}
}

/// Clears best_addr if it equals `addr` and was confirmed before `confirmed_before`.
///
/// If the given addr is currently the best address, **and** the best address was
/// confirmed longer ago than the provided time, then this clears the best address.
pub fn clear_if_addr_older(
&mut self,
addr: SocketAddr,
confirmed_before: Instant,
reason: ClearReason,
has_relay: bool,
) {
if let Some(ref inner) = self.0 {
if inner.addr.addr == addr && inner.confirmed_at < confirmed_before {
self.clear(reason, has_relay);
}
/// Clears the best address if equal to `addr`.
pub fn clear_if_equals(&mut self, addr: SocketAddr, reason: ClearReason, has_relay: bool) {
if self.addr() == Some(addr) {
self.clear(reason, has_relay)
}
}

Expand Down Expand Up @@ -221,7 +200,7 @@ impl BestAddr {
}

pub fn addr(&self) -> Option<SocketAddr> {
self.0.as_ref().map(|a| a.addr.addr)
self.0.as_ref().map(BestAddrInner::addr)
}
}

Expand Down
35 changes: 24 additions & 11 deletions iroh-net/src/magicsock/node_map/node_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use super::IpPort;
/// See [`NodeState::prune_direct_addresses`].
pub(super) const MAX_INACTIVE_DIRECT_ADDRESSES: usize = 20;

/// How long since an endpoint path was last active before it might be pruned.
/// How long since an endpoint path was last alive before it might be pruned.
const LAST_ALIVE_PRUNE_DURATION: Duration = Duration::from_secs(120);

/// How long we wait for a pong reply before assuming it's never coming.
Expand Down Expand Up @@ -410,15 +410,28 @@ impl NodeState {
SendAddr::Udp(addr) => {
if let Some(path_state) = self.direct_addr_state.get_mut(&addr.into()) {
path_state.last_ping = None;
// only clear the best address if there was no sign of life from this path
// within the time the pong should have arrived
let consider_alive = path_state
.last_alive()
.map(|last_alive| last_alive.elapsed() <= PING_TIMEOUT_DURATION)
.unwrap_or(false);
if !consider_alive {
self.best_addr.clear_if_equals(
addr,
ClearReason::PongTimeout,
self.relay_url().is_some(),
)
}
} else {
// If we have no state for the best addr it should have been cleared
// anyway.
self.best_addr.clear_if_equals(
addr,
ClearReason::PongTimeout,
self.relay_url.is_some(),
);
}

// If we fail to ping our current best addr, it is not that good anymore.
self.best_addr.clear_if_addr_older(
addr,
sp.at,
ClearReason::PongTimeout,
self.relay_url.is_some(),
);
}
SendAddr::Relay(ref url) => {
if let Some((home_relay, relay_state)) = self.relay_url.as_mut() {
Expand Down Expand Up @@ -1142,10 +1155,10 @@ impl PathState {

/// Check whether this path is considered active.
///
/// Active means the path has received payload messages within the lat
/// Active means the path has received payload messages within the last
/// [`SESSION_ACTIVE_TIMEOUT`].
///
/// Note that an endpoint might be alive but not active if it's contactable but not in
/// Note that a path might be alive but not active if it's contactable but not in
/// use.
pub(super) fn is_active(&self) -> bool {
self.last_payload_msg
Expand Down

0 comments on commit a2cb330

Please sign in to comment.