Skip to content

Commit

Permalink
change(net): cleanups and renames
Browse files Browse the repository at this point in the history
* move dial_peer onto MagicEndpoint
* some renames for clarity
* remove iroh_net::client module
  • Loading branch information
Frando committed Jun 29, 2023
1 parent 4bc150d commit 6d83ceb
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 105 deletions.
12 changes: 6 additions & 6 deletions iroh-bytes/src/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ pub async fn run_ticket(
keylog: bool,
derp_map: Option<DerpMap>,
) -> Result<get_response_machine::AtInitial> {
let connection = iroh_net::client::dial_peer(
ticket.addrs(),
let connection = iroh_net::MagicEndpoint::dial_peer(
ticket.peer(),
&crate::P2P_ALPN,
keylog,
ticket.addrs(),
derp_map,
keylog,
)
.await?;

Expand Down Expand Up @@ -624,12 +624,12 @@ pub async fn run(
request: AnyGetRequest,
opts: Options,
) -> anyhow::Result<get_response_machine::AtInitial> {
let connection = iroh_net::client::dial_peer(
&opts.addrs,
let connection = iroh_net::MagicEndpoint::dial_peer(
opts.peer_id,
&crate::P2P_ALPN,
opts.keylog,
&opts.addrs,
opts.derp_map,
opts.keylog,
)
.await?;
Ok(run_connection(connection, request))
Expand Down
3 changes: 2 additions & 1 deletion iroh-net/examples/magic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use clap::Parser;
use ed25519_dalek::SigningKey as SecretKey;
use iroh_net::{
defaults::default_derp_map,
endpoint::{accept_conn, MagicEndpoint},
hp::derp::{DerpMap, UseIpv4, UseIpv6},
magic_endpoint::accept_conn,
tls::{Keypair, PeerId},
MagicEndpoint,
};
use tracing::{debug, info};
use url::Url;
Expand Down
58 changes: 0 additions & 58 deletions iroh-net/src/client.rs

This file was deleted.

2 changes: 1 addition & 1 deletion iroh-net/src/hp/magicsock/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2442,7 +2442,7 @@ pub(crate) mod tests {

use super::*;
use crate::{
endpoint::MagicEndpoint,
MagicEndpoint,
hp::{
derp::{DerpNode, DerpRegion, UseIpv4, UseIpv6},
stun,
Expand Down
5 changes: 3 additions & 2 deletions iroh-net/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#![recursion_limit = "256"]

pub mod client;
pub mod defaults;
pub mod endpoint;
pub mod magic_endpoint;
pub mod hp;
pub mod net;
pub mod tls;
pub mod util;

pub use magic_endpoint::MagicEndpoint;
82 changes: 52 additions & 30 deletions iroh-net/src/endpoint.rs → iroh-net/src/magic_endpoint.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{
net::SocketAddr,
net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
sync::{Arc, Mutex},
time::Duration,
};
Expand Down Expand Up @@ -73,7 +73,7 @@ impl MagicEndpointBuilder {
self
}

/// Optionally provides a func to be called when endpoints change.
/// Optionally set a callback function to be called when endpoints change.
#[allow(clippy::type_complexity)]
pub fn on_endpoints(
mut self,
Expand All @@ -83,13 +83,13 @@ impl MagicEndpointBuilder {
self
}

/// Optionally provides a func to be called when a connection is made to a DERP server.
/// Optionally set a callback funcion to be called when a connection is made to a DERP server.
pub fn on_derp_active(mut self, on_derp_active: Box<dyn Fn() + Send + Sync + 'static>) -> Self {
self.callbacks.on_derp_active = Some(on_derp_active);
self
}

/// A callback that provides a `cfg::NetInfo` when discovered network conditions change.
/// Optionally set a callback function that provides a [cfg::NetInfo] when discovered network conditions change.
pub fn on_net_info(
mut self,
on_net_info: Box<dyn Fn(cfg::NetInfo) + Send + Sync + 'static>,
Expand All @@ -99,6 +99,11 @@ impl MagicEndpointBuilder {
}

/// Bind the magic endpoint on the specified socket address.
///
/// The *bind_addr* is the address that should be bound locally. Even though this is an
/// outgoing connection a socket must be bound and this is explicit. The main choice to
/// make here is the address family: IPv4 or IPv6. Otherwise you normally bind to the
/// `UNSPECIFIED` address on port `0` thus allowing the kernel to do the right thing.
pub async fn bind(self, bind_addr: SocketAddr) -> anyhow::Result<MagicEndpoint> {
let keypair = self.keypair.unwrap_or_else(Keypair::generate);
let mut server_config = make_server_config(
Expand Down Expand Up @@ -149,26 +154,38 @@ impl MagicEndpoint {
MagicEndpointBuilder::default()
}

/// Create a quinn endpoint backed by a magicsock.
///
/// The *bind_addr* is the address that should be bound locally. Even though this is an
/// outgoing connection a socket must be bound and this is explicit. The main choice to
/// make here is the address family: IPv4 or IPv6. Otherwise you normally bind to the
/// `UNSPECIFIED` address on port `0` thus allowing the kernel to do the right thing.
///
/// If *peer_id* is present it will verify during the TLS connection setup that the remote
/// connected to has the required [`PeerId`], otherwise this will connect to any peer.
/// Connect to a remote endpoint, creating an endpoint on the fly.
///
/// The *alpn_protocols* are the list of Application-Layer Protocol Neotiation identifiers
/// you are happy to accept.
///
/// If *keylog* is `true` and the KEYLOGFILE environment variable is present it will be
/// considered a filename to which the TLS pre-master keys are logged. This can be useful
/// to be able to decrypt captured traffic for debugging purposes.
/// The PeerId and the ALPN protocol are required. If you happen to know dialable addresses of
/// the remote endpoint, they can be specified and will be added to the endpoint's peer map.
/// If no addresses are specified, the endpoint will try to dial the peer through the
/// configured DERP servers.
pub async fn dial_peer(
peer_id: PeerId,
alpn_protocol: &[u8],
known_addrs: &[SocketAddr],
derp_map: Option<DerpMap>,
keylog: bool,
) -> anyhow::Result<quinn::Connection> {
let bind_addr = if known_addrs.iter().any(|addr| addr.ip().is_ipv6()) {
SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0).into()
} else {
SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0).into()
};
let endpoint =
MagicEndpoint::bind(Keypair::generate(), bind_addr, None, derp_map, None, keylog)
.await?;
endpoint
.connect(peer_id, alpn_protocol, known_addrs)
.await
.context("failed to connect to provider")
}

/// Create a quinn endpoint backed by a magicsock.
///
/// Finally the *derp_map* specifies the DERP servers that can be used to establish this
/// connection.
pub(crate) async fn bind(
/// This is for internal use, the public interface is the [MagicEndpointBuilder] obtained from
/// [Self::builder]. See the methods on the builder for documentation of the parameters.
async fn bind(
keypair: Keypair,
bind_addr: SocketAddr,
server_config: Option<quinn::ServerConfig>,
Expand Down Expand Up @@ -217,6 +234,11 @@ impl MagicEndpoint {
self.keypair.public().into()
}

/// Get the keypair of this endpoint.
pub fn keypair(&self) -> &Keypair {
&self.keypair
}

/// Get the local addresses on which the underlying magic socket is bound.
///
/// Returns a tuple of the IPv4 and the optional IPv6 address.
Expand Down Expand Up @@ -244,7 +266,9 @@ impl MagicEndpoint {
alpn: &[u8],
known_addrs: &[SocketAddr],
) -> anyhow::Result<quinn::Connection> {
self.add_known_addrs(peer_id, known_addrs).await?;
if !known_addrs.is_empty() {
self.add_known_addrs(peer_id, known_addrs).await?;
}

let node_key: hp::key::node::PublicKey = peer_id.into();
let addr = self
Expand All @@ -268,13 +292,13 @@ impl MagicEndpoint {
"connecting to {}: (via {} - {:?})",
peer_id, addr, known_addrs
);

// TODO: We'd eventually want to replace "localhost" with something that makes more sense.
let connect = self
.endpoint
.connect_with(client_config, addr, "localhost")?;

let connection = connect.await.context("failed connecting to provider")?;

Ok(connection)
connect.await.context("failed connecting to provider")
}

/// Inform the magic socket about addresses of the peer.
Expand Down Expand Up @@ -392,10 +416,8 @@ mod test {

use futures::future::BoxFuture;

use crate::{
endpoint::{accept_conn, MagicEndpoint},
hp::magicsock::conn_tests::{run_derp_and_stun, setup_logging},
};
use super::{accept_conn, MagicEndpoint};
use crate::hp::magicsock::conn_tests::{run_derp_and_stun, setup_logging};

const TEST_ALPN: &[u8] = b"n0/iroh/test";

Expand Down
21 changes: 19 additions & 2 deletions iroh/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::net::{Ipv4Addr, SocketAddrV4};
use std::sync::Arc;
use std::time::Duration;
use std::{net::SocketAddr, path::PathBuf};

use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
use iroh_bytes::{cid::Blake3Cid, protocol::RequestToken, provider::Ticket, runtime};
use iroh_net::{client::create_quinn_client, tls::PeerId};
use iroh_net::tls::PeerId;
use quic_rpc::transport::quinn::QuinnConnection;
use quic_rpc::RpcClient;

Expand Down Expand Up @@ -235,7 +236,7 @@ async fn make_rpc_client(
) -> anyhow::Result<RpcClient<ProviderService, QuinnConnection<ProviderResponse, ProviderRequest>>>
{
let bind_addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0).into();
let endpoint = create_quinn_client(bind_addr, None, vec![RPC_ALPN.to_vec()], false)?;
let endpoint = create_quinn_client(bind_addr, vec![RPC_ALPN.to_vec()], false)?;
let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), rpc_port);
let server_name = "localhost".to_string();
let connection = QuinnConnection::new(endpoint, addr, server_name);
Expand All @@ -247,6 +248,22 @@ async fn make_rpc_client(
Ok(client)
}

pub fn create_quinn_client(
bind_addr: SocketAddr,
alpn_protocols: Vec<Vec<u8>>,
keylog: bool,
) -> Result<quinn::Endpoint> {
let keypair = iroh_net::tls::Keypair::generate();
let tls_client_config = iroh_net::tls::make_client_config(&keypair, None, alpn_protocols, keylog)?;
let mut client_config = quinn::ClientConfig::new(Arc::new(tls_client_config));
let mut endpoint = quinn::Endpoint::client(bind_addr)?;
let mut transport_config = quinn::TransportConfig::default();
transport_config.keep_alive_interval(Some(Duration::from_secs(1)));
client_config.transport_config(Arc::new(transport_config));
endpoint.set_default_client_config(client_config);
Ok(endpoint)
}

#[cfg(feature = "metrics")]
pub fn init_metrics_collection(
metrics_addr: Option<SocketAddr>,
Expand Down
2 changes: 1 addition & 1 deletion iroh/src/commands/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use clap::Subcommand;
use indicatif::{HumanBytes, MultiProgress, ProgressBar};
use iroh_bytes::tokio_util::ProgressWriter;
use iroh_net::{
endpoint::MagicEndpoint,
MagicEndpoint,
hp::{
self,
derp::{DerpMap, UseIpv4, UseIpv6},
Expand Down
2 changes: 1 addition & 1 deletion iroh/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use iroh_bytes::{
runtime,
util::{Hash, Progress},
};
use iroh_net::endpoint::MagicEndpoint;
use iroh_net::{
MagicEndpoint,
hp::{cfg::Endpoint, derp::DerpMap},
tls::{self, Keypair, PeerId},
};
Expand Down
6 changes: 3 additions & 3 deletions iroh/tests/provide.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use anyhow::{anyhow, bail, Context, Result};
use bytes::Bytes;
use futures::{future::BoxFuture, FutureExt};
use iroh::node::{Event, Node};
use iroh_net::client::dial_peer;
use iroh_net::MagicEndpoint;
use rand::RngCore;
use testdir::testdir;
use tokio::{fs, io::AsyncWriteExt, sync::broadcast};
Expand Down Expand Up @@ -583,7 +583,7 @@ async fn test_run_fsm() {
let addrs = node.local_endpoint_addresses().await.unwrap();
let peer_id = node.peer_id();
tokio::time::timeout(Duration::from_secs(10), async move {
let connection = dial_peer(&addrs, peer_id, &iroh_bytes::P2P_ALPN, true, None).await?;
let connection = MagicEndpoint::dial_peer(peer_id, &iroh_bytes::P2P_ALPN, &addrs, None, true).await?;
let request = GetRequest::all(hash).into();
let stream = get::run_connection(connection, request);
let (collection, children, _) = aggregate_get_response(stream).await?;
Expand Down Expand Up @@ -788,7 +788,7 @@ async fn test_token_passthrough() -> Result<()> {
let addrs = provider.local_endpoint_addresses().await?;
let peer_id = provider.peer_id();
tokio::time::timeout(Duration::from_secs(10), async move {
dial_peer(&addrs, peer_id, &iroh_bytes::P2P_ALPN, true, None).await?;
MagicEndpoint::dial_peer(peer_id, &iroh_bytes::P2P_ALPN, &addrs, None, true).await?;
let request = GetRequest::all(hash).with_token(token).into();
let response = get::run(
request,
Expand Down

0 comments on commit 6d83ceb

Please sign in to comment.