Skip to content

Commit

Permalink
refactor(iroh)!: make iroh::tls private (#3018)
Browse files Browse the repository at this point in the history
## Description

- makes `iroh::tls` private
- match quinns tls setup for benchmarking

## Breaking Changes

- `iroh::tls` is removed from the public API

## Notes & open questions

The goal is to reduce the API surface of `iroh`, to what is really
needed. I couldn't find any critical usage of this in our dependencies.

## Change checklist

- [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.
- [ ] Tests if relevant.
- [x] All breaking changes documented.
  • Loading branch information
dignifiedquire authored Dec 10, 2024
1 parent 6a62c80 commit 0fe7e8b
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ jobs:
# uses: obi1kenobi/cargo-semver-checks-action@v2
uses: n0-computer/cargo-semver-checks-action@feat-baseline
with:
package: iroh, iroh-base, iroh-dns-server, iroh-net-bench, iroh-relay, iroh-net-report
package: iroh, iroh-base, iroh-dns-server, iroh-bench, iroh-relay, iroh-net-report
baseline-rev: ${{ env.HEAD_COMMIT_SHA }}
use-cache: false

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ env:
RUSTFLAGS: -Dwarnings
RUSTDOCFLAGS: -Dwarnings
SCCACHE_CACHE_SIZE: "10G"
CRATES_LIST: "iroh,iroh-net-bench,iroh-test,iroh-dns-server,iroh-relay,iroh-net-report"
CRATES_LIST: "iroh,iroh-bench,iroh-test,iroh-dns-server,iroh-relay,iroh-net-report"
IROH_FORCE_STAGING_RELAYS: "1"

jobs:
Expand Down
40 changes: 20 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion iroh-net-report/src/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/// The STUN port as defined by [RFC 8489](<https://www.rfc-editor.org/rfc/rfc8489#section-18.6>)
pub const DEFAULT_STUN_PORT: u16 = 3478;

/// Contains all timeouts that we use in `iroh-net_report`.
/// Contains all timeouts that we use in `iroh-net-report`.
pub(crate) mod timeouts {
use std::time::Duration;

Expand Down
2 changes: 1 addition & 1 deletion iroh/bench/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "iroh-net-bench"
name = "iroh-bench"
version = "0.29.0"
edition = "2021"
license = "MIT OR Apache-2.0"
Expand Down
15 changes: 11 additions & 4 deletions iroh/bench/src/bin/bulk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::collections::BTreeMap;
use anyhow::Result;
use clap::Parser;
#[cfg(not(any(target_os = "freebsd", target_os = "openbsd", target_os = "netbsd")))]
use iroh_net_bench::quinn;
use iroh_net_bench::{configure_tracing_subscriber, iroh, rt, s2n, Commands, Opt};
use iroh_bench::quinn;
use iroh_bench::{configure_tracing_subscriber, iroh, rt, s2n, Commands, Opt};

fn main() {
let cmd = Commands::parse();
Expand Down Expand Up @@ -135,11 +135,17 @@ pub fn run_iroh(opt: Opt) -> Result<()> {

#[cfg(not(any(target_os = "freebsd", target_os = "openbsd", target_os = "netbsd")))]
pub fn run_quinn(opt: Opt) -> Result<()> {
use rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer};

let server_span = tracing::error_span!("server");
let runtime = rt();
let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
let key = PrivatePkcs8KeyDer::from(cert.key_pair.serialize_der());
let cert = CertificateDer::from(cert.cert);

let (server_addr, endpoint) = {
let _guard = server_span.enter();
quinn::server_endpoint(&runtime, &opt)
quinn::server_endpoint(&runtime, cert.clone(), key.into(), &opt)
};

let server_thread = std::thread::spawn(move || {
Expand All @@ -151,10 +157,11 @@ pub fn run_quinn(opt: Opt) -> Result<()> {

let mut handles = Vec::new();
for id in 0..opt.clients {
let cert = cert.clone();
handles.push(std::thread::spawn(move || {
let _guard = tracing::error_span!("client", id).entered();
let runtime = rt();
match runtime.block_on(quinn::client(server_addr, opt)) {
match runtime.block_on(quinn::client(server_addr, cert, opt)) {
Ok(stats) => Ok(stats),
Err(e) => {
eprintln!("client failed: {e:#}");
Expand Down
2 changes: 1 addition & 1 deletion iroh/bench/src/iroh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
client_handler, stats::TransferResult, ClientStats, ConnectionSelector, EndpointSelector, Opt,
};

pub const ALPN: &[u8] = b"n0/iroh-net-bench/0";
pub const ALPN: &[u8] = b"n0/iroh-bench/0";

/// Creates a server endpoint which runs on the given runtime
pub fn server_endpoint(
Expand Down
2 changes: 1 addition & 1 deletion iroh/bench/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub mod s2n;
pub mod stats;

#[derive(Parser, Debug, Clone, Copy)]
#[clap(name = "iroh-net-bench")]
#[clap(name = "iroh-bench")]
pub enum Commands {
Iroh(Opt),
#[cfg(not(any(target_os = "freebsd", target_os = "openbsd", target_os = "netbsd")))]
Expand Down
136 changes: 53 additions & 83 deletions iroh/bench/src/quinn.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,57 @@
use std::{
net::SocketAddr,
net::{IpAddr, Ipv4Addr, SocketAddr},
sync::Arc,
time::{Duration, Instant},
};

use anyhow::{Context, Result};
use bytes::Bytes;
use quinn::{Connection, Endpoint, RecvStream, SendStream, TokioRuntime, TransportConfig};
use socket2::{Domain, Protocol, Socket, Type};
use quinn::{
crypto::rustls::QuicClientConfig, Connection, Endpoint, RecvStream, SendStream, TransportConfig,
};
use rustls::{
pki_types::{CertificateDer, PrivateKeyDer},
RootCertStore,
};
use tracing::{trace, warn};

use crate::{
client_handler, stats::TransferResult, ClientStats, ConnectionSelector, EndpointSelector, Opt,
};

/// Derived from the iroh udp SOCKET_BUFFER_SIZE
const SOCKET_BUFFER_SIZE: usize = 7 << 20;
pub const ALPN: &[u8] = b"n0/quinn-bench/0";

/// Creates a server endpoint which runs on the given runtime
pub fn server_endpoint(rt: &tokio::runtime::Runtime, opt: &Opt) -> (SocketAddr, quinn::Endpoint) {
let secret_key = iroh::key::SecretKey::generate();
let crypto = iroh::tls::make_server_config(&secret_key, vec![ALPN.to_vec()], false).unwrap();

let transport = transport_config(opt.max_streams, opt.initial_mtu);

let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(crypto));
server_config.transport_config(Arc::new(transport));

let addr = SocketAddr::new("127.0.0.1".parse().unwrap(), 0);

let socket = bind_socket(addr).unwrap();

let _guard = rt.enter();
rt.block_on(async move {
let ep = quinn::Endpoint::new(
Default::default(),
Some(server_config),
socket,
Arc::new(TokioRuntime),
pub fn server_endpoint(
rt: &tokio::runtime::Runtime,
cert: CertificateDer<'static>,
key: PrivateKeyDer<'static>,
opt: &Opt,
) -> (SocketAddr, quinn::Endpoint) {
let cert_chain = vec![cert];
let mut server_config = quinn::ServerConfig::with_single_cert(cert_chain, key).unwrap();
server_config.transport = Arc::new(transport_config(opt.max_streams, opt.initial_mtu));

let endpoint = {
let _guard = rt.enter();
quinn::Endpoint::server(
server_config,
SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0),
)
.unwrap();
let addr = ep.local_addr().unwrap();
(addr, ep)
})
.unwrap()
};
let server_addr = endpoint.local_addr().unwrap();
(server_addr, endpoint)
}

/// Create and run a client
pub async fn client(server_addr: SocketAddr, opt: Opt) -> Result<ClientStats> {
pub async fn client(
server_addr: SocketAddr,
server_cert: CertificateDer<'static>,
opt: Opt,
) -> Result<ClientStats> {
let client_start = std::time::Instant::now();
let (endpoint, connection) = connect_client(server_addr, opt).await?;
let (endpoint, connection) = connect_client(server_addr, server_cert, opt).await?;
let client_connect_time = client_start.elapsed();
let mut res = client_handler(
EndpointSelector::Quinn(endpoint),
Expand All @@ -64,29 +66,34 @@ pub async fn client(server_addr: SocketAddr, opt: Opt) -> Result<ClientStats> {
/// Create a client endpoint and client connection
pub async fn connect_client(
server_addr: SocketAddr,
server_cert: CertificateDer<'_>,
opt: Opt,
) -> Result<(::quinn::Endpoint, Connection)> {
let secret_key = iroh::key::SecretKey::generate();
let quic_client_config =
iroh::tls::make_client_config(&secret_key, None, vec![ALPN.to_vec()], false)?;
let mut config = quinn::ClientConfig::new(Arc::new(quic_client_config));
let endpoint =
quinn::Endpoint::client(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0)).unwrap();

let transport = transport_config(opt.max_streams, opt.initial_mtu);
let mut roots = RootCertStore::empty();
roots.add(server_cert)?;

// let mut config = quinn::ClientConfig::new(Arc::new(crypto));
config.transport_config(Arc::new(transport));
let provider = rustls::crypto::ring::default_provider();

let addr = SocketAddr::new("127.0.0.1".parse().unwrap(), 0);
let crypto = rustls::ClientConfig::builder_with_provider(provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_root_certificates(roots)
.with_no_client_auth();

let socket = bind_socket(addr).unwrap();
let mut client_config = quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(crypto)?));
client_config.transport_config(Arc::new(transport_config(opt.max_streams, opt.initial_mtu)));

let ep =
quinn::Endpoint::new(Default::default(), None, socket, Arc::new(TokioRuntime)).unwrap();
let connection = ep
.connect_with(config, server_addr, "local")?
let connection = endpoint
.connect_with(client_config, server_addr, "localhost")
.unwrap()
.await
.context("connecting")?;
Ok((ep, connection))
.context("unable to connect")?;
trace!("connected");

Ok((endpoint, connection))
}

pub fn transport_config(max_streams: usize, initial_mtu: u16) -> TransportConfig {
Expand All @@ -104,43 +111,6 @@ pub fn transport_config(max_streams: usize, initial_mtu: u16) -> TransportConfig
config
}

fn bind_socket(addr: SocketAddr) -> Result<std::net::UdpSocket> {
let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))
.context("create socket")?;

if addr.is_ipv6() {
socket.set_only_v6(false).context("set_only_v6")?;
}

socket
.bind(&socket2::SockAddr::from(addr))
.context("binding endpoint")?;
socket
.set_send_buffer_size(SOCKET_BUFFER_SIZE)
.context("send buffer size")?;
socket
.set_recv_buffer_size(SOCKET_BUFFER_SIZE)
.context("recv buffer size")?;

let buf_size = socket.send_buffer_size().context("send buffer size")?;
if buf_size < SOCKET_BUFFER_SIZE {
warn!(
"Unable to set desired send buffer size. Desired: {}, Actual: {}",
SOCKET_BUFFER_SIZE, buf_size
);
}

let buf_size = socket.recv_buffer_size().context("recv buffer size")?;
if buf_size < SOCKET_BUFFER_SIZE {
warn!(
"Unable to set desired recv buffer size. Desired: {}, Actual: {}",
SOCKET_BUFFER_SIZE, buf_size
);
}

Ok(socket.into())
}

async fn drain_stream(
stream: &mut RecvStream,
read_unordered: bool,
Expand Down
2 changes: 1 addition & 1 deletion iroh/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ pub mod endpoint;
mod magicsock;
pub mod metrics;
pub mod protocol;
pub mod tls;
mod tls;

pub(crate) mod util;

Expand Down

0 comments on commit 0fe7e8b

Please sign in to comment.