Skip to content

Commit f1c174b

Browse files
authored
Merge pull request #3 from n0-computer/rae/docs-review
Docs ready for review
2 parents 71c97d3 + 5fa0d56 commit f1c174b

18 files changed

+841
-177
lines changed

about/changelog.mdx

Lines changed: 0 additions & 5 deletions
This file was deleted.

about/roadmap.mdx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,30 @@
22
title: "Roadmap"
33
---
44

5-
Placeholder: High-level roadmap and planned features.
5+
## now
6+
7+
## next
8+
9+
#### Draft specification
10+
11+
Draft a specification for the iroh protocol, outlining all open standards iroh uses, noting any deviations
12+
13+
self-signed TLS
14+
QUIC
15+
ICE over QUIC
16+
STUN over QUIC
17+
DNS Discovery
18+
Pkarr
19+
MDNs
20+
WebSockets
21+
iroh relay
22+
finalize 1.0 spec
23+
ratify the iroh 1.0 wire protocol
24+
25+
Finalize FFI integration
26+
protocol developers have a clear path for integrating rust protocols into other languages
27+
28+
documentation refinement
29+
ensure documentation is accurate and robust
30+
31+
## later

concepts/discovery.mdx

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,15 @@ Endpoint discovery is an automated system for an [Endpoint](/concepts/endpoints)
1414

1515
## Discovery Services
1616

17-
There are four different implementations of the discovery service in iroh. iroh
18-
uses the DNS discovery system to resolve EndpointIds to addresses, but you can choose to opt-in and configure
19-
iroh to use any of the other discovery systems.
17+
There are four different implementations of the discovery service in iroh. **By default, iroh uses DNS discovery** to resolve EndpointIds to addresses. Local and DHT discovery are **disabled by default** and must be explicitly configured if you want to use them.
2018

2119

22-
| Name | Description | |
20+
| Name | Description | Default |
2321
| --- | --- | --- |
24-
| [DNS](/connecting/global-discovery) | uses a custom Domain Name System server |
25-
| [Local](/connecting/local-discovery) | uses an mDNS-like system to find endpoints on the local network |
26-
| [Pkarr](/connecting/global-discovery#pkarr-discovery) | uses Pkarr Servers over HTTP |
27-
| [DHT](/conecting/global-discovery/#dht-discovery) | uses the BitTorrent Mainline DHT |
22+
| [DNS](#node-discovery-via-dns) | uses a custom Domain Name System server | ✅ Enabled |
23+
| [Local](#local-discovery) | uses an mDNS-like system to find endpoints on the local network | ❌ Disabled |
24+
| [Pkarr](#node-announces-via-pkarr) | uses Pkarr Servers over HTTP | ✅ Enabled (via DNS) |
25+
| [DHT](#dht-discovery) | uses the BitTorrent Mainline DHT | ❌ Disabled |
2826

2927
### The motivation
3028

@@ -87,7 +85,7 @@ that node. So the Pkarr packet currently only needs to contain the Node ID and
8785
the relay URL of its preferred relay server (which we call its “home relay”).
8886
When Pkarr publishing is enabled on your iroh node, your node will create a
8987
Pkarr packet with its Node ID and relay URL, sign it, and defaults to publishing
90-
on an `iroh-dns` server that is run by number0.
88+
on an `iroh-dns` server that is run by [the n0 team](https://n0.computer).
9189

9290
From there, others can discover your dialing information by resolving your Node
9391
ID using regular DNS. It’s worth noting that others must still learn your node
@@ -97,21 +95,25 @@ The following sections describe the format of the Pkarr publishing records and N
9795

9896
## Node discovery via DNS
9997

100-
When connecting to an unknown `EndpointId`, the DNS discovery mechanism in iroh will perform a DNS query to discover relays or addresses for the node. The DNS discovery is configured with a *origin domain* (which defaults to *dns.iroh.link*, a server run by n0). iroh will then perform a DNS query through the configured DNS resolver (which defaults to using the host system's nameservers):
98+
When connecting to an unknown `EndpointId`, the DNS discovery mechanism in iroh will perform a DNS query to discover relays or addresses for the node. The DNS discovery is configured with a *origin domain* (which defaults to *dns.iroh.link*, a server run by n0). iroh will then perform a DNS query through the configured DNS resolver (which defaults to using the host system's nameservers):
10199

102100
`_iroh.<z32-node-id>.<origin-domain> TXT`
103101

104-
- `_iroh` is the record name defined in this spec
105-
- `<z32-node-id>` is the [z32](https://crates.io/crates/z32) encoding of the 32-byte long `EndpointId` (which is a string of 52 characters)
106-
- `<origin-domain>` is the configured origin domain
107-
- `TXT` is the queried record type
102+
- `_iroh` is the record name defined in this spec
103+
- `<z32-node-id>` is the [z32](https://crates.io/crates/z32) encoding of the 32-byte long `EndpointId` (which is a string of 52 characters)
104+
- `<origin-domain>` is the configured origin domain
105+
- `TXT` is the queried record type
108106

109-
The returned TXT records must contain a string value of the form `key=value`, as defined in [RFC1464](https://www.rfc-editor.org/rfc/rfc1464).
107+
The returned TXT records must contain a string value of the form `key=value`, as defined in [RFC1464](https://www.rfc-editor.org/rfc/rfc1464).
110108

111109
This spec defines the following attributes:
112110

113-
- `relay=<url>`: The home relay for this node, e.g. `https://euw1-1.derp.iroh.network`.
114-
- `addr=<addr> <addr> ..` A space-separated list of socket addresses for this iroh node. Each address is an IPv4 or IPv6 address with a port (e.g. `1.2.3.4:7367` or `[::1]:3521`
111+
- `relay=<url>`: The home relay for this node, e.g. `https://euw1-1.derp.iroh.network`.
112+
- `addr=<addr> <addr> ..` A space-separated list of socket addresses for this iroh node. Each address is an IPv4 or IPv6 address with a port (e.g. `1.2.3.4:7367` or `[::1]:3521`)
113+
114+
<Note>
115+
**Ready to use DNS discovery?** Learn how to configure DNS discovery in your application in the [DNS Discovery guide](/connecting/dns-discovery).
116+
</Note>
115117

116118
## Node announces via `pkarr`
117119

@@ -122,7 +124,7 @@ must be `_iroh.<node-id>.` The encoded node ID must be the root name, no other
122124
origin but `.` (the single dot) is permitted.
123125

124126
Those packets are published to a Pkarr relay server, which is a HTTP service
125-
handling PUT requests with the signed packets. irohs Pkarr server is
127+
handling PUT requests with the signed packets. iroh's Pkarr server is
126128
[`iroh-dns-server`](https://crates.io/crates/iroh-dns-server), which serves the
127129
received records over DNS. Pkarr packets can also be published onto the
128130
bittorrent mainline DHT, as specified by Pkarr (this is not yet supported in
@@ -132,12 +134,29 @@ DNS servers that support this spec will receive these Pkarr signed packets,
132134
check their signature and format validity, and then serve each contained record,
133135
with the DNS server's configured *origin domain* appended to all record names.
134136

137+
<Note>
138+
**Want to publish via Pkarr?** This is handled automatically when using DNS discovery. See the [DNS Discovery guide](/connecting/dns-discovery) for configuration details.
139+
</Note>
135140

136141
## Local Discovery
137142

138-
Global servers aren't the only way to find other iroh endpoint. Iroh also supports local
143+
**Note: Local discovery is disabled by default and must be explicitly enabled.**
144+
145+
Global servers aren't the only way to find other iroh endpoints. Iroh also supports local
139146
discovery, where endpoints on the same local network can find each other &
140-
exchange dialing information without a relay using mDNS. This is useful for
141-
offline environments, or for bootstrapping a network before a relay is available. For
142-
more info on configuring local discovery, see the [local discovery
143-
documentation](/connecting/local-discovery).
147+
exchange dialing information without a relay using mDNS. This is useful for
148+
offline environments, or for bootstrapping a network before a relay is available.
149+
150+
<Note>
151+
**Want to enable local discovery?** Learn how to configure and enable mDNS-based local discovery in the [Local Discovery guide](/connecting/local-discovery).
152+
</Note>
153+
154+
## DHT Discovery
155+
156+
**Note: DHT discovery is disabled by default and must be explicitly enabled.**
157+
158+
The Distributed Hash Table (DHT) discovery uses the BitTorrent Mainline DHT to publish and discover node addresses in a fully decentralized manner. This allows nodes to find each other without relying on centralized DNS servers.
159+
160+
<Note>
161+
**Want to enable DHT discovery?** Learn how to configure and enable DHT-based discovery in the [DHT Discovery guide](/connecting/dht-discovery).
162+
</Note>

concepts/holepunching.mdx

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,64 @@
22
title: "Holepunching"
33
---
44

5-
Placeholder: Describe NAT traversal and holepunching techniques.
5+
When two devices want to connect directly over the internet, they face a common problem: **Network Address Translation (NAT)**. Most home and office networks use NAT, which acts like a one-way door—devices inside the network can reach out to the internet, but the internet can't easily reach back in.
6+
7+
## The Problem: NAT Blocks Direct Connections
8+
9+
Imagine you're trying to video call a friend. Both of you are behind routers at home. When you try to connect directly to each other, your routers block the incoming connection because they don't recognize it as a response to something you requested. This is NAT protecting your network.
10+
11+
Traditionally, this problem was solved by:
12+
- **Port forwarding**: Manually configuring your router to allow specific connections (tedious and requires technical knowledge)
13+
- **Relay servers**: Routing all traffic through a third-party server (slow and expensive)
14+
15+
Neither solution is ideal for peer-to-peer applications.
16+
17+
## The Solution: Holepunching
18+
19+
**Holepunching** is a clever technique that tricks NAT routers into allowing direct connections between peers without manual configuration or relying entirely on relay servers.
20+
21+
Here's how it works:
22+
23+
### 1. Initial Contact Through a Relay
24+
25+
Both peers first connect to a shared [relay server](/concepts/relays). The relay acts as a meeting point where peers can coordinate without being able to connect directly yet.
26+
27+
### 2. Sharing Connection Information
28+
29+
Through the relay, peers exchange their:
30+
- **Public IP addresses** (how they appear to the outside internet)
31+
- **Port numbers** (the specific door number the router assigned them)
32+
- **Local addresses** (in case they're on the same network)
33+
34+
### 3. Simultaneous Outbound Connection
35+
36+
Here's the magic: both peers try to connect to each other **at the same time**. When peer A sends a packet to peer B's public address, A's router creates a temporary rule allowing responses from B. When peer B sends a packet to peer A at the same moment, B's router does the same.
37+
38+
Because both routers now have rules expecting traffic from each other, the packets get through, and a direct connection is established!
39+
40+
### 4. Fallback to Relay
41+
42+
If holepunching fails (some networks use particularly strict NAT configurations), iroh automatically falls back to routing traffic through the relay server. This ensures connections always work, even if they can't be direct.
43+
44+
## Why This Matters
45+
46+
With holepunching, iroh applications can:
47+
- **Connect directly** between devices without manual network configuration
48+
- **Reduce latency** by avoiding relay servers when possible
49+
- **Save bandwidth** by keeping data transfer peer-to-peer
50+
- **Maintain privacy** by not routing all traffic through third parties
51+
52+
The best part? All of this happens automatically—you don't need to understand the technical details to benefit from it.
53+
54+
## How iroh Implements Holepunching
55+
56+
iroh uses a sophisticated holepunching implementation built on top of QUIC and integrates with the relay system. For technical details on the implementation, see:
57+
58+
- [iroh's holepunching implementation](https://docs.rs/iroh/latest/iroh/endpoint/index.html#nat-traversal)
59+
- [Relay system documentation](/concepts/relays)
60+
- [Dedicated infrastructure setup](/deployment/dedicated-infrastructure)
61+
- [Endpoint configuration](https://docs.rs/iroh/latest/iroh/endpoint/struct.Endpoint.html)
62+
63+
<Note>
64+
Holepunching works in most network configurations, but some corporate firewalls or cellular networks may still require relay fallback. iroh handles this automatically.
65+
</Note>

concepts/relays.mdx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,31 @@ There are situations where a direct connection _can't_ be established, and in th
1919

2020
We're working on formally collecting the direct connection rate from production iroh networks. Anecdotal evidence points to the holepunching rate being around 90%, meaning 9 out of 10 times, a direct connection is established.
2121

22+
### Why this architecture is powerful
23+
24+
This approach makes uptime management significantly easier compared to
25+
traditional client-server architectures:
26+
27+
**Stateless servers, stateful clients**
28+
Unlike traditional servers that store your application's data and state, relay
29+
servers are just connection facilitators. All your business logic and data lives
30+
in your clients. This means:
31+
32+
- **No database synchronization** - You don't need to worry about keeping multiple server databases in sync or handling data replication
33+
- **No state migration** - When a relay goes down, clients simply reconnect to another relay without any data loss or state transfer
34+
- **Simple server management** - Relay servers are lightweight and easy to spin up or down. No complex deployment procedures or data migration steps
35+
36+
**Automatic failover**
37+
iroh clients automatically try multiple relays when connecting. If one relay is unavailable, clients seamlessly fall back to another relay in your list without application-level retry logic. Your peers will find each other as long as at least one relay is reachable.
38+
39+
**Multi-cloud resilience**
40+
For even better guarantees, you can distribute relays across multiple cloud providers. If one provider experiences an outage, your application keeps running on relays hosted elsewhere. Since relays don't store state, you can freely mix providers without worrying about cross-cloud data consistency.
41+
42+
**Cost-effective scaling**
43+
Adding capacity means spinning up more lightweight relay instances, not provisioning databases or managing complex stateful server infrastructure. You can easily scale up for peak usage and scale down during quiet periods.
44+
45+
This architecture inverts the traditional model: instead of treating servers as precious stateful resources and clients as disposable, relay-based architectures treat relays as disposable connection facilitators while clients own the application state and logic.
46+
2247
## Connection Changes
2348

2449
During the lifespan of a connection, networking conditions can change, for

connecting/creating-endpoint.mdx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use iroh::Endpoint;
2525

2626
#[tokio::main]
2727
async fn main() {
28-
let endpoint = Endpoint::builder().bind().await?;
28+
let endpoint = Endpoint::bind().await?;
2929
// ...
3030
}
3131
```
@@ -35,3 +35,13 @@ async fn main() {
3535
incoming connections
3636
2. `await` keyword is used to wait for the endpoint
3737
to be created in an asynchronous context.
38+
39+
## Next Steps
40+
41+
With an endpoint created, you can now start discovering and connecting to other endpoints.
42+
43+
Explore the following guides to learn more:
44+
- [DNS Global Discovery](/connecting/dns-discovery)
45+
- [Local Network Discovery](/connecting/local-discovery)
46+
- [Gossip and Topic Broadcast](/connecting/gossip)
47+
- [Writing a Protocol](/protocols/writing-a-protocol)

connecting/dns-discovery.mdx

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,73 @@ home relay addresses. This allows any iroh endpoint to be discoverable globally,
99
as long as they are connected to the same relay that is reachable from the public
1010
internet.
1111

12+
## Using DNS Discovery
13+
14+
DNS discovery is the default discovery mechanism in iroh, so you don't need to
15+
do anything special to enable it.
16+
17+
[Number 0](https://n0.computer) provides a set of public DNS servers that are
18+
free to use, and are configured by default. You're more than welcome to run
19+
production systems using the public relays if you find performance acceptable.
20+
The public servers do rate-limit traffic, there is no guaranteed uptime.
21+
22+
If you need more capacity or uptime guarantees or SLAs, you can
23+
run your own DNS server, or [contact us about hosted DNS
24+
options](https://cal.com/team/number-0/n0-protocol-services?overlayCalendar=true).
25+
26+
1227
```rust
1328
use iroh::Endpoint;
29+
use iroh_tickets::endpoint::EndpointTicket;
1430

1531
#[tokio::main]
1632
async fn main() -> anyhow::Result<()> {
1733
let endpoint = Endpoint::bind().await?;
1834

1935
println!("endpoint id: {:?}", endpoint.id());
36+
37+
let ticket = EndpointTicket::new(endpoint.addr());
38+
println!("Share this ticket to let others connect to your endpoint: {ticket}");
39+
2040
Ok(())
2141
}
2242
```
2343

24-
To discover other endpoints, you can use an EndpointId or a [Ticket](/concepts/tickets) that contains
44+
To discover other endpoints over DNS, you can use an EndpointId or a [Ticket](/concepts/tickets) that contains
2545
an EndpointId.
2646

27-
## Dedicated DNS Server
47+
## Use your own DNS Server
2848

2949
By default, iroh will look up the endpoint on a public shared instance of the
3050
DNS discovery server. If you'd like to run your own private DNS discovery server
3151
for more guaranteed privacy and uptime guarantees, you can configure iroh to use
3252
it.
3353

3454

55+
Two nodes must connect to the same DNS discovery server to find each other using
56+
DNS discovery.
57+
3558
TODO: rust code for custom dns server
3659

60+
## Disable DNS Discovery
61+
62+
DNS discovery is opt-out, so if you don't want your endpoint to be discoverable
63+
via DNS, you can disable it by using the `Endpoint::empty_builder` method
64+
instead of `Endpoint::builder`.
65+
66+
67+
```rust
68+
use iroh::Endpoint;
69+
#[tokio::main]
70+
async fn main() -> anyhow::Result<()> {
71+
let endpoint = Endpoint::empty_builder().bind().await?;
72+
// your code here
73+
Ok(())
74+
}
75+
```
76+
3777
## Important notes
3878

39-
1. DNS discovery is the default discovery mechanism in iroh, so you don't need
40-
to do anything special to enable it.
41-
2. DNS discovery only publishes the home relay of an endpoint, not its direct
42-
addresses.
43-
3. DNS discovery is opt-out, so if you don't want your endpoint to be
44-
discoverable via DNS, you can disable it by using the
45-
`Endpoint::empty_builder` method instead of `Endpoint::builder`.
46-
4. Two nodes must connect to the same DNS discovery server to find each other using DNS discovery.
4779

4880

4981

0 commit comments

Comments
 (0)