Blog Index

iroh 0.19.0 - Make it your own

by ramfox

Welcome to a new release of iroh, the open-source distributed systems toolkit with tools for connecting devices directly, moving data, and syncing state.

This release is all about making iroh more customizable for your own particular use case!

Better late than never 😂

Iroh has committed to a two week release cadence, which, if you've been following along closely, we didn't hit this week! On Monday, our normal release day, we found a critical bug. It only showed up rarely, and under high load, but we felt it was important to clean it up immediately.

Turns out, our RPC channels were not cancel-safe. We made the appropriate adjustment to the quic-rpc crate, which is a crate that we've written allowing many different RPC streaming options used in combination with a few different transports (including using QUIC streams or in memory channels). We then upgraded quic-rpc in iroh to fix the issue.

Check out PR #2416 on iroh and PR #87 on quic-rpc for details.

Custom Protocols

We’ve made it even easier to use iroh as the networking layer for your protocol! You can now add custom protocols when building an iroh Node, using the new ProtocolBuilder:

use std::sync::Arc;
use anyhow::Result;
use futures_lite::future::Boxed as BoxedFuture;
use iroh::{node::{Node, ProtocolHandler}, net::endpoint::Connecting, client::Iroh};

#[tokio::main]
async fn main() -> Result<()> {

	const MY_ALPN: &[u8] = b"my-protocol/1";

	#[derive(Debug)]
	struct MyProtocol {
	   client: Iroh
	}

	impl ProtocolHandler for MyProtocol {
	   fn accept(self: Arc<Self>, conn: Connecting) -> BoxedFuture<Result<()>> {
	       todo!();
	   }
	}

	// Build an in-memory node
	let unspawned_node = Node::memory()
	   .build()
	   .await?;

	// Create a handle to that node in the form of a `Client`, so
	// that your protocol has access to the underlying store.
	let client = unspawned_node.client().clone();
	let handler = MyProtocol { client };

	// Add your custom ALPN and handler code and spawn the iroh `Node`
	let node = unspawned_node
	   .accept(MY_ALPN, Arc::new(handler))
	   .spawn()
	   .await?;
	node.shutdown().await?;
	Ok(())
}

Take a look at the custom protocol work for a more fleshed-out example.

Check out PR #2358 for details.

Iroh without Docs

We’ve made the iroh Node more versatile! Let’s say you want to use iroh for networking and storage but don’t have a use case for iroh docs. We’ve made it dead simple to disable docs, so you can use the iroh Node for your exact purposes without worrying that you are dragging around pieces you don’t need.

Use Builder::disable_docs() when building the iroh Node; you’ll have just that. When called, the docs engine will not be spawned and the docs protocol will not be registered. Incoming docs connections will be dropped, and all docs-related RPC calls will return an error "docs are disabled".

Check out PR #2390 for details.

Easier RPC connections

If you plan to run iroh in some unusual architecture, this is the release for you.

We’ve added APIs to help launch an iroh Client that communicates to an iroh Node in a different process. Using Iroh::connect_addr, you can build an iroh Client that makes RPC calls to a given SocketAddr. We’ve also added Node::my_rpc_port to allow the iroh Node to communicate what RPC port it is running on.

This, most notably, will help with running iroh in docker. Keep your eyes peeled for some news in the coming weeks…

Check out PR #2398 for details.

Relay Server cleanup

The relay server got some much-needed love. Refactoring the code has allowed us to add the ability to run the relay behind a reverse proxy, disable captive portal responses, and run the server without TLS. The new configuration file has other options to allow for more customization, all of which are explained in the API Changes section below.

Check out PR #2341 for details.

⚠️ Breaking Changes

Protocol Changes

None!

API Changes

  • iroh
    • Builder loses the E type parameter
    • ProtocolBuilder loses the E type parameter
    • rpc_endpoint takes a boxed::ServerEndpoint
    • renamed
      • client::Iroh::connect -> client::Iroh::connect_path
    • added
      • client::Iroh::connect_addr
      • rpc_port field to client::NodeStatus
  • iroh-net
    • The configuration file format for the relay server has changed, deployments will need to updated. For the full format see struct Config in iroh-net/src/bin/iroh-relay.rs. Here a summary:
      • The 3 parts of the server now have an independent enable setting: enable_relayenable_stun and enable_metrics. If omitted they default to true.
      • The way to specify which addresses the server listens on has changed: http_bind_addr is for the relay server, stun_bind_addr for the STUN server, metrics_bind_addr is for the optional metrics server and tls.https_bind_addr is for when TLS is enabled. Note these are now all full socket addresses. All have sensible defaults if omitted.
      • There are new options in tls.cert_path and tls.key_path which allow more control over where the manual TLS keys are to be read from.
    • removed
      • iroh_net::config is removed.
      • iroh_net::config::NetInfo -> removed
      • iroh_net::config::LinkInfo -> removed
      • Endpoing::my_addr_with_endpoints has been removed.
    • renamed
      • Endpoint::local_endpoints -> Endpoint::direct_addresses
      • endpoint::LocalEndpointStream -> endpoint::DirectAddrStream
      • config::Endpoint -> magicsock::DirectAddr
      • config::EndpointType -> magicsock::DirectAddrType
      • Endpoint::local_addr -> Endpoint::bound_sockets
      • Endpoint::my_addr -> Endpoint::node_addr
      • Endpoint::my_relay -> Endpoint::home_relay
      • defaults::DEFAULT_RELAY_STUN_PORT → defaults::DEFAULT_STUN_PORT
    • changed
      • endpoint::Connecting::alpn returns Vec<u8> instead of String
  • iroh-gossip
    • net::Gossip::update_endpoints -> net::Gossip::update_direct_addresses

But wait, there's more!

Many bugs were squashed, and smaller features were added. For all those details, check out the full changelog: https://github.com/n0-computer/iroh/releases/tag/v0.19.0.

If you want to know what is coming up, check out the 0.20.0 milestone, and if you have any wishes, let us know about the issues! If you need help using iroh or just want to chat, please join us on discord! And to keep up with all things iroh, check out our Twitter.

Iroh is a dial-any-device networking library that just works. Compose from an ecosystem of ready-made protocols to get the features you need, or go fully custom on a clean abstraction over dumb pipes. Iroh is open source, and already running in production on hundreds of thousands of devices.
To get started, take a look at our docs, dive directly into the code, or chat with us in our discord channel.