Skip to content

Commit 7b286ef

Browse files
authored
Merge pull request #35 from n0-computer/rae/iroh-0.97
feat: 0.97
2 parents d7831ad + 49ffbb8 commit 7b286ef

File tree

14 files changed

+223
-59
lines changed

14 files changed

+223
-59
lines changed

connecting/creating-endpoint.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ This method initializes a new endpoint and binds it to a local address, allowing
1515
to listen for incoming connections.
1616

1717
```rust
18-
use iroh::Endpoint;
18+
use iroh::{Endpoint, presets};
19+
use anyhow::Result;
1920

2021
#[tokio::main]
21-
async fn main() {
22-
let endpoint = Endpoint::bind().await?;
22+
async fn main() -> Result<()> {
23+
let endpoint = Endpoint::bind(presets::N0).await?;
2324
// ...
25+
Ok(())
2426
}
2527
```
2628

connecting/dns-discovery.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ options](https://cal.com/team/number-0/n0-protocol-services?overlayCalendar=true
2525

2626

2727
```rust
28-
use iroh::Endpoint;
28+
use iroh::{Endpoint, presets};
2929
use iroh_tickets::endpoint::EndpointTicket;
3030

3131
#[tokio::main]
3232
async fn main() -> anyhow::Result<()> {
33-
let endpoint = Endpoint::bind().await?;
33+
let endpoint = Endpoint::bind(presets::N0).await?;
3434

3535
println!("endpoint id: {:?}", endpoint.id());
3636

connecting/gossip.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ There are different ways to structure your application around topics, depending
4747
### Example
4848

4949
```rust
50-
use iroh::{protocol::Router, Endpoint, EndpointId};
50+
use iroh::{protocol::Router, Endpoint, EndpointId, presets};
5151
use iroh_gossip::{api::Event, Gossip, TopicId};
5252
use n0_error::{Result, StdResultExt};
5353
use n0_future::StreamExt;
@@ -56,7 +56,7 @@ use n0_future::StreamExt;
5656
async fn main() -> Result<()> {
5757
// create an iroh endpoint that includes the standard discovery mechanisms
5858
// we've built at number0
59-
let endpoint = Endpoint::bind().await?;
59+
let endpoint = Endpoint::bind(presets::N0).await?;
6060

6161
// build gossip protocol
6262
let gossip = Gossip::builder().spawn(endpoint.clone());

connecting/local-discovery.mdx

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
---
2-
title: "mDNS and Bluetooth"
2+
title: "mDNS"
33
---
44

5-
Local discovery adds the ability to use physical radios to discover other iroh
6-
endpoints. This is useful for local networks where the internet may not be available or reliable.
5+
The mDNS discovery mechanism will automatically broadcast your endpoint's
6+
presence on the local network, and listen for other endpoints doing the same. When
7+
another endpoint is discovered, the dialing information is exchanged, and a
8+
connection can be established directly over the local network without needing a relay.
79

8-
Local connections can be faster and more reliable than internet-based connections, especially in
9-
environments with poor connectivity. They also enhance privacy by keeping communications within a local area.
10+
Devices need to be connected to the same local network for mDNS discovery to
11+
work. This can be a Wi-Fi network, an Ethernet network, or even a mobile
12+
hotspot. mDNS is not designed to work over the internet or across different
13+
networks.
1014

11-
## mDNS
15+
## Usage
1216

13-
Local Discovery is _not_ enabled by default, and must be enabled by the user.
17+
Local Discovery is _not_ enabled by default, and must be enabled explicitly.
1418
You'll need to add the `discovery-local-network` feature flag to your
1519
`Cargo.toml` to use it.
1620

@@ -23,23 +27,13 @@ iroh = { version = "0.nn", features = ["address-lookup-mdns"] }
2327
Then configure your endpoint to use local discovery concurrently with the default DNS discovery:
2428

2529
```rust
26-
use iroh::Endpoint;
30+
use iroh::{Endpoint, presets};
2731

2832
let mdns = iroh::address_lookup::mdns::MdnsAddressLookup::builder();
2933
let ep = Endpoint::builder()
3034
.address_lookup(mdns)
31-
.bind()
35+
.bind(presets::N0)
3236
.await?;
3337
```
3438

35-
The mDNS discovery mechanism will automatically broadcast your endpoint's
36-
presence on the local network, and listen for other endpoints doing the same. When
37-
another endpoint is discovered, the dialing information is exchanged, and a
38-
connection can be established directly over the local network without needing a relay.
39-
4039
For more information on how mDNS discovery works, see the [mDNS documentation](https://docs.rs/iroh/latest/iroh/address_lookup/mdns/index.html).
41-
42-
## Bluetooth
43-
44-
Bluetooth discovery is currently under development and will be available in a
45-
future release of iroh. For more information, please [contact us](https://cal.com/team/number-0/n0-protocol-services).

docs.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
]
3535
},
3636
{
37-
"group": "Forming a Network",
37+
"group": "Creating Connections",
3838
"pages": [
3939
"connecting/creating-endpoint",
4040
"connecting/custom-relays",
@@ -46,7 +46,7 @@
4646
]
4747
},
4848
{
49-
"group": "Building your App",
49+
"group": "Sending Data",
5050
"pages": [
5151
"protocols/kv-crdts",
5252
"protocols/blobs",
@@ -58,6 +58,14 @@
5858
"protocols/using-quic"
5959
]
6060
},
61+
{
62+
"group": "Transports",
63+
"pages": [
64+
"transports/tor",
65+
"transports/nym",
66+
"transports/bluetooth"
67+
]
68+
},
6169
{
6270
"group": "Deployment",
6371
"pages": [

examples/chat.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,12 @@ Topics are the fundamental unit of communication in the gossip protocol. Here's
134134
```rust
135135
use anyhow::Result;
136136
use iroh::protocol::Router;
137-
use iroh::Endpoint;
137+
use iroh::{Endpoint, presets};
138138
use iroh_gossip::{net::Gossip, proto::TopicId};
139139

140140
#[tokio::main]
141141
async fn main() -> Result<()> {
142-
let endpoint = Endpoint::bind().await?;
142+
let endpoint = Endpoint::bind(presets::N0).await?;
143143

144144
println!("> our endpoint id: {}", endpoint.id());
145145
let gossip = Gossip::builder().spawn(endpoint.clone());
@@ -324,7 +324,7 @@ use std::collections::HashMap;
324324
use anyhow::Result;
325325
use futures_lite::StreamExt;
326326
use iroh::protocol::Router;
327-
use iroh::{Endpoint, EndpointId};
327+
use iroh::{Endpoint, EndpointId, presets};
328328
use iroh_gossip::{
329329
api::{GossipReceiver, Event},
330330
net::Gossip,
@@ -334,7 +334,7 @@ use serde::{Deserialize, Serialize};
334334

335335
#[tokio::main]
336336
async fn main() -> Result<()> {
337-
let endpoint = Endpoint::bind().await?;
337+
let endpoint = Endpoint::bind(presets::N0).await?;
338338

339339
println!("> our endpoint id: {}", endpoint.id());
340340
let gossip = Gossip::builder().spawn(endpoint.clone());
@@ -535,7 +535,7 @@ use std::{collections::HashMap, fmt, str::FromStr};
535535
use anyhow::Result;
536536
use clap::Parser;
537537
use futures_lite::StreamExt;
538-
use iroh::{protocol::Router, Endpoint, EndpointAddr, EndpointId};
538+
use iroh::{protocol::Router, Endpoint, EndpointAddr, EndpointId, presets};
539539
use iroh_gossip::{
540540
api::{GossipReceiver, Event},
541541
net::Gossip,
@@ -591,7 +591,7 @@ async fn main() -> Result<()> {
591591
}
592592
};
593593

594-
let endpoint = Endpoint::bind().await?;
594+
let endpoint = Endpoint::bind(presets::N0).await?;
595595

596596
println!("> our endpoint id: {}", endpoint.id());
597597
let gossip = Gossip::builder().spawn(endpoint.clone());

protocols/blobs.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ This is what manages the possibly changing network underneath, maintains a conne
104104
async fn main() -> anyhow::Result<()> {
105105
// Create an endpoint, it allows creating and accepting
106106
// connections in the iroh p2p world
107-
let endpoint = Endpoint::bind().await?;
107+
let endpoint = Endpoint::bind(presets::N0).await?;
108108

109109
// ...
110110

@@ -124,7 +124,7 @@ It loads files from your file system and provides a protocol for seekable, resum
124124
async fn main() -> anyhow::Result<()> {
125125
// Create an endpoint, it allows creating and accepting
126126
// connections in the iroh p2p world
127-
let endpoint = Endpoint::bind().await?;
127+
let endpoint = Endpoint::bind(presets::N0).await?;
128128

129129
// We initialize an in-memory backing store for iroh-blobs
130130
let store = MemStore::new();

protocols/rpc.mdx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ But we said that we wanted to be able to seamlessly switch between remote or loc
169169
```rust
170170
enum Client {
171171
Local(mpsc::Sender<FullRequest>),
172-
Remote(quinn::Connection),
172+
Remote(noq::Connection),
173173
}
174174

175175
impl Client {
@@ -206,7 +206,7 @@ But what about all this boilerplate?
206206

207207
**The `irpc` crate is meant solely to reduce the tedious boilerplate involved in writing the above manually.**
208208

209-
It does *not* abstract over the connection type - it only supports [iroh-quinn] send and receive streams out of the box, so the only two possible connection types are `iroh` p2p QUIC connections and normal QUIC connections. It also does not abstract over the local channel type - a local channel is always a `tokio::sync::mpsc` channel. Serialization is always using postcard and length prefixes are always postcard varints.
209+
It does *not* abstract over the connection type - it only supports [noq] QUIC send and receive streams out of the box, so the only two possible connection types are `iroh` p2p QUIC connections and normal QUIC connections. It also does not abstract over the local channel type - a local channel is always a `tokio::sync::mpsc` channel. Serialization is always using postcard and length prefixes are always postcard varints.
210210

211211
So let's see what our kv service looks like using `irpc`:
212212

@@ -286,8 +286,8 @@ converting the result into a futures `Stream` or the updates into a futures
286286
services that can be used in-process or across processes, not to provide an
287287
opinionated high level API.
288288

289-
For stream based rpc calls, there is an issue you should be aware of. The quinn
290-
`SendStream` will send a finish message when dropped. So if you have a finite
289+
For stream based rpc calls, there is an issue you should be aware of. The noq
290+
QUIC `SendStream` will send a finish message when dropped. So if you have a finite
291291
stream, you might want to have an explicit end marker that you send before
292292
dropping the sender to allow the remote side to distinguish between successful
293293
termination and abnormal termination. E.g. the `SetFromStream` request from
@@ -330,9 +330,9 @@ If you are reading from a remote source, and there is a problem with the connect
330330

331331
But what about writing? E.g. you got a task that performs an expensive computation and writes updates to the remote in regular intervals. You will only detect that the remote side is gone once you write, so if you write infrequently you will perform an expensive computation despite the remote side no longer being available or interested.
332332

333-
To solve this, an irpc Sender has a [closed](https://docs.rs/irpc/0.5.0/irpc/channel/mpsc/enum.Sender.html#method.closed) function that you can use to detect the remote closing without having to send a message. This wraps [tokio::sync::mpsc::Sender::closed](https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.Sender.html#method.closed) for local streams and [quinn::SendStream::stopped](https://docs.rs/iroh-quinn/latest/iroh_quinn/struct.SendStream.html#method.stopped) for remote streams.
333+
To solve this, an irpc Sender has a [closed](https://docs.rs/irpc/0.5.0/irpc/channel/mpsc/enum.Sender.html#method.closed) function that you can use to detect the remote closing without having to send a message. This wraps [tokio::sync::mpsc::Sender::closed](https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.Sender.html#method.closed) for local streams and [noq::SendStream::stopped](https://github.com/n0-computer/noq) for remote QUIC streams.
334334

335-
## Alternatives to iroh-quinn
335+
## Alternatives to noq
336336

337337
If you integrate iroh protocols into an existing application, it could be that you already have a rpc system that you are happy with, like [grpc](https://grpc.io/) or [json-rpc](https://www.jsonrpc.org/).
338338

@@ -361,9 +361,9 @@ and maintained.
361361
## References
362362

363363
- [postcard](https://docs.rs/postcard/latest/postcard/)
364-
- [iroh-quinn](https://docs.rs/iroh-quinn/latest/iroh_quinn/)
365-
- [RecvStream](https://docs.rs/iroh-quinn/latest/iroh_quinn/struct.RecvStream.html)
366-
- [SendStream](https://docs.rs/iroh-quinn/latest/iroh_quinn/struct.SendStream.html)
364+
- [noq](https://github.com/n0-computer/noq)
365+
- [RecvStream](https://github.com/n0-computer/noq)
366+
- [SendStream](https://github.com/n0-computer/noq)
367367
- [Stream](https://docs.rs/futures/latest/futures/prelude/trait.Stream.html)
368368
- [Sink](https://docs.rs/futures/latest/futures/sink/trait.Sink.html)
369369
- [snafu](https://docs.rs/snafu/latest/snafu/)

protocols/using-quic.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,26 @@
22
title: "Using QUIC"
33
---
44

5-
## Why this matters for iroh
5+
Every endpoint uses QUIC over UDP by default — no configuration required.
66

7-
iroh is built on top of QUIC, providing connectivity, NAT traversal, and encrypted connections out of the box. While iroh handles the hard parts of networking—holepunching, relay servers, and discovery—**you still need to design how your application exchanges data once connected**.
7+
iroh's QUIC implementation is built on
8+
[noq](https://github.com/n0-computer/noq), which includes multipath support and
9+
QUIC NAT traversal.
10+
11+
All connections are encrypted and authenticated using TLS 1.3. Holepunching,
12+
relay fallback, and multipath are all handled at the QUIC layer automatically.
13+
14+
## Custom transports
15+
16+
QUIC over UDP is the default, but iroh supports plugging in additional custom
17+
transports alongside it.
18+
19+
All transports, even custom transports [Tor](/transports/tor), [Nym](/transports/nym), and
20+
[Bluetooth](/transports/bluetooth) deliver QUIC datagrams.
21+
22+
## Using QUIC
23+
24+
While iroh handles the hard parts of networking—holepunching, relay servers, and discovery—**you still need to design how your application exchanges data once connected**.
825

926
Many developers reach for iroh expecting it to completely abstract away the underlying transport. However, iroh intentionally exposes QUIC's powerful stream API because:
1027

@@ -15,7 +32,7 @@ Many developers reach for iroh expecting it to completely abstract away the unde
1532
Think of iroh as giving you **reliable, secure tunnels between peers**. This guide shows you how to use QUIC's streaming patterns to build efficient protocols inside those tunnels. Whether you're adapting an existing protocol or designing something new, understanding these patterns will help you make the most of iroh's capabilities.
1633

1734
<Note>
18-
iroh uses a fork of [Quinn](https://docs.rs/iroh-quinn/latest/iroh_quinn/), a pure-Rust implementation of QUIC maintained by [n0.computer](https://n0.computer). Quinn is production-ready, actively maintained, and used by projects beyond iroh. If you need lower-level QUIC access or want to understand the implementation details, check out the [Quinn documentation](https://docs.rs/iroh-quinn/latest/iroh_quinn/).
35+
iroh uses [noq](https://github.com/n0-computer/noq), a pure-Rust QUIC implementation maintained by [n0.computer](https://n0.computer). noq is production-ready, actively maintained, and used by projects beyond iroh. If you need lower-level QUIC access or want to understand the implementation details, check out the [noq repository](https://github.com/n0-computer/noq).
1936
</Note>
2037

2138

protocols/writing-a-protocol.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Now, we can modify our router so it handles incoming connections with our newly
8787

8888
```rs
8989
async fn start_accept_side() -> anyhow::Result<iroh::protocol::Router> {
90-
let endpoint = iroh::Endpoint::bind().await?;
90+
let endpoint = iroh::Endpoint::bind(iroh::presets::N0).await?;
9191

9292
let router = iroh::protocol::Router::builder(endpoint)
9393
.accept(ALPN, Echo) // This makes the router handle incoming connections with our ALPN via Echo::accept!
@@ -164,7 +164,7 @@ This follows the [request-response pattern](/protocols/using-quic#request-and-re
164164

165165
```rs
166166
async fn connect_side(addr: EndpointAddr) -> Result<()> {
167-
let endpoint = Endpoint::bind().await?;
167+
let endpoint = Endpoint::bind(iroh::presets::N0).await?;
168168

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

0 commit comments

Comments
 (0)