Skip to content

Commit 7887fb5

Browse files
authored
refactor: minor cleanups in endpoint state (#3626)
## Description This has a few minor cleanups without any functional changes in the endpoint state actor: * Remove double handle upgrade * Add helper function `to_transport_addr` on the relay mapped addr map * Use hash map `entry` API instead of `get` and `expect` * Use `if let` chains to remove a level of indentation ## Breaking Changes <!-- Optional, if there are any breaking changes document them, including how to migrate older code. --> ## Notes & open questions <!-- Any notes, remarks or open questions you have to make about the PR. --> ## Change checklist <!-- Remove any that are not relevant. --> - [ ] Self-review. - [ ] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [ ] Tests if relevant. - [ ] All breaking changes documented. - [ ] List all breaking changes in the above "Breaking Changes" section. - [ ] Open an issue or PR on any number0 repos that are affected by this breaking change. Give guidance on how the updates should be handled or do the actual updates themselves. The major ones are: - [ ] [`quic-rpc`](https://github.com/n0-computer/quic-rpc) - [ ] [`iroh-gossip`](https://github.com/n0-computer/iroh-gossip) - [ ] [`iroh-blobs`](https://github.com/n0-computer/iroh-blobs) - [ ] [`dumbpipe`](https://github.com/n0-computer/dumbpipe) - [ ] [`sendme`](https://github.com/n0-computer/sendme)
1 parent d1c1dab commit 7887fb5

File tree

2 files changed

+82
-70
lines changed

2 files changed

+82
-70
lines changed

iroh/src/magicsock/endpoint_map/endpoint_state.rs

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::{
3131
endpoint::DirectAddr,
3232
magicsock::{
3333
DiscoState, HEARTBEAT_INTERVAL, MagicsockMetrics, PATH_MAX_IDLE_TIMEOUT,
34-
mapped_addrs::{AddrMap, MappedAddr, MultipathMappedAddr, RelayMappedAddr},
34+
mapped_addrs::{AddrMap, MappedAddr, RelayMappedAddr},
3535
transports::{self, OwnedTransmit},
3636
},
3737
util::MaybeFuture,
@@ -341,60 +341,54 @@ impl EndpointStateActor {
341341
let events = BroadcastStream::new(conn.path_events());
342342
let stream = events.map(move |evt| (conn_id, evt));
343343
self.path_events.push(Box::pin(stream));
344-
self.connections.insert(
345-
conn_id,
346-
ConnectionState {
344+
let conn_state = self
345+
.connections
346+
.entry(conn_id)
347+
.insert_entry(ConnectionState {
347348
handle: handle.clone(),
348349
pub_open_paths: paths_watchable,
349350
paths: Default::default(),
350351
open_paths: Default::default(),
351352
path_ids: Default::default(),
352-
},
353-
);
353+
})
354+
.into_mut();
354355

355356
// Store PathId(0), set path_status and select best path, check if holepunching
356357
// is needed.
357-
if let Some(conn) = handle.upgrade() {
358-
if let Some(path) = conn.path(PathId::ZERO) {
359-
if let Some(path_remote) = path
360-
.remote_address()
361-
.map_or(None, |remote| Some(MultipathMappedAddr::from(remote)))
362-
.and_then(|mmaddr| mmaddr.to_transport_addr(&self.relay_mapped_addrs))
363-
{
364-
trace!(?path_remote, "added new connection");
365-
let path_remote_is_ip = path_remote.is_ip();
366-
let status = match path_remote {
367-
transports::Addr::Ip(_) => PathStatus::Available,
368-
transports::Addr::Relay(_, _) => PathStatus::Backup,
369-
};
370-
path.set_status(status).ok();
371-
let conn_state =
372-
self.connections.get_mut(&conn_id).expect("inserted above");
373-
conn_state.add_open_path(path_remote.clone(), PathId::ZERO);
374-
self.paths
375-
.entry(path_remote)
376-
.or_default()
377-
.sources
378-
.insert(Source::Connection, Instant::now());
379-
self.select_path();
380-
381-
if path_remote_is_ip {
382-
// We may have raced this with a relay address. Try and add any
383-
// relay addresses we have back.
384-
let relays = self
385-
.paths
386-
.keys()
387-
.filter(|a| a.is_relay())
388-
.cloned()
389-
.collect::<Vec<_>>();
390-
for remote in relays {
391-
self.open_path(&remote);
392-
}
393-
}
358+
if let Some(path) = conn.path(PathId::ZERO)
359+
&& let Ok(socketaddr) = path.remote_address()
360+
&& let Some(path_remote) = self.relay_mapped_addrs.to_transport_addr(socketaddr)
361+
{
362+
trace!(?path_remote, "added new connection");
363+
let path_remote_is_ip = path_remote.is_ip();
364+
let status = match path_remote {
365+
transports::Addr::Ip(_) => PathStatus::Available,
366+
transports::Addr::Relay(_, _) => PathStatus::Backup,
367+
};
368+
path.set_status(status).ok();
369+
conn_state.add_open_path(path_remote.clone(), PathId::ZERO);
370+
self.paths
371+
.entry(path_remote)
372+
.or_default()
373+
.sources
374+
.insert(Source::Connection, Instant::now());
375+
self.select_path();
376+
377+
if path_remote_is_ip {
378+
// We may have raced this with a relay address. Try and add any
379+
// relay addresses we have back.
380+
let relays = self
381+
.paths
382+
.keys()
383+
.filter(|a| a.is_relay())
384+
.cloned()
385+
.collect::<Vec<_>>();
386+
for remote in relays {
387+
self.open_path(&remote);
394388
}
395389
}
396-
self.trigger_holepunching().await;
397390
}
391+
self.trigger_holepunching().await;
398392
}
399393
}
400394

@@ -802,10 +796,8 @@ impl EndpointStateActor {
802796
path.set_keep_alive_interval(Some(HEARTBEAT_INTERVAL)).ok();
803797
path.set_max_idle_timeout(Some(PATH_MAX_IDLE_TIMEOUT)).ok();
804798

805-
if let Some(path_remote) = path
806-
.remote_address()
807-
.map_or(None, |remote| Some(MultipathMappedAddr::from(remote)))
808-
.and_then(|mmaddr| mmaddr.to_transport_addr(&self.relay_mapped_addrs))
799+
if let Ok(socketaddr) = path.remote_address()
800+
&& let Some(path_remote) = self.relay_mapped_addrs.to_transport_addr(socketaddr)
809801
{
810802
event!(
811803
target: "iroh::_events::path::open",
@@ -1156,6 +1148,8 @@ impl ConnectionState {
11561148
/// Watchables for the open paths and selected transmission path in a connection.
11571149
///
11581150
/// This is stored in the [`Connection`], and the watchables are set from within the endpoint state actor.
1151+
///
1152+
/// [`Connection`]: crate::endpoint::Connection
11591153
#[derive(Debug, Default, Clone)]
11601154
pub(crate) struct PathsWatchable {
11611155
/// Watchable for the open paths (in this connection).

iroh/src/magicsock/mapped_addrs.rs

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -95,28 +95,6 @@ impl From<SocketAddr> for MultipathMappedAddr {
9595
}
9696
}
9797

98-
impl MultipathMappedAddr {
99-
pub(super) fn to_transport_addr(
100-
&self,
101-
relay_mapped_addrs: &AddrMap<(RelayUrl, EndpointId), RelayMappedAddr>,
102-
) -> Option<transports::Addr> {
103-
match self {
104-
Self::Mixed(_) => {
105-
error!("Mixed addr has no transports::Addr");
106-
None
107-
}
108-
Self::Relay(mapped) => match relay_mapped_addrs.lookup(mapped) {
109-
Some(parts) => Some(transports::Addr::from(parts)),
110-
None => {
111-
error!("Unknown RelayMappedAddr");
112-
None
113-
}
114-
},
115-
Self::Ip(addr) => Some(transports::Addr::from(*addr)),
116-
}
117-
}
118-
}
119-
12098
/// An address used to address a endpoint on any or all paths.
12199
///
122100
/// This is only used for initially connecting to a remote endpoint. We instruct Quinn to
@@ -307,3 +285,43 @@ impl<K, V> Default for AddrMapInner<K, V> {
307285
}
308286
}
309287
}
288+
289+
/// Functions for the relay mapped address map.
290+
impl AddrMap<(RelayUrl, EndpointId), RelayMappedAddr> {
291+
/// Converts a mapped socket address to a transport address.
292+
///
293+
/// This takes a socket address, converts it into a [`MultipathMappedAddr`] and then tries
294+
/// to convert the mapped address into a [`transports::Addr`].
295+
///
296+
/// Returns `Some` with the transport address for IP mapped addresses and for relay mapped
297+
/// addresses if an entry for the mapped address exists in `self`.
298+
///
299+
/// Returns `None` and emits an error log if the mapped address is a [`MultipathMappedAddr::Mixed`],
300+
/// or if the mapped address is a [`MultipathMappedAddr::Relay`] and `self` does not contain the
301+
/// mapped address.
302+
pub(crate) fn to_transport_addr(
303+
&self,
304+
addr: impl Into<MultipathMappedAddr>,
305+
) -> Option<transports::Addr> {
306+
match addr.into() {
307+
MultipathMappedAddr::Mixed(_) => {
308+
error!(
309+
"Failed to convert addr to transport addr: Mixed mapped addr has no transport address"
310+
);
311+
None
312+
}
313+
MultipathMappedAddr::Relay(relay_mapped_addr) => {
314+
match self.lookup(&relay_mapped_addr) {
315+
Some(parts) => Some(transports::Addr::from(parts)),
316+
None => {
317+
error!(
318+
"Failed to convert addr to transport addr: Unknown relay mapped addr"
319+
);
320+
None
321+
}
322+
}
323+
}
324+
MultipathMappedAddr::Ip(addr) => Some(transports::Addr::from(addr)),
325+
}
326+
}
327+
}

0 commit comments

Comments
 (0)