What is n0-computer/iroh? A Peer-to-Peer QUIC Networking Library in Rust
n0-computer/iroh is a Rust workspace providing a high-level API for establishing direct, encrypted peer-to-peer connections over QUIC, with built-in NAT traversal, relay fallback, and DNS-based endpoint discovery.
n0-computer/iroh is an open-source Rust library maintained by n0 computer that abstracts the complexity of peer-to-peer networking. Built atop the QUIC transport protocol, it enables developers to create direct connections between endpoints using cryptographic keys as identifiers, eliminating the need for manual NAT traversal or custom certificate management.
Core Architecture of n0-computer/iroh
Endpoint-Centric Design with Cryptographic Identity
At the heart of n0-computer/iroh lies the Endpoint, defined in iroh/src/lib.rs and implemented in iroh/src/endpoint/mod.rs. Each peer instantiates an Endpoint that owns a long-term key pair consisting of a SecretKey and PublicKey. The public key serves dual purposes: it acts as the cryptographic identity and as the EndpointId, eliminating the need for separate certificate authorities or DNS names.
Endpoints bind to UDP sockets and manage the entire connection lifecycle, from initial handshake to stream multiplexing. The builder pattern, accessible via Endpoint::builder(), allows configuration of ALPN protocols, relay settings, and address lookup mechanisms before calling bind() to activate the endpoint.
Relay Infrastructure and NAT Traversal
By default, every endpoint connects to a home relay identified by a RelayUrl. The iroh-relay crate provides both client and server implementations, with the server logic residing in iroh-relay/src/server/http_server.rs. These relays forward encrypted traffic when direct connectivity is impossible.
When NAT traversal is required, iroh attempts hole-punching to establish a direct UDP path between peers. Once a direct route is discovered, traffic automatically migrates off the relay, optimizing for latency and throughput. This process is transparent to the application layer, requiring no manual intervention.
Address Discovery via DNS
To connect peers without pre-sharing IP addresses, n0-computer/iroh implements DnsAddressLookup in iroh/src/address_lookup/dns.rs. This module resolves an EndpointId to its current relay URL and direct addresses using DNS-based pkarr records. The iroh-dns crate provides the underlying resolver, while iroh-dns-server offers a standalone server implementation for hosting these records.
Workspace Structure and Source Files
The n0-computer/iroh repository is organized as a Cargo workspace with clear separation of concerns:
iroh/src/lib.rs– Public API façade, re-exportingEndpoint,RelayUrl, and connection typesiroh/src/endpoint/mod.rs– Endpoint builder, connection management, and stream handlingiroh/src/address_lookup/dns.rs– DNS-based discovery implementationiroh-base/src/lib.rs– Shared primitives includingEndpointId,RelayUrl, and cryptographic typesiroh-relay/src/server/http_server.rs– HTTP and QUIC server handling relay traffic forwardingiroh-dns/src/lib.rs– Core DNS resolver forpkarrrecord resolutioniroh-dns-server/src/main.rs– Standalone DNS server for endpoint record publication
Practical Usage: Establishing Connections
The following examples demonstrate the complete lifecycle of a peer-to-peer connection using n0-computer/iroh.
Basic Echo Server and Client
This example shows a server accepting connections and echoing data back, while a client connects and exchanges messages:
use iroh::{Endpoint, EndpointAddr, endpoint::presets};
use n0_error::{Result, StdResultExt};
#[tokio::main]
async fn main() -> Result<()> {
// Server setup
let server_ep = Endpoint::builder(presets::N0)
.alpns(vec![b"my-echo".to_vec()])
.bind()
.await?;
// Spawn server task
tokio::spawn(async move {
let conn = server_ep.accept().await?.await?;
let (mut send, mut recv) = conn.accept_bi().await?;
tokio::io::copy(&mut recv, &mut send).await?;
send.finish()?;
conn.closed().await;
Ok::<_, n0_error::Error>(())
});
// Client setup
let peer_addr: EndpointAddr = /* obtain from DNS or configuration */ todo!();
let client_ep = Endpoint::bind(presets::N0).await?;
let conn = client_ep.connect(peer_addr, b"my-echo").await?;
// Open bidirectional stream
let (mut send, mut recv) = conn.open_bi().await?;
send.write_all(b"Hello, iroh!").await?;
send.finish()?;
let mut buf = Vec::new();
recv.read_to_end(&mut buf).await?;
println!("Echo: {}", String::from_utf8_lossy(&buf));
// Cleanup
conn.close(0u32.into(), b"bye");
client_ep.close().await;
Ok(())
}
The implementation leverages open_bi() and accept_bi() for bidirectional streams, while accept() handles incoming connections. Note that streams are lightweight and can be created on-demand, though the sender must transmit data before the receiver's accept_* call returns.
DNS-Based Address Lookup
For scenarios where direct IP addresses are unknown, configure the endpoint with DnsAddressLookup:
use iroh::{Endpoint, endpoint::presets};
use iroh::address_lookup::DnsAddressLookup;
#[tokio::main]
async fn main() -> Result<()> {
let lookup = DnsAddressLookup::default();
let ep = Endpoint::builder(presets::N0)
.address_lookup(lookup)
.alpns(vec![b"my-protocol".to_vec()])
.bind()
.await?;
// Connect using only the EndpointId (public key)
// ep.connect(endpoint_id, ...).await?;
Ok(())
}
This configuration enables resolution of remote endpoints through the DNS infrastructure defined in iroh-dns/src/lib.rs.
Security and Encryption Model
n0-computer/iroh utilizes TLS over QUIC for all connections, but with a simplified trust model. Rather than traditional certificate chains, authentication relies on the EndpointId (the peer's PublicKey). When a connection is established, the endpoint automatically validates that the remote party possesses the private key corresponding to the claimed EndpointId, providing mutual authentication without certificate management overhead.
All traffic is encrypted end-to-end, including when traversing relay servers. The relay infrastructure in iroh-relay only forwards opaque encrypted packets and cannot inspect payload contents.
Summary
- n0-computer/iroh is a Rust workspace providing high-level peer-to-peer networking over QUIC
- Endpoints use cryptographic key pairs (
SecretKey/PublicKey) as identifiers, with the public key serving as theEndpointId - Relay support enables connectivity behind NATs, with automatic migration to direct paths when hole-punching succeeds
- DNS address lookup allows discovery of peers using only their
EndpointIdviaDnsAddressLookupiniroh/src/address_lookup/dns.rs - Stream multiplexing supports both unidirectional and bidirectional QUIC streams created on-demand
Frequently Asked Questions
What transport protocol does n0-computer/iroh use?
n0-computer/iroh is built on top of QUIC, a modern transport protocol operating over UDP that provides built-in encryption, multiplexed streams, and connection migration. The library leverages QUIC's capabilities to handle multiple simultaneous streams over a single connection while maintaining low latency.
How does n0-computer/iroh handle NAT traversal?
When direct connectivity is blocked by NAT, endpoints utilize a home relay (RelayUrl) to forward encrypted traffic. Simultaneously, the library attempts hole-punching to establish a direct UDP path. Once successful, traffic transparently migrates from the relay to the direct connection without dropping the connection or requiring application changes.
What is the relationship between EndpointId and PublicKey?
In iroh-base/src/lib.rs, the EndpointId is defined as the PublicKey of the endpoint's key pair. This design choice eliminates the need for separate identifiers or certificate management, as the public key cryptographically identifies the peer and enables authentication during the QUIC handshake.
Do I need to run my own relay server to use n0-computer/iroh?
No. The library defaults to using public relays operated by n0 computer (accessible via presets::N0). However, you can configure custom relays by specifying alternative RelayUrl values in the Endpoint builder, or run your own infrastructure using the iroh-relay crate and iroh-relay/src/server/http_server.rs implementation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →