Skip to content

Commit 6b1186f

Browse files
refactor(iroh-net): Keep connection name, remove connection count (#2779)
## Description These are two cleanups in the relay client: - The `relay::Client` hands out a connection object when asked to connect. This `Conn` was imported with rename to `RelayClient` which was a bit confusing as this was already the relay client. It is now left at it's original name which makes a lot more sense. The related builder struct etc are renamed to match. - The `relay::Client` had a counter for the number of connections made to the relay. That seems fun, but was entirely unused. If this is a useful thing to have it should probably be a counter metric instead but let's not add anything that no one is using. Removing this makes a lot of APIs a bit simpler and removes some state tracking. ## Breaking Changes None hopefully, please let this all be internal APIs. ## Notes & open questions <!-- Any notes, remarks or open questions you have to make about the PR. --> ## 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. - ~~[ ] All breaking changes documented.~~ --------- Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com>
1 parent bd5e4fa commit 6b1186f

File tree

5 files changed

+73
-81
lines changed

5 files changed

+73
-81
lines changed

iroh-net/src/magicsock/relay_actor.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,7 @@ impl ActiveRelay {
165165
Ok(())
166166
}
167167

168-
async fn handle_relay_msg(
169-
&mut self,
170-
msg: Result<(ReceivedMessage, usize), ClientError>,
171-
) -> ReadResult {
168+
async fn handle_relay_msg(&mut self, msg: Result<ReceivedMessage, ClientError>) -> ReadResult {
172169
match msg {
173170
Err(err) => {
174171
warn!("recv error {:?}", err);
@@ -200,7 +197,7 @@ impl ActiveRelay {
200197
None => ReadResult::Break,
201198
}
202199
}
203-
Ok((msg, _conn_gen)) => {
200+
Ok(msg) => {
204201
// reset
205202
self.backoff.reset();
206203
let now = Instant::now();

iroh-net/src/relay/client.rs

+57-68
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,12 @@ use tokio_util::task::AbortOnDropHandle;
2727
use tracing::{debug, error, event, info_span, trace, warn, Instrument, Level};
2828
use url::Url;
2929

30-
use conn::{
31-
Conn as RelayClient, ConnBuilder as RelayClientBuilder, ConnReader,
32-
ConnReceiver as RelayClientReceiver, ConnWriter, ReceivedMessage,
33-
};
30+
use conn::{Conn, ConnBuilder, ConnReader, ConnReceiver, ConnWriter, ReceivedMessage};
3431
use streams::{downcast_upgrade, MaybeTlsStream, ProxyStream};
3532

3633
use crate::defaults::timeouts::relay::*;
3734
use crate::dns::{DnsResolver, ResolverExt};
38-
use crate::key::{PublicKey, SecretKey};
35+
use crate::key::{NodeId, PublicKey, SecretKey};
3936
use crate::relay::codec::DerpCodec;
4037
use crate::relay::http::{Protocol, RELAY_PATH};
4138
use crate::relay::RelayUrl;
@@ -140,7 +137,7 @@ pub struct Client {
140137

141138
#[derive(Debug)]
142139
enum ActorMessage {
143-
Connect(oneshot::Sender<Result<(RelayClient, usize), ClientError>>),
140+
Connect(oneshot::Sender<Result<Conn, ClientError>>),
144141
NotePreferred(bool),
145142
LocalAddr(oneshot::Sender<Result<Option<SocketAddr>, ClientError>>),
146143
Ping(oneshot::Sender<Result<Duration, ClientError>>),
@@ -154,19 +151,18 @@ enum ActorMessage {
154151
/// Receiving end of a [`Client`].
155152
#[derive(Debug)]
156153
pub struct ClientReceiver {
157-
msg_receiver: mpsc::Receiver<Result<(ReceivedMessage, usize), ClientError>>,
154+
msg_receiver: mpsc::Receiver<Result<ReceivedMessage, ClientError>>,
158155
}
159156

160157
#[derive(derive_more::Debug)]
161158
struct Actor {
162159
secret_key: SecretKey,
163160
can_ack_pings: bool,
164161
is_preferred: bool,
165-
relay_client: Option<(RelayClient, RelayClientReceiver)>,
162+
relay_conn: Option<(Conn, ConnReceiver)>,
166163
is_closed: bool,
167164
#[debug("address family selector callback")]
168165
address_family_selector: Option<Box<dyn Fn() -> BoxFuture<bool> + Send + Sync + 'static>>,
169-
conn_gen: usize,
170166
url: RelayUrl,
171167
protocol: Protocol,
172168
#[debug("TlsConnector")]
@@ -334,10 +330,9 @@ impl ClientBuilder {
334330
secret_key: key,
335331
can_ack_pings: self.can_ack_pings,
336332
is_preferred: self.is_preferred,
337-
relay_client: None,
333+
relay_conn: None,
338334
is_closed: false,
339335
address_family_selector: self.address_family_selector,
340-
conn_gen: 0,
341336
pings: PingTracker::default(),
342337
ping_tasks: Default::default(),
343338
url: self.url,
@@ -371,9 +366,8 @@ impl ClientBuilder {
371366
}
372367

373368
impl ClientReceiver {
374-
/// Reads a message from the server. Returns the message and the `conn_get`, or the number of
375-
/// re-connections this Client has ever made
376-
pub async fn recv(&mut self) -> Option<Result<(ReceivedMessage, usize), ClientError>> {
369+
/// Reads a message from the server.
370+
pub async fn recv(&mut self) -> Option<Result<ReceivedMessage, ClientError>> {
377371
self.msg_receiver.recv().await
378372
}
379373
}
@@ -399,13 +393,13 @@ impl Client {
399393
}
400394
}
401395

402-
/// Connect to a relay Server and returns the underlying relay Client.
396+
/// Connects to a relay Server and returns the underlying relay connection.
403397
///
404398
/// Returns [`ClientError::Closed`] if the [`Client`] is closed.
405399
///
406400
/// If there is already an active relay connection, returns the already
407401
/// connected [`crate::relay::RelayConn`].
408-
pub async fn connect(&self) -> Result<(RelayClient, usize), ClientError> {
402+
pub async fn connect(&self) -> Result<Conn, ClientError> {
409403
self.send_actor(ActorMessage::Connect).await
410404
}
411405

@@ -475,7 +469,7 @@ impl Actor {
475469
async fn run(
476470
mut self,
477471
mut inbox: mpsc::Receiver<ActorMessage>,
478-
msg_sender: mpsc::Sender<Result<(ReceivedMessage, usize), ClientError>>,
472+
msg_sender: mpsc::Sender<Result<ReceivedMessage, ClientError>>,
479473
) {
480474
// Add an initial connection attempt.
481475
if let Err(err) = self.connect("initial connect").await {
@@ -485,7 +479,7 @@ impl Actor {
485479
loop {
486480
tokio::select! {
487481
res = self.recv_detail() => {
488-
if let Ok((ReceivedMessage::Pong(ping), _)) = res {
482+
if let Ok(ReceivedMessage::Pong(ping)) = res {
489483
match self.pings.unregister(ping, "pong") {
490484
Some(chan) => {
491485
if chan.send(()).is_err() {
@@ -503,7 +497,7 @@ impl Actor {
503497
Some(msg) = inbox.recv() => {
504498
match msg {
505499
ActorMessage::Connect(s) => {
506-
let res = self.connect("actor msg").await.map(|(client, _, count)| (client, count));
500+
let res = self.connect("actor msg").await.map(|(client, _)| (client));
507501
s.send(res).ok();
508502
},
509503
ActorMessage::NotePreferred(is_preferred) => {
@@ -549,46 +543,51 @@ impl Actor {
549543
}
550544
}
551545

546+
/// Returns a connection to the relay.
547+
///
548+
/// If the client is currently connected, the existing connection is returned; otherwise,
549+
/// a new connection is made.
550+
///
551+
/// Returns:
552+
/// - A clonable connection object which can send DISCO messages to the relay.
553+
/// - A reference to a channel receiving DISCO messages from the relay.
552554
async fn connect(
553555
&mut self,
554556
why: &'static str,
555-
) -> Result<(RelayClient, &'_ mut RelayClientReceiver, usize), ClientError> {
557+
) -> Result<(Conn, &'_ mut ConnReceiver), ClientError> {
556558
debug!(
557559
"connect: {}, current client {}",
558560
why,
559-
self.relay_client.is_some()
561+
self.relay_conn.is_some()
560562
);
561563

562564
if self.is_closed {
563565
return Err(ClientError::Closed);
564566
}
565567
async move {
566-
if self.relay_client.is_none() {
568+
if self.relay_conn.is_none() {
567569
trace!("no connection, trying to connect");
568-
let (relay_client, receiver) =
569-
tokio::time::timeout(CONNECT_TIMEOUT, self.connect_0())
570-
.await
571-
.map_err(|_| ClientError::ConnectTimeout)??;
570+
let (conn, receiver) = tokio::time::timeout(CONNECT_TIMEOUT, self.connect_0())
571+
.await
572+
.map_err(|_| ClientError::ConnectTimeout)??;
572573

573-
self.relay_client = Some((relay_client.clone(), receiver));
574-
self.next_conn();
574+
self.relay_conn = Some((conn, receiver));
575575
} else {
576576
trace!("already had connection");
577577
}
578-
let count = self.current_conn();
579-
let (relay_client, receiver) = self
580-
.relay_client
578+
let (conn, receiver) = self
579+
.relay_conn
581580
.as_mut()
582581
.map(|(c, r)| (c.clone(), r))
583582
.expect("just checked");
584583

585-
Ok((relay_client, receiver, count))
584+
Ok((conn, receiver))
586585
}
587586
.instrument(info_span!("connect"))
588587
.await
589588
}
590589

591-
async fn connect_0(&self) -> Result<(RelayClient, RelayClientReceiver), ClientError> {
590+
async fn connect_0(&self) -> Result<(Conn, ConnReceiver), ClientError> {
592591
let (reader, writer, local_addr) = match self.protocol {
593592
Protocol::Websocket => {
594593
let (reader, writer) = self.connect_ws().await?;
@@ -601,14 +600,14 @@ impl Actor {
601600
}
602601
};
603602

604-
let (relay_client, receiver) =
605-
RelayClientBuilder::new(self.secret_key.clone(), local_addr, reader, writer)
603+
let (conn, receiver) =
604+
ConnBuilder::new(self.secret_key.clone(), local_addr, reader, writer)
606605
.build()
607606
.await
608607
.map_err(|e| ClientError::Build(e.to_string()))?;
609608

610-
if self.is_preferred && relay_client.note_preferred(true).await.is_err() {
611-
relay_client.close().await;
609+
if self.is_preferred && conn.note_preferred(true).await.is_err() {
610+
conn.close().await;
612611
return Err(ClientError::Send);
613612
}
614613

@@ -620,7 +619,7 @@ impl Actor {
620619
);
621620

622621
trace!("connect_0 done");
623-
Ok((relay_client, receiver))
622+
Ok((conn, receiver))
624623
}
625624

626625
async fn connect_ws(&self) -> Result<(ConnReader, ConnWriter), ClientError> {
@@ -732,8 +731,8 @@ impl Actor {
732731

733732
// only send the preference if we already have a connection
734733
let res = {
735-
if let Some((ref client, _)) = self.relay_client {
736-
client.note_preferred(is_preferred).await
734+
if let Some((ref conn, _)) = self.relay_conn {
735+
conn.note_preferred(is_preferred).await
737736
} else {
738737
return;
739738
}
@@ -749,23 +748,23 @@ impl Actor {
749748
if self.is_closed {
750749
return None;
751750
}
752-
if let Some((ref client, _)) = self.relay_client {
753-
client.local_addr()
751+
if let Some((ref conn, _)) = self.relay_conn {
752+
conn.local_addr()
754753
} else {
755754
None
756755
}
757756
}
758757

759758
async fn ping(&mut self, s: oneshot::Sender<Result<Duration, ClientError>>) {
760-
let connect_res = self.connect("ping").await.map(|(c, _, _)| c);
759+
let connect_res = self.connect("ping").await.map(|(c, _)| c);
761760
let (ping, recv) = self.pings.register();
762761
trace!("ping: {}", hex::encode(ping));
763762

764763
self.ping_tasks.spawn(async move {
765764
let res = match connect_res {
766-
Ok(client) => {
765+
Ok(conn) => {
767766
let start = Instant::now();
768-
if let Err(err) = client.send_ping(ping).await {
767+
if let Err(err) = conn.send_ping(ping).await {
769768
warn!("failed to send ping: {:?}", err);
770769
Err(ClientError::Send)
771770
} else {
@@ -782,10 +781,10 @@ impl Actor {
782781
});
783782
}
784783

785-
async fn send(&mut self, dst_key: PublicKey, b: Bytes) -> Result<(), ClientError> {
786-
trace!(dst = %dst_key.fmt_short(), len = b.len(), "send");
787-
let (client, _, _) = self.connect("send").await?;
788-
if client.send(dst_key, b).await.is_err() {
784+
async fn send(&mut self, remote_node: NodeId, payload: Bytes) -> Result<(), ClientError> {
785+
trace!(remote_node = %remote_node.fmt_short(), len = payload.len(), "send");
786+
let (conn, _) = self.connect("send").await?;
787+
if conn.send(remote_node, payload).await.is_err() {
789788
self.close_for_reconnect().await;
790789
return Err(ClientError::Send);
791790
}
@@ -795,8 +794,8 @@ impl Actor {
795794
async fn send_pong(&mut self, data: [u8; 8]) -> Result<(), ClientError> {
796795
debug!("send_pong");
797796
if self.can_ack_pings {
798-
let (client, _, _) = self.connect("send_pong").await?;
799-
if client.send_pong(data).await.is_err() {
797+
let (conn, _) = self.connect("send_pong").await?;
798+
if conn.send_pong(data).await.is_err() {
800799
self.close_for_reconnect().await;
801800
return Err(ClientError::Send);
802801
}
@@ -817,16 +816,7 @@ impl Actor {
817816
if self.is_closed {
818817
return false;
819818
}
820-
self.relay_client.is_some()
821-
}
822-
823-
fn current_conn(&self) -> usize {
824-
self.conn_gen
825-
}
826-
827-
fn next_conn(&mut self) -> usize {
828-
self.conn_gen = self.conn_gen.wrapping_add(1);
829-
self.conn_gen
819+
self.relay_conn.is_some()
830820
}
831821

832822
fn tls_servername(&self) -> Option<rustls::pki_types::ServerName> {
@@ -987,13 +977,12 @@ impl Actor {
987977
}
988978
}
989979

990-
async fn recv_detail(&mut self) -> Result<(ReceivedMessage, usize), ClientError> {
991-
if let Some((_client, client_receiver)) = self.relay_client.as_mut() {
980+
async fn recv_detail(&mut self) -> Result<ReceivedMessage, ClientError> {
981+
if let Some((_conn, conn_receiver)) = self.relay_conn.as_mut() {
992982
trace!("recv_detail tick");
993-
match client_receiver.recv().await {
983+
match conn_receiver.recv().await {
994984
Ok(msg) => {
995-
let current_gen = self.current_conn();
996-
return Ok((msg, current_gen));
985+
return Ok(msg);
997986
}
998987
Err(e) => {
999988
self.close_for_reconnect().await;
@@ -1012,8 +1001,8 @@ impl Actor {
10121001
/// requires a connection, it will call `connect`.
10131002
async fn close_for_reconnect(&mut self) {
10141003
debug!("close for reconnect");
1015-
if let Some((client, _)) = self.relay_client.take() {
1016-
client.close().await
1004+
if let Some((conn, _)) = self.relay_conn.take() {
1005+
conn.close().await
10171006
}
10181007
}
10191008
}

iroh-net/src/relay/client/conn.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ pub struct Conn {
4646
inner: Arc<ConnTasks>,
4747
}
4848

49+
/// The channel on which a relay connection sends received messages.
50+
///
51+
/// The [`Conn`] to a relay is easily clonable but can only send DISCO messages to a relay
52+
/// server. This is the counterpart which receives DISCO messages from the relay server for
53+
/// a connection. It is not clonable.
4954
#[derive(Debug)]
5055
pub struct ConnReceiver {
5156
/// The reader channel, receiving incoming messages.
@@ -376,7 +381,7 @@ impl ConnBuilder {
376381
recv_msgs: writer_recv,
377382
}
378383
.run()
379-
.instrument(info_span!("client.writer")),
384+
.instrument(info_span!("conn.writer")),
380385
);
381386

382387
let (reader_sender, reader_recv) = mpsc::channel(PER_CLIENT_READ_QUEUE_DEPTH);
@@ -412,6 +417,7 @@ impl ConnBuilder {
412417
}
413418
}
414419
}
420+
.instrument(info_span!("conn.reader"))
415421
});
416422

417423
let conn = Conn {

0 commit comments

Comments
 (0)