Skip to content

Commit 6285cb7

Browse files
committed
bump iroh-quinn
1 parent b324c7a commit 6285cb7

File tree

3 files changed

+95
-61
lines changed

3 files changed

+95
-61
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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,6 @@ unused-async = "warn"
4545
iroh-quinn = { git = "https://github.com/n0-computer/quinn", branch = "Frando/pathstats" }
4646
iroh-quinn-udp = { git = "https://github.com/n0-computer/quinn", branch = "Frando/pathstats" }
4747
iroh-quinn-proto = { git = "https://github.com/n0-computer/quinn", branch = "Frando/pathstats" }
48+
# iroh-quinn = { path = "../quinn/quinn" }
49+
# iroh-quinn-udp = { path = "../quinn/quinn-udp" }
50+
# iroh-quinn-proto = { path = "../quinn/quinn-proto" }

iroh/src/socket/remote_map/remote_state/path_watcher.rs

Lines changed: 89 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
use std::task::Poll;
22

33
use iroh_base::TransportAddr;
4+
use n0_error::stack_error;
45
use n0_future::time::Duration;
56
use n0_watcher::{Watchable, Watcher};
6-
use quinn::WeakPathHandle;
77
use quinn_proto::PathId;
88
use smallvec::SmallVec;
99

1010
use crate::{endpoint::PathStats, socket::transports};
1111

12-
/// List of [`PathInfo`] for a connection.
12+
/// List of [`PathInfo`] for the network paths of a [`Connection`].
13+
///
14+
/// This struct implements [`IntoIterator`].
15+
///
16+
/// [`Connection`]: crate::endpoint::Connection
1317
#[derive(Debug, Clone, Eq, PartialEq, Default)]
1418
pub struct PathInfoList(SmallVec<[PathInfo; 4]>);
1519

20+
#[derive(Debug, Clone, Eq, PartialEq, Default)]
21+
struct PathDataList(SmallVec<[PathData; 4]>);
22+
1623
impl PathInfoList {
17-
/// TODO
24+
/// Returns an iterator over the path infos.
1825
pub fn iter(&self) -> impl Iterator<Item = &PathInfo> {
1926
self.0.iter()
2027
}
@@ -51,39 +58,37 @@ impl Iterator for PathInfoListIntoIter {
5158
}
5259
}
5360

61+
/// Watcher for the open paths and selected transmission path in a connection.
5462
#[derive(Clone, Debug)]
5563
pub struct PathWatcher {
56-
paths: n0_watcher::Direct<PathInfoList>,
64+
paths: n0_watcher::Direct<PathDataList>,
5765
selected_path: n0_watcher::Direct<Option<transports::Addr>>,
5866
current: PathInfoList,
5967
}
6068

6169
impl PathWatcher {
62-
fn apply_selected_path(&mut self) {
63-
if let Some(selected_path) = self.selected_path.peek() {
64-
for path in self.current.0.iter_mut() {
65-
path.is_selected = selected_path.is_transport_addr(&path.remote_addr);
66-
}
67-
}
70+
fn update_current(&mut self) {
71+
let selected_path = self.selected_path.peek();
72+
let data = self.paths.peek();
73+
let current = data
74+
.0
75+
.iter()
76+
.filter_map(|data| PathInfo::new(data, selected_path.as_ref()))
77+
.collect();
78+
self.current = PathInfoList(current)
6879
}
6980
}
7081

7182
impl Watcher for PathWatcher {
7283
type Value = PathInfoList;
7384

7485
fn update(&mut self) -> bool {
75-
let mut updated = false;
76-
if self.paths.update() {
77-
self.current = self.paths.peek().clone();
78-
updated = true;
79-
}
80-
if self.selected_path.update() {
81-
updated = true;
82-
}
83-
if updated {
84-
self.apply_selected_path();
86+
if self.paths.update() || self.selected_path.update() {
87+
self.update_current();
88+
true
89+
} else {
90+
false
8591
}
86-
updated
8792
}
8893

8994
fn peek(&self) -> &Self::Value {
@@ -100,27 +105,55 @@ impl Watcher for PathWatcher {
100105
) -> Poll<Result<(), n0_watcher::Disconnected>> {
101106
let poll_paths = self.paths.poll_updated(cx)?;
102107
let poll_selected = self.selected_path.poll_updated(cx)?;
103-
if poll_paths.is_ready() {
104-
self.current = self.paths.peek().clone();
105-
self.apply_selected_path();
106-
Poll::Ready(Ok(()))
107-
} else if poll_selected.is_ready() {
108-
self.apply_selected_path();
108+
if poll_paths.is_ready() || poll_selected.is_ready() {
109+
self.update_current();
109110
Poll::Ready(Ok(()))
110111
} else {
111112
Poll::Pending
112113
}
113114
}
114115
}
115116

116-
/// TODO
117+
#[derive(derive_more::Debug, Clone)]
118+
struct PathData {
119+
handle: quinn::WeakPathHandle,
120+
remote_addr: TransportAddr,
121+
is_closed: bool,
122+
is_abandoned: bool,
123+
}
124+
125+
impl PartialEq for PathData {
126+
fn eq(&self, other: &Self) -> bool {
127+
self.handle.id() == other.handle.id()
128+
&& self.remote_addr == other.remote_addr
129+
&& self.is_closed == other.is_closed
130+
&& self.is_abandoned == other.is_abandoned
131+
}
132+
}
133+
impl Eq for PathData {}
134+
135+
impl PathData {
136+
fn new(conn: &quinn::Connection, id: PathId, remote_addr: TransportAddr) -> Option<Self> {
137+
let handle = conn.path(id)?;
138+
Some(PathData {
139+
handle: handle.weak_handle(),
140+
remote_addr,
141+
is_closed: false,
142+
is_abandoned: false,
143+
})
144+
}
145+
}
146+
147+
/// Information about a network transmission path used by a [`Connection`].
148+
///
149+
/// [`Connection`]: crate::endpoint::Connection
117150
#[derive(derive_more::Debug, Clone)]
118151
pub struct PathInfo {
119-
handle: WeakPathHandle,
152+
handle: quinn::Path,
120153
remote_addr: TransportAddr,
121154
is_selected: bool,
122-
pub(super) is_closed: bool,
123-
pub(super) is_abandoned: bool,
155+
is_closed: bool,
156+
is_abandoned: bool,
124157
}
125158

126159
impl PartialEq for PathInfo {
@@ -136,27 +169,21 @@ impl PartialEq for PathInfo {
136169
impl Eq for PathInfo {}
137170

138171
impl PathInfo {
139-
pub(crate) fn new(
140-
conn: &quinn::Connection,
141-
id: PathId,
142-
remote_addr: TransportAddr,
143-
selected_path: Option<&transports::Addr>,
144-
) -> Option<Self> {
145-
let path = conn.path(id)?;
146-
let is_closed = path.status().is_err();
147-
let handle = path.weak_handle();
172+
fn new(data: &PathData, selected_path: Option<&transports::Addr>) -> Option<Self> {
173+
let handle = data.handle.upgrade()?;
148174
let is_selected = selected_path
149175
.as_ref()
150-
.map(|addr| addr.is_transport_addr(&remote_addr))
176+
.map(|addr| addr.is_transport_addr(&data.remote_addr))
151177
.unwrap_or(false);
152178
Some(PathInfo {
153179
handle,
154-
remote_addr,
180+
remote_addr: data.remote_addr.clone(),
155181
is_selected,
156-
is_closed,
157-
is_abandoned: false,
182+
is_closed: data.is_closed,
183+
is_abandoned: data.is_abandoned,
158184
})
159185
}
186+
160187
/// Returns the [`PathId`] of this path.
161188
pub fn id(&self) -> PathId {
162189
self.handle.id()
@@ -191,20 +218,26 @@ impl PathInfo {
191218

192219
/// Returns stats for this transmission path.
193220
///
194-
/// Returns empty stats if the connection is dropped.
221+
/// Returns an error if the underlying connection has been dropped.
195222
pub fn stats(&self) -> PathStats {
196-
self.handle.upgrade().map(|p| p.stats()).unwrap_or_default()
223+
self.handle.stats()
197224
}
198225

199226
/// Current best estimate of this paths's latency (round-trip-time)
227+
///
228+
/// Returns an error if the underlying connection has been dropped.
200229
pub fn rtt(&self) -> Duration {
201230
self.stats().rtt
202231
}
203232
}
204233

234+
#[stack_error(derive, add_meta)]
235+
#[error("Connection is dropped")]
236+
pub struct ConnectionDroppedError;
237+
205238
#[derive(Debug, Clone)]
206239
pub(crate) struct PathWatchable {
207-
paths: Watchable<PathInfoList>,
240+
paths: Watchable<PathDataList>,
208241
selected_path: Watchable<Option<transports::Addr>>,
209242
}
210243

@@ -217,30 +250,30 @@ impl PathWatchable {
217250
}
218251

219252
pub(super) fn insert(&self, conn: &quinn::Connection, id: PathId, remote_addr: TransportAddr) {
220-
let info = PathInfo::new(conn, id, remote_addr, self.selected_path.get().as_ref());
221-
if let Some(info) = info {
222-
self.update(move |list| list.push(info));
253+
let data = PathData::new(conn, id, remote_addr);
254+
if let Some(data) = data {
255+
self.update(move |list| list.push(data));
223256
}
224257
}
225258

226259
pub(super) fn set_closed(&self, id: PathId) {
227260
self.update(|list| {
228-
if let Some(item) = list.iter_mut().find(|p| p.id() == id) {
261+
if let Some(item) = list.iter_mut().find(|p| p.handle.id() == id) {
229262
item.is_closed = true;
230263
}
231264
});
232265
}
233266

234267
pub(super) fn set_abandoned(&self, id: PathId) {
235268
self.update(|list| {
236-
if let Some(item) = list.iter_mut().find(|p| p.id() == id) {
269+
if let Some(item) = list.iter_mut().find(|p| p.handle.id() == id) {
237270
item.is_closed = true;
238271
item.is_abandoned = true;
239272
}
240273
});
241274
}
242275

243-
fn update(&self, f: impl FnOnce(&mut SmallVec<[PathInfo; 4]>)) {
276+
fn update(&self, f: impl FnOnce(&mut SmallVec<[PathData; 4]>)) {
244277
let mut value = self.paths.get();
245278
f(&mut value.0);
246279
if !self.paths.has_watchers() {
@@ -250,14 +283,12 @@ impl PathWatchable {
250283
}
251284

252285
pub(crate) fn watch(&self) -> PathWatcher {
253-
let paths = self.paths.watch();
254-
let current = paths.peek().clone();
255286
let mut watcher = PathWatcher {
256-
paths,
287+
paths: self.paths.watch(),
257288
selected_path: self.selected_path.watch(),
258-
current,
289+
current: Default::default(),
259290
};
260-
watcher.apply_selected_path();
291+
watcher.update_current();
261292
watcher
262293
}
263294
}

0 commit comments

Comments
 (0)