Skip to content

Commit 8d819f0

Browse files
perf: various improvements
Co-authored-by: Philipp Krüger <philipp.krueger1@gmail.com>
1 parent 4b6824c commit 8d819f0

File tree

6 files changed

+52
-40
lines changed

6 files changed

+52
-40
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,10 @@ netwatch = { git = "https://github.com/n0-computer/net-tools", branch = "main" }
5252
# iroh-quinn = { path = "../iroh-quinn/quinn" }
5353
# iroh-quinn-proto = { path = "../iroh-quinn/quinn-proto" }
5454
# iroh-quinn-udp = { path = "../iroh-quinn/quinn-udp" }
55+
56+
57+
[patch."https://github.com/n0-computer/quinn"]
58+
59+
# iroh-quinn = { path = "../iroh-quinn/quinn" }
60+
# iroh-quinn-proto = { path = "../iroh-quinn/quinn-proto" }
61+
# iroh-quinn-udp = { path = "../iroh-quinn/quinn-udp" }

iroh/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ iroh-base = { version = "0.95.1", default-features = false, features = ["key", "
3333
iroh-relay = { version = "0.95", path = "../iroh-relay", default-features = false }
3434
n0-future = "0.3.0"
3535
n0-error = "0.1.0"
36-
n0-watcher = "0.5"
36+
n0-watcher = "0.6"
3737
netwatch = { version = "0.12" }
3838
pin-project = "1"
3939
pkarr = { version = "5", default-features = false, features = ["relays"] }

iroh/src/magicsock.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ pub(crate) mod endpoint_map;
7575
pub(crate) mod mapped_addrs;
7676
pub(crate) mod transports;
7777

78-
use mapped_addrs::{EndpointIdMappedAddr, MappedAddr};
79-
8078
pub use self::{endpoint_map::PathInfo, metrics::Metrics};
79+
use self::{
80+
mapped_addrs::{EndpointIdMappedAddr, MappedAddr},
81+
transports::Addr,
82+
};
8183

8284
// TODO: Use this
8385
// /// How long we consider a QAD-derived endpoint valid for. UDP NAT mappings typically
@@ -489,18 +491,18 @@ impl MagicSock {
489491

490492
#[cfg_attr(windows, allow(dead_code))]
491493
fn normalized_local_addr(&self) -> io::Result<SocketAddr> {
492-
let addrs = self.local_addrs_watch.clone().get();
494+
let addrs = self.local_addrs_watch.peek();
493495

494496
let mut ipv4_addr = None;
495497
for addr in addrs {
496-
let Some(addr) = addr.into_socket_addr() else {
497-
continue;
498-
};
499-
if addr.is_ipv6() {
500-
return Ok(addr);
501-
}
502-
if addr.is_ipv4() && ipv4_addr.is_none() {
503-
ipv4_addr.replace(addr);
498+
match addr {
499+
Addr::Ip(addr @ SocketAddr::V6(_)) => {
500+
return Ok(*addr);
501+
}
502+
Addr::Ip(addr @ SocketAddr::V4(_)) if ipv4_addr.is_none() => {
503+
ipv4_addr.replace(*addr);
504+
}
505+
_ => {}
504506
}
505507
}
506508
match ipv4_addr {
@@ -550,11 +552,12 @@ impl MagicSock {
550552

551553
let mut quic_packets_total = 0;
552554

553-
for ((quinn_meta, buf), source_addr) in metas
554-
.iter_mut()
555-
.zip(bufs.iter_mut())
556-
.zip(source_addrs.iter())
557-
{
555+
// zip is slow :(
556+
for i in 0..metas.len() {
557+
let quinn_meta = &mut metas[i];
558+
let buf = &mut bufs[i];
559+
let source_addr = &source_addrs[i];
560+
558561
let mut buf_contains_quic_datagrams = false;
559562
let mut quic_datagram_count = 0;
560563
if quinn_meta.len > quinn_meta.stride {
@@ -578,11 +581,9 @@ impl MagicSock {
578581
// relies on quinn::EndpointConfig::grease_quic_bit being set to `false`,
579582
// which we do in Endpoint::bind.
580583
if let Some((sender, sealed_box)) = disco::source_and_box(datagram) {
581-
trace!(src = ?source_addr, len = datagram.len(), "UDP recv: DISCO packet");
582584
self.handle_disco_message(sender, sealed_box, source_addr);
583585
datagram[0] = 0u8;
584586
} else {
585-
trace!(src = ?source_addr, len = datagram.len(), "UDP recv: QUIC packet");
586587
match source_addr {
587588
transports::Addr::Ip(SocketAddr::V4(..)) => {
588589
self.metrics

iroh/src/magicsock/endpoint_map/endpoint_state.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,10 +1183,10 @@ impl ConnectionState {
11831183
pub(crate) struct PathsWatcher(
11841184
Box<
11851185
n0_watcher::Map<
1186-
(
1186+
n0_watcher::Tuple<
11871187
n0_watcher::Direct<PathAddrList>,
11881188
n0_watcher::Direct<Option<transports::Addr>>,
1189-
),
1189+
>,
11901190
PathInfoList,
11911191
>,
11921192
>,
@@ -1195,8 +1195,12 @@ pub(crate) struct PathsWatcher(
11951195
impl n0_watcher::Watcher for PathsWatcher {
11961196
type Value = PathInfoList;
11971197

1198-
fn get(&mut self) -> Self::Value {
1199-
self.0.get()
1198+
fn update(&mut self) -> bool {
1199+
self.0.update()
1200+
}
1201+
1202+
fn peek(&self) -> &Self::Value {
1203+
self.0.peek()
12001204
}
12011205

12021206
fn is_connected(&self) -> bool {
@@ -1206,7 +1210,7 @@ impl n0_watcher::Watcher for PathsWatcher {
12061210
fn poll_updated(
12071211
&mut self,
12081212
cx: &mut std::task::Context<'_>,
1209-
) -> Poll<Result<Self::Value, n0_watcher::Disconnected>> {
1213+
) -> Poll<Result<(), n0_watcher::Disconnected>> {
12101214
self.0.poll_updated(cx)
12111215
}
12121216
}

iroh/src/magicsock/transports.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{
33
io::{self, IoSliceMut},
44
net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6},
55
pin::Pin,
6-
sync::{Arc, atomic::AtomicUsize},
6+
sync::Arc,
77
task::{Context, Poll},
88
};
99

@@ -34,18 +34,20 @@ pub(crate) struct Transports {
3434
ip: Vec<IpTransport>,
3535
relay: Vec<RelayTransport>,
3636

37-
poll_recv_counter: AtomicUsize,
37+
poll_recv_counter: usize,
38+
/// Cache for source addrs, to speed up access
39+
source_addrs: [Addr; quinn_udp::BATCH_SIZE],
3840
}
3941

4042
#[cfg(not(wasm_browser))]
4143
pub(crate) type LocalAddrsWatch = n0_watcher::Map<
42-
(
44+
n0_watcher::Tuple<
4345
n0_watcher::Join<SocketAddr, n0_watcher::Direct<SocketAddr>>,
4446
n0_watcher::Join<
4547
Option<(RelayUrl, EndpointId)>,
4648
n0_watcher::Map<n0_watcher::Direct<Option<RelayUrl>>, Option<(RelayUrl, EndpointId)>>,
4749
>,
48-
),
50+
>,
4951
Vec<Addr>,
5052
>;
5153

@@ -69,6 +71,7 @@ impl Transports {
6971
ip,
7072
relay,
7173
poll_recv_counter: Default::default(),
74+
source_addrs: Default::default(),
7275
}
7376
}
7477

@@ -80,15 +83,15 @@ impl Transports {
8083
msock: &MagicSock,
8184
) -> Poll<io::Result<usize>> {
8285
debug_assert_eq!(bufs.len(), metas.len(), "non matching bufs & metas");
86+
debug_assert!(bufs.len() <= quinn_udp::BATCH_SIZE, "too many buffers");
8387
if msock.is_closing() {
8488
return Poll::Pending;
8589
}
8690

87-
let mut source_addrs = vec![Addr::default(); metas.len()];
88-
match self.inner_poll_recv(cx, bufs, metas, &mut source_addrs)? {
91+
match self.inner_poll_recv(cx, bufs, metas)? {
8992
Poll::Pending | Poll::Ready(0) => Poll::Pending,
9093
Poll::Ready(n) => {
91-
msock.process_datagrams(&mut bufs[..n], &mut metas[..n], &source_addrs[..n]);
94+
msock.process_datagrams(&mut bufs[..n], &mut metas[..n], &self.source_addrs[..n]);
9295
Poll::Ready(Ok(n))
9396
}
9497
}
@@ -100,13 +103,12 @@ impl Transports {
100103
cx: &mut Context,
101104
bufs: &mut [IoSliceMut<'_>],
102105
metas: &mut [quinn_udp::RecvMeta],
103-
source_addrs: &mut [Addr],
104106
) -> Poll<io::Result<usize>> {
105107
debug_assert_eq!(bufs.len(), metas.len(), "non matching bufs & metas");
106108

107109
macro_rules! poll_transport {
108110
($socket:expr) => {
109-
match $socket.poll_recv(cx, bufs, metas, source_addrs)? {
111+
match $socket.poll_recv(cx, bufs, metas, &mut self.source_addrs)? {
110112
Poll::Pending | Poll::Ready(0) => {}
111113
Poll::Ready(n) => {
112114
return Poll::Ready(Ok(n));
@@ -117,9 +119,7 @@ impl Transports {
117119

118120
// To improve fairness, every other call reverses the ordering of polling.
119121

120-
let counter = self
121-
.poll_recv_counter
122-
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
122+
let counter = self.poll_recv_counter.wrapping_add(1);
123123

124124
if counter % 2 == 0 {
125125
#[cfg(not(wasm_browser))]
@@ -156,7 +156,7 @@ impl Transports {
156156
let ips = n0_watcher::Join::new(self.ip.iter().map(|t| t.local_addr_watch()));
157157
let relays = n0_watcher::Join::new(self.relay.iter().map(|t| t.local_addr_watch()));
158158

159-
(ips, relays).map(|(ips, relays)| {
159+
ips.or(relays).map(|(ips, relays)| {
160160
ips.into_iter()
161161
.map(Addr::from)
162162
.chain(

0 commit comments

Comments
 (0)