From dc81754cb959f8202f6f6da5e7d4c5d4697ad947 Mon Sep 17 00:00:00 2001 From: tesol2y090 Date: Tue, 24 Dec 2024 14:39:00 +0700 Subject: [PATCH 1/3] feat: remove support_draft_29 field --- transports/quic/src/config.rs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/transports/quic/src/config.rs b/transports/quic/src/config.rs index c623632ddc6..d13a5cf6284 100644 --- a/transports/quic/src/config.rs +++ b/transports/quic/src/config.rs @@ -51,16 +51,6 @@ pub struct Config { /// of a connection. pub max_connection_data: u32, - /// Support QUIC version draft-29 for dialing and listening. - /// - /// Per default only QUIC Version 1 / [`libp2p_core::multiaddr::Protocol::QuicV1`] - /// is supported. - /// - /// If support for draft-29 is enabled servers support draft-29 and version 1 on all - /// QUIC listening addresses. - /// As client the version is chosen based on the remote's address. - pub support_draft_29: bool, - /// TLS client config for the inner [`quinn::ClientConfig`]. client_tls_config: Arc, /// TLS server config for the inner [`quinn::ServerConfig`]. @@ -85,7 +75,6 @@ impl Config { Self { client_tls_config, server_tls_config, - support_draft_29: false, handshake_timeout: Duration::from_secs(5), max_idle_timeout: 10 * 1000, max_concurrent_stream_limit: 256, @@ -132,7 +121,6 @@ impl From for QuinnConfig { keep_alive_interval, max_connection_data, max_stream_data, - support_draft_29, handshake_timeout: _, keypair, mtu_discovery_config, @@ -169,9 +157,7 @@ impl From for QuinnConfig { }) .unwrap_or_default(); - if !support_draft_29 { - endpoint_config.supported_versions(vec![1]); - } + endpoint_config.supported_versions(vec![1]); QuinnConfig { client_config, From d5e1031221268241df98bed21ba296a2f2d96c80 Mon Sep 17 00:00:00 2001 From: tesol2y090 Date: Tue, 24 Dec 2024 15:59:37 +0700 Subject: [PATCH 2/3] feat: remove support_draft_29, version field --- transports/quic/src/transport.rs | 126 +++++++++---------------------- 1 file changed, 36 insertions(+), 90 deletions(-) diff --git a/transports/quic/src/transport.rs b/transports/quic/src/transport.rs index 63a65ce99cc..2efa9fe8cbd 100644 --- a/transports/quic/src/transport.rs +++ b/transports/quic/src/transport.rs @@ -60,7 +60,6 @@ use crate::{ /// By default only QUIC Version 1 (RFC 9000) is supported. In the [`Multiaddr`] this maps to /// [`libp2p_core::multiaddr::Protocol::QuicV1`]. /// The [`libp2p_core::multiaddr::Protocol::Quic`] codepoint is interpreted as QUIC version -/// draft-29 and only supported if [`Config::support_draft_29`] is set to `true`. /// Note that in that case servers support both version an all QUIC listening addresses. /// /// Version draft-29 should only be used to connect to nodes from other libp2p implementations @@ -72,8 +71,6 @@ pub struct GenTransport { quinn_config: QuinnConfig, /// Timeout for the [`Connecting`] future. handshake_timeout: Duration, - /// Whether draft-29 is supported for dialing and listening. - support_draft_29: bool, /// Streams of active [`Listener`]s. listeners: SelectAll>, /// Dialer for each socket family if no matching listener exists. @@ -88,7 +85,6 @@ impl GenTransport

{ /// Create a new [`GenTransport`] with the given [`Config`]. pub fn new(config: Config) -> Self { let handshake_timeout = config.handshake_timeout; - let support_draft_29 = config.support_draft_29; let quinn_config = config.into(); Self { listeners: SelectAll::new(), @@ -96,7 +92,6 @@ impl GenTransport

{ handshake_timeout, dialer: HashMap::new(), waker: None, - support_draft_29, hole_punch_attempts: Default::default(), } } @@ -142,7 +137,7 @@ impl GenTransport

{ (SocketAddr, ProtocolVersion, Option), TransportError<::Error>, > { - let (socket_addr, version, peer_id) = multiaddr_to_socketaddr(&addr, self.support_draft_29) + let (socket_addr, version, peer_id) = multiaddr_to_socketaddr(&addr) .ok_or_else(|| TransportError::MultiaddrNotSupported(addr.clone()))?; if check_unspecified_addr && (socket_addr.port() == 0 || socket_addr.ip().is_unspecified()) { @@ -228,20 +223,14 @@ impl Transport for GenTransport

{ listener_id: ListenerId, addr: Multiaddr, ) -> Result<(), TransportError> { - let (socket_addr, version, _peer_id) = self.remote_multiaddr_to_socketaddr(addr, false)?; + let (socket_addr, _, _peer_id) = self.remote_multiaddr_to_socketaddr(addr, false)?; let endpoint_config = self.quinn_config.endpoint_config.clone(); let server_config = self.quinn_config.server_config.clone(); let socket = self.create_socket(socket_addr).map_err(Self::Error::from)?; let socket_c = socket.try_clone().map_err(Self::Error::from)?; let endpoint = Self::new_endpoint(endpoint_config, Some(server_config), socket)?; - let listener = Listener::new( - listener_id, - socket_c, - endpoint, - self.handshake_timeout, - version, - )?; + let listener = Listener::new(listener_id, socket_c, endpoint, self.handshake_timeout)?; self.listeners.push(listener); if let Some(waker) = self.waker.take() { @@ -272,8 +261,7 @@ impl Transport for GenTransport

{ addr: Multiaddr, dial_opts: DialOpts, ) -> Result> { - let (socket_addr, version, peer_id) = - self.remote_multiaddr_to_socketaddr(addr.clone(), true)?; + let (socket_addr, _, peer_id) = self.remote_multiaddr_to_socketaddr(addr.clone(), true)?; match (dial_opts.role, dial_opts.port_use) { (Endpoint::Dialer, _) | (Endpoint::Listener, PortUse::Reuse) => { @@ -300,10 +288,7 @@ impl Transport for GenTransport

{ dialer }; let handshake_timeout = self.handshake_timeout; - let mut client_config = self.quinn_config.client_config.clone(); - if version == ProtocolVersion::Draft29 { - client_config.version(0xff00_001d); - } + let client_config = self.quinn_config.client_config.clone(); Ok(Box::pin(async move { // This `"l"` seems necessary because an empty string is an invalid domain // name. While we don't use domain names, the underlying rustls library @@ -385,10 +370,7 @@ impl Transport for GenTransport

{ local_addr, send_back_addr, } => { - let socket_addr = - multiaddr_to_socketaddr(&send_back_addr, self.support_draft_29) - .unwrap() - .0; + let socket_addr = multiaddr_to_socketaddr(&send_back_addr).unwrap().0; if let Some(sender) = self.hole_punch_attempts.remove(&socket_addr) { match sender.send(upgrade) { @@ -426,9 +408,6 @@ struct Listener { /// Id of the listener. listener_id: ListenerId, - /// Version of the supported quic protocol. - version: ProtocolVersion, - /// Endpoint endpoint: quinn::Endpoint, @@ -463,7 +442,6 @@ impl Listener

{ socket: UdpSocket, endpoint: quinn::Endpoint, handshake_timeout: Duration, - version: ProtocolVersion, ) -> Result { let if_watcher; let pending_event; @@ -475,7 +453,7 @@ impl Listener

{ } else { if_watcher = None; listening_addresses.insert(local_addr.ip()); - let ma = socketaddr_to_multiaddr(&local_addr, version); + let ma = socketaddr_to_multiaddr(&local_addr); pending_event = Some(TransportEvent::NewAddress { listener_id, listen_addr: ma, @@ -490,7 +468,6 @@ impl Listener

{ socket, accept, listener_id, - version, handshake_timeout, if_watcher, is_closed: false, @@ -539,9 +516,7 @@ impl Listener

{ loop { match ready!(P::poll_if_event(if_watcher, cx)) { Ok(IfEvent::Up(inet)) => { - if let Some(listen_addr) = - ip_to_listenaddr(&endpoint_addr, inet.addr(), self.version) - { + if let Some(listen_addr) = ip_to_listenaddr(&endpoint_addr, inet.addr()) { tracing::debug!( address=%listen_addr, "New listen address" @@ -554,9 +529,7 @@ impl Listener

{ } } Ok(IfEvent::Down(inet)) => { - if let Some(listen_addr) = - ip_to_listenaddr(&endpoint_addr, inet.addr(), self.version) - { + if let Some(listen_addr) = ip_to_listenaddr(&endpoint_addr, inet.addr()) { tracing::debug!( address=%listen_addr, "Expired listen address" @@ -608,9 +581,9 @@ impl Stream for Listener

{ } }; - let local_addr = socketaddr_to_multiaddr(&self.socket_addr(), self.version); + let local_addr = socketaddr_to_multiaddr(&self.socket_addr()); let remote_addr = connecting.remote_address(); - let send_back_addr = socketaddr_to_multiaddr(&remote_addr, self.version); + let send_back_addr = socketaddr_to_multiaddr(&remote_addr); let event = TransportEvent::Incoming { upgrade: Connecting::new(connecting, self.handshake_timeout), @@ -648,7 +621,6 @@ impl fmt::Debug for Listener

{ #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum ProtocolVersion { V1, // i.e. RFC9000 - Draft29, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -683,24 +655,19 @@ impl From for SocketFamily { /// /// Returns `None` if the `ip` is not the same socket family as the /// address that the endpoint is bound to. -fn ip_to_listenaddr( - endpoint_addr: &SocketAddr, - ip: IpAddr, - version: ProtocolVersion, -) -> Option { +fn ip_to_listenaddr(endpoint_addr: &SocketAddr, ip: IpAddr) -> Option { // True if either both addresses are Ipv4 or both Ipv6. if !SocketFamily::is_same(&endpoint_addr.ip(), &ip) { return None; } let socket_addr = SocketAddr::new(ip, endpoint_addr.port()); - Some(socketaddr_to_multiaddr(&socket_addr, version)) + Some(socketaddr_to_multiaddr(&socket_addr)) } /// Tries to turn a QUIC multiaddress into a UDP [`SocketAddr`]. Returns None if the format /// of the multiaddr is wrong. fn multiaddr_to_socketaddr( addr: &Multiaddr, - support_draft_29: bool, ) -> Option<(SocketAddr, ProtocolVersion, Option)> { let mut iter = addr.iter(); let proto1 = iter.next()?; @@ -716,56 +683,52 @@ fn multiaddr_to_socketaddr( _ => return None, } } - let version = match proto3 { - Protocol::QuicV1 => ProtocolVersion::V1, - Protocol::Quic if support_draft_29 => ProtocolVersion::Draft29, + + match proto3 { + Protocol::QuicV1 => (), _ => return None, }; match (proto1, proto2) { - (Protocol::Ip4(ip), Protocol::Udp(port)) => { - Some((SocketAddr::new(ip.into(), port), version, peer_id)) - } - (Protocol::Ip6(ip), Protocol::Udp(port)) => { - Some((SocketAddr::new(ip.into(), port), version, peer_id)) - } + (Protocol::Ip4(ip), Protocol::Udp(port)) => Some(( + SocketAddr::new(ip.into(), port), + ProtocolVersion::V1, + peer_id, + )), + (Protocol::Ip6(ip), Protocol::Udp(port)) => Some(( + SocketAddr::new(ip.into(), port), + ProtocolVersion::V1, + peer_id, + )), _ => None, } } /// Turns an IP address and port into the corresponding QUIC multiaddr. -fn socketaddr_to_multiaddr(socket_addr: &SocketAddr, version: ProtocolVersion) -> Multiaddr { - let quic_proto = match version { - ProtocolVersion::V1 => Protocol::QuicV1, - ProtocolVersion::Draft29 => Protocol::Quic, - }; +fn socketaddr_to_multiaddr(socket_addr: &SocketAddr) -> Multiaddr { Multiaddr::empty() .with(socket_addr.ip().into()) .with(Protocol::Udp(socket_addr.port())) - .with(quic_proto) + .with(Protocol::QuicV1) } #[cfg(test)] #[cfg(any(feature = "async-std", feature = "tokio"))] mod tests { - use futures::future::poll_fn; - use super::*; #[test] fn multiaddr_to_udp_conversion() { - assert!(multiaddr_to_socketaddr( - &"/ip4/127.0.0.1/udp/1234".parse::().unwrap(), - true - ) - .is_none()); + assert!( + multiaddr_to_socketaddr(&"/ip4/127.0.0.1/udp/1234".parse::().unwrap()) + .is_none() + ); assert_eq!( multiaddr_to_socketaddr( &"/ip4/127.0.0.1/udp/12345/quic-v1" .parse::() - .unwrap(), - false + .unwrap() ), Some(( SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12345,), @@ -778,7 +741,6 @@ mod tests { &"/ip4/255.255.255.255/udp/8080/quic-v1" .parse::() .unwrap(), - false ), Some(( SocketAddr::new(IpAddr::V4(Ipv4Addr::new(255, 255, 255, 255)), 8080,), @@ -790,7 +752,7 @@ mod tests { multiaddr_to_socketaddr( &"/ip4/127.0.0.1/udp/55148/quic-v1/p2p/12D3KooW9xk7Zp1gejwfwNpfm6L9zH5NL4Bx5rm94LRYJJHJuARZ" .parse::() - .unwrap(), false + .unwrap() ), Some((SocketAddr::new( IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), @@ -798,10 +760,7 @@ mod tests { ), ProtocolVersion::V1, Some("12D3KooW9xk7Zp1gejwfwNpfm6L9zH5NL4Bx5rm94LRYJJHJuARZ".parse().unwrap()))) ); assert_eq!( - multiaddr_to_socketaddr( - &"/ip6/::1/udp/12345/quic-v1".parse::().unwrap(), - false - ), + multiaddr_to_socketaddr(&"/ip6/::1/udp/12345/quic-v1".parse::().unwrap(),), Some(( SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 12345,), ProtocolVersion::V1, @@ -813,7 +772,6 @@ mod tests { &"/ip6/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/udp/8080/quic-v1" .parse::() .unwrap(), - false ), Some(( SocketAddr::new( @@ -828,21 +786,9 @@ mod tests { ); assert!(multiaddr_to_socketaddr( - &"/ip4/127.0.0.1/udp/1234/quic".parse::().unwrap(), - false + &"/ip4/127.0.0.1/udp/1234/quic".parse::().unwrap() ) .is_none()); - assert_eq!( - multiaddr_to_socketaddr( - &"/ip4/127.0.0.1/udp/1234/quic".parse::().unwrap(), - true - ), - Some(( - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 1234,), - ProtocolVersion::Draft29, - None - )) - ); } #[cfg(feature = "async-std")] From 55e7f87d6a654634f31c6e43b1c2cb849018d590 Mon Sep 17 00:00:00 2001 From: tesol2y090 Date: Tue, 24 Dec 2024 16:00:22 +0700 Subject: [PATCH 3/3] feat: remove unused field in test --- transports/quic/tests/smoke.rs | 104 ++------------------------------- 1 file changed, 4 insertions(+), 100 deletions(-) diff --git a/transports/quic/tests/smoke.rs b/transports/quic/tests/smoke.rs index 5fbef84649e..7e9b6a69243 100644 --- a/transports/quic/tests/smoke.rs +++ b/transports/quic/tests/smoke.rs @@ -1,36 +1,22 @@ #![cfg(any(feature = "async-std", feature = "tokio"))] -use std::{ - future::Future, - io, - num::NonZeroU8, - pin::Pin, - sync::{Arc, Mutex}, - task::Poll, - time::Duration, -}; +use std::{future::Future, io, num::NonZeroU8, pin::Pin, task::Poll, time::Duration}; use futures::{ channel::{mpsc, oneshot}, future, - future::{poll_fn, BoxFuture, Either}, + future::{poll_fn, Either}, stream::StreamExt, AsyncReadExt, AsyncWriteExt, FutureExt, SinkExt, }; -use futures_timer::Delay; use libp2p_core::{ multiaddr::Protocol, muxing::{StreamMuxerBox, StreamMuxerExt, SubstreamBox}, - transport::{ - Boxed, DialOpts, ListenerId, OrTransport, PortUse, TransportError, TransportEvent, - }, - upgrade, Endpoint, Multiaddr, Transport, + transport::{Boxed, DialOpts, ListenerId, PortUse, TransportEvent}, + Endpoint, Multiaddr, Transport, }; use libp2p_identity::PeerId; -use libp2p_noise as noise; use libp2p_quic as quic; -use libp2p_tcp as tcp; -use libp2p_yamux as yamux; use quic::Provider; use rand::RngCore; use tracing_subscriber::EnvFilter; @@ -295,88 +281,6 @@ fn concurrent_connections_and_streams_tokio() { .quickcheck(prop:: as fn(_, _) -> _); } -#[cfg(feature = "tokio")] -#[tokio::test] -async fn draft_29_support() { - use std::task::Poll; - - use futures::{future::poll_fn, select}; - use libp2p_core::transport::TransportError; - - let _ = tracing_subscriber::fmt() - .with_env_filter(EnvFilter::from_default_env()) - .try_init(); - - let (_, mut a_transport) = - create_transport::(|cfg| cfg.support_draft_29 = true); - let (_, mut b_transport) = - create_transport::(|cfg| cfg.support_draft_29 = true); - - // If a server supports draft-29 all its QUIC addresses can be dialed on draft-29 or version-1 - let a_quic_addr = start_listening(&mut a_transport, "/ip4/127.0.0.1/udp/0/quic").await; - let a_quic_mapped_addr = swap_protocol!(a_quic_addr, Quic => QuicV1); - let a_quic_v1_addr = start_listening(&mut a_transport, "/ip4/127.0.0.1/udp/0/quic-v1").await; - let a_quic_v1_mapped_addr = swap_protocol!(a_quic_v1_addr, QuicV1 => Quic); - - connect(&mut a_transport, &mut b_transport, a_quic_addr.clone()).await; - connect(&mut a_transport, &mut b_transport, a_quic_mapped_addr).await; - connect(&mut a_transport, &mut b_transport, a_quic_v1_addr).await; - connect(&mut a_transport, &mut b_transport, a_quic_v1_mapped_addr).await; - - let (_, mut c_transport) = - create_transport::(|cfg| cfg.support_draft_29 = false); - assert!(matches!( - c_transport.dial( - a_quic_addr, - DialOpts { - role: Endpoint::Dialer, - port_use: PortUse::New - } - ), - Err(TransportError::MultiaddrNotSupported(_)) - )); - - // Test disabling draft-29 on a server. - let (_, mut d_transport) = - create_transport::(|cfg| cfg.support_draft_29 = false); - assert!(matches!( - d_transport.listen_on( - ListenerId::next(), - "/ip4/127.0.0.1/udp/0/quic".parse().unwrap() - ), - Err(TransportError::MultiaddrNotSupported(_)) - )); - let d_quic_v1_addr = start_listening(&mut d_transport, "/ip4/127.0.0.1/udp/0/quic-v1").await; - let d_quic_addr_mapped = swap_protocol!(d_quic_v1_addr, QuicV1 => Quic); - let dial = b_transport - .dial( - d_quic_addr_mapped, - DialOpts { - role: Endpoint::Dialer, - port_use: PortUse::Reuse, - }, - ) - .unwrap(); - let drive_transports = poll_fn::<(), _>(|cx| { - let _ = b_transport.poll_next_unpin(cx); - let _ = d_transport.poll_next_unpin(cx); - Poll::Pending - }); - select! { - _ = drive_transports.fuse() => {} - result = dial.fuse() => { - #[allow(clippy::single_match)] - match result { - Ok(_) => panic!("Unexpected success dialing version-1-only server with draft-29."), - // FIXME: We currently get a Handshake timeout if the server does not support our version. - // Correct would be to get an quinn error "VersionMismatch". - Err(_) => {} - // Err(e) => assert!(format!("{:?}", e).contains("VersionMismatch"), "Got unexpected error {}", e), - } - } - } -} - #[cfg(feature = "async-std")] #[async_std::test] async fn backpressure() {