iroh 1.0.0-rc.1 - The last one
by Friedel Ziegelmayer & Rüdiger KlaehnWelcome to iroh@1.0.0-rc.1, the last release candidate before 1.0.
Since the first release candidate two weeks ago we collected feedback from you, fixed bugs, and made the (hopefully) last API adjustments we wanted to make before stabilizing. Unless something serious comes up, the next release is 1.0.
📣 Call to the community
This is the last release candidate before 1.0. If you're still on 0.35 and have been waiting for things to settle, please try this release and let us know if you hit any issues.
🥊 Hard-NAT holepunching
Until this release, iroh could holepunch when the client initiating the connection was behind a hard NAT (endpoint-dependent NAT mapping) and the server behind an easy NAT (endpoint-independent NAT mapping), but not the reverse. With this release, the asymmetric case where the server is behind a hard NAT also works.
See noq#672 and #4254 for more details.
🛣️ Configurable path selection
For users building on top of custom transports, iroh now exposes a PathSelector trait that decides which path a connection uses.
trait PathSelector {
fn select(&self, ctx: PathSelectionContext<'_>) -> PathSelection;
}
PathSelectionContext exposes the currently selected path and an iterator over PathSelectionData, which today contains the path address and stats. PathSelection is a newtype over Option<Addr>. Configure a selector via Endpoint::builder().path_selector(...).
The trait and the new types are gated behind the unstable-custom-transports feature. Keep in mind that this means they are not covered by the 1.0 stability guarantees and may break in future releases.
See #4232 for more details.
🔐 Pluggable relay access control
The relay's access control has been redesigned. The AccessConfig enum is gone, replaced by an AccessControl trait with on_connect and on_disconnect hooks. Each connection gets a ConnectionId that is passed to both callbacks.
trait AccessControl {
async fn on_connect(&self, req: &ClientRequest) -> Access;
async fn on_disconnect(&self, id: ConnectionId);
}
With the ConnectionId, an AccessControl implementation can track active connections and proactively disconnect clients when their access is revoked, via the new iroh_relay::server::clients::Clients::disconnect API. No need to wait for the client to make another request.
The Bucket rate-limit primitive is now public, for embedders that mount the relay protocol via their own HTTP server (e.g. axum).
See #4276 and #4242 for more details.
⚡ Faster Endpoint::close
Shutdown now skips the draining period when it can. Closing is near-instant when the peer already closed remotely, and roughly one RTT otherwise if there is no packet loss.
🧹 Stability fixes
- Remote state races — Two related bugs in the remote map could double-spawn
RemoteStateActors or shut one down whileResolveRemoterequests were still pending. Both fixed in #4271 and #4272. - Path abandonment scope — Abandoning a path on one connection no longer abandons it on every other connection that shares the same address. Other connections will abandon it themselves if it's unusable. Fixed in #4284.
- Static musl builds — A CI fix forces non-PIE
crt1.oso the static musl release binaries link again. Fixed in #4258.
📐 FourTuple plumbing
Internally the selected path is now tracked as a FourTuple (local + remote address) throughout both send and receive paths. The user-visible changes are small:
IncomingLocalAddrhas been renamed toLocalTransportAddrto reflect that it is used on both sides; theRelayvariant is now a tuple variant.PathEventvariants are now#[non_exhaustive].- Custom transport implementations get a new
src: Option<&CustomAddr>argument onCustomSender::poll_send, matching the source-pinning the IP transport already supports.
See #4273 and #4281 for more details.
⚠️ Breaking Changes
iroh- removed
iroh::endpoint::IncomingLocalAddr— renamed toLocalTransportAddr(#4273)
- changed
- added
iroh::endpoint::transports::LocalTransportAddr(replacesIncomingLocalAddr); theRelayvariant is now a tuple variant (#4273)iroh::endpoint::Builder::path_selector(#4232)- under
unstable-custom-transports:endpoint::transports::PathSelector,PathSelection,PathSelectionContext,PathSelectionData,FourTuple(#4232, #4281)
- removed
iroh-relay- removed
- changed
iroh_relay::server::RelayConfig::accessisArc<dyn DynAccessControl>instead ofAccessConfig.RelayService::newandiroh::test_utils::run_relay_server_with_accesstake the same type (#4276)iroh_relay::server::Access::Denyis now a struct variantDeny { reason: Option<String> };Accessis no longerCopy(#4276)iroh_relay::server::ClientRequest::newtakes(EndpointId, ProtocolVersion, http::request::Parts), including the negotiated protocol version (#4276)iroh_relay::protos::handshake::SuccessfulAuthentication::authorize_iftakesAccessinstead ofbool(#4276)iroh_relay::server::client::Config::newtakes(OnDisconnectGuard, RelayedStream, ProtocolVersion)instead of(EndpointId, RelayedStream, ProtocolVersion); the publicConfig::endpoint_idfield is replaced byConfig::guard(#4276)
- added
iroh-base- added
iroh_base::SignatureParsingErroris now re-exported (#4285)
- added
- Deps
- Updated to
noq@1.0.0-rc.1(#4287)
- Updated to
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/v1.0.0-rc.1.
If you want to know what is coming up, check out the milestones, 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, Mastodon, and Bluesky.
To get started, take a look at our docs, dive directly into the code, or chat with us in our discord channel.