Skip to content

Commit

Permalink
refactor: remove magicsock / quinn::Endpoint circular dependency
Browse files Browse the repository at this point in the history
`MagicSock::spawn` creates a `quinn::Endpoint`. `MagicSock` is now an `AsyncUdpSocket`, and can be passed into the `quinn::Endpoint`. `magicsock::Handle` now owns the `quinn::Endpoint`, and `iroh::Endpoint` interacts with the `quinn::Endpoint` through `Handle::endpoint()`.

This allows us to pass the `quinn::Endpoint` to the `magicsock::Actor` for use in QAD, without any circular dependencies.
  • Loading branch information
“ramfox” committed Dec 14, 2024
1 parent 3a89d92 commit 0919e95
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 140 deletions.
2 changes: 1 addition & 1 deletion iroh/examples/listen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async fn main() -> anyhow::Result<()> {
// Use `RelayMode::Custom` to pass in a `RelayMap` with custom relay urls.
// Use `RelayMode::Disable` to disable holepunching and relaying over HTTPS
// If you want to experiment with relaying using your own relay server, you must pass in the same custom relay url to both the `listen` code AND the `connect` code
.relay_mode(RelayMode::Default)
.relay_mode(RelayMode::Staging)
// you can choose a port to bind to, but passing in `0` will bind the socket to a random available port
.bind()
.await?;
Expand Down
49 changes: 11 additions & 38 deletions iroh/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ impl Builder {
1 => Some(discovery.into_iter().next().unwrap()),
_ => Some(Box::new(ConcurrentDiscovery::from_services(discovery))),
};
let server_config = static_config.create_server_config(self.alpn_protocols)?;

let msock_opts = magicsock::Options {
addr_v4: self.addr_v4,
addr_v6: self.addr_v6,
Expand All @@ -158,10 +160,11 @@ impl Builder {
discovery,
proxy_url: self.proxy_url,
dns_resolver,
server_config,
#[cfg(any(test, feature = "test-utils"))]
insecure_skip_relay_cert_verify: self.insecure_skip_relay_cert_verify,
};
Endpoint::bind(static_config, msock_opts, self.alpn_protocols).await
Endpoint::bind(static_config, msock_opts).await
}

// # The very common methods everyone basically needs.
Expand Down Expand Up @@ -414,7 +417,6 @@ impl Builder {
self
}
}

/// Configuration for a [`quinn::Endpoint`] that cannot be changed at runtime.
#[derive(Debug)]
struct StaticConfig {
Expand All @@ -425,7 +427,7 @@ struct StaticConfig {

impl StaticConfig {
/// Create a [`quinn::ServerConfig`] with the specified ALPN protocols.
fn create_server_config(&self, alpn_protocols: Vec<Vec<u8>>) -> Result<ServerConfig> {
fn create_server_config(&self, alpn_protocols: Vec<Vec<u8>>) -> Result<quinn::ServerConfig> {
let server_config = make_server_config(
&self.secret_key,
alpn_protocols,
Expand Down Expand Up @@ -478,7 +480,6 @@ pub fn make_server_config(
#[derive(Clone, Debug)]
pub struct Endpoint {
msock: Handle,
endpoint: quinn::Endpoint,
rtt_actor: Arc<rtt_actor::RttHandle>,
cancel_token: CancellationToken,
static_config: Arc<StaticConfig>,
Expand All @@ -501,40 +502,17 @@ impl Endpoint {
/// This is for internal use, the public interface is the [`Builder`] obtained from
/// [Self::builder]. See the methods on the builder for documentation of the parameters.
#[instrument("ep", skip_all, fields(me = %static_config.secret_key.public().fmt_short()))]
async fn bind(
static_config: StaticConfig,
msock_opts: magicsock::Options,
initial_alpns: Vec<Vec<u8>>,
) -> Result<Self> {
async fn bind(static_config: StaticConfig, msock_opts: magicsock::Options) -> Result<Self> {
let msock = magicsock::MagicSock::spawn(msock_opts).await?;
trace!("created magicsock");

let server_config = static_config.create_server_config(initial_alpns)?;

let mut endpoint_config = quinn::EndpointConfig::default();
// Setting this to false means that quinn will ignore packets that have the QUIC fixed bit
// set to 0. The fixed bit is the 3rd bit of the first byte of a packet.
// For performance reasons and to not rewrite buffers we pass non-QUIC UDP packets straight
// through to quinn. We set the first byte of the packet to zero, which makes quinn ignore
// the packet if grease_quic_bit is set to false.
endpoint_config.grease_quic_bit(false);

let endpoint = quinn::Endpoint::new_with_abstract_socket(
endpoint_config,
Some(server_config),
Arc::new(msock.clone()),
Arc::new(quinn::TokioRuntime),
)?;
trace!("created quinn endpoint");
debug!(version = env!("CARGO_PKG_VERSION"), "iroh Endpoint created");
let ep = Self {
msock: msock.clone(),
endpoint: endpoint.clone(),
rtt_actor: Arc::new(rtt_actor::RttHandle::new()),
cancel_token: CancellationToken::new(),
static_config: Arc::new(static_config),
};
msock.set_quic_endpoint(Some(endpoint));
Ok(ep)
}

Expand All @@ -544,7 +522,7 @@ impl Endpoint {
/// Note that this *overrides* the current list of ALPNs.
pub fn set_alpns(&self, alpns: Vec<Vec<u8>>) -> Result<()> {
let server_config = self.static_config.create_server_config(alpns)?;
self.endpoint.set_server_config(Some(server_config));
self.msock.endpoint().set_server_config(Some(server_config));
Ok(())
}

Expand Down Expand Up @@ -648,7 +626,8 @@ impl Endpoint {

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

let connection = connect
Expand Down Expand Up @@ -678,7 +657,7 @@ impl Endpoint {
/// [`Endpoint::close`].
pub fn accept(&self) -> Accept<'_> {
Accept {
inner: self.endpoint.accept(),
inner: self.msock.endpoint().accept(),
ep: self.clone(),
}
}
Expand Down Expand Up @@ -958,13 +937,7 @@ impl Endpoint {
if self.is_closed() {
return Ok(());
}

self.cancel_token.cancel();
tracing::debug!("Closing connections");
self.endpoint.close(0u16.into(), b"");
self.endpoint.wait_idle().await;

tracing::debug!("Connections closed");
self.msock.close().await?;
Ok(())
}
Expand Down Expand Up @@ -1049,7 +1022,7 @@ impl Endpoint {
}
#[cfg(test)]
pub(crate) fn endpoint(&self) -> &quinn::Endpoint {
&self.endpoint
self.msock.endpoint()
}
}

Expand Down
Loading

0 comments on commit 0919e95

Please sign in to comment.