Skip to content

Commit 14bae03

Browse files
authored
refactor(iroh)!: Use FourTuple for selected path (#4273)
## Description Track the selected path in the RemoteStateActor by FourTuple. Handling and exposing the local address is .. weird: * For IP transports, it is the address of the local socket, if known * For relay transports, we never set the local_ip in the recv meta. * For custom transports, the custom transport implementation can set a `CustomAddr` in `RecvMeta`, which we convert to a mapped addr with port 0 internally in the recv path The address we get back from noq for a path is this address. We don't want to ever expose mapped addresses, so we need to convert this address into something else. We have a precedent: We recently introduced a `IncomingLocalAddr` which is basically this. So I decided to reuse this type and renam eit to `LocalTransportAddr`, which mirrors `TransportAddr` nicely. The conversions are nothing to be happy about, but I don't see a solid alternative right now without larger refactors. ## Breaking Changes * changed: The variants of `iroh::endpoint::PathEvent` are now marked `#[non_exhaustive]` * renamed: `iroh::endpoint::IncomingLocalAddr` -> `iroh::endpoint::LocalTransportAddr`, and the `Relay` variant is now a tuple variant ## Notes & open questions Instead of reusing and renaming the exisitng `IncomingLocalAddr`, we could also expose local_addr as `Option<LocalTransportAddr>`, with `enum LocalTransportAddr { Ip(IpAddr), Custom(CustomAddr) }`, i.e. remove the `Relay` case. I had this in an earlier version but then found yet another public address type a bit too much so instead went for the existing `IncomingLocalAddr`. ## Change checklist <!-- Remove any that are not relevant. --> - [x] Self-review. - [x] 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. - [x] Tests if relevant. - [x] All breaking changes documented.
1 parent 0c60851 commit 14bae03

10 files changed

Lines changed: 342 additions & 134 deletions

File tree

iroh/examples/transfer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ fn spawn_path_watcher(
961961
id,
962962
remote_addr,
963963
last_stats,
964+
..
964965
} => {
965966
paths.push(PathData {
966967
id,

iroh/src/endpoint.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub use super::socket::{
4242
Path, PathEvent, PathEventStream, PathList, PathListIter, PathListStream, RemoteInfo,
4343
TransportAddrInfo, TransportAddrUsage,
4444
},
45+
transports::LocalTransportAddr,
4546
};
4647
#[cfg(wasm_browser)]
4748
use crate::address_lookup::PkarrResolver;
@@ -81,8 +82,8 @@ pub use self::quic::{QlogConfig, QlogFactory, QlogFileFactory};
8182
pub use self::{
8283
connection::{
8384
Accept, Accepting, AlpnError, AuthenticationError, Connecting, ConnectingError, Connection,
84-
ConnectionState, HandshakeCompleted, Incoming, IncomingAddr, IncomingLocalAddr,
85-
IncomingZeroRtt, IncomingZeroRttConnection, OutgoingZeroRtt, OutgoingZeroRttConnection,
85+
ConnectionState, HandshakeCompleted, Incoming, IncomingAddr, IncomingZeroRtt,
86+
IncomingZeroRttConnection, OutgoingZeroRtt, OutgoingZeroRttConnection,
8687
RemoteEndpointIdError, RetryError, WeakConnectionHandle, ZeroRttStatus,
8788
},
8889
quic::{
@@ -1682,11 +1683,6 @@ impl Endpoint {
16821683
self.inner.to_transport_addr(addr)
16831684
}
16841685

1685-
/// Reverse-resolves a custom mapped address back to its [`iroh_base::CustomAddr`].
1686-
pub(crate) fn lookup_custom_addr(&self, addr: SocketAddr) -> Option<iroh_base::CustomAddr> {
1687-
self.inner.lookup_custom_addr(addr)
1688-
}
1689-
16901686
#[cfg(all(test, with_crypto_provider))]
16911687
pub(crate) fn inner(&self) -> Result<Arc<EndpointInner>, EndpointError> {
16921688
if self.is_closed() {
@@ -3491,7 +3487,7 @@ mod tests {
34913487
if let PathEvent::Closed {
34923488
remote_addr,
34933489
last_stats,
3494-
id: _,
3490+
..
34953491
} = event
34963492
{
34973493
stats.insert(remote_addr, *last_stats);

iroh/src/endpoint/connection.rs

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use std::{
2020
any::Any,
2121
future::{Future, IntoFuture},
22-
net::{IpAddr, SocketAddr},
22+
net::SocketAddr,
2323
pin::Pin,
2424
sync::Arc,
2525
task::Poll,
@@ -48,7 +48,7 @@ use crate::{
4848
socket::{
4949
RemoteStateActorStoppedError,
5050
remote_map::{PathEventStream, PathList, PathListStream, PathStateReceiver},
51-
transports,
51+
transports::{self, LocalTransportAddr},
5252
},
5353
};
5454

@@ -92,21 +92,6 @@ impl From<transports::Addr> for IncomingAddr {
9292
}
9393
}
9494

95-
/// The local address that received an incoming connection.
96-
#[derive(Debug, Clone, PartialEq, Eq)]
97-
#[non_exhaustive]
98-
pub enum IncomingLocalAddr {
99-
/// The local IP, if the OS surfaced it.
100-
Ip(Option<IpAddr>),
101-
/// The relay this connection arrived through.
102-
Relay {
103-
/// The URL of the relay.
104-
url: RelayUrl,
105-
},
106-
/// The local custom address, if the transport reports one.
107-
Custom(Option<iroh_base::CustomAddr>),
108-
}
109-
11095
/// Future produced by [`Endpoint::accept`].
11196
#[derive(derive_more::Debug)]
11297
#[pin_project]
@@ -208,18 +193,10 @@ impl Incoming {
208193
}
209194

210195
/// Returns the local address that received this incoming connection.
211-
pub fn local_addr(&self) -> IncomingLocalAddr {
212-
match self.ep.to_transport_addr(self.inner.remote_address()) {
213-
transports::Addr::Ip(_) => IncomingLocalAddr::Ip(self.inner.local_ip()),
214-
transports::Addr::Relay(url, _) => IncomingLocalAddr::Relay { url },
215-
transports::Addr::Custom(_) => {
216-
let local = self
217-
.inner
218-
.local_ip()
219-
.and_then(|ip| self.ep.lookup_custom_addr(SocketAddr::new(ip, 0)));
220-
IncomingLocalAddr::Custom(local)
221-
}
222-
}
196+
pub fn local_addr(&self) -> LocalTransportAddr {
197+
let remote_addr = self.inner.remote_address();
198+
let local_ip = self.inner.local_ip();
199+
self.ep.inner.to_local_transport_addr(local_ip, remote_addr)
223200
}
224201

225202
/// Returns the remote address of this incoming connection.

iroh/src/socket.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ use crate::net_report::QuicConfig;
6868
use crate::{
6969
address_lookup::{self, AddressLookupFailed, EndpointData, UserData},
7070
defaults::timeouts::NET_REPORT_TIMEOUT,
71-
endpoint::{RelayStatus, hooks::EndpointHooksList, quic::QuicTransportConfig},
71+
endpoint::{
72+
LocalTransportAddr, RelayStatus, hooks::EndpointHooksList, quic::QuicTransportConfig,
73+
},
7274
metrics::EndpointMetrics,
7375
net_report::{self, IfStateDetails, Report},
7476
portmapper,
@@ -533,14 +535,17 @@ impl Socket {
533535
.unwrap_or(transports::Addr::Ip(addr))
534536
}
535537

536-
/// Reverse-resolves a custom mapped address back to its [`iroh_base::CustomAddr`].
537-
pub(crate) fn lookup_custom_addr(&self, addr: SocketAddr) -> Option<iroh_base::CustomAddr> {
538-
match MultipathMappedAddr::from(addr) {
539-
MultipathMappedAddr::Custom(custom_mapped) => {
540-
self.mapped_addrs.custom_addrs.lookup(&custom_mapped)
541-
}
542-
_ => None,
543-
}
538+
pub(crate) fn to_local_transport_addr(
539+
&self,
540+
local_ip: Option<IpAddr>,
541+
remote_addr: SocketAddr,
542+
) -> LocalTransportAddr {
543+
let remote_addr = self.to_transport_addr(remote_addr);
544+
LocalTransportAddr::from_noq_local_ip(
545+
local_ip,
546+
&remote_addr,
547+
&self.mapped_addrs.custom_addrs,
548+
)
544549
}
545550

546551
/// Reference to the internal Address Lookup

iroh/src/socket/mapped_addrs.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,17 @@ impl MappedAddr for CustomMappedAddr {
287287
}
288288
}
289289

290+
impl TryFrom<IpAddr> for CustomMappedAddr {
291+
type Error = CustomMappedAddrError;
292+
293+
fn try_from(value: IpAddr) -> std::result::Result<Self, Self::Error> {
294+
match value {
295+
IpAddr::V4(_) => Err(e!(CustomMappedAddrError)),
296+
IpAddr::V6(addr) => addr.try_into(),
297+
}
298+
}
299+
}
300+
290301
impl TryFrom<Ipv6Addr> for CustomMappedAddr {
291302
type Error = CustomMappedAddrError;
292303

0 commit comments

Comments
 (0)