Skip to content

Commit b27d0ee

Browse files
apollo_quic_datagrams
1 parent 68d9360 commit b27d0ee

File tree

15 files changed

+2754
-0
lines changed

15 files changed

+2754
-0
lines changed

Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ members = [
6666
"crates/apollo_proc_macros_tests",
6767
"crates/apollo_propeller",
6868
"crates/apollo_protobuf",
69+
"crates/apollo_quic_datagrams",
6970
"crates/apollo_reverts",
7071
"crates/apollo_rpc",
7172
"crates/apollo_rpc_execution",
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
## 0.13.0
2+
3+
- Remove `async-std` support.
4+
See [PR 5954](https://github.com/libp2p/rust-libp2p/pull/5954)
5+
6+
- Deprecate `Config::support_draft_29`.
7+
See [PR 5786](https://github.com/libp2p/rust-libp2p/pull/5786).
8+
9+
## 0.12.0
10+
11+
<!-- Update to libp2p-core v0.43.0 -->
12+
13+
## 0.11.1
14+
15+
- Update `libp2p-tls` to version `0.5.0`, see [PR 5547]
16+
17+
[PR 5547]: https://github.com/libp2p/rust-libp2p/pull/5547
18+
19+
## 0.11.0
20+
21+
- Implement refactored `Transport`.
22+
See [PR 4568](https://github.com/libp2p/rust-libp2p/pull/4568)
23+
24+
## 0.10.3
25+
26+
- Update `quinn` to 0.11 and `libp2p-tls` to 0.4.0.
27+
See [PR 5316](https://github.com/libp2p/rust-libp2p/pull/5316)
28+
29+
- Allow configuring MTU discovery upper bound.
30+
See [PR 5386](https://github.com/libp2p/rust-libp2p/pull/5386).
31+
32+
## 0.10.2
33+
34+
- Change `max_idle_timeout`to 10s.
35+
See [PR 4965](https://github.com/libp2p/rust-libp2p/pull/4965).
36+
37+
## 0.10.1
38+
39+
- Allow disabling path MTU discovery.
40+
See [PR 4823](https://github.com/libp2p/rust-libp2p/pull/4823).
41+
42+
## 0.10.0
43+
44+
- Improve hole-punch timing.
45+
This should improve success rates for hole-punching QUIC connections.
46+
See [PR 4549](https://github.com/libp2p/rust-libp2p/pull/4549).
47+
- Remove deprecated `Error::EndpointDriverCrashed` variant.
48+
See [PR 4738](https://github.com/libp2p/rust-libp2p/pull/4738).
49+
50+
## 0.9.3
51+
52+
- No longer report error when explicit closing of a QUIC endpoint succeeds.
53+
See [PR 4621].
54+
55+
- Support QUIC stateless resets for supported `libp2p_identity::Keypair`s. See [PR 4554].
56+
57+
[PR 4621]: https://github.com/libp2p/rust-libp2p/pull/4621
58+
[PR 4554]: https://github.com/libp2p/rust-libp2p/pull/4554
59+
60+
## 0.9.2
61+
62+
- Cut stable release.
63+
64+
## 0.9.2-alpha
65+
66+
- Add support for reusing an existing socket when dialing localhost address.
67+
See [PR 4304].
68+
69+
[PR 4304]: https://github.com/libp2p/rust-libp2p/pull/4304
70+
71+
## 0.9.1-alpha
72+
73+
- Allow listening on ipv4 and ipv6 separately.
74+
See [PR 4289].
75+
76+
[PR 4289]: https://github.com/libp2p/rust-libp2p/pull/4289
77+
78+
## 0.9.0-alpha
79+
80+
- Use `quinn` instead of `quinn-proto`.
81+
See [PR 3454].
82+
83+
[PR 3454]: https://github.com/libp2p/rust-libp2p/pull/3454
84+
85+
## 0.8.0-alpha
86+
87+
- Raise MSRV to 1.65.
88+
See [PR 3715].
89+
90+
- Add hole punching support by implementing `Transport::dial_as_listener`. See [PR 3964].
91+
92+
[PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715
93+
[PR 3964]: https://github.com/libp2p/rust-libp2p/pull/3964
94+
95+
## 0.7.0-alpha.3
96+
97+
- Depend `libp2p-tls` `v0.1.0`.
98+
99+
## 0.7.0-alpha.2
100+
101+
- Update to `libp2p-tls` `v0.1.0-alpha.2`.
102+
103+
- Update to `libp2p-core` `v0.39.0`.
104+
105+
- Add opt-in support for the `/quic` codepoint, interpreted as QUIC version draft-29.
106+
See [PR 3151].
107+
108+
- Wake the transport's task when a new dialer or listener is added. See [3342].
109+
110+
- Discard correct waker upon accepting inbound stream. See [PR 3420].
111+
112+
[PR 3151]: https://github.com/libp2p/rust-libp2p/pull/3151
113+
[PR 3342]: https://github.com/libp2p/rust-libp2p/pull/3342
114+
[PR 3420]: https://github.com/libp2p/rust-libp2p/pull/3420
115+
116+
## 0.7.0-alpha
117+
118+
- Initial alpha release.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
[package]
2+
name = "apollo_quic_datagrams"
3+
version = "0.13.0"
4+
authors = ["Parity Technologies <[email protected]>"]
5+
edition.workspace = true
6+
description = "TLS based QUIC transport implementation for libp2p"
7+
repository = "https://github.com/libp2p/rust-libp2p"
8+
license = "MIT"
9+
10+
[dependencies]
11+
futures = { workspace = true }
12+
futures-timer = "3.0.3"
13+
if-watch = "3.2.0"
14+
libp2p = { workspace = true, features = [
15+
"dns",
16+
"gossipsub",
17+
"identify",
18+
"kad",
19+
"macros",
20+
"noise",
21+
"quic",
22+
"serde",
23+
"tcp",
24+
"tls",
25+
"tokio",
26+
"yamux",
27+
] }
28+
quinn = { version = "0.11.6", default-features = false, features = ["futures-io", "rustls"] }
29+
rand = { workspace = true }
30+
rustls = { version = "0.23.9", default-features = false }
31+
thiserror = { workspace = true }
32+
tokio = { workspace = true, features = ["net", "rt", "time"], optional = true }
33+
tracing = { workspace = true }
34+
socket2 = { workspace = true }
35+
ring = "0.17"
36+
37+
[features]
38+
tokio = ["dep:tokio", "if-watch/tokio", "quinn/runtime-tokio"]
39+
40+
# Passing arguments to the docsrs builder in order to properly document cfg's.
41+
# More information: https://docs.rs/about/builds#cross-compiling
42+
[package.metadata.docs.rs]
43+
all-features = true
44+
45+
[dev-dependencies]
46+
libp2p = { workspace = true }
47+
quickcheck = { workspace = true }
48+
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] }
49+
tracing-subscriber = { workspace = true, features = ["env-filter"] }
50+
51+
[[test]]
52+
name = "stream_compliance"
53+
required-features = ["tokio"]
54+
55+
[lints]
56+
workspace = true
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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 std::sync::Arc;
22+
use std::time::Duration;
23+
24+
use libp2p::tls;
25+
use quinn::crypto::rustls::{QuicClientConfig, QuicServerConfig};
26+
use quinn::{MtuDiscoveryConfig, VarInt};
27+
28+
/// Config for the transport.
29+
#[derive(Clone)]
30+
pub struct Config {
31+
/// Timeout for the initial handshake when establishing a connection.
32+
/// The actual timeout is the minimum of this and the [`Config::max_idle_timeout`].
33+
pub handshake_timeout: Duration,
34+
/// Maximum duration of inactivity in ms to accept before timing out the connection.
35+
pub max_idle_timeout: u32,
36+
/// Period of inactivity before sending a keep-alive packet.
37+
/// Must be set lower than the idle_timeout of both
38+
/// peers to be effective.
39+
///
40+
/// See [`quinn::TransportConfig::keep_alive_interval`] for more
41+
/// info.
42+
pub keep_alive_interval: Duration,
43+
/// Maximum number of incoming bidirectional streams that may be open
44+
/// concurrently by the remote peer.
45+
pub max_concurrent_stream_limit: u32,
46+
47+
/// Max unacknowledged data in bytes that may be sent on a single stream.
48+
pub max_stream_data: u32,
49+
50+
/// Max unacknowledged data in bytes that may be sent in total on all streams
51+
/// of a connection.
52+
pub max_connection_data: u32,
53+
54+
/// Support QUIC version draft-29 for dialing and listening.
55+
///
56+
/// Per default only QUIC Version 1 / [`libp2p_core::multiaddr::Protocol::QuicV1`]
57+
/// is supported.
58+
///
59+
/// If support for draft-29 is enabled servers support draft-29 and version 1 on all
60+
/// QUIC listening addresses.
61+
/// As client the version is chosen based on the remote's address.
62+
#[deprecated(note = "QUIC draft versions are no longer supported")]
63+
pub support_draft_29: bool,
64+
65+
/// TLS client config for the inner [`quinn::ClientConfig`].
66+
client_tls_config: Arc<QuicClientConfig>,
67+
/// TLS server config for the inner [`quinn::ServerConfig`].
68+
server_tls_config: Arc<QuicServerConfig>,
69+
/// Libp2p identity of the node.
70+
keypair: libp2p::identity::Keypair,
71+
72+
/// Parameters governing MTU discovery. See [`MtuDiscoveryConfig`] for details.
73+
mtu_discovery_config: Option<MtuDiscoveryConfig>,
74+
}
75+
76+
#[expect(deprecated)]
77+
impl Config {
78+
/// Creates a new configuration object with default values.
79+
pub fn new(keypair: &libp2p::identity::Keypair) -> Self {
80+
let client_tls_config = Arc::new(
81+
QuicClientConfig::try_from(tls::make_client_config(keypair, None).unwrap()).unwrap(),
82+
);
83+
let server_tls_config = Arc::new(
84+
QuicServerConfig::try_from(tls::make_server_config(keypair).unwrap()).unwrap(),
85+
);
86+
Self {
87+
client_tls_config,
88+
server_tls_config,
89+
support_draft_29: false,
90+
handshake_timeout: Duration::from_secs(5),
91+
max_idle_timeout: 10 * 1000,
92+
max_concurrent_stream_limit: 256,
93+
keep_alive_interval: Duration::from_secs(5),
94+
max_connection_data: 15_000_000,
95+
96+
// Ensure that one stream is not consuming the whole connection.
97+
max_stream_data: 10_000_000,
98+
keypair: keypair.clone(),
99+
mtu_discovery_config: Some(Default::default()),
100+
}
101+
}
102+
103+
/// Set the upper bound to the max UDP payload size that MTU discovery will search for.
104+
pub fn mtu_upper_bound(mut self, value: u16) -> Self {
105+
self.mtu_discovery_config.get_or_insert_with(Default::default).upper_bound(value);
106+
self
107+
}
108+
109+
/// Disable MTU path discovery (it is enabled by default).
110+
pub fn disable_path_mtu_discovery(mut self) -> Self {
111+
self.mtu_discovery_config = None;
112+
self
113+
}
114+
}
115+
116+
/// Represents the inner configuration for [`quinn`].
117+
#[derive(Debug, Clone)]
118+
pub(crate) struct QuinnConfig {
119+
pub(crate) client_config: quinn::ClientConfig,
120+
pub(crate) server_config: quinn::ServerConfig,
121+
pub(crate) endpoint_config: quinn::EndpointConfig,
122+
}
123+
124+
#[expect(deprecated)]
125+
impl From<Config> for QuinnConfig {
126+
fn from(config: Config) -> QuinnConfig {
127+
let Config {
128+
client_tls_config,
129+
server_tls_config,
130+
max_idle_timeout,
131+
max_concurrent_stream_limit,
132+
keep_alive_interval,
133+
max_connection_data,
134+
max_stream_data,
135+
support_draft_29,
136+
handshake_timeout: _,
137+
keypair,
138+
mtu_discovery_config,
139+
} = config;
140+
let mut transport = quinn::TransportConfig::default();
141+
// Disable uni-directional streams.
142+
transport.max_concurrent_uni_streams(0u32.into());
143+
transport.max_concurrent_bidi_streams(max_concurrent_stream_limit.into());
144+
// Disable datagrams.
145+
transport.datagram_receive_buffer_size(None);
146+
transport.keep_alive_interval(Some(keep_alive_interval));
147+
transport.max_idle_timeout(Some(VarInt::from_u32(max_idle_timeout).into()));
148+
transport.allow_spin(false);
149+
transport.stream_receive_window(max_stream_data.into());
150+
transport.receive_window(max_connection_data.into());
151+
transport.mtu_discovery_config(mtu_discovery_config);
152+
let transport = Arc::new(transport);
153+
154+
let mut server_config = quinn::ServerConfig::with_crypto(server_tls_config);
155+
server_config.transport = Arc::clone(&transport);
156+
// Disables connection migration.
157+
// Long-term this should be enabled, however we then need to handle address change
158+
// on connections in the `Connection`.
159+
server_config.migration(false);
160+
161+
let mut client_config = quinn::ClientConfig::new(client_tls_config);
162+
client_config.transport_config(transport);
163+
164+
let mut endpoint_config = keypair
165+
.derive_secret(b"libp2p quic stateless reset key")
166+
.map(|secret| {
167+
let reset_key = Arc::new(ring::hmac::Key::new(ring::hmac::HMAC_SHA256, &secret));
168+
quinn::EndpointConfig::new(reset_key)
169+
})
170+
.unwrap_or_default();
171+
172+
if !support_draft_29 {
173+
endpoint_config.supported_versions(vec![1]);
174+
}
175+
176+
QuinnConfig { client_config, server_config, endpoint_config }
177+
}
178+
}

0 commit comments

Comments
 (0)