Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions h3-quinn/src/datagram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ fn convert_h3_error_to_datagram_error(
ConnectionErrorIncoming::ApplicationClose { error_code } => {
h3_datagram::ConnectionErrorIncoming::ApplicationClose { error_code }
}
ConnectionErrorIncoming::ConnectionClosed { error_code } => {
h3_datagram::ConnectionErrorIncoming::ConnectionClosed { error_code }
}
ConnectionErrorIncoming::Timeout => h3_datagram::ConnectionErrorIncoming::Timeout,
ConnectionErrorIncoming::InternalError(err) => {
h3_datagram::ConnectionErrorIncoming::InternalError(err)
Expand Down
29 changes: 27 additions & 2 deletions h3-quinn/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,44 @@ fn convert_connection_error(e: quinn::ConnectionError) -> h3::quic::ConnectionEr
error_code: application_close.error_code.into(),
}
}
quinn::ConnectionError::ConnectionClosed(connection_close) => {
ConnectionErrorIncoming::ConnectionClosed {
error_code: connection_close.error_code.into(),
}
}
quinn::ConnectionError::TimedOut => ConnectionErrorIncoming::Timeout,

error @ quinn::ConnectionError::VersionMismatch
| error @ quinn::ConnectionError::Reset
| error @ quinn::ConnectionError::LocallyClosed
| error @ quinn::ConnectionError::CidsExhausted
| error @ quinn::ConnectionError::TransportError(_)
| error @ quinn::ConnectionError::ConnectionClosed(_) => {
| error @ quinn::ConnectionError::TransportError(_) => {
ConnectionErrorIncoming::Undefined(Arc::new(error))
}
}
}

#[cfg(test)]
mod tests {
use super::convert_connection_error;
use h3::quic::ConnectionErrorIncoming;
use quinn::{ConnectionClose, ConnectionError, TransportErrorCode};

#[test]
fn connection_closed_is_mapped_to_structured_variant() {
let error = ConnectionError::ConnectionClosed(ConnectionClose {
error_code: TransportErrorCode::NO_ERROR,
frame_type: None,
reason: Default::default(),
});

assert!(matches!(
convert_connection_error(error),
ConnectionErrorIncoming::ConnectionClosed { error_code: 0 }
));
}
}

impl<B> quic::OpenStreams<B> for Connection
where
B: Buf,
Expand Down
7 changes: 6 additions & 1 deletion h3/src/error/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! This is the public facing error types for the h3 crate
use crate::quic::ConnectionErrorIncoming;
use crate::quic::{ConnectionErrorIncoming, QUIC_NO_ERROR};

use super::{codes::Code, internal_error::InternalConnectionError};

Expand Down Expand Up @@ -51,6 +51,11 @@ impl ConnectionError {
{
true
}
ConnectionError::Remote(ConnectionErrorIncoming::ConnectionClosed { error_code })
if *error_code == QUIC_NO_ERROR =>
{
true
}
_ => false,
}
}
Expand Down
14 changes: 14 additions & 0 deletions h3/src/quic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ use crate::error::Code;
pub use crate::proto::stream::{InvalidStreamId, StreamId};
pub use crate::stream::WriteBuf;

/// QUIC transport close code indicating graceful shutdown.
pub const QUIC_NO_ERROR: u64 = 0;

/// Error type to communicate that the quic connection was closed
///
/// This is used by to implement the quic abstraction traits
Expand All @@ -23,6 +26,11 @@ pub enum ConnectionErrorIncoming {
/// http3 error code
error_code: u64,
},
/// QUIC connection was closed by peer
ConnectionClosed {
/// QUIC transport error code
error_code: u64,
},
/// Quic connection timeout
Timeout,
/// This variant can be used to signal, that an internal error occurred within the trait implementations
Expand All @@ -42,6 +50,9 @@ impl Debug for ConnectionErrorIncoming {
let error_code = Code::from(*error_code);
write!(f, "ApplicationClose({})", error_code)
}
Self::ConnectionClosed { error_code } => {
write!(f, "ConnectionClosed({:#x})", error_code)
}
Self::Timeout => write!(f, "Timeout"),
Self::InternalError(arg0) => f.debug_tuple("InternalError").field(arg0).finish(),
Self::Undefined(arg0) => f.debug_tuple("Undefined").field(arg0).finish(),
Expand Down Expand Up @@ -100,6 +111,9 @@ impl Display for ConnectionErrorIncoming {
let error_code = Code::from(*error_code);
write!(f, "ApplicationClose: {}", error_code)
}
ConnectionErrorIncoming::ConnectionClosed { error_code } => {
write!(f, "ConnectionClosed: {:#x}", error_code)
}
ConnectionErrorIncoming::Timeout => write!(f, "Timeout"),
ConnectionErrorIncoming::InternalError(error) => {
write!(
Expand Down
Loading