Iroh Connections Fallback to Relay Servers: Automatic Failover Explained
Yes, Iroh automatically falls back to relay servers when direct peer-to-peer connections fail, using a path selector that prioritizes direct IP paths while treating relay transport as a backup option.
The n0-computer/iroh library implements seamless connection failover through its path selection architecture. When building peer-to-peer applications with Iroh, Iroh connections fallback to relay servers transparently whenever NAT traversal or firewall restrictions block direct connectivity, requiring no additional application code.
How the BiasedRttPathSelector Prioritizes Direct Paths
The default path selection logic lives in iroh/src/socket/remote_map/biased_rtt_path_selector.rs. The BiasedRttPathSelector sorts candidate paths by biased round-trip time, preferring IPv6 over IPv4, and treating relay paths as the lowest-priority option.
This architecture ensures that relays function strictly as a backup mechanism. The selector only returns a relay address after all direct candidates have been rejected or deemed unreachable, making the fallback behavior automatic and transparent to the application layer.
Configuring Relay Servers as Fallback Transport
Relay servers are configured through the Builder::relay_mode method in iroh/src/endpoint.rs#L442-L452. When you configure relay mode, the relay transport is added to the endpoint's available transports but explicitly marked as a fallback transport.
This means the relay infrastructure is registered and maintained, but the Endpoint will not utilize it unless the path selector determines that direct IP paths are unavailable. The RelayActor (found in iroh/src/socket/transports/relay/actor.rs) maintains persistent QUIC connections to these configured relay servers, supplying a ready-to-use Client when the selector ultimately chooses a relay path.
The Connection Flow: From Direct to Relay
The failover process follows a strict sequence implemented across several core components:
-
Address Resolution: When
Endpoint::connectis called (seeiroh/src/endpoint.rs#L1024-L1030), the endpoint resolves the remoteEndpointAddrinto a list of candidate addresses. This list includes direct IP addresses first, followed by any available relay URLs. -
Path Selection: The
BiasedRttPathSelectororders the candidates, always ranking direct paths above relay paths based on the biased RTT algorithm. -
Fallback Execution: If none of the direct candidates are reachable (due to NAT traversal failure, firewall restrictions, or absent public IP), the selector picks the relay transport. The
RelayActorsupplies an active QUIC client to the selected relay, and the connection completes over that relay connection. -
Address Updates: The endpoint continually updates its own
EndpointAddrvia theWatchermechanism (seeiroh/src/endpoint.rs#L1482-L1490), advertising reachable direct addresses and the current relay URL. This ensures peers dialing the endpoint know whether direct connectivity is possible or if they must initiate a relay fallback immediately.
Practical Implementation Example
The following code demonstrates the default configuration that enables automatic relay fallback:
use iroh::{Endpoint, endpoint::presets};
#[tokio::main]
async fn main() -> Result<(), iroh::Error> {
// Build an endpoint with the default relay configuration (RelayMode::Default)
let ep = Endpoint::builder(presets::N0)
.relay_mode(iroh::relay::RelayMode::Default) // relay is a fallback
.bind()
.await?;
// Remote address may contain direct IPs, but also a relay URL.
// If the direct IPs are unreachable, the connection will automatically use the relay.
let remote_addr = "iroh://[email protected]"; // example EndpointAddr
let conn = ep.connect(remote_addr, b"my-alpn").await?;
println!("connection established (direct or via relay)");
Ok(())
}
In this example, relay_mode(RelayMode::Default) registers the default relay server(s) as a fallback transport. The connect call does not need to specify a relay URL; the endpoint uses the relay map only when direct IP routes fail, as determined by the BiasedRttPathSelector.
Summary
- Iroh connections fallback to relay servers automatically when direct peer-to-peer connectivity cannot be established.
- The
BiasedRttPathSelectoriniroh/src/socket/remote_map/biased_rtt_path_selector.rstreats relay paths as the lowest-priority option, ensuring direct paths are always attempted first. - The
Builder::relay_modemethod registers relay servers as fallback transports without requiring manual intervention during connection. - The
RelayActormanages persistent QUIC connections to relay servers, providing seamless failover when the path selector rejects all direct candidates. - No application code changes are required to handle the fallback; the behavior is transparent and controlled by the endpoint's path selection policy.
Frequently Asked Questions
How does Iroh decide when to use a relay server instead of a direct connection?
The BiasedRttPathSelector evaluates all candidate paths for a connection, ranking them by biased round-trip time with a preference for IPv6 over IPv4. Relay paths are explicitly ranked as the lowest priority. Only when all direct IP candidates are deemed unreachable does the selector choose a relay path, triggering the connection to route through the relay server.
Do I need to configure relay fallback manually in my Iroh application?
No. When you configure relay_mode using RelayMode::Default or custom relay maps, the relay transport is automatically registered as a fallback. As shown in iroh/src/endpoint.rs#L442-L452, the relay is added to the transport list with fallback semantics, meaning the Endpoint will only utilize it when the path selector determines direct connectivity is impossible.
What happens if both direct connections and the relay server fail?
If the BiasedRttPathSelector cannot establish connectivity through any direct IP addresses and the relay connection also fails, the Endpoint::connect call will return an error. The connection attempt fails only after exhausting all available paths, including the configured relay servers. The application receives the connection failure and can implement retry logic if desired.
Is traffic encrypted when using Iroh relay fallback?
Yes. According to the implementation in iroh/src/socket/transports/relay/actor.rs, the RelayActor maintains persistent QUIC connections to relay servers. All traffic forwarded through the relay uses these QUIC connections, which provide encryption and authentication. The relay server forwards encrypted datagrams between peers without accessing the plaintext content, ensuring end-to-end security even during fallback scenarios.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →