Skip to content

Commit 9d1a2fa

Browse files
fix: preserve transporterror knowledge
1 parent a75ad0d commit 9d1a2fa

File tree

3 files changed

+66
-13
lines changed

3 files changed

+66
-13
lines changed

quinn-proto/src/connection/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,8 @@ impl Connection {
12111211
let max_frame_size = builder.frame_space_remaining();
12121212
match self.state.as_type() {
12131213
StateType::Closed => {
1214-
let reason = &self.state.as_closed().expect("checked");
1214+
let reason: Close =
1215+
self.state.as_closed().expect("checked").clone().into();
12151216
if space_id == SpaceId::Data || reason.is_transport_layer() {
12161217
reason.encode(&mut builder.frame_space_mut(), max_frame_size)
12171218
} else {

quinn-proto/src/connection/state.rs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use bytes::Bytes;
22

33
use crate::frame::Close;
4-
use crate::{ConnectionError, TransportErrorCode};
4+
use crate::{
5+
ApplicationClose, ConnectionClose, ConnectionError, TransportError, TransportErrorCode,
6+
};
57

68
#[allow(unreachable_pub)] // fuzzing only
79
#[derive(Debug, Clone)]
@@ -27,7 +29,7 @@ impl State {
2729
}
2830
}
2931

30-
pub(super) fn as_closed(&self) -> Option<&Close> {
32+
pub(super) fn as_closed(&self) -> Option<&CloseReason> {
3133
if let InnerState::Closed {
3234
ref remote_reason, ..
3335
} = self.inner
@@ -118,7 +120,7 @@ impl State {
118120
}
119121
}
120122

121-
pub(super) fn move_to_closed<R: Into<Close>>(&mut self, reason: R) {
123+
pub(super) fn move_to_closed<R: Into<CloseReason>>(&mut self, reason: R) {
122124
assert!(
123125
matches!(
124126
self.inner,
@@ -134,7 +136,7 @@ impl State {
134136
};
135137
}
136138

137-
pub(super) fn move_to_closed_local<R: Into<Close>>(&mut self, reason: R) {
139+
pub(super) fn move_to_closed_local<R: Into<CloseReason>>(&mut self, reason: R) {
138140
assert!(
139141
matches!(
140142
self.inner,
@@ -225,13 +227,65 @@ pub(super) enum StateType {
225227
Drained,
226228
}
227229

230+
#[derive(Debug, Clone)]
231+
pub(super) enum CloseReason {
232+
TransportError(TransportError),
233+
Connection(ConnectionClose),
234+
Application(ApplicationClose),
235+
}
236+
237+
impl From<TransportError> for CloseReason {
238+
fn from(x: TransportError) -> Self {
239+
Self::TransportError(x)
240+
}
241+
}
242+
impl From<ConnectionClose> for CloseReason {
243+
fn from(x: ConnectionClose) -> Self {
244+
Self::Connection(x)
245+
}
246+
}
247+
impl From<ApplicationClose> for CloseReason {
248+
fn from(x: ApplicationClose) -> Self {
249+
Self::Application(x)
250+
}
251+
}
252+
253+
impl From<Close> for CloseReason {
254+
fn from(value: Close) -> Self {
255+
match value {
256+
Close::Application(reason) => Self::Application(reason),
257+
Close::Connection(reason) => Self::Connection(reason),
258+
}
259+
}
260+
}
261+
262+
impl From<CloseReason> for ConnectionError {
263+
fn from(value: CloseReason) -> Self {
264+
match value {
265+
CloseReason::TransportError(err) => Self::TransportError(err),
266+
CloseReason::Connection(reason) => Self::ConnectionClosed(reason),
267+
CloseReason::Application(reason) => Self::ApplicationClosed(reason),
268+
}
269+
}
270+
}
271+
272+
impl From<CloseReason> for Close {
273+
fn from(value: CloseReason) -> Self {
274+
match value {
275+
CloseReason::TransportError(err) => Self::Connection(err.into()),
276+
CloseReason::Connection(reason) => Self::Connection(reason),
277+
CloseReason::Application(reason) => Self::Application(reason),
278+
}
279+
}
280+
}
281+
228282
#[derive(Debug, Clone)]
229283
enum InnerState {
230284
Handshake(Handshake),
231285
Established,
232286
Closed {
233287
/// The reason the remote closed the connection, or the reason we are sending to the remote.
234-
remote_reason: Close,
288+
remote_reason: CloseReason,
235289
/// Set to true if we closed the connection locally
236290
is_local: bool,
237291
/// Did we read this as error already?

quinn-proto/src/tests/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,11 +438,9 @@ fn reject_self_signed_server_cert() {
438438

439439
pair.drive();
440440

441-
assert_matches!(
442-
pair.client_conn_mut(client_ch).poll(),
443-
Some(Event::ConnectionLost { reason: ConnectionError::ConnectionClosed(ref reason)})
444-
if reason.error_code == TransportErrorCode::crypto(AlertDescription::UnknownCA.into())
445-
);
441+
assert_matches!(pair.client_conn_mut(client_ch).poll(),
442+
Some(Event::ConnectionLost { reason: ConnectionError::TransportError(ref error)})
443+
if error.code == TransportErrorCode::crypto(AlertDescription::UnknownCA.into()));
446444
}
447445

448446
#[test]
@@ -499,8 +497,8 @@ fn reject_missing_client_cert() {
499497
Some(Event::HandshakeDataReady)
500498
);
501499
assert_matches!(pair.server_conn_mut(server_ch).poll(),
502-
Some(Event::ConnectionLost { reason: ConnectionError::ConnectionClosed(ref close)})
503-
if close.error_code == TransportErrorCode::crypto(AlertDescription::CertificateRequired.into()));
500+
Some(Event::ConnectionLost { reason: ConnectionError::TransportError(ref error)})
501+
if error.code == TransportErrorCode::crypto(AlertDescription::CertificateRequired.into()));
504502
}
505503

506504
#[test]

0 commit comments

Comments
 (0)