Skip to content

Commit 6078fc6

Browse files
transports/{tcp,dns,websocket}: Remove Clone imp for *Config (#2682)
This commit removes the `Clone` implementation on `GenTcpConfig` and consequently the `Clone` implementations on `GenDnsConfig` and `WsConfig`. When port-reuse is enabled, `GenTcpConfig` tracks the addresses it is listening in a `HashSet`. This `HashSet` is shared with the `TcpListenStream`s via an `Arc<Mutex<_>>`. Given that `Clone` is `derive`d on `GenTcpConfig`, cloning a `GenTcpConfig`, results in both instances sharing the same set of listen addresses. This is not intuitive. This behavior is for example error prone in the scenario where one wants to speak both plain DNS/TCP and Websockets. Say a user creates the transport in the following way: ``` Rust let transport = { let tcp = tcp::TcpConfig::new().nodelay(true).port_reuse(true); let dns_tcp = dns::DnsConfig::system(tcp).await?; let ws_dns_tcp = websocket::WsConfig::new(dns_tcp.clone()); dns_tcp.or_transport(ws_dns_tcp) }; ``` Both `dns_tcp` and `ws_dns_tcp` share the set of listen addresses, given the `dns_tcp.clone()` to create the `ws_dns_tcp`. Thus, with port-reuse, a Websocket dial might reuse a DNS/TCP listening port instead of a Websocket listening port. With this commit a user is forced to do the below, preventing the above error: ``` Rust let transport = { let dns_tcp = dns::DnsConfig::system(tcp::TcpConfig::new().nodelay(true).port_reuse(true)).await?; let ws_dns_tcp = websocket::WsConfig::new( dns::DnsConfig::system(tcp::TcpConfig::new().nodelay(true).port_reuse(true)).await?, ); dns_tcp.or_transport(ws_dns_tcp) }; ``` Co-authored-by: Thomas Eizinger <[email protected]>
1 parent 2804756 commit 6078fc6

File tree

8 files changed

+29
-24
lines changed

8 files changed

+29
-24
lines changed

src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,10 @@ pub async fn development_transport(
201201
keypair: identity::Keypair,
202202
) -> std::io::Result<core::transport::Boxed<(PeerId, core::muxing::StreamMuxerBox)>> {
203203
let transport = {
204-
let tcp = tcp::TcpConfig::new().nodelay(true);
205-
let dns_tcp = dns::DnsConfig::system(tcp).await?;
206-
let ws_dns_tcp = websocket::WsConfig::new(dns_tcp.clone());
204+
let dns_tcp = dns::DnsConfig::system(tcp::TcpConfig::new().nodelay(true)).await?;
205+
let ws_dns_tcp = websocket::WsConfig::new(
206+
dns::DnsConfig::system(tcp::TcpConfig::new().nodelay(true)).await?,
207+
);
207208
dns_tcp.or_transport(ws_dns_tcp)
208209
};
209210

@@ -258,9 +259,10 @@ pub fn tokio_development_transport(
258259
keypair: identity::Keypair,
259260
) -> std::io::Result<core::transport::Boxed<(PeerId, core::muxing::StreamMuxerBox)>> {
260261
let transport = {
261-
let tcp = tcp::TokioTcpConfig::new().nodelay(true);
262-
let dns_tcp = dns::TokioDnsConfig::system(tcp)?;
263-
let ws_dns_tcp = websocket::WsConfig::new(dns_tcp.clone());
262+
let dns_tcp = dns::TokioDnsConfig::system(tcp::TokioTcpConfig::new().nodelay(true))?;
263+
let ws_dns_tcp = websocket::WsConfig::new(dns::TokioDnsConfig::system(
264+
tcp::TokioTcpConfig::new().nodelay(true),
265+
)?);
264266
dns_tcp.or_transport(ws_dns_tcp)
265267
};
266268

transports/deflate/tests/test.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ async fn run(message1: Vec<u8>) {
5454
});
5555

5656
let mut listener = transport
57-
.clone()
5857
.listen_on("/ip4/0.0.0.0/tcp/0".parse().expect("multiaddr"))
5958
.expect("listener");
6059

transports/dns/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
- Update to `libp2p-core` `v0.33.0`.
44

5+
- Remove implementation of `Clone` on `GenDnsConfig`. See [PR 2682].
6+
7+
[PR 2682]: https://github.com/libp2p/rust-libp2p/pull/2682
8+
59
# 0.32.1
610

711
- Update to `trust-dns` `v0.21`. See [PR 2543].

transports/dns/src/lib.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ pub type DnsConfig<T> = GenDnsConfig<T, AsyncStdConnection, AsyncStdConnectionPr
107107
pub type TokioDnsConfig<T> = GenDnsConfig<T, TokioConnection, TokioConnectionProvider>;
108108

109109
/// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses.
110-
#[derive(Clone)]
111110
pub struct GenDnsConfig<T, C, P>
112111
where
113112
C: DnsHandle<Error = ResolveError>,
@@ -628,7 +627,7 @@ mod tests {
628627
}
629628
}
630629

631-
async fn run<T, C, P>(transport: GenDnsConfig<T, C, P>)
630+
async fn run<T, C, P>(mut transport: GenDnsConfig<T, C, P>)
632631
where
633632
C: DnsHandle<Error = ResolveError>,
634633
P: ConnectionProvider<Conn = C>,
@@ -638,31 +637,27 @@ mod tests {
638637
{
639638
// Success due to existing A record for example.com.
640639
let _ = transport
641-
.clone()
642640
.dial("/dns4/example.com/tcp/20000".parse().unwrap())
643641
.unwrap()
644642
.await
645643
.unwrap();
646644

647645
// Success due to existing AAAA record for example.com.
648646
let _ = transport
649-
.clone()
650647
.dial("/dns6/example.com/tcp/20000".parse().unwrap())
651648
.unwrap()
652649
.await
653650
.unwrap();
654651

655652
// Success due to pass-through, i.e. nothing to resolve.
656653
let _ = transport
657-
.clone()
658654
.dial("/ip4/1.2.3.4/tcp/20000".parse().unwrap())
659655
.unwrap()
660656
.await
661657
.unwrap();
662658

663659
// Success due to the DNS TXT records at _dnsaddr.bootstrap.libp2p.io.
664660
let _ = transport
665-
.clone()
666661
.dial("/dnsaddr/bootstrap.libp2p.io".parse().unwrap())
667662
.unwrap()
668663
.await
@@ -672,7 +667,6 @@ mod tests {
672667
// an entry with suffix `/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN`,
673668
// i.e. a bootnode with such a peer ID.
674669
let _ = transport
675-
.clone()
676670
.dial("/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN".parse().unwrap())
677671
.unwrap()
678672
.await
@@ -681,7 +675,6 @@ mod tests {
681675
// Failure due to the DNS TXT records at _dnsaddr.libp2p.io not having
682676
// an entry with a random `p2p` suffix.
683677
match transport
684-
.clone()
685678
.dial(
686679
format!("/dnsaddr/bootstrap.libp2p.io/p2p/{}", PeerId::random())
687680
.parse()
@@ -697,7 +690,6 @@ mod tests {
697690

698691
// Failure due to no records.
699692
match transport
700-
.clone()
701693
.dial("/dns4/example.invalid/tcp/20000".parse().unwrap())
702694
.unwrap()
703695
.await

transports/tcp/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
- Update to `libp2p-core` `v0.33.0`.
44

5+
- Remove implementation of `Clone` on `GenTcpConfig`. See [PR 2682].
6+
7+
[PR 2682]: https://github.com/libp2p/rust-libp2p/pull/2682
8+
59
# 0.32.0 [2022-02-22]
610

711
- Update to `libp2p-core` `v0.32.0`.

transports/tcp/src/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ use std::{
6767
use provider::{IfEvent, Provider};
6868

6969
/// The configuration for a TCP/IP transport capability for libp2p.
70-
#[derive(Clone, Debug)]
70+
#[derive(Debug)]
7171
pub struct GenTcpConfig<T> {
7272
/// The type of the I/O provider.
7373
_impl: std::marker::PhantomData<T>,
@@ -258,7 +258,7 @@ where
258258
/// let listen_addr2: Multiaddr = "/ip4/127.0.0.1/tcp/9002".parse().unwrap();
259259
///
260260
/// let mut tcp1 = TcpConfig::new().port_reuse(true);
261-
/// let mut listener1 = tcp1.clone().listen_on(listen_addr1.clone()).expect("listener");
261+
/// let mut listener1 = tcp1.listen_on(listen_addr1.clone()).expect("listener");
262262
/// match listener1.next().await.expect("event")? {
263263
/// ListenerEvent::NewAddress(listen_addr) => {
264264
/// println!("Listening on {:?}", listen_addr);
@@ -269,7 +269,7 @@ where
269269
/// }
270270
///
271271
/// let mut tcp2 = TcpConfig::new().port_reuse(true);
272-
/// let mut listener2 = tcp2.clone().listen_on(listen_addr2).expect("listener");
272+
/// let mut listener2 = tcp2.listen_on(listen_addr2).expect("listener");
273273
/// match listener2.next().await.expect("event")? {
274274
/// ListenerEvent::NewAddress(listen_addr) => {
275275
/// println!("Listening on {:?}", listen_addr);
@@ -952,7 +952,7 @@ mod tests {
952952
) {
953953
let dest_addr = ready_rx.next().await.unwrap();
954954
let mut tcp = GenTcpConfig::<T>::new().port_reuse(true);
955-
let mut listener = tcp.clone().listen_on(addr).unwrap();
955+
let mut listener = tcp.listen_on(addr).unwrap();
956956
match listener.next().await.unwrap().unwrap() {
957957
ListenerEvent::NewAddress(_) => {
958958
// Check that tcp and listener share the same port reuse SocketAddr
@@ -1018,8 +1018,8 @@ mod tests {
10181018
env_logger::try_init().ok();
10191019

10201020
async fn listen_twice<T: Provider>(addr: Multiaddr) {
1021-
let tcp = GenTcpConfig::<T>::new().port_reuse(true);
1022-
let mut listener1 = tcp.clone().listen_on(addr).unwrap();
1021+
let mut tcp = GenTcpConfig::<T>::new().port_reuse(true);
1022+
let mut listener1 = tcp.listen_on(addr).unwrap();
10231023
match listener1.next().await.unwrap().unwrap() {
10241024
ListenerEvent::NewAddress(addr1) => {
10251025
// Check that tcp and listener share the same port reuse SocketAddr
@@ -1032,7 +1032,7 @@ mod tests {
10321032
assert_eq!(port_reuse_tcp, port_reuse_listener1);
10331033

10341034
// Listen on the same address a second time.
1035-
let mut listener2 = tcp.clone().listen_on(addr1.clone()).unwrap();
1035+
let mut listener2 = tcp.listen_on(addr1.clone()).unwrap();
10361036
match listener2.next().await.unwrap().unwrap() {
10371037
ListenerEvent::NewAddress(addr2) => {
10381038
assert_eq!(addr1, addr2);

transports/websocket/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
- Update to `libp2p-core` `v0.33.0`.
44

5+
- Remove implementation of `Clone` on `WsConfig`. See [PR 2682].
6+
7+
[PR 2682]: https://github.com/libp2p/rust-libp2p/pull/2682
8+
59
# 0.34.0 [2022-02-22]
610

711
- Update to `libp2p-core` `v0.32.0`.

transports/websocket/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use std::{
4444
};
4545

4646
/// A Websocket transport.
47-
#[derive(Debug, Clone)]
47+
#[derive(Debug)]
4848
pub struct WsConfig<T: Transport>
4949
where
5050
T: Transport,

0 commit comments

Comments
 (0)