Skip to content

Commit c728824

Browse files
authored
feat(relay): hide internals of Connection
Relayed connections to other peers are created from streams to the relay itself. Internally, such a connection has different states. These however are not relevant to the user and should be encapsulated to allow for more backwards-compatible changes. The only interface exposed is `AsyncRead` and `AsyncWrite`. Resolves: #3255. Pull-Request: #3829.
1 parent 30d2c75 commit c728824

File tree

3 files changed

+59
-36
lines changed

3 files changed

+59
-36
lines changed

protocols/relay/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
- Raise MSRV to 1.65.
44
See [PR 3715].
55

6+
- Hide internals of `Connection` and expose only `AsyncRead` and `AsyncWrite`.
7+
See [PR 3829].
8+
69
[PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715
10+
[PR 3829]: https://github.com/libp2p/rust-libp2p/pull/3829
711

812
## 0.15.2
913

protocols/relay/src/priv_client.rs

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ use libp2p_swarm::{
4545
};
4646
use std::collections::{hash_map, HashMap, VecDeque};
4747
use std::io::{Error, ErrorKind, IoSlice};
48-
use std::ops::DerefMut;
4948
use std::pin::Pin;
5049
use std::task::{Context, Poll};
5150
use transport::Transport;
@@ -387,32 +386,43 @@ impl NetworkBehaviour for Behaviour {
387386
}
388387
}
389388

390-
/// A [`NegotiatedSubstream`] acting as a [`Connection`].
391-
pub enum Connection {
389+
/// Represents a connection to another peer via a relay.
390+
///
391+
/// Internally, this uses a stream to the relay.
392+
pub struct Connection {
393+
state: ConnectionState,
394+
}
395+
396+
enum ConnectionState {
392397
InboundAccepting {
393-
accept: BoxFuture<'static, Result<Connection, Error>>,
398+
accept: BoxFuture<'static, Result<ConnectionState, Error>>,
394399
},
395400
Operational {
396401
read_buffer: Bytes,
397402
substream: NegotiatedSubstream,
403+
/// "Drop notifier" pattern to signal to the transport that the connection has been dropped.
404+
///
405+
/// This is flagged as "dead-code" by the compiler because we never read from it here.
406+
/// However, it is actual use is to trigger the `Canceled` error in the `Transport` when this `Sender` is dropped.
407+
#[allow(dead_code)]
398408
drop_notifier: oneshot::Sender<void::Void>,
399409
},
400410
}
401411

402-
impl Unpin for Connection {}
412+
impl Unpin for ConnectionState {}
403413

404-
impl Connection {
414+
impl ConnectionState {
405415
pub(crate) fn new_inbound(
406416
circuit: inbound_stop::Circuit,
407417
drop_notifier: oneshot::Sender<void::Void>,
408418
) -> Self {
409-
Connection::InboundAccepting {
419+
ConnectionState::InboundAccepting {
410420
accept: async {
411421
let (substream, read_buffer) = circuit
412422
.accept()
413423
.await
414424
.map_err(|e| Error::new(ErrorKind::Other, e))?;
415-
Ok(Connection::Operational {
425+
Ok(ConnectionState::Operational {
416426
read_buffer,
417427
substream,
418428
drop_notifier,
@@ -427,7 +437,7 @@ impl Connection {
427437
read_buffer: Bytes,
428438
drop_notifier: oneshot::Sender<void::Void>,
429439
) -> Self {
430-
Connection::Operational {
440+
ConnectionState::Operational {
431441
substream,
432442
read_buffer,
433443
drop_notifier,
@@ -442,35 +452,41 @@ impl AsyncWrite for Connection {
442452
buf: &[u8],
443453
) -> Poll<Result<usize, Error>> {
444454
loop {
445-
match self.deref_mut() {
446-
Connection::InboundAccepting { accept } => {
447-
*self = ready!(accept.poll_unpin(cx))?;
455+
match &mut self.state {
456+
ConnectionState::InboundAccepting { accept } => {
457+
*self = Connection {
458+
state: ready!(accept.poll_unpin(cx))?,
459+
};
448460
}
449-
Connection::Operational { substream, .. } => {
461+
ConnectionState::Operational { substream, .. } => {
450462
return Pin::new(substream).poll_write(cx, buf);
451463
}
452464
}
453465
}
454466
}
455467
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Error>> {
456468
loop {
457-
match self.deref_mut() {
458-
Connection::InboundAccepting { accept } => {
459-
*self = ready!(accept.poll_unpin(cx))?;
469+
match &mut self.state {
470+
ConnectionState::InboundAccepting { accept } => {
471+
*self = Connection {
472+
state: ready!(accept.poll_unpin(cx))?,
473+
};
460474
}
461-
Connection::Operational { substream, .. } => {
475+
ConnectionState::Operational { substream, .. } => {
462476
return Pin::new(substream).poll_flush(cx);
463477
}
464478
}
465479
}
466480
}
467481
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Error>> {
468482
loop {
469-
match self.deref_mut() {
470-
Connection::InboundAccepting { accept } => {
471-
*self = ready!(accept.poll_unpin(cx))?;
483+
match &mut self.state {
484+
ConnectionState::InboundAccepting { accept } => {
485+
*self = Connection {
486+
state: ready!(accept.poll_unpin(cx))?,
487+
};
472488
}
473-
Connection::Operational { substream, .. } => {
489+
ConnectionState::Operational { substream, .. } => {
474490
return Pin::new(substream).poll_close(cx);
475491
}
476492
}
@@ -483,11 +499,13 @@ impl AsyncWrite for Connection {
483499
bufs: &[IoSlice],
484500
) -> Poll<Result<usize, Error>> {
485501
loop {
486-
match self.deref_mut() {
487-
Connection::InboundAccepting { accept } => {
488-
*self = ready!(accept.poll_unpin(cx))?;
502+
match &mut self.state {
503+
ConnectionState::InboundAccepting { accept } => {
504+
*self = Connection {
505+
state: ready!(accept.poll_unpin(cx))?,
506+
};
489507
}
490-
Connection::Operational { substream, .. } => {
508+
ConnectionState::Operational { substream, .. } => {
491509
return Pin::new(substream).poll_write_vectored(cx, bufs);
492510
}
493511
}
@@ -502,11 +520,13 @@ impl AsyncRead for Connection {
502520
buf: &mut [u8],
503521
) -> Poll<Result<usize, Error>> {
504522
loop {
505-
match self.deref_mut() {
506-
Connection::InboundAccepting { accept } => {
507-
*self = ready!(accept.poll_unpin(cx))?;
523+
match &mut self.state {
524+
ConnectionState::InboundAccepting { accept } => {
525+
*self = Connection {
526+
state: ready!(accept.poll_unpin(cx))?,
527+
};
508528
}
509-
Connection::Operational {
529+
ConnectionState::Operational {
510530
read_buffer,
511531
substream,
512532
..

protocols/relay/src/priv_client/handler.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,11 @@ impl Handler {
189189

190190
let (tx, rx) = oneshot::channel();
191191
self.alive_lend_out_substreams.push(rx);
192-
let connection = super::Connection::new_inbound(inbound_circuit, tx);
192+
let connection = super::ConnectionState::new_inbound(inbound_circuit, tx);
193193

194194
pending_msgs.push_back(transport::ToListenerMsg::IncomingRelayedConnection {
195-
stream: connection,
195+
// stream: connection,
196+
stream: super::Connection { state: connection },
196197
src_peer_id,
197198
relay_peer_id: self.remote_peer_id,
198199
relay_addr: self.remote_addr.clone(),
@@ -271,11 +272,9 @@ impl Handler {
271272
OutboundOpenInfo::Connect { send_back },
272273
) => {
273274
let (tx, rx) = oneshot::channel();
274-
match send_back.send(Ok(super::Connection::new_outbound(
275-
substream,
276-
read_buffer,
277-
tx,
278-
))) {
275+
match send_back.send(Ok(super::Connection {
276+
state: super::ConnectionState::new_outbound(substream, read_buffer, tx),
277+
})) {
279278
Ok(()) => {
280279
self.alive_lend_out_substreams.push(rx);
281280
self.queued_events.push_back(ConnectionHandlerEvent::Custom(

0 commit comments

Comments
 (0)