n0-computer /iroh
IP addresses break, dial keys instead. A library that adds QUIC + NAT Traversal to your apps.
★ 12,919⑂ 758👁 101▤ 74
12,919
stars
+0+12+268
758
forks
101
watchers
–
prs
–
issues
74
releases
–
discussions
README
less net work for networks
Docs Site
|
Rust Docs
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]