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::Error as CryptoError;
12 
13 mod ackrate;
14 mod addr_valid;
15 mod cc;
16 mod cid;
17 mod connection;
18 mod crypto;
19 mod dump;
20 mod events;
21 mod fc;
22 mod frame;
23 mod pace;
24 mod packet;
25 mod path;
26 mod qlog;
27 mod recovery;
28 mod recv_stream;
29 mod rtt;
30 mod send_stream;
31 mod sender;
32 pub mod server;
33 mod stats;
34 pub mod stream_id;
35 pub mod streams;
36 pub mod tparams;
37 mod tracking;
38 
39 pub use self::cc::CongestionControlAlgorithm;
40 pub use self::cid::{
41     ConnectionId, ConnectionIdDecoder, ConnectionIdGenerator, ConnectionIdRef,
42     EmptyConnectionIdGenerator, RandomConnectionIdGenerator,
43 };
44 pub use self::connection::{
45     params::ConnectionParameters, params::ACK_RATIO_SCALE, Connection, Output, State, ZeroRttState,
46 };
47 pub use self::events::{ConnectionEvent, ConnectionEvents};
48 pub use self::frame::CloseError;
49 pub use self::packet::QuicVersion;
50 pub use self::stats::Stats;
51 pub use self::stream_id::{StreamId, StreamType};
52 
53 pub use self::recv_stream::RECV_BUFFER_SIZE;
54 pub use self::send_stream::SEND_BUFFER_SIZE;
55 
56 pub type TransportError = u64;
57 const ERROR_APPLICATION_CLOSE: TransportError = 12;
58 const ERROR_AEAD_LIMIT_REACHED: TransportError = 15;
59 
60 #[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
61 #[allow(clippy::pub_enum_variant_names)]
62 pub enum Error {
63     NoError,
64     // Each time tihe error is return a different parameter is supply.
65     // This will be use to distinguish each occurance of this error.
66     InternalError(u16),
67     ConnectionRefused,
68     FlowControlError,
69     StreamLimitError,
70     StreamStateError,
71     FinalSizeError,
72     FrameEncodingError,
73     TransportParameterError,
74     ProtocolViolation,
75     InvalidToken,
76     ApplicationError,
77     CryptoError(CryptoError),
78     QlogError,
79     CryptoAlert(u8),
80     EchRetry(Vec<u8>),
81 
82     // All internal errors from here.  Please keep these sorted.
83     AckedUnsentPacket,
84     ConnectionIdLimitExceeded,
85     ConnectionIdsExhausted,
86     ConnectionState,
87     DecodingFrame,
88     DecryptError,
89     HandshakeFailed,
90     IdleTimeout,
91     IntegerOverflow,
92     InvalidInput,
93     InvalidMigration,
94     InvalidPacket,
95     InvalidResumptionToken,
96     InvalidRetry,
97     InvalidStreamId,
98     KeysDiscarded,
99     /// Packet protection keys are exhausted.
100     /// Also used when too many key updates have happened.
101     KeysExhausted,
102     /// Packet protection keys aren't available yet for the identified space.
103     KeysPending(crypto::CryptoSpace),
104     /// An attempt to update keys can be blocked if
105     /// a packet sent with the current keys hasn't been acknowledged.
106     KeyUpdateBlocked,
107     NoAvailablePath,
108     NoMoreData,
109     NotConnected,
110     PacketNumberOverlap,
111     PeerApplicationError(AppError),
112     PeerError(TransportError),
113     StatelessReset,
114     TooMuchData,
115     UnexpectedMessage,
116     UnknownConnectionId,
117     UnknownFrameType,
118     VersionNegotiation,
119     WrongRole,
120 }
121 
122 impl Error {
code(&self) -> TransportError123     pub fn code(&self) -> TransportError {
124         match self {
125             Self::NoError
126             | Self::IdleTimeout
127             | Self::PeerError(_)
128             | Self::PeerApplicationError(_) => 0,
129             Self::ConnectionRefused => 2,
130             Self::FlowControlError => 3,
131             Self::StreamLimitError => 4,
132             Self::StreamStateError => 5,
133             Self::FinalSizeError => 6,
134             Self::FrameEncodingError => 7,
135             Self::TransportParameterError => 8,
136             Self::ProtocolViolation => 10,
137             Self::InvalidToken => 11,
138             Self::KeysExhausted => ERROR_AEAD_LIMIT_REACHED,
139             Self::ApplicationError => ERROR_APPLICATION_CLOSE,
140             Self::NoAvailablePath => 16,
141             Self::CryptoAlert(a) => 0x100 + u64::from(*a),
142             // As we have a special error code for ECH fallbacks, we lose the alert.
143             // Send the server "ech_required" directly.
144             Self::EchRetry(_) => 0x100 + 121,
145             // All the rest are internal errors.
146             _ => 1,
147         }
148     }
149 }
150 
151 impl From<CryptoError> for Error {
from(err: CryptoError) -> Self152     fn from(err: CryptoError) -> Self {
153         qinfo!("Crypto operation failed {:?}", err);
154         match err {
155             CryptoError::EchRetry(config) => Self::EchRetry(config),
156             _ => Self::CryptoError(err),
157         }
158     }
159 }
160 
161 impl From<::qlog::Error> for Error {
from(_err: ::qlog::Error) -> Self162     fn from(_err: ::qlog::Error) -> Self {
163         Self::QlogError
164     }
165 }
166 
167 impl From<std::num::TryFromIntError> for Error {
from(_: std::num::TryFromIntError) -> Self168     fn from(_: std::num::TryFromIntError) -> Self {
169         Self::IntegerOverflow
170     }
171 }
172 
173 impl ::std::error::Error for Error {
source(&self) -> Option<&(dyn ::std::error::Error + 'static)>174     fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
175         match self {
176             Self::CryptoError(e) => Some(e),
177             _ => None,
178         }
179     }
180 }
181 
182 impl ::std::fmt::Display for Error {
fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result183     fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
184         write!(f, "Transport error: {:?}", self)
185     }
186 }
187 
188 pub type AppError = u64;
189 
190 #[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
191 pub enum ConnectionError {
192     Transport(Error),
193     Application(AppError),
194 }
195 
196 impl ConnectionError {
app_code(&self) -> Option<AppError>197     pub fn app_code(&self) -> Option<AppError> {
198         match self {
199             Self::Application(e) => Some(*e),
200             _ => None,
201         }
202     }
203 }
204 
205 impl From<CloseError> for ConnectionError {
from(err: CloseError) -> Self206     fn from(err: CloseError) -> Self {
207         match err {
208             CloseError::Transport(c) => Self::Transport(Error::PeerError(c)),
209             CloseError::Application(c) => Self::Application(c),
210         }
211     }
212 }
213 
214 pub type Res<T> = std::result::Result<T, Error>;
215