Skip to content

Commit ce3efcf

Browse files
kppthomaseizinger
authored andcommitted
refactor(quic): rewrite quic using quinn
Rewrite quic using quinn instead of quinn-proto. libp2p-quic::endpoint::Driver is eliminated (and that hard quinn-proto machinery). Also: - ECN bits are handled - Support Generic Send Offload (GSO) Pull-Request: #3454.
1 parent dea9604 commit ce3efcf

17 files changed

+608
-1803
lines changed

Cargo.lock

+35-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ libp2p-perf = { version = "0.2.0", path = "protocols/perf" }
8484
libp2p-ping = { version = "0.43.0", path = "protocols/ping" }
8585
libp2p-plaintext = { version = "0.40.0", path = "transports/plaintext" }
8686
libp2p-pnet = { version = "0.23.0", path = "transports/pnet" }
87-
libp2p-quic = { version = "0.8.0-alpha", path = "transports/quic" }
87+
libp2p-quic = { version = "0.9.0-alpha", path = "transports/quic" }
8888
libp2p-relay = { version = "0.16.1", path = "protocols/relay" }
8989
libp2p-rendezvous = { version = "0.13.0", path = "protocols/rendezvous" }
9090
libp2p-request-response = { version = "0.25.1", path = "protocols/request-response" }

transports/quic/CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 0.9.0-alpha - unreleased
2+
3+
- Use `quinn` instead of `quinn-proto`.
4+
See [PR 3454].
5+
6+
[PR 3454]: https://github.com/libp2p/rust-libp2p/pull/3454
7+
18
## 0.8.0-alpha
29

310
- Raise MSRV to 1.65.

transports/quic/Cargo.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "libp2p-quic"
3-
version = "0.8.0-alpha"
3+
version = "0.9.0-alpha"
44
authors = ["Parity Technologies <[email protected]>"]
55
edition = "2021"
66
rust-version = { workspace = true }
@@ -19,15 +19,15 @@ libp2p-tls = { workspace = true }
1919
libp2p-identity = { workspace = true }
2020
log = "0.4"
2121
parking_lot = "0.12.0"
22-
quinn-proto = { version = "0.10.1", default-features = false, features = ["tls-rustls"] }
22+
quinn = { version = "0.10.1", default-features = false, features = ["tls-rustls", "futures-io"] }
2323
rand = "0.8.5"
2424
rustls = { version = "0.21.2", default-features = false }
2525
thiserror = "1.0.44"
2626
tokio = { version = "1.29.1", default-features = false, features = ["net", "rt", "time"], optional = true }
2727

2828
[features]
29-
tokio = ["dep:tokio", "if-watch/tokio"]
30-
async-std = ["dep:async-std", "if-watch/smol"]
29+
tokio = ["dep:tokio", "if-watch/tokio", "quinn/runtime-tokio"]
30+
async-std = ["dep:async-std", "if-watch/smol", "quinn/runtime-async-std"]
3131

3232
# Passing arguments to the docsrs builder in order to properly document cfg's.
3333
# More information: https://docs.rs/about/builds#cross-compiling

transports/quic/src/config.rs

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the "Software"),
5+
// to deal in the Software without restriction, including without limitation
6+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7+
// and/or sell copies of the Software, and to permit persons to whom the
8+
// Software is furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19+
// DEALINGS IN THE SOFTWARE.
20+
21+
use quinn::VarInt;
22+
use std::{sync::Arc, time::Duration};
23+
24+
/// Config for the transport.
25+
#[derive(Clone)]
26+
pub struct Config {
27+
/// Timeout for the initial handshake when establishing a connection.
28+
/// The actual timeout is the minimum of this and the [`Config::max_idle_timeout`].
29+
pub handshake_timeout: Duration,
30+
/// Maximum duration of inactivity in ms to accept before timing out the connection.
31+
pub max_idle_timeout: u32,
32+
/// Period of inactivity before sending a keep-alive packet.
33+
/// Must be set lower than the idle_timeout of both
34+
/// peers to be effective.
35+
///
36+
/// See [`quinn::TransportConfig::keep_alive_interval`] for more
37+
/// info.
38+
pub keep_alive_interval: Duration,
39+
/// Maximum number of incoming bidirectional streams that may be open
40+
/// concurrently by the remote peer.
41+
pub max_concurrent_stream_limit: u32,
42+
43+
/// Max unacknowledged data in bytes that may be send on a single stream.
44+
pub max_stream_data: u32,
45+
46+
/// Max unacknowledged data in bytes that may be send in total on all streams
47+
/// of a connection.
48+
pub max_connection_data: u32,
49+
50+
/// Support QUIC version draft-29 for dialing and listening.
51+
///
52+
/// Per default only QUIC Version 1 / [`libp2p_core::multiaddr::Protocol::QuicV1`]
53+
/// is supported.
54+
///
55+
/// If support for draft-29 is enabled servers support draft-29 and version 1 on all
56+
/// QUIC listening addresses.
57+
/// As client the version is chosen based on the remote's address.
58+
pub support_draft_29: bool,
59+
60+
/// TLS client config for the inner [`quinn::ClientConfig`].
61+
client_tls_config: Arc<rustls::ClientConfig>,
62+
/// TLS server config for the inner [`quinn::ServerConfig`].
63+
server_tls_config: Arc<rustls::ServerConfig>,
64+
}
65+
66+
impl Config {
67+
/// Creates a new configuration object with default values.
68+
pub fn new(keypair: &libp2p_identity::Keypair) -> Self {
69+
let client_tls_config = Arc::new(libp2p_tls::make_client_config(keypair, None).unwrap());
70+
let server_tls_config = Arc::new(libp2p_tls::make_server_config(keypair).unwrap());
71+
Self {
72+
client_tls_config,
73+
server_tls_config,
74+
support_draft_29: false,
75+
handshake_timeout: Duration::from_secs(5),
76+
max_idle_timeout: 30 * 1000,
77+
max_concurrent_stream_limit: 256,
78+
keep_alive_interval: Duration::from_secs(15),
79+
max_connection_data: 15_000_000,
80+
81+
// Ensure that one stream is not consuming the whole connection.
82+
max_stream_data: 10_000_000,
83+
}
84+
}
85+
}
86+
87+
/// Represents the inner configuration for [`quinn`].
88+
#[derive(Debug, Clone)]
89+
pub(crate) struct QuinnConfig {
90+
pub(crate) client_config: quinn::ClientConfig,
91+
pub(crate) server_config: quinn::ServerConfig,
92+
pub(crate) endpoint_config: quinn::EndpointConfig,
93+
}
94+
95+
impl From<Config> for QuinnConfig {
96+
fn from(config: Config) -> QuinnConfig {
97+
let Config {
98+
client_tls_config,
99+
server_tls_config,
100+
max_idle_timeout,
101+
max_concurrent_stream_limit,
102+
keep_alive_interval,
103+
max_connection_data,
104+
max_stream_data,
105+
support_draft_29,
106+
handshake_timeout: _,
107+
} = config;
108+
let mut transport = quinn::TransportConfig::default();
109+
// Disable uni-directional streams.
110+
transport.max_concurrent_uni_streams(0u32.into());
111+
transport.max_concurrent_bidi_streams(max_concurrent_stream_limit.into());
112+
// Disable datagrams.
113+
transport.datagram_receive_buffer_size(None);
114+
transport.keep_alive_interval(Some(keep_alive_interval));
115+
transport.max_idle_timeout(Some(VarInt::from_u32(max_idle_timeout).into()));
116+
transport.allow_spin(false);
117+
transport.stream_receive_window(max_stream_data.into());
118+
transport.receive_window(max_connection_data.into());
119+
let transport = Arc::new(transport);
120+
121+
let mut server_config = quinn::ServerConfig::with_crypto(server_tls_config);
122+
server_config.transport = Arc::clone(&transport);
123+
// Disables connection migration.
124+
// Long-term this should be enabled, however we then need to handle address change
125+
// on connections in the `Connection`.
126+
server_config.migration(false);
127+
128+
let mut client_config = quinn::ClientConfig::new(client_tls_config);
129+
client_config.transport_config(transport);
130+
131+
let mut endpoint_config = quinn::EndpointConfig::default();
132+
if !support_draft_29 {
133+
endpoint_config.supported_versions(vec![1]);
134+
}
135+
136+
QuinnConfig {
137+
client_config,
138+
server_config,
139+
endpoint_config,
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)