Skip to content

Commit 59b5bf9

Browse files
feat!: add iroh-relay crate (#2873)
## Description Adds a new crate `iroh-relay`. It's structured as follows: - protos: protocols the server is able to handle, this includes the relay protocol, stun, and partially disco. - server: the server code, as it was already in the og mod - client: the client code, as it was already in the og mod - server binary (bin `iroh-relay`) as it was previously in iroh-net's bin. This moves the code around in the least disruptive possible way to give us a starting point over which to improve this. Check the notes and open questions for future work ## Breaking Changes - `iroh_net::relay` is removed. `RelayUrl`, `RelayMode`, `RelayNode` and `RelayMap` are moved to the top (`iroh_net`). All other members of this module are now moved to the new crate `iroh-relay` ## Notes & open questions - Disco includes a transaction id defined in terms of stun's transaction id. Every use of this is now directly from `stun_rs` to make it clear this is not defined in terms of the relay's stun server. The relay can't read the contents of disco packages so I consider this the right thing to do, even if the types are actually the same. - The relay needs to identify Disco packages to queue them separately. Disco is not yet its own crate because we do not know its future. Based on this I chose to duplicate the code that does the identification. But just this signals we should start the work on deciding what disco looks like in a post ts world to de-duplicate this code and use it from a single source. The code as it stands is highly unlikely to change; however, any change to the protocol's wrapper would now need to be changed in two places, which is ofc not ideal. - The relay's "protocol" includes quite a lot of non protocol code, that probably belongs more to the server. I was really tempted to try to move this code to better places but in reality this is not the time. The purpose of this PR is among many others, to allow for future work like this. - What used to be called the relay module had a lot of relay-related code without a clear objective or offering. This includes for example, all the relay map related code. The relay as a protocol, server, and client, has absolutely no need for these types. Relay topology is entirely a `iroh`/`iroh-net` topic. On the same page is the infra-related code. Nothing in the protocol, server or client is different depending on the infra values. This is entirely a `iroh`/`iroh-net` topic. Based on these arguments, these types, functions, etc that were part of the relay module have actually stayed in `iroh-net` instead. - I did a couple passes of `udeps`, but it's messy. Optional dependencies are their own feature so they aren't flagged as unused. There are (in general, not in the relay) dependencies that differ in targets, and the features combinations also affect this as well. So the deps that remain are a "reasonable best effort" in accordance with our CI checks. In reality, - and in particular when checking feature combinations with `fc` - there's a lot of work left to do on that front. - The crate's version is 0.29 because there's no point in setting the version to 0.28, which will never be released, to then later be changed to 0.29. This might be unexpected but it's the option that reduces senseless future work. - dns code is duplicated. This is unfortunate but since it's only used in tests to configure the client there's really not much to do here. Most of what this does are fixes we should try to upstream ## Change checklist - [x] Self-review. - [x] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [ ] ~~Tests if relevant.~~ - [x] All breaking changes documented.
1 parent c96b032 commit 59b5bf9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1262
-907
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ jobs:
190190
# uses: obi1kenobi/cargo-semver-checks-action@v2
191191
uses: n0-computer/cargo-semver-checks-action@feat-baseline
192192
with:
193-
package: iroh, iroh-base, iroh-cli, iroh-dns-server, iroh-metrics, iroh-net, iroh-net-bench, iroh-router, netwatch, portmapper
193+
package: iroh, iroh-base, iroh-cli, iroh-dns-server, iroh-metrics, iroh-net, iroh-net-bench, iroh-router, netwatch, portmapper, iroh-relay
194194
baseline-rev: ${{ env.HEAD_COMMIT_SHA }}
195195
use-cache: false
196196

.github/workflows/tests.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ env:
2323
RUSTFLAGS: -Dwarnings
2424
RUSTDOCFLAGS: -Dwarnings
2525
SCCACHE_CACHE_SIZE: "50G"
26-
CRATES_LIST: "iroh,iroh-metrics,iroh-net,iroh-net-bench,iroh-test,iroh-cli,iroh-dns-server,iroh-router,netwatch,portmapper"
26+
CRATES_LIST: "iroh,iroh-metrics,iroh-net,iroh-net-bench,iroh-test,iroh-cli,iroh-dns-server,iroh-router,netwatch,portmapper,iroh-relay"
2727
IROH_FORCE_STAGING_RELAYS: "1"
2828

2929
jobs:

Cargo.lock

+65-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ members = [
88
"iroh-test",
99
"iroh-net/bench",
1010
"iroh-cli",
11+
"iroh-relay",
1112
"iroh-router",
1213
"net-tools/netwatch",
1314
"net-tools/portmapper",

iroh-cli/src/commands/blobs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use iroh::{
3333
},
3434
Iroh,
3535
},
36-
net::{key::PublicKey, relay::RelayUrl, NodeAddr},
36+
net::{key::PublicKey, NodeAddr, RelayUrl},
3737
};
3838
use tokio::io::AsyncWriteExt;
3939

iroh-cli/src/commands/doctor.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ use iroh::{
3838
key::{PublicKey, SecretKey},
3939
metrics::MagicsockMetrics,
4040
netcheck,
41-
relay::{RelayMap, RelayMode, RelayUrl},
4241
ticket::NodeTicket,
43-
Endpoint, NodeAddr, NodeId,
42+
Endpoint, NodeAddr, NodeId, RelayMap, RelayMode, RelayUrl,
4443
},
4544
util::{path::IrohPaths, progress::ProgressWriter},
4645
};

iroh-cli/src/commands/net.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use iroh::{
1212
client::Iroh,
1313
net::{
1414
endpoint::{DirectAddrInfo, RemoteInfo},
15-
relay::RelayUrl,
16-
NodeAddr, NodeId,
15+
NodeAddr, NodeId, RelayUrl,
1716
},
1817
};
1918

iroh-cli/src/commands/start.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use anyhow::Result;
1111
use colored::Colorize;
1212
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
1313
use iroh::{
14-
net::relay::{RelayMap, RelayMode},
14+
net::{RelayMap, RelayMode},
1515
node::{Node, RpcStatus, DEFAULT_RPC_ADDR},
1616
};
1717
use tracing::{info_span, trace, Instrument};

iroh-cli/src/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use anyhow::{anyhow, bail, Context, Result};
1313
use iroh::{
1414
client::Iroh,
1515
docs::{AuthorId, NamespaceId},
16-
net::relay::{RelayMap, RelayNode},
16+
net::{RelayMap, RelayNode},
1717
node::GcPolicy,
1818
};
1919
use parking_lot::RwLock;

iroh-net/Cargo.toml

+7-26
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ workspace = true
1919
cc = "=1.1.31" # enforce cc version, because of https://github.com/rust-lang/cc-rs/issues/1278
2020

2121
anyhow = { version = "1" }
22+
axum = { version = "0.7.4", optional = true }
2223
backoff = "0.4.0"
2324
base64 = "0.22.1"
2425
bytes = "1.7"
26+
clap = { version = "4", features = ["derive"], optional = true }
2527
der = { version = "0.7", features = ["alloc", "derive"] }
2628
derive_more = { version = "1.0.0", features = ["debug", "display", "from", "try_into", "deref"] }
2729
futures-buffered = "0.2.8"
@@ -40,6 +42,7 @@ hyper = { version = "1", features = ["server", "client", "http1"] }
4042
hyper-util = "0.1.1"
4143
igd-next = { version = "0.15.1", features = ["aio_tokio"] }
4244
iroh-base = { version = "0.28.0", features = ["key"] }
45+
iroh-relay = { version = "0.28", path = "../iroh-relay" }
4346
libc = "0.2.139"
4447
netdev = "0.30.0"
4548
netwatch = { version = "0.1.0", path = "../net-tools/netwatch" }
@@ -55,6 +58,7 @@ quinn-proto = { package = "iroh-quinn-proto", version = "0.12.0" }
5558
quinn-udp = { package = "iroh-quinn-udp", version = "0.5.5" }
5659
rand = "0.8"
5760
rcgen = "0.12"
61+
regex = { version = "1.7.1", optional = true }
5862
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"] }
5963
ring = "0.17"
6064
rustls = { version = "0.23", default-features = false, features = ["ring"] }
@@ -72,6 +76,7 @@ tokio-tungstenite = "0.21"
7276
tokio-tungstenite-wasm = "0.3"
7377
tokio-util = { version = "0.7.12", features = ["io-util", "io", "codec", "rt"] }
7478
tracing = "0.1"
79+
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }
7580
tungstenite = "0.21"
7681
url = { version = "2.4", features = ["serde"] }
7782
watchable = "1.1.2"
@@ -80,15 +85,6 @@ webpki-roots = "0.26"
8085
x509-parser = "0.16"
8186
z32 = "1.0.3"
8287

83-
# iroh-relay
84-
axum = { version = "0.7.4", optional = true }
85-
clap = { version = "4", features = ["derive"], optional = true }
86-
regex = { version = "1.7.1", optional = true }
87-
rustls-pemfile = { version = "2.1", optional = true }
88-
toml = { version = "0.8", optional = true }
89-
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }
90-
tokio-rustls-acme = { version = "0.4", optional = true }
91-
9288
# metrics
9389
iroh-metrics = { version = "0.28.0", default-features = false }
9490
strum = { version = "0.26.2", features = ["derive"] }
@@ -114,14 +110,12 @@ axum = { version = "0.7.4" }
114110
clap = { version = "4", features = ["derive"] }
115111
criterion = "0.5.1"
116112
crypto_box = { version = "0.9.1", features = ["serde", "chacha20"] }
117-
ntest = "0.9"
118113
pretty_assertions = "1.4"
119-
proptest = "1.2.0"
120114
rand_chacha = "0.3.1"
121115
tokio = { version = "1", features = ["io-util", "sync", "rt", "net", "fs", "macros", "time", "test-util"] }
122116
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
123117
iroh-test = "0.28.0"
124-
iroh-net = { path = ".", features = ["iroh-relay"] }
118+
iroh-net = { path = "." }
125119
serde_json = "1.0.107"
126120
testresult = "0.4.0"
127121
mainline = "2.0.1"
@@ -135,24 +129,11 @@ duct = "0.13.6"
135129

136130
[features]
137131
default = ["metrics", "discovery-pkarr-dht"]
138-
iroh-relay = [
139-
"dep:tokio-rustls-acme",
140-
"dep:axum",
141-
"dep:clap",
142-
"dep:toml",
143-
"dep:rustls-pemfile",
144-
"dep:regex",
145-
"dep:tracing-subscriber"
146-
]
147132
metrics = ["iroh-metrics/metrics"]
148-
test-utils = ["iroh-relay"]
133+
test-utils = ["iroh-relay/test-utils", "iroh-relay/server", "dep:axum"]
149134
discovery-local-network = ["dep:swarm-discovery"]
150135
discovery-pkarr-dht = ["pkarr/dht", "dep:genawaiter"]
151136

152-
[[bin]]
153-
name = "iroh-relay"
154-
required-features = ["iroh-relay"]
155-
156137
[package.metadata.docs.rs]
157138
all-features = true
158139
rustdoc-args = ["--cfg", "iroh_docsrs"]

iroh-net/bench/src/iroh.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ use bytes::Bytes;
88
use futures_lite::StreamExt as _;
99
use iroh_net::{
1010
endpoint::{Connection, ConnectionError, RecvStream, SendStream, TransportConfig},
11-
relay::{RelayMap, RelayMode, RelayUrl},
12-
Endpoint, NodeAddr,
11+
Endpoint, NodeAddr, RelayMap, RelayMode, RelayUrl,
1312
};
1413
use tracing::{trace, warn};
1514

iroh-net/examples/connect-unreliable.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ use std::net::SocketAddr;
1010
use anyhow::Context;
1111
use clap::Parser;
1212
use futures_lite::StreamExt;
13-
use iroh_net::{
14-
key::SecretKey,
15-
relay::{RelayMode, RelayUrl},
16-
Endpoint, NodeAddr,
17-
};
13+
use iroh_net::{key::SecretKey, Endpoint, NodeAddr, RelayMode, RelayUrl};
1814
use tracing::info;
1915

2016
// An example ALPN that we are using to communicate over the `Endpoint`

iroh-net/examples/connect.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ use std::net::SocketAddr;
1010
use anyhow::Context;
1111
use clap::Parser;
1212
use futures_lite::StreamExt;
13-
use iroh_net::{
14-
key::SecretKey,
15-
relay::{RelayMode, RelayUrl},
16-
Endpoint, NodeAddr,
17-
};
13+
use iroh_net::{key::SecretKey, Endpoint, NodeAddr, RelayMode, RelayUrl};
1814
use tracing::info;
1915

2016
// An example ALPN that we are using to communicate over the `Endpoint`

iroh-net/examples/listen-unreliable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! $ cargo run --example listen-unreliable
66
use anyhow::Context;
77
use futures_lite::StreamExt;
8-
use iroh_net::{key::SecretKey, relay::RelayMode, Endpoint};
8+
use iroh_net::{key::SecretKey, Endpoint, RelayMode};
99
use tracing::{info, warn};
1010

1111
// An example ALPN that we are using to communicate over the `Endpoint`

iroh-net/examples/listen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::time::Duration;
77

88
use anyhow::Context;
99
use futures_lite::StreamExt;
10-
use iroh_net::{endpoint::ConnectionError, key::SecretKey, relay::RelayMode, Endpoint};
10+
use iroh_net::{endpoint::ConnectionError, key::SecretKey, Endpoint, RelayMode};
1111
use tracing::{debug, info, warn};
1212

1313
// An example ALPN that we are using to communicate over the `Endpoint`

iroh-net/src/defaults.rs

+1-27
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use url::Url;
44

5-
use crate::relay::{RelayMap, RelayNode};
5+
use crate::{RelayMap, RelayNode};
66

77
/// The default STUN port used by the Relay server.
88
///
@@ -164,30 +164,4 @@ pub(crate) mod timeouts {
164164

165165
/// Default Pinger timeout
166166
pub(crate) const DEFAULT_PINGER_TIMEOUT: Duration = Duration::from_secs(5);
167-
168-
/// Timeouts specifically used in the iroh-relay
169-
pub(crate) mod relay {
170-
use super::*;
171-
172-
/// Timeout used by the relay client while connecting to the relay server,
173-
/// using `TcpStream::connect`
174-
pub(crate) const DIAL_NODE_TIMEOUT: Duration = Duration::from_millis(1500);
175-
/// Timeout for expecting a pong from the relay server
176-
pub(crate) const PING_TIMEOUT: Duration = Duration::from_secs(5);
177-
/// Timeout for the entire relay connection, which includes dns, dialing
178-
/// the server, upgrading the connection, and completing the handshake
179-
pub(crate) const CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
180-
/// Timeout for our async dns resolver
181-
pub(crate) const DNS_TIMEOUT: Duration = Duration::from_secs(1);
182-
183-
/// Maximum time the client will wait to receive on the connection, since
184-
/// the last message. Longer than this time and the client will consider
185-
/// the connection dead.
186-
pub(crate) const CLIENT_RECV_TIMEOUT: Duration = Duration::from_secs(120);
187-
188-
/// Maximum time the server will attempt to get a successful write to the connection.
189-
#[cfg(feature = "iroh-relay")]
190-
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "iroh-relay")))]
191-
pub(crate) const SERVER_WRITE_TIMEOUT: Duration = Duration::from_secs(2);
192-
}
193167
}

0 commit comments

Comments
 (0)