Skip to content

Commit cf0f8cc

Browse files
ramfox“ramfox”
and
“ramfox”
authored
feat(iroh-net-report)!: add QUIC address discovery probes (#3028)
## Description Adds probes for QUIC Address Discovery. ## Breaking Changes - `iroh-net-report` - changed - `iroh_net_report::Client::get_report` takes new parameter `quic_config: net_report::QuicConfig` - `iroh_net_report::Client::get_report_channel` takes new parameter `quic_config: net_report::QuicConfig` ## Notes & open questions Next PR is properly adding this to iroh (& a new PR for iroh-doctor). `magicsock.rs` was adjusted so that `iroh` can still depend on the repo version of `net-report`, but does not enable QAD. ## 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. - [x] Tests if relevant. - [x] All breaking changes documented. --------- Co-authored-by: “ramfox” <“kasey@n0.computer”>
1 parent 6a988a5 commit cf0f8cc

File tree

9 files changed

+326
-54
lines changed

9 files changed

+326
-54
lines changed

Cargo.lock

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

iroh-net-report/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ iroh-metrics = { version = "0.29.0", default-features = false }
2727
iroh-relay = { version = "0.29", path = "../iroh-relay" }
2828
netwatch = { version = "0.2.0" }
2929
portmapper = { version = "0.2.0", default-features = false }
30+
quinn = { package = "iroh-quinn", version = "0.12.0" }
3031
rand = "0.8"
3132
reqwest = { version = "0.12", default-features = false }
3233
rustls = { version = "0.23", default-features = false }

iroh-net-report/src/defaults.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
//! Default values used in net_report.
22
3-
/// The default STUN port used by the Relay server.
4-
///
5-
/// The STUN port as defined by [RFC 8489](<https://www.rfc-editor.org/rfc/rfc8489#section-18.6>)
6-
pub const DEFAULT_STUN_PORT: u16 = 3478;
3+
pub(crate) use iroh_base::relay_map::{DEFAULT_RELAY_QUIC_PORT, DEFAULT_STUN_PORT};
74

85
/// Contains all timeouts that we use in `iroh-net-report`.
96
pub(crate) mod timeouts {

iroh-net-report/src/lib.rs

+32-5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ mod ping;
3434
mod reportgen;
3535

3636
pub use metrics::Metrics;
37+
pub use reportgen::QuicConfig;
3738

3839
const FULL_REPORT_INTERVAL: Duration = Duration::from_secs(5 * 60);
3940

@@ -240,13 +241,23 @@ impl Client {
240241
///
241242
/// If these are not passed in this will bind sockets for STUN itself, though results
242243
/// may not be as reliable.
244+
///
245+
/// The *quic_config* takes a [`QuicConfig`], a combination of a QUIC endpoint and
246+
/// a client configuration that can be use for verifying the relay server connection.
247+
/// When available, the report will attempt to get an observed public address
248+
/// using QUIC address discovery.
249+
///
250+
/// When `None`, it will disable the QUIC address discovery probes.
243251
pub async fn get_report(
244252
&mut self,
245253
dm: RelayMap,
246254
stun_conn4: Option<Arc<UdpSocket>>,
247255
stun_conn6: Option<Arc<UdpSocket>>,
256+
quic_config: Option<QuicConfig>,
248257
) -> Result<Arc<Report>> {
249-
let rx = self.get_report_channel(dm, stun_conn4, stun_conn6).await?;
258+
let rx = self
259+
.get_report_channel(dm, stun_conn4, stun_conn6, quic_config)
260+
.await?;
250261
match rx.await {
251262
Ok(res) => res,
252263
Err(_) => Err(anyhow!("channel closed, actor awol")),
@@ -259,6 +270,7 @@ impl Client {
259270
dm: RelayMap,
260271
stun_conn4: Option<Arc<UdpSocket>>,
261272
stun_conn6: Option<Arc<UdpSocket>>,
273+
quic_config: Option<QuicConfig>,
262274
) -> Result<oneshot::Receiver<Result<Arc<Report>>>> {
263275
// TODO: consider if RelayMap should be made to easily clone? It seems expensive
264276
// right now.
@@ -268,6 +280,7 @@ impl Client {
268280
relay_map: dm,
269281
stun_sock_v4: stun_conn4,
270282
stun_sock_v6: stun_conn6,
283+
quic_config,
271284
response_tx: tx,
272285
})
273286
.await?;
@@ -307,6 +320,11 @@ pub(crate) enum Message {
307320
///
308321
/// Like `stun_sock_v4` but for IPv6.
309322
stun_sock_v6: Option<Arc<UdpSocket>>,
323+
/// Endpoint and client configuration to create a QUIC
324+
/// connection to do QUIC address discovery.
325+
///
326+
/// If not provided, will not do QUIC address discovery.
327+
quic_config: Option<QuicConfig>,
310328
/// Channel to receive the response.
311329
response_tx: oneshot::Sender<Result<Arc<Report>>>,
312330
},
@@ -446,9 +464,16 @@ impl Actor {
446464
relay_map,
447465
stun_sock_v4,
448466
stun_sock_v6,
467+
quic_config,
449468
response_tx,
450469
} => {
451-
self.handle_run_check(relay_map, stun_sock_v4, stun_sock_v6, response_tx);
470+
self.handle_run_check(
471+
relay_map,
472+
stun_sock_v4,
473+
stun_sock_v6,
474+
quic_config,
475+
response_tx,
476+
);
452477
}
453478
Message::ReportReady { report } => {
454479
self.handle_report_ready(report);
@@ -476,6 +501,7 @@ impl Actor {
476501
relay_map: RelayMap,
477502
stun_sock_v4: Option<Arc<UdpSocket>>,
478503
stun_sock_v6: Option<Arc<UdpSocket>>,
504+
quic_config: Option<QuicConfig>,
479505
response_tx: oneshot::Sender<Result<Arc<Report>>>,
480506
) {
481507
if self.current_report_run.is_some() {
@@ -526,6 +552,7 @@ impl Actor {
526552
relay_map,
527553
stun_sock_v4,
528554
stun_sock_v6,
555+
quic_config,
529556
self.dns_resolver.clone(),
530557
);
531558

@@ -975,7 +1002,7 @@ mod tests {
9751002
// Note that the ProbePlan will change with each iteration.
9761003
for i in 0..5 {
9771004
println!("--round {}", i);
978-
let r = client.get_report(dm.clone(), None, None).await?;
1005+
let r = client.get_report(dm.clone(), None, None, None).await?;
9791006

9801007
assert!(r.udp, "want UDP");
9811008
assert_eq!(
@@ -1016,7 +1043,7 @@ mod tests {
10161043
let resolver = crate::dns::tests::resolver();
10171044
let mut client = Client::new(None, resolver.clone())?;
10181045

1019-
let r = client.get_report(dm, None, None).await?;
1046+
let r = client.get_report(dm, None, None, None).await?;
10201047
let mut r: Report = (*r).clone();
10211048
r.portmap_probe = None;
10221049

@@ -1285,7 +1312,7 @@ mod tests {
12851312
)
12861313
};
12871314

1288-
let r = client.get_report(dm, Some(sock), None).await?;
1315+
let r = client.get_report(dm, Some(sock), None, None).await?;
12891316
dbg!(&r);
12901317
assert_eq!(r.hair_pinning, Some(true));
12911318

0 commit comments

Comments
 (0)