Skip to content

Commit

Permalink
Upgrade to Quinn 0.11 (#238)
Browse files Browse the repository at this point in the history
* h3-quinn: avoid direct dependency on quinn-proto

* fix race conditions in tests

* Upgrade to Quinn 0.11

* update example quinn

* fix test

---------

Co-authored-by: ruben <ruben.buehler@t-online.de>
  • Loading branch information
djc and Ruben2424 authored May 20, 2024
1 parent eb79204 commit 0561867
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 110 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ env:
RUST_BACKTRACE: 1
toolchain_style: stable
toolchain_msrv: 1.63
toolchain_h3_quinn_msrv: 1.63
toolchain_h3_quinn_msrv: 1.66
toolchain_doc: nightly-2023-10-21
toolchain_lint: stable
toolchain_fuzz: nightly-2023-10-21
Expand Down
10 changes: 5 additions & 5 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ h3 = { path = "../h3" }
h3-quinn = { path = "../h3-quinn" }
h3-webtransport = { path = "../h3-webtransport" }
http = "1"
quinn = { version = "0.10", default-features = false, features = [
quinn = { version = "0.11", default-features = false, features = [
"runtime-tokio",
"tls-rustls",
"rustls",
"ring",
] }
rcgen = { version = "0.12" }
rustls = { version = "0.21", features = ["dangerous_configuration"] }
rustls-native-certs = "0.6"
rcgen = { version = "0.13" }
rustls = { version = "0.23", default-features = false, features = ["logging", "ring", "std"] }
rustls-native-certs = "0.7"
structopt = "0.3"
tokio = { version = "1.27", features = ["full"] }
tracing = "0.1.37"
Expand Down
12 changes: 6 additions & 6 deletions examples/client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{path::PathBuf, sync::Arc};

use futures::future;
use rustls::pki_types::CertificateDer;
use structopt::StructOpt;
use tokio::io::AsyncWriteExt;
use tracing::{error, info};
Expand Down Expand Up @@ -64,7 +65,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
match rustls_native_certs::load_native_certs() {
Ok(certs) => {
for cert in certs {
if let Err(e) = roots.add(&rustls::Certificate(cert.0)) {
if let Err(e) = roots.add(cert) {
error!("failed to parse trust anchor: {}", e);
}
}
Expand All @@ -76,14 +77,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// load certificate of CA who issues the server certificate
// NOTE that this should be used for dev only
if let Err(e) = roots.add(&rustls::Certificate(std::fs::read(opt.ca)?)) {
if let Err(e) = roots.add(CertificateDer::from(std::fs::read(opt.ca)?)) {
error!("failed to parse trust anchor: {}", e);
}

let mut tls_config = rustls::ClientConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_protocol_versions(&[&rustls::version::TLS13])?
.with_root_certificates(roots)
.with_no_client_auth();

Expand All @@ -99,7 +97,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

let mut client_endpoint = h3_quinn::quinn::Endpoint::client("[::]:0".parse().unwrap())?;

let client_config = quinn::ClientConfig::new(Arc::new(tls_config));
let client_config = quinn::ClientConfig::new(Arc::new(
quinn::crypto::rustls::QuicClientConfig::try_from(tls_config)?,
));
client_endpoint.set_default_client_config(client_config);

let conn = client_endpoint.connect(addr, auth.host())?.await?;
Expand Down
15 changes: 6 additions & 9 deletions examples/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use std::{net::SocketAddr, path::PathBuf, sync::Arc};

use bytes::{Bytes, BytesMut};
use http::{Request, StatusCode};
use rustls::{Certificate, PrivateKey};
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
use structopt::StructOpt;
use tokio::{fs::File, io::AsyncReadExt};
use tracing::{error, info, trace_span};

use h3::{error::ErrorLevel, quic::BidiStream, server::RequestStream};
use h3_quinn::quinn;
use h3_quinn::quinn::{self, crypto::rustls::QuicServerConfig};

#[derive(StructOpt, Debug)]
#[structopt(name = "server")]
Expand Down Expand Up @@ -84,21 +84,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// create quinn server endpoint and bind UDP socket

// both cert and key must be DER-encoded
let cert = Certificate(std::fs::read(cert)?);
let key = PrivateKey(std::fs::read(key)?);
let cert = CertificateDer::from(std::fs::read(cert)?);
let key = PrivateKeyDer::try_from(std::fs::read(key)?)?;

let mut tls_config = rustls::ServerConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_no_client_auth()
.with_single_cert(vec![cert], key)?;

tls_config.max_early_data_size = u32::MAX;
tls_config.alpn_protocols = vec![ALPN.into()];

let server_config = quinn::ServerConfig::with_crypto(Arc::new(tls_config));
let server_config =
quinn::ServerConfig::with_crypto(Arc::new(QuicServerConfig::try_from(tls_config)?));
let endpoint = quinn::Endpoint::server(server_config, opt.listen)?;

info!("listening on {}", opt.listen);
Expand Down
15 changes: 6 additions & 9 deletions examples/webtransport_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ use h3::{
quic::{self, RecvDatagramExt, SendDatagramExt, SendStreamUnframed},
server::Connection,
};
use h3_quinn::quinn;
use h3_quinn::quinn::{self, crypto::rustls::QuicServerConfig};
use h3_webtransport::{
server::{self, WebTransportSession},
stream,
};
use http::Method;
use rustls::{Certificate, PrivateKey};
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
use std::{net::SocketAddr, path::PathBuf, sync::Arc, time::Duration};
use structopt::StructOpt;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
Expand Down Expand Up @@ -81,14 +81,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// create quinn server endpoint and bind UDP socket

// both cert and key must be DER-encoded
let cert = Certificate(std::fs::read(cert)?);
let key = PrivateKey(std::fs::read(key)?);
let cert = CertificateDer::from(std::fs::read(cert)?);
let key = PrivateKeyDer::try_from(std::fs::read(key)?)?;

let mut tls_config = rustls::ServerConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_no_client_auth()
.with_single_cert(vec![cert], key)?;

Expand All @@ -102,7 +98,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
];
tls_config.alpn_protocols = alpn;

let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(tls_config));
let mut server_config =
quinn::ServerConfig::with_crypto(Arc::new(QuicServerConfig::try_from(tls_config)?));
let mut transport_config = quinn::TransportConfig::default();
transport_config.keep_alive_interval(Some(Duration::from_secs(2)));
server_config.transport = Arc::new(transport_config);
Expand Down
5 changes: 2 additions & 3 deletions h3-quinn/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "h3-quinn"
version = "0.0.5"
rust-version = "1.63"
rust-version = "1.66"
authors = ["Jean-Christophe BEGUE <jc.begue@pm.me>"]
edition = "2021"
documentation = "https://docs.rs/h3-quinn"
Expand All @@ -15,10 +15,9 @@ license = "MIT"
[dependencies]
h3 = { version = "0.0.4", path = "../h3" }
bytes = "1"
quinn = { version = "0.10", default-features = false, features = [
quinn = { version = "0.11", default-features = false, features = [
"futures-io",
] }
quinn-proto = { version = "0.10", default-features = false }
tokio-util = { version = "0.7.9" }
futures = { version = "0.3.28" }
tokio = { version = "1", features = ["io-util"], default-features = false }
33 changes: 17 additions & 16 deletions h3-quinn/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use futures::{
stream::{self, BoxStream},
StreamExt,
};
use quinn::ReadDatagram;
pub use quinn::{self, AcceptBi, AcceptUni, Endpoint, OpenBi, OpenUni, VarInt, WriteError};
use quinn::{ApplicationClose, ClosedStream, ReadDatagram};

use h3::{
ext::Datagram,
Expand Down Expand Up @@ -81,10 +81,9 @@ impl Error for ConnectionError {

fn err_code(&self) -> Option<u64> {
match self.0 {
quinn::ConnectionError::ApplicationClosed(quinn_proto::ApplicationClose {
error_code,
..
}) => Some(error_code.into_inner()),
quinn::ConnectionError::ApplicationClosed(ApplicationClose { error_code, .. }) => {
Some(error_code.into_inner())
}
_ => None,
}
}
Expand Down Expand Up @@ -529,7 +528,7 @@ impl Error for ReadError {
fn err_code(&self) -> Option<u64> {
match self.0 {
quinn::ReadError::ConnectionLost(quinn::ConnectionError::ApplicationClosed(
quinn_proto::ApplicationClose { error_code, .. },
ApplicationClose { error_code, .. },
)) => Some(error_code.into_inner()),
quinn::ReadError::Reset(error_code) => Some(error_code.into_inner()),
_ => None,
Expand Down Expand Up @@ -593,12 +592,8 @@ where
Poll::Ready(Ok(()))
}

fn poll_finish(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
self.stream
.as_mut()
.unwrap()
.poll_finish(cx)
.map_err(Into::into)
fn poll_finish(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(self.stream.as_mut().unwrap().finish().map_err(|e| e.into()))
}

fn reset(&mut self, reset_code: u64) {
Expand Down Expand Up @@ -680,6 +675,8 @@ pub enum SendStreamError {
/// Error when the stream is not ready, because it is still sending
/// data from a previous call
NotReady,
/// Error when the stream is closed
StreamClosed(ClosedStream),
}

impl From<SendStreamError> for std::io::Error {
Expand All @@ -689,6 +686,7 @@ impl From<SendStreamError> for std::io::Error {
SendStreamError::NotReady => {
std::io::Error::new(std::io::ErrorKind::Other, "send stream is not ready")
}
SendStreamError::StreamClosed(err) => err.into(),
}
}
}
Expand All @@ -707,6 +705,12 @@ impl From<WriteError> for SendStreamError {
}
}

impl From<ClosedStream> for SendStreamError {
fn from(value: ClosedStream) -> Self {
Self::StreamClosed(value)
}
}

impl Error for SendStreamError {
fn is_timeout(&self) -> bool {
matches!(
Expand All @@ -721,10 +725,7 @@ impl Error for SendStreamError {
match self {
Self::Write(quinn::WriteError::Stopped(error_code)) => Some(error_code.into_inner()),
Self::Write(quinn::WriteError::ConnectionLost(
quinn::ConnectionError::ApplicationClosed(quinn_proto::ApplicationClose {
error_code,
..
}),
quinn::ConnectionError::ApplicationClosed(ApplicationClose { error_code, .. }),
)) => Some(error_code.into_inner()),
_ => None,
}
Expand Down
10 changes: 5 additions & 5 deletions h3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ fastrand = "2.0.1"
assert_matches = "1.5.0"
futures-util = { version = "0.3", default-features = false, features = ["io"] }
proptest = "1"
quinn = { version = "0.10", default-features = false, features = [
quinn = { version = "0.11", default-features = false, features = [
"runtime-tokio",
"tls-rustls",
"rustls",
"ring",
] }
quinn-proto = { version = "0.10", default-features = false }
rcgen = "0.12"
rustls = "0.21"
quinn-proto = { version = "0.11", default-features = false }
rcgen = "0.13"
rustls = { version = "0.23", default-features = false, features = ["logging", "ring", "std"] }
tokio = { version = "1", features = ["rt", "macros", "io-util", "io-std"] }
tracing-subscriber = { version = "0.3", default-features = false, features = [
"fmt",
Expand Down
Loading

0 comments on commit 0561867

Please sign in to comment.