# Key Modules in the iroh Repository: A Complete Architectural Breakdown

> Explore the key modules in the iroh repository: endpoint, address_lookup, tls, protocol, iroh-relay, and iroh-dns-server. Understand iroh's P2P architecture and discovery mechanisms.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: architecture
- Published: 2026-06-23

---

**The iroh repository is organized around the `endpoint` module for peer-to-peer connectivity, `address_lookup` for DNS and PKARR-based discovery, `tls` and `protocol` for QUIC encryption, with supporting infrastructure in `iroh-relay`, `iroh-dns-server`, and shared primitives in `iroh-base`.**

The iroh networking stack provides a Rust-based framework for building peer-to-peer applications over QUIC. Understanding the key modules in the iroh repository is essential for developers integrating custom protocols, running infrastructure, or optimizing connection performance. This guide maps the crate structure to specific source files in the `n0-computer/iroh` codebase and demonstrates how the modules interact during a typical connection lifecycle.

## Core Client-Side Modules

### Endpoint (iroh/src/endpoint/mod.rs)

The **`endpoint`** module forms the primary public API. It exposes the `Endpoint` struct, which manages node identity, connection establishment, and stream multiplexing. In [`iroh/src/endpoint/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/mod.rs), the `Endpoint::builder()` method configures relay selection via `RelayMode` and initializes the QUIC stack with custom TLS handlers. The `Connection` type, returned by `Endpoint::connect()`, provides `open_bi()` and `open_uni()` methods for stream creation.

### Address Resolution (iroh/src/address_lookup/)

Before connecting, an `EndpointId` must resolve to reachable addresses. The **`address_lookup`** directory contains multiple strategies:

- **`DnsAddressLookup`**: Resolves endpoints via DNS TXT records (defined in [`iroh/src/address_lookup/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/dns.rs))
- **`PkarrAddressLookup`**: Uses the PKARR protocol for decentralized discovery (defined in [`iroh/src/address_lookup/pkarr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/pkarr.rs))

Both implement the `AddressLookup` trait, returning a relay URL and direct addresses.

### TLS and Protocol Handlers

QUIC connections rely on the **`tls`** module ([`iroh/src/tls/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls/mod.rs)) for certificate verification, providing `TlsConnector` and `TlsAcceptor` wrappers. The **`protocol`** module ([`iroh/src/protocol/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/protocol/mod.rs)) defines the custom iroh relaying protocol through the `Protocol` and `Message` types, handling frame encoding for relayed traffic.

## Observability and Diagnostics

### Metrics (iroh/src/metrics.rs)

Runtime observability is handled by the **`metrics`** module, exposing Prometheus-compatible counters through the `Metrics` and `ConnectionMetrics` structs. These track connection establishment latency, throughput, and relay utilization as implemented in [`iroh/src/metrics.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/metrics.rs).

### Network Reporting (iroh/src/net_report/mod.rs)

The optional **`net_report`** feature provides path quality analysis. `NetReportConfig` configures probe behavior, while the `Probe` struct measures relay latency and NAT traversal success rates, enabling dynamic path selection. The implementation resides in [`iroh/src/net_report/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/net_report/mod.rs).

## Infrastructure and Server Components

### Relay Server (iroh-relay/)

The **`iroh-relay`** crate contains the server-side implementation for traffic forwarding. In [`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs), the `RelayServer` type accepts TLS-protected QUIC sessions and routes encrypted payloads between peers. Client-side relay configuration uses `RelayMap` and `RelayConfig` from [`iroh/src/relay_map.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/relay_map.rs).

### DNS Services (iroh-dns-server/ and iroh-dns/)

Discovery infrastructure includes the **`iroh-dns`** crate, which provides `DnsResolver` utilities in [`iroh-dns/src/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns/src/dns.rs) for client-side queries. The **`iroh-dns-server`** crate implements the publishing side, with `DnsServer` and `HttpApi` defined in [`iroh-dns-server/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns-server/src/server.rs), serving TXT records for endpoint discovery.

## Shared Primitives and Testing

### iroh-base (iroh-base/src/lib.rs)

Cryptographic primitives and identifiers live in **`iroh-base`**. This crate defines `EndpointId`, `PublicKey`, `SecretKey`, and `RelayUrl` types used across the entire ecosystem, ensuring type safety between crates without circular dependencies. The definitions are centralized in [`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs).

### Benchmarking (iroh/bench/src/lib.rs)

Performance validation occurs in **`iroh-bench`**, located at [`iroh/bench/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/bench/src/lib.rs), which implements throughput and latency benchmarks for connection setup and data transfer.

## How the Modules Interact During Connection

When `Endpoint::connect()` is invoked, the following sequence executes:

1. **Resolution**: The endpoint queries its configured `AddressLookup` (defaulting to `DnsAddressLookup`) to resolve the target `EndpointId` to a `RelayUrl` and direct addresses.
2. **Relay Negotiation**: If direct connection fails, the endpoint establishes a QUIC connection to the relay using `TlsConnector` from the `tls` module, negotiating the custom `Protocol` defined in [`iroh/src/protocol/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/protocol/mod.rs).
3. **Hole Punching**: Simultaneously, the endpoint attempts NAT traversal for direct peer-to-peer connectivity.
4. **Stream Establishment**: Once connected, the `Connection` type exposes `open_bi()` and `open_uni()` methods for application data.
5. **Telemetry**: Throughout the lifecycle, `Metrics` counters update, and optional `NetReport` probes collect path quality data.

## Practical Code Examples

### Creating a Client Endpoint

```rust
#[cfg(with_crypto_provider)]
async fn simple_client() -> n0_error::Result<()> {
    // Create an endpoint bound to the default "number 0" preset.
    let ep = iroh::Endpoint::bind(iroh::endpoint::presets::N0).await?;

    // Connect to a remote endpoint (replace with a real EndpointId).
    let remote_id = "VQ6X...".parse::<iroh::EndpointId>()?;
    let conn = ep.connect(remote_id, b"my-alpn").await?;

    // Open a bi-directional stream and exchange a hello message.
    let (mut send, mut recv) = conn.open_bi().await?;
    send.write_all(b"hello").await?;
    send.finish().await?;

    let reply = recv.read_to_end(usize::MAX).await?;
    println!("remote said: {}", String::from_utf8_lossy(&reply));
    Ok(())
}

```

This example uses the `endpoint`, `address_lookup` (via defaults), `tls`, and `protocol` modules as defined in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs).

### Configuring Custom DNS Lookup

```rust
use iroh::address_lookup::DnsAddressLookup;
use iroh::endpoint::Builder;

#[cfg(with_crypto_provider)]
async fn custom_dns_lookup() -> n0_error::Result<()> {
    // Build a DNS lookup that uses the staging domain.
    let dns_lookup = DnsAddressLookup::builder("iroh-staging.example".into()).build();

    // Attach the lookup to the endpoint builder.
    let ep = Builder::new()
        .address_lookup(dns_lookup)
        .bind()
        .await?;

    Ok(())
}

```

The lookup implementation lives in [`iroh/src/address_lookup/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/dns.rs).

### Running a Relay Server

```rust
use iroh_relay::RelayServer;
use std::net::SocketAddr;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Listen on a UDP port for QUIC connections.
    let addr: SocketAddr = "[::]:443".parse()?;
    let server = RelayServer::bind(addr).await?;
    println!("Relay listening on {}", addr);
    server.serve().await?;
    Ok(())
}

```

Core server logic is located in [`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs).

## Summary

- **`endpoint`** ([`iroh/src/endpoint/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/mod.rs)): Core public API managing QUIC connections and stream multiplexing.
- **`address_lookup`** (`iroh/src/address_lookup/`): Pluggable discovery via DNS or PKARR, resolving `EndpointId` to network addresses.
- **`tls`** ([`iroh/src/tls/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls/mod.rs)) and **`protocol`** ([`iroh/src/protocol/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/protocol/mod.rs)): Handle encrypted QUIC communication and custom relay framing.
- **`metrics`** ([`iroh/src/metrics.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/metrics.rs)) and **`net_report`** ([`iroh/src/net_report/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/net_report/mod.rs)): Provide runtime observability and network quality diagnostics.
- **`iroh-relay`** ([`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs)): Server-side traffic forwarding and relay infrastructure.
- **`iroh-dns-server`** ([`iroh-dns-server/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns-server/src/server.rs)) and **`iroh-dns`**: DNS publishing and resolution services for endpoint discovery.
- **`iroh-base`** ([`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs)): Shared cryptographic primitives including `EndpointId`, `PublicKey`, and `SecretKey`.

## Frequently Asked Questions

### What is the entry point for creating connections in iroh?

The `Endpoint` struct in [`iroh/src/endpoint/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/mod.rs) serves as the primary entry point. Use `Endpoint::bind()` or `Endpoint::builder()` to configure a node, then call `Endpoint::connect()` with a target `EndpointId` and ALPN protocol identifier to establish peer-to-peer sessions.

### How does iroh resolve peer addresses without a central coordinator?

The `address_lookup` module supports decentralized discovery. By default, it uses `DnsAddressLookup` to query DNS TXT records, but can be configured to use `PkarrAddressLookup` for PKARR-based resolution. Both strategies are implemented in [`iroh/src/address_lookup/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/dns.rs) and [`iroh/src/address_lookup/pkarr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/pkarr.rs) respectively.

### Can I run my own relay server instead of using the default infrastructure?

Yes. The `iroh-relay` crate provides the `RelayServer` type, which you can bind to a UDP socket using `RelayServer::bind()` as shown in [`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs). This allows complete control over traffic forwarding while maintaining compatibility with iroh clients.

### Where are the cryptographic types like EndpointId and PublicKey defined?

These primitives reside in the `iroh-base` crate, specifically in [`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs). This separation prevents circular dependencies between the client, relay, and DNS components while ensuring type consistency across the networking stack.