From bbf4869992182e22f1502b89c07618a91b7641e6 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Wed, 29 Mar 2023 09:36:58 +0200 Subject: [PATCH] ref: Clean up public API regarding bound/local/listening addresses (#891) This primarily renames .available_addresses() to .listen_addresses() and .listen_addr() to .local_address(). this makes .local_address() consistent with e.g. quinn's API and avoids the confusion between available on the machine vs uses by the provider. --- src/lib.rs | 12 ++++++------ src/main.rs | 4 ++-- src/net.rs | 7 +++++-- src/provider/mod.rs | 32 +++++++++++++++++++------------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4e2dbd2999..324feaf2a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,7 +161,7 @@ mod tests { provider.auth_token(), expect_hash.into(), expect_name.clone(), - provider.listen_addr(), + provider.local_address(), provider.peer_id(), content.to_vec(), ))); @@ -250,7 +250,7 @@ mod tests { }); let opts = get::Options { - addr: dbg!(provider.listen_addr()), + addr: dbg!(provider.local_address()), peer_id: Some(provider.peer_id()), keylog: true, }; @@ -346,7 +346,7 @@ mod tests { .spawn() .unwrap(); let auth_token = provider.auth_token(); - let provider_addr = provider.listen_addr(); + let provider_addr = provider.local_address(); // This tasks closes the connection on the provider side as soon as the transfer // completes. @@ -419,7 +419,7 @@ mod tests { .bind_addr("127.0.0.1:0".parse().unwrap()) .spawn()?; let auth_token = provider.auth_token(); - let provider_addr = provider.listen_addr(); + let provider_addr = provider.local_address(); let timeout = tokio::time::timeout( std::time::Duration::from_secs(10), @@ -466,7 +466,7 @@ mod tests { } }; let auth_token = provider.auth_token(); - let addr = provider.listen_addr(); + let addr = provider.local_address(); let peer_id = Some(provider.peer_id()); tokio::time::timeout( Duration::from_secs(10), @@ -500,7 +500,7 @@ mod tests { .spawn() .unwrap(); let _drop_guard = provider.cancel_token().drop_guard(); - let ticket = provider.ticket(hash); + let ticket = provider.ticket(hash).unwrap(); let mut on_connected = false; let mut on_collection = false; let mut on_blob = false; diff --git a/src/main.rs b/src/main.rs index 07f2ce7cbb..1646e7e53d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -534,7 +534,7 @@ async fn main_impl() -> Result<()> { ) .await?; let controller = provider.controller(); - let mut ticket = provider.ticket(Hash::from([0u8; 32])); + let mut ticket = provider.ticket(Hash::from([0u8; 32]))?; // task that will add data to the provider, either from a file or from stdin let fut = tokio::spawn(async move { @@ -694,7 +694,7 @@ async fn provide( builder.keypair(keypair).spawn()? }; - println!("Listening address: {}", provider.listen_addr()); + println!("Listening address: {}", provider.local_address()); println!("PeerID: {}", provider.peer_id()); println!("Auth token: {}", provider.auth_token()); println!(); diff --git a/src/net.rs b/src/net.rs index 7439667b8c..1fac419cf3 100644 --- a/src/net.rs +++ b/src/net.rs @@ -2,6 +2,8 @@ use std::net::{IpAddr, Ipv6Addr, SocketAddr}; +use anyhow::{ensure, Result}; + const IFF_UP: u32 = 0x1; const IFF_LOOPBACK: u32 = 0x8; @@ -147,7 +149,7 @@ const fn is_unicast_link_local(addr: Ipv6Addr) -> bool { } /// Given a listen/bind address, finds all the local addresses for that address family. -pub fn find_local_addresses(listen_addr: SocketAddr) -> Vec { +pub(crate) fn find_local_addresses(listen_addr: SocketAddr) -> Result> { let listen_ip = listen_addr.ip(); let listen_port = listen_addr.port(); let addrs: Vec = match listen_ip.is_unspecified() { @@ -168,7 +170,8 @@ pub fn find_local_addresses(listen_addr: SocketAddr) -> Vec { } false => vec![listen_addr], }; - addrs + ensure!(!addrs.is_empty(), "No local addresses found"); + Ok(addrs) } #[cfg(test)] diff --git a/src/provider/mod.rs b/src/provider/mod.rs index 0f477a0032..a33eba606b 100644 --- a/src/provider/mod.rs +++ b/src/provider/mod.rs @@ -379,11 +379,22 @@ impl Provider { Builder::with_db(db) } - /// Returns the address on which the server is listening for connections. - pub fn listen_addr(&self) -> SocketAddr { + /// The address on which the provider socket is bound. + /// + /// Note that this could be an unspecified address, if you need an address on which you + /// can contact the provider consider using [`Provider::listen_addresses`]. However the + /// port will always be the concrete port. + pub fn local_address(&self) -> SocketAddr { self.inner.listen_addr } + /// Returns all addresses on which the provider is reachable. + /// + /// This will never be empty. + pub fn listen_addresses(&self) -> Result> { + find_local_addresses(self.inner.listen_addr) + } + /// Returns the [`PeerId`] of the provider. pub fn peer_id(&self) -> PeerId { self.inner.keypair.public().into() @@ -410,20 +421,15 @@ impl Provider { /// Return a single token containing everything needed to get a hash. /// /// See [`Ticket`] for more details of how it can be used. - pub fn ticket(&self, hash: Hash) -> Ticket { + pub fn ticket(&self, hash: Hash) -> Result { // TODO: Verify that the hash exists in the db? - let addrs = find_local_addresses(self.inner.listen_addr); - Ticket { + let addrs = self.listen_addresses()?; + Ok(Ticket { hash, peer: self.peer_id(), addrs, token: self.inner.auth_token, - } - } - - /// Returns all available addresses on the local machine. - pub fn available_addresses(&self) -> Vec { - find_local_addresses(self.inner.listen_addr) + }) } /// Aborts the provider. @@ -551,7 +557,7 @@ impl RpcHandler { } async fn addrs(self, _: AddrsRequest) -> AddrsResponse { AddrsResponse { - addrs: find_local_addresses(self.inner.listen_addr), + addrs: find_local_addresses(self.inner.listen_addr).unwrap_or_default(), } } async fn shutdown(self, request: ShutdownRequest) { @@ -1383,7 +1389,7 @@ mod tests { .spawn() .unwrap(); let _drop_guard = provider.cancel_token().drop_guard(); - let ticket = provider.ticket(hash); + let ticket = provider.ticket(hash).unwrap(); println!("addrs: {:?}", ticket.addrs); assert!(!ticket.addrs.is_empty()); }