# Technical Documentation: n0-computer/iroh

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/n0-computer/iroh)

### Overview (`README.md`)

<h1 align="center"><a href="https://iroh.computer"><img alt="iroh" src="./.img/iroh_wordmark.svg" width="100" /></a></h1>

<h3 align="center">
less net work for networks
</h3>

[](https://docs.rs/iroh/)
[](https://crates.io/crates/iroh)
[](https://crates.io/crates/iroh)
[](https://discord.com/invite/DpmJgtU7cW)
[](https://www.youtube.com/@n0computer)
[](LICENSE-MIT)
[](LICENSE-APACHE)
[](https://github.com/n0-computer/iroh/actions/workflows/ci.yml)

<div align="center">
  <h3>
    <a href="https://iroh.computer/docs">
      Docs Site
    </a>
    <span> | </span>
    <a href="https://docs.rs/iroh">
      Rust Docs
    </a>
  </h3>
</div>
<br/>

## What is iroh?

Iroh gives you an API for dialing by public key.
You say “connect to that phone”, iroh will find & maintain the fastest connection for you, regardless of where it is.

### Hole-punching

The fastest route is a direct connection, so if necessary, iroh tries to hole-punch.
Should this fail, it can fall back to an open ecosystem of public relay servers.
To ensure these connections are as fast as possible, we [continuously measure iroh][iroh-perf].

### Built on [QUIC]

Iroh uses [noq] to establish [QUIC] connections between endpoints.
This way you get authenticated encryption, concurrent streams with stream priorities, a datagram transport and avoid head-of-line-blocking out of the box.

## Compose Protocols

Use pre-existing protocols built on iroh instead of writing your own:
- [iroh-blobs] for [BLAKE3]-based content-addressed blob transfer scaling from kilobytes to terabytes
- [iroh-gossip] for establishing publish-subscribe overlay networks that scale, requiring only resources that your average phone can handle
- [iroh-docs] for an eventually-consistent key-value store of [iroh-blobs] blobs

## Getting Started

### Rust Library

It's easiest to use iroh from rust.
Install it using `cargo add iroh`, then on the connecting side:

```rs
const ALPN: &[u8] = b"iroh-example/echo/0";

let endpoint = Endpoint::bind().await?;

// Open a connection to the accepting endpoint
let conn = endpoint.connect(addr, ALPN).await?;

// Open a bidirectional QUIC stream
let (mut send, mut recv) = conn.open_bi().await?;

// Send some data to be echoed
send.write_all(b"Hello, world!").await?;
send.finish()?;

// Receive the echo
let response = recv.read_to_end(1000).await?;
assert_eq!(&response, b"Hello, world!");

// As the side receiving the last application data - say goodbye
conn.close(0u32.into(), b"bye!");

// Close the endpoint and all its connections
endpoint.close().await;
```

And on the accepting side:
```rs
let endpoint = Endpoint::bind().await?;

let router = Router::builder(endpoint)
    .accept(ALPN.to_vec(), Arc::new(Echo))
    .spawn()
    .await?;

// The protocol definition:
#[derive(Debug, Clone)]
struct Echo;

impl ProtocolHandler for Echo {
    async fn accept(&self, connection: Connection) -> Result<()> {
        let (mut send, mut recv) = connection.accept_bi().await?;

        // Echo any bytes received back directly.
        let bytes_sent = tokio::io::copy(&mut recv, &mut send).await?;

        send.finish()?;
        connection.closed().await;

        Ok(())
    }
}
```

The full example code with more comments can be found at [`echo.rs`][echo-rs].

Or use one of the pre-existing protocols, e.g. [iroh-blobs] or [iroh-gossip].

### Other Languages

If you want to use iroh from other languages, make sure to check out [iroh-ffi], the repository for FFI bindings.

### Links

- [Introducing Iroh (video)][iroh-yt-video]
- [Iroh Documentation][docs]
- [Iroh Examples]
- [Iroh Experiments]

## Repository Structure

This repository contains a workspace of crates:
- `iroh`: The core library for hole-punching & communicating with relays.
- `iroh-relay`: The relay client and server implementation. This is the code we run in production for the public relays (and you can, too!).
- `iroh-base`: Common types like `EndpointId` or `RelayUrl`.
- `iroh-dns-server`: DNS server implementation powering the DNS/Pkarr address lookup for EndpointIds, running at dns.iroh.link.

## License

Copyright 2025 N0, INC.

This project is licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
   https://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or
   https://opensource.org/licenses/MIT)

at your option.

## Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

[QUIC]: https://en.wikipedia.org/wiki/QUIC
[BLAKE3]: https://github.com/BLAKE3-team/BLAKE3
[noq]: https://github.com/n0-computer/noq
[iroh-blobs]: https://github.com/n0-computer/iroh-blobs
[iroh-gossip]: https://github.com/n0-computer/iroh-gossip
[iroh-docs]: https://github.com/n0-computer/iroh-docs
[iroh-doctor]: https://github.com/n0-computer/iroh-doctor
[willow protocol]: https://willowprotocol.org
[iroh-ffi]: https://github.com/n0-computer/iroh-ffi
[iroh-yt-video]: https://www.youtube.com/watch?v=RwAt36Xe3UI_
[Iroh Examples]: https://github.com/n0-computer/iroh-examples
[Iroh Experiments]: https://github.com/n0-computer/iroh-experiments
[echo-rs]: /iroh/examples/echo.rs
[iroh-perf]: https://perf.iroh.computer
[docs]: https://docs.iroh.computer

---

### Overview (`docker/README.md`)

# Iroh Docker Images

## Intro

A set of docker images provided to easily run iroh in a containerized environment.
Features `iroh-relay` and `iroh-dns-server`.

The provided `Docker` files are intended for CI use but can be also manually built.

## Building

- All commands are run from the root folder
- If you're on macOS run `docker buildx build -f docker/Dockerfile --target iroh-relay --platform linux/arm64/v8 --tag n0computer/iroh-relay:latest .`
- If you're on linux run `docker buildx build -f docker/Dockerfile --target iroh-relay --platform linux/amd64 --tag n0computer/iroh-relay:latest .`
- Switch out `--target iroh-relay` for `iroh-dns-server`

## Running

### iroh-relay

- Provide a config file: `docker run -v /path/to/iroh-relay.conf:/config/iroh-relay.conf -p 80:80 -p 443:443 -p 3478:3478/udp -p 9090:9090 -it n0computer/iroh-relay:latest <params> --config /config/iroh-relay.conf`

### iroh-dns-server

- Provide a config file: `docker run -v /path/to/iroh-dns-server.conf:/config/iroh-dns-server.conf -p 53:53/udp -p 9090:9090 -it n0computer/iroh-dns-server:latest <params> --config /config/iroh-dns-server.conf`

---

### Overview (`iroh-base/README.md`)

# iroh-base

This crate provides base types and utilities used throughout Iroh.

# License

This project is licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
   https://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or
   https://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.

---

### Overview (`iroh-dns-server/README.md`)

# iroh-dns-server

A server that functions as a [pkarr](https://github.com/Nuhvi/pkarr/) relay and
[DNS](https://de.wikipedia.org/wiki/Domain_Name_System) server.

This server compiles to a binary `iroh-dns-server`. It needs a config file, of
which there are two examples included:

- [`config.dev.toml`](./config.dev.toml) - suitable for local development
- [`config.prod.toml`](./config.prod.toml) - suitable for production, after
  adjusting the domain names and IP addresses

The server will expose the following services:

- A DNS server listening on UDP and TCP for DNS queries
- A HTTP and/or HTTPS server which provides the following routes:
  - `/pkarr`: `GET` and `PUT` for pkarr signed packets
  - `/dns-query`: Answer DNS queries over
    [DNS-over-HTTPS](https://datatracker.ietf.org/doc/html/rfc8484)

All received and valid pkarr signed packets will be served over DNS. The pkarr
packet origin will be appended with the origin as configured by this server.

# License

This project is licensed under either of

- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
  https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.

---

### Overview (`iroh-dns/README.md`)

# iroh-dns

DNS-based endpoint discovery for Iroh.

This crate contains the core types for publishing and resolving iroh endpoint information via DNS, using the [pkarr](pkarr.org) signed packet format.

# License

This project is licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
   https://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or
   https://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.

---

### Overview (`iroh-relay/README.md`)

# Iroh Relay

Iroh's relay is a feature within [iroh], a peer-to-peer networking system
designed to facilitate direct, encrypted connections between devices. Iroh aims
to simplify decentralized communication by automatically handling connections
through "relays" when direct connections aren't immediately possible. The relay
server helps establish connections by temporarily routing encrypted traffic
until a direct, P2P connection is feasible. Once this direct path is set up,
the relay server steps back, and the data flows directly between devices. This
approach allows Iroh to maintain a secure, low-latency connection, even in
challenging network situations.

This crate provides a complete setup for creating and interacting with iroh
relays, including:
- Relay Protocol: The protocol used to communicate between relay servers and
  clients
- Relay Server: A fully-fledged iroh-relay server over HTTP or HTTPS.
  Optionally will also expose a QAD endpoint and metrics.
- Relay Client: A client for establishing connections to the relay.
- Server Binary: A CLI for running your own relay server. It can be configured
  to also expose metrics.


Used in [iroh], created with love by the [n0 team](https://n0.computer/).

## Build the server

You can build an optimised release of `iroh-relay` by running `cargo build`
with the appropriate flags from the workspace parent directory as follows.

```
cd ../
cargo build \
  --profile optimized-release \
  --package iroh-relay \
  --features server
```

You will find the optimised binary at `target/optimized-release/iroh-relay`.

## Access control

The relay server supports several access control modes, configured via the
`access` field in the TOML config file.

### Allow everyone (default)

```toml
access = "everyone"
```

### Allowlist / Denylist by endpoint ID

```toml
# Allow only specific endpoints
access.allowlist = ["<endpoint-id>", "<endpoint-id>"]

# Or block specific endpoints and allow everyone else
access.denylist = ["<endpoint-id>"]
```

### Shared token (local, no external service)

Requires connecting clients to present one of the configured shared secrets via an
`Authorization: Bearer <token>` header, or a `?token=` URL query parameter.

```toml
access.shared_token = ["token-a", "token-b"]
```

The token list can also be overridden by the `IROH_RELAY_ACCESS_TOKEN` environment
variable, which sets a single allowed token and takes precedence over the config file
value. A single value is used (rather than a comma-separated list) to avoid restricting
the character set of tokens.

The token list must not be empty, and no token may be an empty string; the server will
fail to start if either condition is violated.

On the client side, set the token using
[`RelayConfig::with_auth_token`](https://docs.rs/iroh-relay/latest/iroh_relay/struct.RelayConfig.html#method.with_auth_token)
or
[`RelayMap::with_auth_token`](https://docs.rs/iroh-relay/latest/iroh_relay/struct.RelayMap.html#method.with_auth_token).

> **Note:** this shared token does not support revocation other than updating the config and restarting the service.

### HTTP callout (external auth service)

The relay calls an external HTTP endpoint for each incoming connection,
passing the connecting endpoint's ID. The token below authenticates the relay
to your auth service (machine-to-machine), not the connecting client.

```toml
access.http.url = "https://your-auth-service.example.com/relay-auth"
# Optional: authenticate the relay's outbound request to your service
access.http.bearer_token = "service-to-service-secret"
```

The bearer token can also be set via the `IROH_RELAY_HTTP_BEARER_TOKEN`
environment variable.

For every connection, the relay sends a `POST` request with no body to
`access.http.url`. The connecting endpoint's ID is sent in the
`X-Iroh-Endpoint-Id` header. If a bearer token is configured, it is sent in an
`Authorization: Bearer <token>` header.

To allow the connection, your service must respond with status `200` and the
response body `true`.

Example request:

```http
POST /relay-auth HTTP/1.1
x-iroh-endpoint-id: da1ee49ba54d124a2e2b0f043bac3d63ec086b0b40e7d0895914898b237e847e
x-iroh-nodeid: da1ee49ba54d124a2e2b0f043bac3d63ec086b0b40e7d0895914898b237e847e
authorization: Bearer service-to-service-secret
accept: */*
host: your-auth-service.example.com
```

> **Note:** the endpoint ID is also sent in the deprecated `X-Iroh-NodeId`
> header for backwards compatibility. It will be removed in a future release.
>New services should use `X-Iroh-Endpoint-Id`.

## Local testing

Advice for testing your application that uses `iroh` with a locally running `iroh-relay` server

### dev mode
When running the relay server using the `--dev` flag, you will:
- only run the server over http, not https
- will NOT run the QUIC endpoint that enables QUIC address discovery

The relay can be contacted at "http://localhost:3340".

Both https and QUIC address discovery require TLS certificates. It's possible to run QUIC address discovery using locally generated TLS certificates, but it takes a few extra steps and so, is disabled by default for now.

### dev mode with QUIC address discovery

So you want to test out QUIC address discovery locally?

In order to do that you need TLS certificates.

The easiest get that is to generate self-signed certificates using `rcgen`
  - get rcgen (`git clone https://github.com/rustls/rcgen`)
  - cd to the `rcgen` directory
  - generate local certs using `cargo run -- -o path/to/certs`

Next, add the certificate paths to your iroh-relay config, here is an example of a config.toml file that will enable quic address discovery.
```toml
enable_quic_addr_discovery = true

[tls]
cert_mode = "Manual"
manual_cert_path = "/path/to/certs/cert.pem"
manual_key_path = "/path/to/certs/cert.key.pem"
```

Then run the server with the `--dev` flag, like you would when normally testing locally:
`cargo run --features="server" --bin iroh-relay -- --config-path=/path/to/config.toml --dev`

The relay server will run over http on port 3340, as it does using the `--dev` flag, but it will also run a QUIC server on port 7824.

The relay will use the configured TLS certificates for the QUIC connection, but use http (rather than https) for the server.

### Using iroh-relay as a library to run in-process relays in integration tests

When using iroh as a transport library in an application or other library, there is a simple way of running an in-process relay server:

- Enable `test-utils` feature of the `iroh` crate
```toml
iroh = { version = "0.95", features = ["test-utils"] }
```
- Spawn a relay server by calling [`iroh::test_utils::run_relay_server().await`](https://docs.rs/iroh/latest/iroh/test_utils/fn.run_relay_server.html)
This will start a relay server with a self-signed TLS certificate, listening on a localhost port, and return the server's URL.
- For the iroh endpoints to successfully connect to the relay, disable TLS certificate verification by calling [`Endpoint::ca_tls_config`](https://docs.rs/iroh/latest/iroh/endpoint/struct.Builder.html#method.ca_tls_config) with  `CaRootConfig::insecure_skip_verify()`.

# License

This project is licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
   https://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or
   https://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.

[iroh]: https://github.com/n0-computer/iroh

---

### Overview (`iroh/README.md`)

<h1 align="center">
<a href="https://iroh.computer">
<img alt="iroh" src="https://raw.githubusercontent.com/n0-computer/iroh/main/.img/iroh_wordmark.svg" width="100" />
</a>
</h1>

<h3 align="center">
less net work for networks
</h3>

[](https://docs.rs/iroh/)
[](https://crates.io/crates/iroh)
[](https://discord.com/invite/DpmJgtU7cW)
[](https://www.youtube.com/@n0computer)
[](LICENSE-MIT)
[](LICENSE-APACHE)

<div align="center">
  <h3>
    <a href="https://iroh.computer/docs">
      Docs Site
    </a>
    <span> | </span>
    <a href="https://docs.rs/iroh">
      Rust Docs
    </a>
  </h3>
</div>
<br/>

Iroh is a Rust library to establish direct connections between endpoints.
It gives you an API for dialing by public key. You say "connect to that
endpoint", and iroh finds and maintains the best connection for you.

Under the hood iroh establishes peer-to-peer [QUIC] connections between
endpoints. The fastest route is a direct connection, so iroh tries to
[hole-punch] one whenever it can. If that fails it falls back to using
relay servers.

Because iroh is built on [QUIC], all connections are end-to-end encrypted and may
carry any number of concurrent streams. Dialing by public key also makes them mutually
authenticated, because each endpoint's public key is its TLS identity.

## Overview

An iroh endpoint is created and controlled by the [`Endpoint`]. Each endpoint
has a unique [`SecretKey`], whose public key is the endpoint's identity, the
[`EndpointId`]. Connections are authenticated against this key, which means an
[`EndpointId`] can't be impersonated.

A connection is usually established with the help of a *relay server*. When an
endpoint is created it connects to the closest relay and designates it as its
*home relay*. Other endpoints reach it first through this relay, then both
sides use QUIC NAT traversal to establish a direct connection. In the rare
cases where a direct connection is not possible, traffic keeps flowing over the
relay.

Relay servers only forward encrypted packets addressed to Endpoint IDs, they
cannot read any traffic between endpoints.

Endpoints can also connect directly without a relay, as long as the accepting
endpoint is directly reachable at one of its addresses.

To discover addressing information for an endpoint, iroh uses
[address lookup services]. With address lookup, you can connect to other
endpoints with only their [`EndpointId`]. Addressing information will then
be resolved on-demand.

The [`N0` preset] installs the DNS/Pkarr address lookup service, which uses
servers hosted by [n0] to provide global lookup for endpoints.

## Example

This is an echo protocol: the accepting side copies back whatever it receives.
The full, commented version is in [`echo.rs`](examples/echo.rs).

```
/* Detailed source-code truncated for AI context efficiency. */
```

More examples live in [`iroh/examples`](examples). Run them with
`cargo run --example NAME`. Details for each are in the file itself.

## Compose protocols

Instead of writing your own, you can build on protocols that already exist on
top of iroh:

- [iroh-blobs] for [BLAKE3]-based content-addressed blob transfer, scaling from
  kilobytes to terabytes.
- [iroh-gossip] for publish-subscribe overlay networks that scale down to what
  an average phone can handle.
- and many more.

To use iroh from other languages, see [iroh-ffi].

## Development

For notes on iroh's structured events and how to build the documentation, see
[DEVELOPMENT.md](DEVELOPMENT.md).

# License

This project is licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
   https://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or
   https://opensource.org/licenses/MIT)

at your option.

### Contribution

See [CONTRIBUTING.md](https://github.com/n0-computer/iroh/blob/main/CONTRIBUTING.md)
for how to get involved.

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.

[QUIC]: https://en.wikipedia.org/wiki/QUIC
[hole-punch]: https://en.wikipedia.org/wiki/Hole_punching_(networking)
[BLAKE3]: https://github.com/BLAKE3-team/BLAKE3
[`Endpoint`]: https://docs.rs/iroh/latest/iroh/struct.Endpoint.html
[`SecretKey`]: https://docs.rs/iroh/latest/iroh/struct.SecretKey.html
[`EndpointId`]: https://docs.rs/iroh/latest/iroh/struct.EndpointId.html
[address lookup services]: https://docs.rs/iroh/latest/iroh/address_lookup/index.html
[`N0` preset]: https://docs.rs/iroh/latest/iroh/endpoint/presets/struct.N0.html
[iroh-blobs]: https://github.com/n0-computer/iroh-blobs
[iroh-gossip]: https://github.com/n0-computer/iroh-gossip
[iroh-ffi]: https://github.com/n0-computer/iroh-ffi
[n0]: https://n0.computer

---

### Iroh Docs Local Relays (`iroh/docs/local_relays.md`)

# Using a local iroh-relay

It's easy to set up a iroh-relay that runs locally on your machine.

Using cargo:

```shell
$ cargo run --bin iroh-relay --features="iroh-relay" -- --dev
```

This will bind the iroh-relay to `[::]3340` and run it over HTTP.

To connect to this iroh-relay when doing your normal iroh commands, adjust the iroh configuration file to read:

```toml
# iroh.config.toml:
[[relays]]
url = "http://localhost:3340"
```

If you want to give a specific port for the iroh-relay to bind to, you can create a iroh-relay config file and pass that file in using the `--config_path` flag. You need to retain a `secret_key`, so it is recommended to run `iroh-relay --config-path [PATH]` once to generate a secret key and save it to the config file before doing further edits to the file.

To change the port you want to listen on, change the port in the `addr` field:

```
# iroh-relay.toml

secret_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
addr = "[::]:12345"
hostname = "my.relay.network"
enable_relay = true
```

Check [the iroh-relay file's](../src/bin/iroh-relay.rs) `Config` struct for documentation on each configuration field.

If you change the local iroh-relay server's configuration, however, be sure to adjust the associated fields in your iroh config as well.

---

### Iroh Docs Relays (`iroh/docs/relays.md`)

# Relays

When an Iroh endpoint starts up, it does a latency test to see which known relay endpoint it is “closest to”. That relay server is considered the Iroh endpoint's home relay server.

An endpoint may be connected to multiple relay servers, but it will advertise its home relay endpoint as the one best used to hole-punch or relay packets through.

You do not need to know an endpoint's relay server in order to connect to them directly, if there are no firewalls or NATs between the two endpoints trying to connect. However, to have any hole punching, you must know at least one relay server to which that endpoint is connected.

We currently run 3 relays.

---

--- METRICS ---
- Files Extracted: 9
- Estimated Token Budget: ~6084 tokens
- Canonical Reference: https://codewiki.google/github.com/n0-computer/iroh
