1 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4 // option. This file may not be copied, modified, or distributed
5 // except according to those terms.
6 
7 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
8 #![warn(clippy::use_self)]
9 
10 use neqo_common::qinfo;
11 use neqo_crypto;
12 
13 mod cc;
14 mod cid;
15 mod connection;
16 mod crypto;
17 mod dump;
18 mod events;
19 mod flow_mgr;
20 mod frame;
21 mod packet;
22 mod path;
23 mod recovery;
24 mod recv_stream;
25 mod send_stream;
26 pub mod server;
27 mod stats;
28 mod stream_id;
29 pub mod tparams;
30 mod tracking;
31 
32 pub use self::cid::ConnectionIdManager;
33 pub use self::connection::{Connection, FixedConnectionIdManager, Output, Role, State};
34 pub use self::events::{ConnectionEvent, ConnectionEvents};
35 pub use self::frame::CloseError;
36 pub use self::frame::StreamType;
37 
38 /// The supported version of the QUIC protocol.
39 pub type Version = u32;
40 pub const QUIC_VERSION: Version = 0xff00_0000 + 27;
41 
42 const LOCAL_IDLE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(60); // 1 minute
43 
44 type TransportError = u64;
45 
46 #[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
47 #[allow(clippy::pub_enum_variant_names)]
48 pub enum Error {
49     NoError,
50     InternalError,
51     ServerBusy,
52     FlowControlError,
53     StreamLimitError,
54     StreamStateError,
55     FinalSizeError,
56     FrameEncodingError,
57     TransportParameterError,
58     ProtocolViolation,
59     InvalidMigration,
60     CryptoError(neqo_crypto::Error),
61     CryptoAlert(u8),
62 
63     // All internal errors from here.
64     AckedUnsentPacket,
65     ConnectionState,
66     DecodingFrame,
67     DecryptError,
68     HandshakeFailed,
69     IdleTimeout,
70     IntegerOverflow,
71     InvalidInput,
72     InvalidPacket,
73     InvalidResumptionToken,
74     InvalidRetry,
75     InvalidStreamId,
76     // Packet protection keys aren't available yet, or they have been discarded.
77     KeysNotFound,
78     // An attempt to update keys can be blocked if
79     // a packet sent with the current keys hasn't been acknowledged.
80     KeyUpdateBlocked,
81     NoMoreData,
82     NotConnected,
83     PacketNumberOverlap,
84     PeerError(TransportError),
85     TooMuchData,
86     UnexpectedMessage,
87     UnknownFrameType,
88     VersionNegotiation,
89     WrongRole,
90     KeysDiscarded,
91 }
92 
93 impl Error {
code(&self) -> TransportError94     pub fn code(&self) -> TransportError {
95         match self {
96             Self::NoError | Self::IdleTimeout => 0,
97             Self::ServerBusy => 2,
98             Self::FlowControlError => 3,
99             Self::StreamLimitError => 4,
100             Self::StreamStateError => 5,
101             Self::FinalSizeError => 6,
102             Self::FrameEncodingError => 7,
103             Self::TransportParameterError => 8,
104             Self::ProtocolViolation => 10,
105             Self::InvalidMigration => 12,
106             Self::CryptoAlert(a) => 0x100 + u64::from(*a),
107             Self::PeerError(a) => *a,
108             // All the rest are internal errors.
109             _ => 1,
110         }
111     }
112 }
113 
114 impl From<neqo_crypto::Error> for Error {
from(err: neqo_crypto::Error) -> Self115     fn from(err: neqo_crypto::Error) -> Self {
116         qinfo!("Crypto operation failed {:?}", err);
117         Self::CryptoError(err)
118     }
119 }
120 
121 impl From<std::num::TryFromIntError> for Error {
from(_: std::num::TryFromIntError) -> Self122     fn from(_: std::num::TryFromIntError) -> Self {
123         Self::IntegerOverflow
124     }
125 }
126 
127 impl ::std::error::Error for Error {
source(&self) -> Option<&(dyn ::std::error::Error + 'static)>128     fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
129         match self {
130             Self::CryptoError(e) => Some(e),
131             _ => None,
132         }
133     }
134 }
135 
136 impl ::std::fmt::Display for Error {
fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result137     fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
138         write!(f, "Transport error: {:?}", self)
139     }
140 }
141 
142 pub type AppError = u64;
143 
144 #[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
145 pub enum ConnectionError {
146     Transport(Error),
147     Application(AppError),
148 }
149 
150 impl ConnectionError {
app_code(&self) -> Option<AppError>151     pub fn app_code(&self) -> Option<AppError> {
152         match self {
153             Self::Application(e) => Some(*e),
154             _ => None,
155         }
156     }
157 }
158 
159 impl From<CloseError> for ConnectionError {
from(err: CloseError) -> Self160     fn from(err: CloseError) -> Self {
161         match err {
162             CloseError::Transport(c) => Self::Transport(Error::PeerError(c)),
163             CloseError::Application(c) => Self::Application(c),
164         }
165     }
166 }
167 
168 pub type Res<T> = std::result::Result<T, Error>;
169