From 3a2faeaf907faa510e9d1347cbb300dc5bedea17 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Thu, 13 Jun 2024 19:09:25 +0200 Subject: [PATCH 1/9] refactor(iroh_net)!: Remove Endpoint::my_addr_with_endpoints (#2359) ## Description This removes the Endpoint::my_addr_with_endpoints API. It is rather esoteric, very easy to do by hand and uses the dreaded endpoint noun in the wrong context. ## Breaking Changes - Endpoing::my_addr_with_endpoints has been removed. ## Notes & open questions ## Change checklist - [x] Self-review. - [x] Documentation updates if relevant. - ~~Tests if relevant.~~ - [x] All breaking changes documented. --- iroh-gossip/src/net.rs | 6 +++++- iroh-net/src/endpoint.rs | 11 ----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/iroh-gossip/src/net.rs b/iroh-gossip/src/net.rs index 756ccfee68..299844e837 100644 --- a/iroh-gossip/src/net.rs +++ b/iroh-gossip/src/net.rs @@ -378,7 +378,11 @@ impl Actor { new_endpoints = self.on_endpoints_rx.recv() => { match new_endpoints { Some(endpoints) => { - let addr = self.endpoint.my_addr_with_endpoints(endpoints)?; + let addr = NodeAddr::from_parts( + self.endpoint.node_id(), + self.endpoint.my_relay(), + endpoints.into_iter().map(|x| x.addr).collect(), + ); let peer_data = encode_peer_data(&addr.info)?; self.handle_in_event(InEvent::UpdatePeerData(peer_data), Instant::now()).await?; } diff --git a/iroh-net/src/endpoint.rs b/iroh-net/src/endpoint.rs index dd1d219569..218164d39e 100644 --- a/iroh-net/src/endpoint.rs +++ b/iroh-net/src/endpoint.rs @@ -28,7 +28,6 @@ use tracing::{debug, info_span, trace, warn}; use url::Url; use crate::{ - config, defaults::default_relay_map, discovery::{Discovery, DiscoveryTask}, dns::{default_resolver, DnsResolver}, @@ -580,16 +579,6 @@ impl Endpoint { Ok(NodeAddr::from_parts(self.node_id(), relay, addrs)) } - /// Returns the [`NodeAddr`] for this endpoint with the provided endpoints. - /// - /// Like [`Endpoint::my_addr`] but uses the provided IP endpoints rather than those from - /// [`Endpoint::local_endpoints`]. - pub fn my_addr_with_endpoints(&self, eps: Vec) -> Result { - let relay = self.my_relay(); - let addrs = eps.into_iter().map(|x| x.addr).collect(); - Ok(NodeAddr::from_parts(self.node_id(), relay, addrs)) - } - /// Returns the [`RelayUrl`] of the Relay server used as home relay. /// /// Every endpoint has a home Relay server which it chooses as the server with the From 100d27d57b28547a0ec5b4719bf25c31427f961e Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Fri, 14 Jun 2024 19:41:24 +0200 Subject: [PATCH 2/9] refactor(iroh-net)!: Rename Endpoint::my_relay to home_relay (#2361) ## Description This renames Endpoint::my_relay to Endpoint::home_relay. This is more descriptive, because home relay is how we describe this in other parts of the documentation. There is also no real consistency of the `my_` prefix, there's only one other API currently which I'll independently propose to remove. ## Breaking Changes - Endpoint::my_relay -> Endpoint::home_relay ## Notes & open questions ## Change checklist - [x] Self-review. - [x] Documentation updates if relevant. - ~~[ ] Tests if relevant.~~ - [x] All breaking changes documented. --- iroh-cli/src/commands/doctor.rs | 2 +- iroh-gossip/src/net.rs | 2 +- iroh-net/examples/connect-unreliable.rs | 2 +- iroh-net/examples/connect.rs | 2 +- iroh-net/examples/listen-unreliable.rs | 2 +- iroh-net/examples/listen.rs | 2 +- iroh-net/src/endpoint.rs | 6 +++--- iroh/src/node.rs | 2 +- iroh/src/node/rpc.rs | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/iroh-cli/src/commands/doctor.rs b/iroh-cli/src/commands/doctor.rs index 156bb4dd9d..4ffe511d98 100644 --- a/iroh-cli/src/commands/doctor.rs +++ b/iroh-cli/src/commands/doctor.rs @@ -742,7 +742,7 @@ async fn accept( secret_key.public(), remote_addrs, ); - if let Some(relay_url) = endpoint.my_relay() { + if let Some(relay_url) = endpoint.home_relay() { println!( "\tUsing just the relay url:\niroh doctor connect {} --relay-url {}\n", secret_key.public(), diff --git a/iroh-gossip/src/net.rs b/iroh-gossip/src/net.rs index 299844e837..d1a33fa962 100644 --- a/iroh-gossip/src/net.rs +++ b/iroh-gossip/src/net.rs @@ -380,7 +380,7 @@ impl Actor { Some(endpoints) => { let addr = NodeAddr::from_parts( self.endpoint.node_id(), - self.endpoint.my_relay(), + self.endpoint.home_relay(), endpoints.into_iter().map(|x| x.addr).collect(), ); let peer_data = encode_peer_data(&addr.info)?; diff --git a/iroh-net/examples/connect-unreliable.rs b/iroh-net/examples/connect-unreliable.rs index b42ae683c3..5438673557 100644 --- a/iroh-net/examples/connect-unreliable.rs +++ b/iroh-net/examples/connect-unreliable.rs @@ -69,7 +69,7 @@ async fn main() -> anyhow::Result<()> { } let relay_url = endpoint - .my_relay() + .home_relay() .expect("should be connected to a relay server, try calling `endpoint.local_endpoints()` or `endpoint.connect()` first, to ensure the endpoint has actually attempted a connection before checking for the connected relay server"); println!("node relay server url: {relay_url}\n"); // Build a `NodeAddr` from the node_id, relay url, and UDP addresses. diff --git a/iroh-net/examples/connect.rs b/iroh-net/examples/connect.rs index 68740e9040..ccaffb6e54 100644 --- a/iroh-net/examples/connect.rs +++ b/iroh-net/examples/connect.rs @@ -66,7 +66,7 @@ async fn main() -> anyhow::Result<()> { } let relay_url = endpoint - .my_relay() + .home_relay() .expect("should be connected to a relay server, try calling `endpoint.local_endpoints()` or `endpoint.connect()` first, to ensure the endpoint has actually attempted a connection before checking for the connected relay server"); println!("node relay server url: {relay_url}\n"); // Build a `NodeAddr` from the node_id, relay url, and UDP addresses. diff --git a/iroh-net/examples/listen-unreliable.rs b/iroh-net/examples/listen-unreliable.rs index 43fe12f81d..ded70a0f56 100644 --- a/iroh-net/examples/listen-unreliable.rs +++ b/iroh-net/examples/listen-unreliable.rs @@ -52,7 +52,7 @@ async fn main() -> anyhow::Result<()> { .join(" "); let relay_url = endpoint - .my_relay() + .home_relay() .expect("should be connected to a relay server, try calling `endpoint.local_endpoints()` or `endpoint.connect()` first, to ensure the endpoint has actually attempted a connection before checking for the connected relay server"); println!("node relay server url: {relay_url}"); println!("\nin a separate terminal run:"); diff --git a/iroh-net/examples/listen.rs b/iroh-net/examples/listen.rs index 4d59472584..9dc38ab258 100644 --- a/iroh-net/examples/listen.rs +++ b/iroh-net/examples/listen.rs @@ -52,7 +52,7 @@ async fn main() -> anyhow::Result<()> { .join(" "); let relay_url = endpoint - .my_relay() + .home_relay() .expect("should be connected to a relay server, try calling `endpoint.local_endpoints()` or `endpoint.connect()` first, to ensure the endpoint has actually attempted a connection before checking for the connected relay server"); println!("node relay server url: {relay_url}"); println!("\nin a separate terminal run:"); diff --git a/iroh-net/src/endpoint.rs b/iroh-net/src/endpoint.rs index 218164d39e..00f3819564 100644 --- a/iroh-net/src/endpoint.rs +++ b/iroh-net/src/endpoint.rs @@ -566,7 +566,7 @@ impl Endpoint { /// Returns the current [`NodeAddr`] for this endpoint. /// /// The returned [`NodeAddr`] will have the current [`RelayUrl`] and local IP endpoints - /// as they would be returned by [`Endpoint::my_relay`] and + /// as they would be returned by [`Endpoint::home_relay`] and /// [`Endpoint::local_endpoints`]. pub async fn my_addr(&self) -> Result { let addrs = self @@ -574,7 +574,7 @@ impl Endpoint { .next() .await .ok_or(anyhow!("No IP endpoints found"))?; - let relay = self.my_relay(); + let relay = self.home_relay(); let addrs = addrs.into_iter().map(|x| x.addr).collect(); Ok(NodeAddr::from_parts(self.node_id(), relay, addrs)) } @@ -591,7 +591,7 @@ impl Endpoint { /// Note that this will be `None` right after the [`Endpoint`] is created since it takes /// some time to connect to find and connect to the home relay server. Use /// [`Endpoint::watch_home_relay`] to wait until the home relay server is available. - pub fn my_relay(&self) -> Option { + pub fn home_relay(&self) -> Option { self.msock.my_relay() } diff --git a/iroh/src/node.rs b/iroh/src/node.rs index 3b9173c706..4290943494 100644 --- a/iroh/src/node.rs +++ b/iroh/src/node.rs @@ -147,7 +147,7 @@ impl Node { /// Get the relay server we are connected to. pub fn my_relay(&self) -> Option { - self.inner.endpoint.my_relay() + self.inner.endpoint.home_relay() } /// Aborts the node. diff --git a/iroh/src/node/rpc.rs b/iroh/src/node/rpc.rs index 6382b50d6a..9a118d523c 100644 --- a/iroh/src/node/rpc.rs +++ b/iroh/src/node/rpc.rs @@ -763,7 +763,7 @@ impl Handler { #[allow(clippy::unused_async)] async fn node_relay(self, _: NodeRelayRequest) -> RpcResult> { - Ok(self.inner.endpoint.my_relay()) + Ok(self.inner.endpoint.home_relay()) } #[allow(clippy::unused_async)] From 61d5109ff7e6f9cdca42af3d27a7681c55400604 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Fri, 14 Jun 2024 22:19:06 +0200 Subject: [PATCH 3/9] refactor(iroh-net)!: Rename Endpoint::my_addr to Endpoint::node_addr (#2362) ## Description This is in line with e.g. Endpoint::node_id. ## Breaking Changes - Endpoint::my_addr -> Endpoint::node_addr ## Notes & open questions Other networking APIs tend to have something like "local_addr", e.g. UdpSocket::local_addr in the standard library or Endpoint::local_addr in Quinn. Sometimes this is because they also have a "peer_addr" version, e.g. UdpSocket::peer_addr. In this light perhaps some of our APIs might benefit from using this for consistency with other API conventions. In this case this would become Endpoint::local_node_addr. We already have Endpoint::local_addr which returns the socket addresses we are bound to. Other candidates would be: - Endpoint::home_relay -> Endpoint::local_home_relay - Endpoint::node_id -> Endpoint::local_node_id - Endpoint::secret_key -> Endpoint::local_secret_key But, you can already see this fall apart. Because our endpoint is not the thing that is connected to a peer (that is the Connection) I don't think it makes sense to use the term "local" in the APIs. And perhaps Endpoint::local_addr should be changed anyway, while it is compatible with other usages it is rather out of tone for us because we have too many kind of addresses (socket address, node address, direct address, ...?). So perhaps that one is better off as Endpoint::bound_sockets or so. ## Change checklist - [x] Self-review. - [x] Documentation updates if relevant. - ~~[ ] Tests if relevant.~~ - [x] All breaking changes documented. --- iroh-gossip/examples/chat.rs | 4 ++-- iroh-net/src/discovery.rs | 10 +++++----- iroh-net/src/endpoint.rs | 10 +++++----- iroh/src/node/builder.rs | 2 +- iroh/src/node/rpc.rs | 4 ++-- iroh/src/node/rpc/docs.rs | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/iroh-gossip/examples/chat.rs b/iroh-gossip/examples/chat.rs index 0bd9a0e1a3..cf99a6942e 100644 --- a/iroh-gossip/examples/chat.rs +++ b/iroh-gossip/examples/chat.rs @@ -108,13 +108,13 @@ async fn main() -> anyhow::Result<()> { .await?; println!("> our node id: {}", endpoint.node_id()); - let my_addr = endpoint.my_addr().await?; + let my_addr = endpoint.node_addr().await?; // create the gossip protocol let gossip = Gossip::from_endpoint(endpoint.clone(), Default::default(), &my_addr.info); // print a ticket that includes our own node id and endpoint addresses let ticket = { - let me = endpoint.my_addr().await?; + let me = endpoint.node_addr().await?; let peers = peers.iter().cloned().chain([me]).collect(); Ticket { topic, peers } }; diff --git a/iroh-net/src/discovery.rs b/iroh-net/src/discovery.rs index 0b935621c2..2cdb1ecb6f 100644 --- a/iroh-net/src/discovery.rs +++ b/iroh-net/src/discovery.rs @@ -416,7 +416,7 @@ mod tests { }; let ep1_addr = NodeAddr::new(ep1.node_id()); // wait for out address to be updated and thus published at least once - ep1.my_addr().await?; + ep1.node_addr().await?; let _conn = ep2.connect(ep1_addr, TEST_ALPN).await?; Ok(()) } @@ -442,7 +442,7 @@ mod tests { }; let ep1_addr = NodeAddr::new(ep1.node_id()); // wait for out address to be updated and thus published at least once - ep1.my_addr().await?; + ep1.node_addr().await?; let _conn = ep2.connect(ep1_addr, TEST_ALPN).await?; Ok(()) } @@ -472,7 +472,7 @@ mod tests { }; let ep1_addr = NodeAddr::new(ep1.node_id()); // wait for out address to be updated and thus published at least once - ep1.my_addr().await?; + ep1.node_addr().await?; let _conn = ep2.connect(ep1_addr, TEST_ALPN).await?; Ok(()) } @@ -495,7 +495,7 @@ mod tests { }; let ep1_addr = NodeAddr::new(ep1.node_id()); // wait for out address to be updated and thus published at least once - ep1.my_addr().await?; + ep1.node_addr().await?; let res = ep2.connect(ep1_addr, TEST_ALPN).await; assert!(res.is_err()); Ok(()) @@ -518,7 +518,7 @@ mod tests { new_endpoint(secret, disco).await }; // wait for out address to be updated and thus published at least once - ep1.my_addr().await?; + ep1.node_addr().await?; let ep1_wrong_addr = NodeAddr { node_id: ep1.node_id(), info: AddrInfo { diff --git a/iroh-net/src/endpoint.rs b/iroh-net/src/endpoint.rs index 00f3819564..15f06d2b24 100644 --- a/iroh-net/src/endpoint.rs +++ b/iroh-net/src/endpoint.rs @@ -568,7 +568,7 @@ impl Endpoint { /// The returned [`NodeAddr`] will have the current [`RelayUrl`] and local IP endpoints /// as they would be returned by [`Endpoint::home_relay`] and /// [`Endpoint::local_endpoints`]. - pub async fn my_addr(&self) -> Result { + pub async fn node_addr(&self) -> Result { let addrs = self .local_endpoints() .next() @@ -1067,7 +1067,7 @@ mod tests { .bind(0) .await .unwrap(); - let my_addr = ep.my_addr().await.unwrap(); + let my_addr = ep.node_addr().await.unwrap(); let res = ep.connect(my_addr.clone(), TEST_ALPN).await; assert!(res.is_err()); let err = res.err().unwrap(); @@ -1341,8 +1341,8 @@ mod tests { .bind(0) .await .unwrap(); - let ep1_nodeaddr = ep1.my_addr().await.unwrap(); - let ep2_nodeaddr = ep2.my_addr().await.unwrap(); + let ep1_nodeaddr = ep1.node_addr().await.unwrap(); + let ep2_nodeaddr = ep2.node_addr().await.unwrap(); ep1.add_node_addr(ep2_nodeaddr.clone()).unwrap(); ep2.add_node_addr(ep1_nodeaddr.clone()).unwrap(); let ep1_nodeid = ep1.node_id(); @@ -1438,7 +1438,7 @@ mod tests { let ep1_nodeid = ep1.node_id(); let ep2_nodeid = ep2.node_id(); - let ep1_nodeaddr = ep1.my_addr().await.unwrap(); + let ep1_nodeaddr = ep1.node_addr().await.unwrap(); tracing::info!( "node id 1 {ep1_nodeid}, relay URL {:?}", ep1_nodeaddr.relay_url() diff --git a/iroh/src/node/builder.rs b/iroh/src/node/builder.rs index db935479f2..59782b2010 100644 --- a/iroh/src/node/builder.rs +++ b/iroh/src/node/builder.rs @@ -437,7 +437,7 @@ where debug!("rpc listening on: {:?}", self.rpc_endpoint.local_addr()); - let addr = endpoint.my_addr().await?; + let addr = endpoint.node_addr().await?; // initialize the gossip protocol let gossip = Gossip::from_endpoint(endpoint.clone(), Default::default(), &addr.info); diff --git a/iroh/src/node/rpc.rs b/iroh/src/node/rpc.rs index 9a118d523c..2ba9e77e02 100644 --- a/iroh/src/node/rpc.rs +++ b/iroh/src/node/rpc.rs @@ -741,7 +741,7 @@ impl Handler { async fn node_status(self, _: NodeStatusRequest) -> RpcResult { Ok(NodeStatus { - addr: self.inner.endpoint.my_addr().await?, + addr: self.inner.endpoint.node_addr().await?, listen_addrs: self .inner .local_endpoint_addresses() @@ -757,7 +757,7 @@ impl Handler { } async fn node_addr(self, _: NodeAddrRequest) -> RpcResult { - let addr = self.inner.endpoint.my_addr().await?; + let addr = self.inner.endpoint.node_addr().await?; Ok(addr) } diff --git a/iroh/src/node/rpc/docs.rs b/iroh/src/node/rpc/docs.rs index a0433a803e..4fbabf64ff 100644 --- a/iroh/src/node/rpc/docs.rs +++ b/iroh/src/node/rpc/docs.rs @@ -146,7 +146,7 @@ impl DocsEngine { mode, addr_options, } = req; - let mut me = self.endpoint.my_addr().await?; + let mut me = self.endpoint.node_addr().await?; me.apply_options(addr_options); let capability = match mode { From e9075f3b93038a74a4f11c545992ac4ba39590d0 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Fri, 14 Jun 2024 22:22:05 +0200 Subject: [PATCH 4/9] refactor(iroh-net)!: Do not use &NodeId in APIs as this is Copy (#2363) ## Description Some of our APIs take NodeId by reference, some by value. NodeId itself however is Copy and takes 32 bytes. I think it is more consistent and rusty to pass this by value and use the Copy semantics. Additionally this renames a few more types from PublicKey to NodeId to keep in line with our convention of using NodeId when used as identifier rather than cryptography. I believe rust-analyser might be inserting PublicKey by itself which is unfortunate. QuicMappedAddr and IpPort are also a Copy types and get the same treatment. ## Breaking Changes - Endpoint::conn_type_stream takes NodeId by value instead of by reference. ## Notes & open questions ## Change checklist - [x] Self-review. - ~~[ ] Documentation updates if relevant.~~ - ~~[ ] Tests if relevant.~~ - [x] All breaking changes documented. --- iroh-cli/src/commands/doctor.rs | 4 +- iroh-net/src/endpoint.rs | 12 +-- iroh-net/src/magicsock.rs | 13 ++-- iroh-net/src/magicsock/node_map.rs | 78 +++++++++---------- iroh-net/src/magicsock/node_map/node_state.rs | 2 +- 5 files changed, 51 insertions(+), 58 deletions(-) diff --git a/iroh-cli/src/commands/doctor.rs b/iroh-cli/src/commands/doctor.rs index 4ffe511d98..e30512c4f3 100644 --- a/iroh-cli/src/commands/doctor.rs +++ b/iroh-cli/src/commands/doctor.rs @@ -692,7 +692,7 @@ async fn connect( let conn = endpoint.connect(node_addr, &DR_RELAY_ALPN).await; match conn { Ok(connection) => { - let maybe_stream = endpoint.conn_type_stream(&node_id); + let maybe_stream = endpoint.conn_type_stream(node_id); let gui = Gui::new(endpoint, node_id); if let Ok(stream) = maybe_stream { log_connection_changes(gui.mp.clone(), node_id, stream); @@ -770,7 +770,7 @@ async fn accept( println!("Accepted connection from {}", remote_peer_id); let t0 = Instant::now(); let gui = Gui::new(endpoint.clone(), remote_peer_id); - if let Ok(stream) = endpoint.conn_type_stream(&remote_peer_id) { + if let Ok(stream) = endpoint.conn_type_stream(remote_peer_id) { log_connection_changes(gui.mp.clone(), remote_peer_id, stream); } let res = active_side(connection, &config, Some(&gui)).await; diff --git a/iroh-net/src/endpoint.rs b/iroh-net/src/endpoint.rs index 15f06d2b24..6b98bd4f45 100644 --- a/iroh-net/src/endpoint.rs +++ b/iroh-net/src/endpoint.rs @@ -501,7 +501,7 @@ impl Endpoint { let rtt_msg = RttMessage::NewConnection { connection: connection.weak_handle(), - conn_type_changes: self.conn_type_stream(node_id)?, + conn_type_changes: self.conn_type_stream(*node_id)?, node_id: *node_id, }; if let Err(err) = self.rtt_actor.msg_tx.send(rtt_msg).await { @@ -700,7 +700,7 @@ impl Endpoint { /// # Errors /// /// Will error if we do not have any address information for the given `node_id`. - pub fn conn_type_stream(&self, node_id: &NodeId) -> Result { + pub fn conn_type_stream(&self, node_id: NodeId) -> Result { self.msock.conn_type_stream(node_id) } @@ -794,7 +794,7 @@ impl Endpoint { // Only return a mapped addr if we have some way of dialing this node, in other // words, we have either a relay URL or at least one direct address. let addr = if self.msock.has_send_address(node_id) { - self.msock.get_mapping_addr(&node_id) + self.msock.get_mapping_addr(node_id) } else { None }; @@ -822,7 +822,7 @@ impl Endpoint { let mut discovery = DiscoveryTask::start(self.clone(), node_id)?; discovery.first_arrived().await?; if self.msock.has_send_address(node_id) { - let addr = self.msock.get_mapping_addr(&node_id).expect("checked"); + let addr = self.msock.get_mapping_addr(node_id).expect("checked"); Ok((addr, Some(discovery))) } else { bail!("Failed to retrieve the mapped address from the magic socket. Unable to dial node {node_id:?}"); @@ -967,7 +967,7 @@ fn try_send_rtt_msg(conn: &quinn::Connection, magic_ep: &Endpoint) { warn!(?conn, "failed to get remote node id"); return; }; - let Ok(conn_type_changes) = magic_ep.conn_type_stream(&peer_id) else { + let Ok(conn_type_changes) = magic_ep.conn_type_stream(peer_id) else { warn!(?conn, "failed to create conn_type_stream"); return; }; @@ -1411,7 +1411,7 @@ mod tests { async fn handle_direct_conn(ep: Endpoint, node_id: PublicKey) -> Result<()> { let node_addr = NodeAddr::new(node_id); ep.add_node_addr(node_addr)?; - let stream = ep.conn_type_stream(&node_id)?; + let stream = ep.conn_type_stream(node_id)?; async fn get_direct_event( src: &PublicKey, dst: &PublicKey, diff --git a/iroh-net/src/magicsock.rs b/iroh-net/src/magicsock.rs index 7437c87694..435e86a841 100644 --- a/iroh-net/src/magicsock.rs +++ b/iroh-net/src/magicsock.rs @@ -33,6 +33,7 @@ use std::{ use anyhow::{anyhow, Context as _, Result}; use bytes::Bytes; use futures_lite::{FutureExt, Stream, StreamExt}; +use iroh_base::key::NodeId; use iroh_metrics::{inc, inc_by}; use quinn::AsyncUdpSocket; use rand::{seq::SliceRandom, Rng, SeedableRng}; @@ -299,8 +300,8 @@ impl MagicSock { } /// Retrieve connection information about a node in the network. - pub fn connection_info(&self, node_key: PublicKey) -> Option { - self.node_map.node_info(&node_key) + pub fn connection_info(&self, node_id: NodeId) -> Option { + self.node_map.node_info(node_id) } /// Returns the local endpoints as a stream. @@ -350,7 +351,7 @@ impl MagicSock { /// /// Will return an error if there is no address information known about the /// given `node_id`. - pub fn conn_type_stream(&self, node_id: &PublicKey) -> Result { + pub fn conn_type_stream(&self, node_id: NodeId) -> Result { self.node_map.conn_type_stream(node_id) } @@ -358,9 +359,9 @@ impl MagicSock { /// /// Note this is a user-facing API and does not wrap the [`SocketAddr`] in a /// [`QuicMappedAddr`] as we do internally. - pub fn get_mapping_addr(&self, node_key: &PublicKey) -> Option { + pub fn get_mapping_addr(&self, node_id: NodeId) -> Option { self.node_map - .get_quic_mapped_addr_for_node_key(node_key) + .get_quic_mapped_addr_for_node_key(node_id) .map(|a| a.0) } @@ -468,7 +469,7 @@ impl MagicSock { let mut transmits_sent = 0; match self .node_map - .get_send_addrs(&dest, self.ipv6_reported.load(Ordering::Relaxed)) + .get_send_addrs(dest, self.ipv6_reported.load(Ordering::Relaxed)) { Some((public_key, udp_addr, relay_url, mut msgs)) => { let mut pings_sent = false; diff --git a/iroh-net/src/magicsock/node_map.rs b/iroh-net/src/magicsock/node_map.rs index c17cfccaeb..7e6e2e74fc 100644 --- a/iroh-net/src/magicsock/node_map.rs +++ b/iroh-net/src/magicsock/node_map.rs @@ -74,11 +74,11 @@ pub(super) struct NodeMapInner { /// You can look up entries in [`NodeMap`] with various keys, depending on the context you /// have for the node. These are all the keys the [`NodeMap`] can use. #[derive(Clone)] -enum NodeStateKey<'a> { - Idx(&'a usize), - NodeId(&'a NodeId), - QuicMappedAddr(&'a QuicMappedAddr), - IpPort(&'a IpPort), +enum NodeStateKey { + Idx(usize), + NodeId(NodeId), + QuicMappedAddr(QuicMappedAddr), + IpPort(IpPort), } impl NodeMap { @@ -112,8 +112,8 @@ impl NodeMap { self.inner.lock().receive_udp(udp_addr) } - pub(super) fn receive_relay(&self, relay_url: &RelayUrl, src: PublicKey) -> QuicMappedAddr { - self.inner.lock().receive_relay(relay_url, &src) + pub(super) fn receive_relay(&self, relay_url: &RelayUrl, src: NodeId) -> QuicMappedAddr { + self.inner.lock().receive_relay(relay_url, src) } pub(super) fn notify_ping_sent( @@ -124,20 +124,20 @@ impl NodeMap { purpose: DiscoPingPurpose, msg_sender: tokio::sync::mpsc::Sender, ) { - if let Some(ep) = self.inner.lock().get_mut(NodeStateKey::Idx(&id)) { + if let Some(ep) = self.inner.lock().get_mut(NodeStateKey::Idx(id)) { ep.ping_sent(dst, tx_id, purpose, msg_sender); } } pub(super) fn notify_ping_timeout(&self, id: usize, tx_id: stun::TransactionId) { - if let Some(ep) = self.inner.lock().get_mut(NodeStateKey::Idx(&id)) { + if let Some(ep) = self.inner.lock().get_mut(NodeStateKey::Idx(id)) { ep.ping_timeout(tx_id); } } pub(super) fn get_quic_mapped_addr_for_node_key( &self, - node_key: &PublicKey, + node_key: NodeId, ) -> Option { self.inner .lock() @@ -172,7 +172,7 @@ impl NodeMap { #[allow(clippy::type_complexity)] pub(super) fn get_send_addrs( &self, - addr: &QuicMappedAddr, + addr: QuicMappedAddr, have_ipv6: bool, ) -> Option<( PublicKey, @@ -223,16 +223,13 @@ impl NodeMap { /// /// Will return an error if there is not an entry in the [`NodeMap`] for /// the `public_key` - pub(super) fn conn_type_stream( - &self, - public_key: &PublicKey, - ) -> anyhow::Result { - self.inner.lock().conn_type_stream(public_key) + pub(super) fn conn_type_stream(&self, node_id: NodeId) -> anyhow::Result { + self.inner.lock().conn_type_stream(node_id) } /// Get the [`NodeInfo`]s for each endpoint - pub(super) fn node_info(&self, public_key: &PublicKey) -> Option { - self.inner.lock().node_info(public_key) + pub(super) fn node_info(&self, node_id: NodeId) -> Option { + self.inner.lock().node_info(node_id) } /// Saves the known node info to the given path, returning the number of nodes persisted. @@ -323,7 +320,7 @@ impl NodeMapInner { fn add_node_addr(&mut self, node_addr: NodeAddr) { let NodeAddr { node_id, info } = node_addr; - let node_state = self.get_or_insert_with(NodeStateKey::NodeId(&node_id), || Options { + let node_state = self.get_or_insert_with(NodeStateKey::NodeId(node_id), || Options { node_id, relay_url: info.relay_url.clone(), active: false, @@ -338,10 +335,10 @@ impl NodeMapInner { fn get_id(&self, id: NodeStateKey) -> Option { match id { - NodeStateKey::Idx(id) => Some(*id), - NodeStateKey::NodeId(node_key) => self.by_node_key.get(node_key).copied(), - NodeStateKey::QuicMappedAddr(addr) => self.by_quic_mapped_addr.get(addr).copied(), - NodeStateKey::IpPort(ipp) => self.by_ip_port.get(ipp).copied(), + NodeStateKey::Idx(id) => Some(id), + NodeStateKey::NodeId(node_key) => self.by_node_key.get(&node_key).copied(), + NodeStateKey::QuicMappedAddr(addr) => self.by_quic_mapped_addr.get(&addr).copied(), + NodeStateKey::IpPort(ipp) => self.by_ip_port.get(&ipp).copied(), } } @@ -373,7 +370,7 @@ impl NodeMapInner { /// Marks the node we believe to be at `ipp` as recently used. fn receive_udp(&mut self, udp_addr: SocketAddr) -> Option<(NodeId, QuicMappedAddr)> { let ip_port: IpPort = udp_addr.into(); - let Some(node_state) = self.get_mut(NodeStateKey::IpPort(&ip_port)) else { + let Some(node_state) = self.get_mut(NodeStateKey::IpPort(ip_port)) else { info!(src=%udp_addr, "receive_udp: no node_state found for addr, ignore"); return None; }; @@ -382,11 +379,11 @@ impl NodeMapInner { } #[instrument(skip_all, fields(src = %src.fmt_short()))] - fn receive_relay(&mut self, relay_url: &RelayUrl, src: &PublicKey) -> QuicMappedAddr { + fn receive_relay(&mut self, relay_url: &RelayUrl, src: NodeId) -> QuicMappedAddr { let node_state = self.get_or_insert_with(NodeStateKey::NodeId(src), || { trace!("packets from unknown node, insert into node map"); Options { - node_id: *src, + node_id: src, relay_url: Some(relay_url.clone()), active: true, } @@ -409,8 +406,8 @@ impl NodeMapInner { } /// Get the [`NodeInfo`]s for each endpoint - fn node_info(&self, public_key: &PublicKey) -> Option { - self.get(NodeStateKey::NodeId(public_key)) + fn node_info(&self, node_id: NodeId) -> Option { + self.get(NodeStateKey::NodeId(node_id)) .map(|ep| ep.info(Instant::now())) } @@ -423,18 +420,18 @@ impl NodeMapInner { /// /// Will return an error if there is not an entry in the [`NodeMap`] for /// the `public_key` - fn conn_type_stream(&self, public_key: &PublicKey) -> anyhow::Result { - match self.get(NodeStateKey::NodeId(public_key)) { + fn conn_type_stream(&self, node_id: NodeId) -> anyhow::Result { + match self.get(NodeStateKey::NodeId(node_id)) { Some(ep) => Ok(ConnectionTypeStream { initial: Some(ep.conn_type()), inner: ep.conn_type_stream(), }), - None => anyhow::bail!("No endpoint for {public_key:?} found"), + None => anyhow::bail!("No endpoint for {node_id:?} found"), } } - fn handle_pong(&mut self, sender: PublicKey, src: &DiscoMessageSource, pong: Pong) { - if let Some(ns) = self.get_mut(NodeStateKey::NodeId(&sender)).as_mut() { + fn handle_pong(&mut self, sender: NodeId, src: &DiscoMessageSource, pong: Pong) { + if let Some(ns) = self.get_mut(NodeStateKey::NodeId(sender)).as_mut() { let insert = ns.handle_pong(&pong, src.into()); if let Some((src, key)) = insert { self.set_node_key_for_ip_port(src, &key); @@ -446,8 +443,8 @@ impl NodeMapInner { } #[must_use = "actions must be handled"] - fn handle_call_me_maybe(&mut self, sender: PublicKey, cm: CallMeMaybe) -> Vec { - let ns_id = NodeStateKey::NodeId(&sender); + fn handle_call_me_maybe(&mut self, sender: NodeId, cm: CallMeMaybe) -> Vec { + let ns_id = NodeStateKey::NodeId(sender); if let Some(id) = self.get_id(ns_id.clone()) { for number in &cm.my_numbers { // ensure the new addrs are known @@ -468,13 +465,8 @@ impl NodeMapInner { } } - fn handle_ping( - &mut self, - sender: PublicKey, - src: SendAddr, - tx_id: TransactionId, - ) -> PingHandled { - let node_state = self.get_or_insert_with(NodeStateKey::NodeId(&sender), || { + fn handle_ping(&mut self, sender: NodeId, src: SendAddr, tx_id: TransactionId) -> PingHandled { + let node_state = self.get_or_insert_with(NodeStateKey::NodeId(sender), || { debug!("received ping: node unknown, add to node map"); Options { node_id: sender, @@ -815,7 +807,7 @@ mod tests { node_map .inner .lock() - .get(NodeStateKey::NodeId(&active_node)) + .get(NodeStateKey::NodeId(active_node)) .expect("should not be pruned"); } } diff --git a/iroh-net/src/magicsock/node_map/node_state.rs b/iroh-net/src/magicsock/node_map/node_state.rs index c72b1118bb..37410b9af8 100644 --- a/iroh-net/src/magicsock/node_map/node_state.rs +++ b/iroh-net/src/magicsock/node_map/node_state.rs @@ -962,7 +962,7 @@ impl NodeState { .reconfirm_if_used(addr.into(), Source::Udp, now); } - pub(super) fn receive_relay(&mut self, url: &RelayUrl, _src: &PublicKey, now: Instant) { + pub(super) fn receive_relay(&mut self, url: &RelayUrl, _src: NodeId, now: Instant) { match self.relay_url.as_mut() { Some((current_home, state)) if current_home == url => { // We received on the expected url. update state. From 53dfed146717febb98af124bf23adcfcdc51a3a7 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Mon, 17 Jun 2024 11:04:03 +0200 Subject: [PATCH 5/9] docs(iroh-net): Update NodeAddr docs (#2365) ## Description This follows https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text and updates the doc comments in an attempt to be more user-friendly. ## Breaking Changes ## Notes & open questions ## Change checklist - [x] Self-review. - [x] Documentation updates if relevant. - ~~[ ] Tests if relevant.~~ - ~~[ ] All breaking changes documented.~~ --- iroh-base/src/key.rs | 4 ++ iroh-base/src/node_addr.rs | 117 ++++++++++++++++++++++++++----------- 2 files changed, 86 insertions(+), 35 deletions(-) diff --git a/iroh-base/src/key.rs b/iroh-base/src/key.rs index a08e52f629..8032d2de04 100644 --- a/iroh-base/src/key.rs +++ b/iroh-base/src/key.rs @@ -94,6 +94,10 @@ pub struct PublicKey([u8; 32]); /// The identifier for a node in the (iroh) network. /// +/// Each node in iroh has a unique identifier created as a cryptographic key. This can be +/// used to globally identify a node. Since it is also a cryptographic key it is also the +/// mechanism by which all traffic is always encrypted for a specific node only. +/// /// This is equivalent to [`PublicKey`]. By convention we will (or should) use `PublicKey` /// as type name when performing cryptographic operations, but use `NodeId` when referencing /// a node. E.g.: diff --git a/iroh-base/src/node_addr.rs b/iroh-base/src/node_addr.rs index b926b3c2fc..505be96b90 100644 --- a/iroh-base/src/node_addr.rs +++ b/iroh-base/src/node_addr.rs @@ -1,3 +1,11 @@ +//! Addressing for iroh nodes. +//! +//! This module contains some common addressing types for iroh. A node is uniquely +//! identified by the [`NodeId`] but that does not make it addressable on the network layer. +//! For this the addition of a [`RelayUrl`] and/or direct addresses are required. +//! +//! The primary way of addressing a node is by using the [`NodeAddr`]. + use std::{collections::BTreeSet, fmt, net::SocketAddr, ops::Deref, str::FromStr}; use anyhow::Context; @@ -6,17 +14,40 @@ use url::Url; use crate::key::{NodeId, PublicKey}; -/// A peer and it's addressing information. +/// Network-level addressing information for an iroh-net node. +/// +/// This combines a node's identifier with network-level addressing information of how to +/// contact the node. +/// +/// To establish a network connection to a node both the [`NodeId`] and one or more network +/// paths are needed. The network paths can come from various sources: +/// +/// - A [discovery] service which can provide routing information for a given [`NodeId`]. +/// +/// - A [`RelayUrl`] of the node's [home relay], this allows establishing the connection via +/// the Relay server and is very reliable. +/// +/// - One or more *direct addresses* on which the node might be reachable. Depending on the +/// network location of both nodes it might not be possible to establish a direct +/// connection without the help of a [Relay server]. +/// +/// This structure will always contain the required [`NodeId`] and will contain an optional +/// number of network-level addressing information. It is a generic addressing type used +/// whenever a connection to other nodes needs to be established. +/// +/// [discovery]: https://docs.rs/iroh_net/*/iroh_net/index.html#node-discovery +/// [home relay]: https://docs.rs/iroh_net/*/iroh_net/relay/index.html +/// [Relay server]: https://docs.rs/iroh_net/*/iroh_net/index.html#relay-servers #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct NodeAddr { - /// The node's public key. - pub node_id: PublicKey, + /// The node's identifier. + pub node_id: NodeId, /// Addressing information to connect to [`Self::node_id`]. pub info: AddrInfo, } impl NodeAddr { - /// Create a new [`NodeAddr`] with empty [`AddrInfo`]. + /// Creates a new [`NodeAddr`] with empty [`AddrInfo`]. pub fn new(node_id: PublicKey) -> Self { NodeAddr { node_id, @@ -24,13 +55,13 @@ impl NodeAddr { } } - /// Add a relay url to the peer's [`AddrInfo`]. + /// Adds a relay url to the node's [`AddrInfo`]. pub fn with_relay_url(mut self, relay_url: RelayUrl) -> Self { self.info.relay_url = Some(relay_url); self } - /// Add the given direct addresses to the peer's [`AddrInfo`]. + /// Adds the given direct addresses to the peer's [`AddrInfo`]. pub fn with_direct_addresses( mut self, addresses: impl IntoIterator, @@ -39,17 +70,38 @@ impl NodeAddr { self } + /// Creates a new [`NodeAddr`] from its parts. + pub fn from_parts( + node_id: PublicKey, + relay_url: Option, + direct_addresses: Vec, + ) -> Self { + Self { + node_id, + info: AddrInfo { + relay_url, + direct_addresses: direct_addresses.into_iter().collect(), + }, + } + } + /// Apply the options to `self`. + /// + /// This is use to more tightly control the information stored in a [`NodeAddr`] + /// received from another API. E.g. to ensure a [discovery] service is used the + /// `AddrInfoOptions::Id`] option could be used to remove all other addressing details. + /// + /// [discovery]: https://docs.rs/iroh_net/*/iroh_net/index.html#node-discovery pub fn apply_options(&mut self, opts: AddrInfoOptions) { self.info.apply_options(opts); } - /// Get the direct addresses of this peer. + /// Returns the direct addresses of this peer. pub fn direct_addresses(&self) -> impl Iterator { self.info.direct_addresses.iter() } - /// Get the relay url of this peer. + /// Returns the relay url of this peer. pub fn relay_url(&self) -> Option<&RelayUrl> { self.info.relay_url.as_ref() } @@ -74,22 +126,34 @@ impl From for NodeAddr { } } -/// Addressing information to connect to a peer. +/// Network paths to contact an iroh-net node. +/// +/// This contains zero or more network paths to establish a connection to an iroh-net node. +/// Unless a [discovery service] is used at least one path is required to connect to an +/// other node, see [`NodeAddr`] for details. +/// +/// [discovery]: https://docs.rs/iroh_net/*/iroh_net/index.html#node-discovery #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct AddrInfo { - /// The peer's home relay url. + /// The node's home relay url. pub relay_url: Option, /// Socket addresses where the peer might be reached directly. pub direct_addresses: BTreeSet, } impl AddrInfo { - /// Return whether this addressing information is empty. + /// Returns whether this addressing information is empty. pub fn is_empty(&self) -> bool { self.relay_url.is_none() && self.direct_addresses.is_empty() } - /// Apply the options to `self`. + /// Applies the options to `self`. + /// + /// This is use to more tightly control the information stored in ab [`AddrInfo`] + /// received from another API. E.g. to ensure a [discovery] service is used the + /// `AddrInfoOptions::Id`] option could be used to remove all other addressing details. + /// + /// [discovery]: https://docs.rs/iroh_net/*/iroh_net/index.html#node-discovery pub fn apply_options(&mut self, opts: AddrInfoOptions) { match opts { AddrInfoOptions::Id => { @@ -109,24 +173,7 @@ impl AddrInfo { } } -impl NodeAddr { - /// Create a new [`NodeAddr`] from its parts. - pub fn from_parts( - node_id: PublicKey, - relay_url: Option, - direct_addresses: Vec, - ) -> Self { - Self { - node_id, - info: AddrInfo { - relay_url, - direct_addresses: direct_addresses.into_iter().collect(), - }, - } - } -} - -/// Options to configure what is included in a `NodeAddr`. +/// Options to configure what is included in a [`NodeAddr`] and [`AddrInfo`]. #[derive( Copy, Clone, @@ -145,11 +192,11 @@ pub enum AddrInfoOptions { /// This usually means that iroh-dns discovery is used to find address information. #[default] Id, - /// Include both the relay URL and the direct addresses. + /// Includes both the relay URL and the direct addresses. RelayAndAddresses, - /// Only include the relay URL. + /// Only includes the relay URL. Relay, - /// Only include the direct addresses. + /// Only includes the direct addresses. Addresses, } @@ -186,7 +233,7 @@ impl From for RelayUrl { } } -/// This is a convenience only to directly parse strings. +/// Support for parsing strings directly. /// /// If you need more control over the error first create a [`Url`] and use [`RelayUrl::from`] /// instead. @@ -205,7 +252,7 @@ impl From for Url { } } -/// Dereference to the wrapped [`Url`]. +/// Dereferences to the wrapped [`Url`]. /// /// Note that [`DerefMut`] is not implemented on purpose, so this type has more flexibility /// to change the inner later. From ac72938d6e558d5561ba0433c404e4db361ea010 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Mon, 17 Jun 2024 14:55:06 +0200 Subject: [PATCH 6/9] chore: deny openssl (#2372) ## Description Update cargo-deny to avoid openssl neaking in. ## Breaking Changes ## Notes & open questions ## Change checklist - [x] Self-review. - ~~[ ] Documentation updates if relevant.~~ - ~~[ ] Tests if relevant.~~ - ~~[ ] All breaking changes documented.~~ --- deny.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deny.toml b/deny.toml index f65fd56cb2..12a7d569e0 100644 --- a/deny.toml +++ b/deny.toml @@ -1,5 +1,9 @@ [bans] multiple-versions = "allow" +deny = [ + "openssl", + "native-tls", +] [licenses] allow = [ From be3e16e7550f5140adce319e40bc14647ed318ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Klaehn?= Date: Mon, 17 Jun 2024 20:54:46 +0300 Subject: [PATCH 7/9] refactor(iroh)!: Use ref-cast instead of fields to get the subsystem clients (#2374) ## Description This is part 2 of replacing the fields in the iroh client with accessors and avoiding having multiple copies of the rpc client handle. ## Breaking Changes Removes the fields of iroh client. They were already marked as deprecated in the last release. ## Notes & open questions ## Change checklist - [x] Self-review. - [x] Documentation updates if relevant. - [ ] ~~Tests if relevant.~~ - [x] All breaking changes documented. --- Cargo.lock | 1 + iroh/Cargo.toml | 1 + iroh/src/client.rs | 43 +++++++++----------------------------- iroh/src/client/authors.rs | 4 +++- iroh/src/client/blobs.rs | 4 +++- iroh/src/client/docs.rs | 4 +++- iroh/src/client/tags.rs | 4 +++- 7 files changed, 24 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a63e49d931..c147fc3047 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2444,6 +2444,7 @@ dependencies = [ "quic-rpc", "rand", "rand_chacha", + "ref-cast", "regex", "serde", "serde_json", diff --git a/iroh/Cargo.toml b/iroh/Cargo.toml index aac6f9a645..8b19019e91 100644 --- a/iroh/Cargo.toml +++ b/iroh/Cargo.toml @@ -53,6 +53,7 @@ walkdir = "2" # Examples clap = { version = "4", features = ["derive"], optional = true } indicatif = { version = "0.17", features = ["tokio"], optional = true } +ref-cast = "1.0.23" [features] default = ["metrics", "fs-store"] diff --git a/iroh/src/client.rs b/iroh/src/client.rs index 66eb926a26..e158bfb355 100644 --- a/iroh/src/client.rs +++ b/iroh/src/client.rs @@ -2,6 +2,7 @@ use futures_lite::{Stream, StreamExt}; use quic_rpc::{RpcClient, ServiceConnection}; +use ref_cast::RefCast; #[doc(inline)] pub use crate::rpc_protocol::RpcService; @@ -25,19 +26,6 @@ mod node; /// Iroh client. #[derive(Debug, Clone)] pub struct Iroh { - /// Client for blobs operations. - #[deprecated(note = "Use `blobs` method instead", since = "0.18.0")] - pub blobs: blobs::Client, - /// Client for docs operations. - #[deprecated(note = "Use `docs` method instead", since = "0.18.0")] - pub docs: docs::Client, - /// Client for author operations. - #[deprecated(note = "Use `authors` method instead", since = "0.18.0")] - pub authors: authors::Client, - /// Client for tags operations. - #[deprecated(note = "Use `tags` method instead", since = "0.18.0")] - pub tags: tags::Client, - rpc: RpcClient, } @@ -47,38 +35,27 @@ where { /// Create a new high-level client to a Iroh node from the low-level RPC client. pub fn new(rpc: RpcClient) -> Self { - #[allow(deprecated)] - Self { - blobs: blobs::Client { rpc: rpc.clone() }, - docs: docs::Client { rpc: rpc.clone() }, - authors: authors::Client { rpc: rpc.clone() }, - tags: tags::Client { rpc: rpc.clone() }, - rpc, - } + Self { rpc } } - /// Client for blobs operations. + /// Blobs client pub fn blobs(&self) -> &blobs::Client { - #[allow(deprecated)] - &self.blobs + blobs::Client::ref_cast(&self.rpc) } - /// Client for docs operations. + /// Docs client pub fn docs(&self) -> &docs::Client { - #[allow(deprecated)] - &self.docs + docs::Client::ref_cast(&self.rpc) } - /// Client for author operations. + /// Authors client pub fn authors(&self) -> &authors::Client { - #[allow(deprecated)] - &self.authors + authors::Client::ref_cast(&self.rpc) } - /// Client for tags operations. + /// Tags client pub fn tags(&self) -> &tags::Client { - #[allow(deprecated)] - &self.tags + tags::Client::ref_cast(&self.rpc) } } diff --git a/iroh/src/client/authors.rs b/iroh/src/client/authors.rs index e6bddbb494..bf642fc3d9 100644 --- a/iroh/src/client/authors.rs +++ b/iroh/src/client/authors.rs @@ -4,6 +4,7 @@ use anyhow::Result; use futures_lite::{stream::StreamExt, Stream}; use iroh_docs::{Author, AuthorId}; use quic_rpc::{RpcClient, ServiceConnection}; +use ref_cast::RefCast; use crate::rpc_protocol::{ AuthorCreateRequest, AuthorDeleteRequest, AuthorExportRequest, AuthorGetDefaultRequest, @@ -13,7 +14,8 @@ use crate::rpc_protocol::{ use super::flatten; /// Iroh authors client. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, RefCast)] +#[repr(transparent)] pub struct Client { pub(super) rpc: RpcClient, } diff --git a/iroh/src/client/blobs.rs b/iroh/src/client/blobs.rs index b887edf9fe..53245acd3d 100644 --- a/iroh/src/client/blobs.rs +++ b/iroh/src/client/blobs.rs @@ -25,6 +25,7 @@ use iroh_blobs::{ use iroh_net::NodeAddr; use portable_atomic::{AtomicU64, Ordering}; use quic_rpc::{client::BoxStreamSync, RpcClient, ServiceConnection}; +use ref_cast::RefCast; use serde::{Deserialize, Serialize}; use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf}; use tokio_util::io::{ReaderStream, StreamReader}; @@ -40,7 +41,8 @@ use crate::rpc_protocol::{ use super::{flatten, tags, Iroh}; /// Iroh blobs client. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, RefCast)] +#[repr(transparent)] pub struct Client { pub(super) rpc: RpcClient, } diff --git a/iroh/src/client/docs.rs b/iroh/src/client/docs.rs index 77e7324411..1b900a9463 100644 --- a/iroh/src/client/docs.rs +++ b/iroh/src/client/docs.rs @@ -22,6 +22,7 @@ use iroh_docs::{ use iroh_net::NodeAddr; use portable_atomic::{AtomicBool, Ordering}; use quic_rpc::{message::RpcMsg, RpcClient, ServiceConnection}; +use ref_cast::RefCast; use serde::{Deserialize, Serialize}; use crate::rpc_protocol::{ @@ -38,7 +39,8 @@ pub use iroh_docs::engine::{Origin, SyncEvent, SyncReason}; use super::{blobs, flatten}; /// Iroh docs client. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, RefCast)] +#[repr(transparent)] pub struct Client { pub(super) rpc: RpcClient, } diff --git a/iroh/src/client/tags.rs b/iroh/src/client/tags.rs index c25111e3e3..9c3ef34f12 100644 --- a/iroh/src/client/tags.rs +++ b/iroh/src/client/tags.rs @@ -4,12 +4,14 @@ use anyhow::Result; use futures_lite::{Stream, StreamExt}; use iroh_blobs::{BlobFormat, Hash, Tag}; use quic_rpc::{RpcClient, ServiceConnection}; +use ref_cast::RefCast; use serde::{Deserialize, Serialize}; use crate::rpc_protocol::{DeleteTagRequest, ListTagsRequest, RpcService}; /// Iroh tags client. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, RefCast)] +#[repr(transparent)] pub struct Client { pub(super) rpc: RpcClient, } From ea7e654f1f7d4f37f8e12c4b79594a541dd823f8 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Mon, 17 Jun 2024 23:14:24 +0200 Subject: [PATCH 8/9] docs(iroh-net): A few small fixes from PR review (#2375) ## Description Some minor typos missed earlier. ## Breaking Changes ## Notes & open questions Followup from https://github.com/n0-computer/iroh/pull/2365 ## Change checklist - [x] Self-review. - [x] Documentation updates if relevant. - ~~[ ] Tests if relevant.~~ - ~~[ ] All breaking changes documented.~~ --- iroh-base/src/node_addr.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iroh-base/src/node_addr.rs b/iroh-base/src/node_addr.rs index 505be96b90..a2b7c39f33 100644 --- a/iroh-base/src/node_addr.rs +++ b/iroh-base/src/node_addr.rs @@ -85,9 +85,9 @@ impl NodeAddr { } } - /// Apply the options to `self`. + /// Applies the options to `self`. /// - /// This is use to more tightly control the information stored in a [`NodeAddr`] + /// This is used to more tightly control the information stored in a [`NodeAddr`] /// received from another API. E.g. to ensure a [discovery] service is used the /// `AddrInfoOptions::Id`] option could be used to remove all other addressing details. /// @@ -149,7 +149,7 @@ impl AddrInfo { /// Applies the options to `self`. /// - /// This is use to more tightly control the information stored in ab [`AddrInfo`] + /// This is used to more tightly control the information stored in ab [`AddrInfo`] /// received from another API. E.g. to ensure a [discovery] service is used the /// `AddrInfoOptions::Id`] option could be used to remove all other addressing details. /// From a5e59397f2f3d5e5df925b7a192570750cfa59ae Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Tue, 18 Jun 2024 01:43:45 +0200 Subject: [PATCH 9/9] refactor(iroh-net)!: Rename Endpoint::local_addr to bound_sockets (#2366) ## Description This renames Endpoint::local_addr to Endpoint::bound_sockets. We have a lot of different meanings for "addr" and also don't really have a notion of "local_" prefix, since the endpoint is not 1:1 connected with a peer. The "local_" naming comes from connected sockets which have local_addr and peer_addr, which is not applicable for the Endpoint. ## Breaking Changes - Endpoint::local_addr -> Endpoint::bound_sockets ## Notes & open questions ## Change checklist - [x] Self-review. - [x] Documentation updates if relevant. - ~~[ ] Tests if relevant.~~ - [x] All breaking changes documented. --- iroh-net/bench/src/iroh.rs | 2 +- iroh-net/src/endpoint.rs | 6 +++--- iroh/src/node.rs | 2 +- iroh/src/node/builder.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iroh-net/bench/src/iroh.rs b/iroh-net/bench/src/iroh.rs index a359be35b2..5a85952b7f 100644 --- a/iroh-net/bench/src/iroh.rs +++ b/iroh-net/bench/src/iroh.rs @@ -29,7 +29,7 @@ pub fn server_endpoint(rt: &tokio::runtime::Runtime, opt: &Opt) -> (NodeAddr, En .bind(0) .await .unwrap(); - let addr = ep.local_addr(); + let addr = ep.bound_sockets(); let addr = SocketAddr::new("127.0.0.1".parse().unwrap(), addr.0.port()); let addr = NodeAddr::new(ep.node_id()).with_direct_addresses([addr]); (addr, ep) diff --git a/iroh-net/src/endpoint.rs b/iroh-net/src/endpoint.rs index 6b98bd4f45..760809c1b4 100644 --- a/iroh-net/src/endpoint.rs +++ b/iroh-net/src/endpoint.rs @@ -650,7 +650,7 @@ impl Endpoint { /// /// The [`Endpoint`] always binds on an IPv4 address and also tries to bind on an IPv6 /// address if available. - pub fn local_addr(&self) -> (SocketAddr, Option) { + pub fn bound_sockets(&self) -> (SocketAddr, Option) { self.msock.local_addr() } @@ -1246,7 +1246,7 @@ mod tests { .bind(0) .await .unwrap(); - let eps = ep.local_addr(); + let eps = ep.bound_sockets(); info!(me = %ep.node_id().fmt_short(), ipv4=%eps.0, ipv6=?eps.1, "server bound"); for i in 0..n_clients { let now = Instant::now(); @@ -1291,7 +1291,7 @@ mod tests { .bind(0) .await .unwrap(); - let eps = ep.local_addr(); + let eps = ep.bound_sockets(); info!(me = %ep.node_id().fmt_short(), ipv4=%eps.0, ipv6=?eps.1, "client bound"); let node_addr = NodeAddr::new(server_node_id).with_relay_url(relay_url); info!(to = ?node_addr, "client connecting"); diff --git a/iroh/src/node.rs b/iroh/src/node.rs index 4290943494..e074efa7b1 100644 --- a/iroh/src/node.rs +++ b/iroh/src/node.rs @@ -107,7 +107,7 @@ impl Node { /// can contact the node consider using [`Node::local_endpoint_addresses`]. However the /// port will always be the concrete port. pub fn local_address(&self) -> Vec { - let (v4, v6) = self.inner.endpoint.local_addr(); + let (v4, v6) = self.inner.endpoint.bound_sockets(); let mut addrs = vec![v4]; if let Some(v6) = v6 { addrs.push(v6); diff --git a/iroh/src/node/builder.rs b/iroh/src/node/builder.rs index 59782b2010..6209883388 100644 --- a/iroh/src/node/builder.rs +++ b/iroh/src/node/builder.rs @@ -552,7 +552,7 @@ where ) { let rpc = RpcServer::new(rpc); let internal_rpc = RpcServer::new(internal_rpc); - let (ipv4, ipv6) = server.local_addr(); + let (ipv4, ipv6) = server.bound_sockets(); debug!( "listening at: {}{}", ipv4,