Skip to main content

emissary_core/error/
mod.rs

1// Permission is hereby granted, free of charge, to any person obtaining a
2// copy of this software and associated documentation files (the "Software"),
3// to deal in the Software without restriction, including without limitation
4// the rights to use, copy, modify, merge, publish, distribute, sublicense,
5// and/or sell copies of the Software, and to permit persons to whom the
6// Software is furnished to do so, subject to the following conditions:
7//
8// The above copyright notice and this permission notice shall be included in
9// all copies or substantial portions of the Software.
10//
11// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
16// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17// DEALINGS IN THE SOFTWARE.
18
19use crate::{
20    error::parser::PacketParseError,
21    i2np::Message,
22    primitives::{MessageId, TunnelId},
23    transport::TerminationReason,
24};
25
26use alloc::string::String;
27use core::fmt;
28
29pub mod parser;
30
31/// SSU2 error.
32#[derive(Debug, PartialEq, Eq)]
33pub enum Ssu2Error {
34    /// Encryption/decryption error.
35    Chacha,
36
37    /// Channel error.
38    Channel(ChannelError),
39
40    /// Invalid protocol version.
41    InvalidVersion,
42
43    /// Malformed packet.
44    Malformed,
45
46    /// Packet is too short.
47    NotEnoughBytes,
48
49    /// Session terminated.
50    SessionTerminated(TerminationReason),
51
52    /// Unexpected message.
53    UnexpectedMessage,
54
55    /// Token mismatch.
56    TokenMismatch,
57
58    /// Network mismatch.
59    NetworkMismatch,
60}
61
62impl fmt::Display for Ssu2Error {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        match self {
65            Self::Chacha => write!(f, "encryption/decryption error"),
66            Self::Channel(error) => write!(f, "{error}"),
67            Self::InvalidVersion => write!(f, "invalid protocol version"),
68            Self::Malformed => write!(f, "malformed packet"),
69            Self::NotEnoughBytes => write!(f, "packet is too short"),
70            Self::SessionTerminated(reason) => write!(f, "session forcibly terminated: {reason:?}"),
71            Self::UnexpectedMessage => write!(f, "unexpected message"),
72            Self::TokenMismatch => write!(f, "token mismatch"),
73            Self::NetworkMismatch => write!(f, "network mismatch"),
74        }
75    }
76}
77
78/// Connection error.
79#[derive(Debug, PartialEq, Eq)]
80pub enum SessionError {
81    /// Session terminated forcibly due to protocol error.
82    SessionTerminated,
83
84    /// Unknown garlic tag.
85    UnknownTag,
86
87    /// Message was malformed.
88    Malformed,
89
90    /// Encryption/decryption error.
91    Chacha,
92
93    /// State machine has entered an invalid state.
94    InvalidState,
95
96    /// Invalid key.
97    InvalidKey,
98
99    /// New session message has an invalid timestamp
100    Timestamp,
101}
102
103impl fmt::Display for SessionError {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        match self {
106            Self::SessionTerminated => write!(f, "session forcibly terminated"),
107            Self::UnknownTag => write!(f, "unknown garlic tag"),
108            Self::Malformed => write!(f, "malformed message"),
109            Self::Chacha => write!(f, "encryption/decryption error"),
110            Self::InvalidState => write!(f, "invalid state"),
111            Self::InvalidKey => write!(f, "invalid key"),
112            Self::Timestamp => write!(f, "excess message timestamp skew"),
113        }
114    }
115}
116
117/// Connection error.
118#[derive(Debug, PartialEq, Eq)]
119pub enum ConnectionError {
120    /// Socket closed.
121    SocketClosed,
122
123    /// Failed to bind to socket.
124    BindFailure,
125
126    /// Keep-alive timeout.
127    KeepAliveTimeout,
128
129    /// Read timeout.
130    ReadTimeout,
131}
132
133impl fmt::Display for ConnectionError {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        match self {
136            Self::SocketClosed => write!(f, "socket closed"),
137            Self::BindFailure => write!(f, "failed to bind to socket"),
138            Self::KeepAliveTimeout => write!(f, "keep-alive timeout"),
139            Self::ReadTimeout => write!(f, "read timeout"),
140        }
141    }
142}
143
144/// I2CP error.
145#[derive(Debug, PartialEq, Eq)]
146pub enum I2cpError {
147    /// Invalid control byte read from the client.
148    InvalidProtocolByte(u8),
149}
150
151impl fmt::Display for I2cpError {
152    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153        match self {
154            Self::InvalidProtocolByte(byte) => write!(f, "invalid protocol byte ({byte})"),
155        }
156    }
157}
158
159/// Query error.
160#[derive(Debug, PartialEq, Eq, Clone, Copy)]
161pub enum QueryError {
162    /// No floodfills.
163    NoFloodfills,
164
165    /// Query timed out.
166    Timeout,
167
168    /// Value not found.
169    ValueNotFound,
170
171    /// Malformed reply.
172    Malformed,
173
174    /// Retry limimt reached.
175    RetryFailure,
176
177    /// No tunnel available to send/receive query/query result.
178    NoTunnel,
179}
180
181impl fmt::Display for QueryError {
182    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183        match self {
184            Self::NoFloodfills => write!(f, "no floodfills"),
185            Self::Timeout => write!(f, "query timed out"),
186            Self::ValueNotFound => write!(f, "value not found"),
187            Self::Malformed => write!(f, "malformed reply"),
188            Self::RetryFailure => write!(f, "operation retried too many times"),
189            Self::NoTunnel => write!(f, "no tunnel available"),
190        }
191    }
192}
193
194/// Streaming protocol error.
195#[derive(Debug, PartialEq, Eq)]
196pub enum StreamingError {
197    /// Mismatch between send and receive stream IDs.
198    StreamIdMismatch(u32, u32),
199
200    /// Signature missing from `SYN` packet.
201    SignatureMissing,
202
203    /// Destination mssing from `SYN` packet.
204    DestinationMissing,
205
206    /// Verifying key missing from included destination.
207    VerifyingKeyMissing,
208
209    /// Replay protection check failed.
210    ///
211    /// NACk field didn't contain destination's ID.
212    ReplayProtectionCheckFailed,
213
214    /// Invalid signature.
215    InvalidSignature,
216
217    /// Malformed packet.
218    Malformed(PacketParseError),
219
220    /// Listener kind mismatch.
221    ///
222    /// Persistent listener registered when one or more ephemeral listeners
223    /// are active or vice versa.
224    ListenerMismatch,
225
226    /// Stream closed.
227    Closed,
228
229    /// Receive window is full.
230    ReceiveWindowFull,
231
232    /// Sequence number for the packet is unexpected high.
233    SequenceNumberTooHigh,
234}
235
236impl From<PacketParseError> for StreamingError {
237    fn from(value: PacketParseError) -> Self {
238        Self::Malformed(value)
239    }
240}
241
242impl fmt::Display for StreamingError {
243    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
244        match self {
245            Self::StreamIdMismatch(send, recv) => {
246                write!(f, "stream mismatch: {send} (send) vs {recv} (recv)")
247            }
248            Self::SignatureMissing => write!(f, "signature missing"),
249            Self::DestinationMissing => write!(f, "destination missing"),
250            Self::VerifyingKeyMissing => write!(f, "verifying key mssing"),
251            Self::ReplayProtectionCheckFailed => {
252                write!(f, "nack field didn't contain correct destination id")
253            }
254            Self::InvalidSignature => write!(f, "invalid signature"),
255            Self::Malformed(error) => write!(f, "malformed packet: {error:?}"),
256            Self::ListenerMismatch => write!(f, "listener kind mismatch"),
257            Self::Closed => write!(f, "stream closed"),
258            Self::ReceiveWindowFull => write!(f, "receive window is full"),
259            Self::SequenceNumberTooHigh => {
260                write!(f, "sequnce number for the packet is unexpectedly high")
261            }
262        }
263    }
264}
265
266/// Channel error.
267#[derive(Debug, PartialEq, Eq)]
268pub enum ChannelError {
269    /// Channel is full.
270    Full,
271
272    /// Channel is closed.
273    Closed,
274
275    /// Channel doesn't exist.
276    DoesntExist,
277}
278
279impl fmt::Display for ChannelError {
280    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281        match self {
282            Self::Full => write!(f, "channel full"),
283            Self::Closed => write!(f, "channel closed"),
284            Self::DoesntExist => write!(f, "channel doesn't exist"),
285        }
286    }
287}
288
289/// Tunnel message rejection reason.
290#[derive(Debug, PartialEq, Eq)]
291pub enum RejectionReason {
292    /// Message/operation not supported.
293    NotSupported,
294
295    /// Invalid checksum.
296    InvalidChecksum,
297}
298
299/// Tunnel error.
300#[derive(Debug, PartialEq, Eq)]
301pub enum TunnelError {
302    /// Tunnel doesn't exist.
303    TunnelDoesntExist(TunnelId),
304
305    /// Invalid hop role for an operation.
306    InvalidHop,
307
308    /// Too many hops.
309    TooManyHops(usize),
310
311    /// Not enough hops.
312    NotEnoughHops(usize),
313
314    /// Invalid tunnel message.
315    InvalidMessage,
316
317    /// Tunnel rejected.
318    TunnelRejected(u8),
319
320    /// Local record not found in the build request.
321    RecordNotFound,
322
323    /// Tunnel message rejected.
324    ///
325    /// This is different from tunnel rejection.
326    MessageRejected(RejectionReason),
327
328    /// Message doesn't exist.
329    MessageDoesntExist(MessageId),
330}
331
332impl fmt::Display for TunnelError {
333    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334        match self {
335            Self::TunnelDoesntExist(tunnel_id) => write!(f, "tunnel ({tunnel_id}) does't exist"),
336            Self::InvalidHop => write!(f, "invalid hop role for operation"),
337            Self::TooManyHops(hops) => write!(f, "too many hops {hops}"),
338            Self::InvalidMessage => write!(f, "invalid tunnel message"),
339            Self::TunnelRejected(reason) => write!(f, "tunnel rejected: {reason}"),
340            Self::NotEnoughHops(hops) => write!(f, "not enough hops {hops}"),
341            Self::RecordNotFound => write!(f, "local record not found"),
342            Self::MessageRejected(reason) => write!(f, "message rejected, reason: {reason:?}"),
343            Self::MessageDoesntExist(message_id) => {
344                write!(f, "message doesn't exist: {message_id}")
345            }
346        }
347    }
348}
349
350/// Route kind for [`RoutingError::RouteNotFound`].
351#[derive(Debug, PartialEq, Eq)]
352pub enum RouteKind {
353    /// Tunnel not found.
354    Tunnel(TunnelId),
355
356    /// Listener for message not found.
357    #[allow(unused)]
358    Message(MessageId),
359}
360
361impl fmt::Display for RouteKind {
362    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363        match self {
364            Self::Tunnel(tunnel_id) => write!(f, "{tunnel_id:?}"),
365            Self::Message(message_id) => write!(f, "{message_id:?}"),
366        }
367    }
368}
369
370/// Message routing error.
371#[derive(Debug)]
372pub enum RoutingError {
373    /// Route not found.
374    #[allow(unused)]
375    RouteNotFound(Message, RouteKind),
376
377    /// Failed to parse route from message.
378    ///
379    /// Message is invalid and doesn't contain a route.
380    #[allow(unused)]
381    FailedToParseRoute(Message),
382
383    /// Channel full.
384    #[allow(unused)]
385    ChannelFull(Message),
386
387    /// Channel closed.
388    #[allow(unused)]
389    ChannelClosed(Message),
390
391    /// Tunnel already exists in the routing table.
392    TunnelExists(TunnelId),
393}
394
395impl fmt::Display for RoutingError {
396    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
397        match self {
398            Self::RouteNotFound(_, route) => write!(f, "route not found: {route}"),
399            Self::FailedToParseRoute(_) => write!(f, "failed to parse route"),
400            Self::ChannelFull(_) => write!(f, "channel full"),
401            Self::ChannelClosed(_) => write!(f, "channel closed"),
402            Self::TunnelExists(tunnel_id) => {
403                write!(f, "tunnel ({tunnel_id}) exists in the routing table")
404            }
405        }
406    }
407}
408
409#[derive(Debug)]
410pub enum Error {
411    Ed25519(ed25519_dalek::ed25519::Error),
412    Chacha20Poly1305(chacha20poly1305::Error),
413    InvalidData,
414    InvalidState,
415    NonceOverflow,
416    NotSupported,
417    EssentialTaskClosed,
418    RouterDoesntExist,
419    DialFailure,
420    Timeout,
421    Tunnel(TunnelError),
422    Channel(ChannelError),
423    Streaming(StreamingError),
424    Query(QueryError),
425    I2cp(I2cpError),
426    Connection(ConnectionError),
427    Custom(String),
428    Missing,
429    Session(SessionError),
430    NetworkMismatch,
431    Expired,
432    Routing(RoutingError),
433    Duplicate,
434    Ssu2(Ssu2Error),
435}
436
437impl fmt::Display for Error {
438    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
439        match self {
440            Self::Ed25519(error) => write!(f, "ed25519 error: {error:?}"),
441            Self::Chacha20Poly1305(error) => write!(f, "chacha20poly1305 error: {error:?}"),
442            Self::InvalidData => write!(f, "invalid data"),
443            Self::InvalidState => write!(f, "invalid state"),
444            Self::NonceOverflow => write!(f, "nonce overflow"),
445            Self::NotSupported => write!(f, "protocol or operation not supported"),
446            Self::EssentialTaskClosed => write!(f, "essential task closed"),
447            Self::RouterDoesntExist => write!(f, "router doesn't exist"),
448            Self::DialFailure => write!(f, "dial failure"),
449            Self::Timeout => write!(f, "operation timed out"),
450            Self::Tunnel(error) => write!(f, "tunnel error: {error}"),
451            Self::Channel(error) => write!(f, "channel error: {error}"),
452            Self::Streaming(error) => write!(f, "streaming protocol error: {error}"),
453            Self::Query(error) => write!(f, "query error: {error}"),
454            Self::I2cp(error) => write!(f, "i2cp error: {error}"),
455            Self::Connection(error) => write!(f, "connection error: {error}"),
456            Self::Custom(error) => write!(f, "{error}"),
457            Self::Missing => write!(f, "value missing"),
458            Self::Session(error) => write!(f, "session error: {error}"),
459            Self::NetworkMismatch => write!(f, "network mismatch"),
460            Self::Expired => write!(f, "message has expired"),
461            Self::Routing(error) => write!(f, "routing: {error}"),
462            Self::Duplicate => write!(f, "duplicate message"),
463            Self::Ssu2(error) => write!(f, "ssu2: {error}"),
464        }
465    }
466}
467
468impl From<ed25519_dalek::ed25519::Error> for Error {
469    fn from(value: ed25519_dalek::ed25519::Error) -> Self {
470        Error::Ed25519(value)
471    }
472}
473
474impl From<chacha20poly1305::Error> for Error {
475    fn from(value: chacha20poly1305::Error) -> Self {
476        Error::Chacha20Poly1305(value)
477    }
478}
479
480// TODO: not good, fix chacha error
481impl From<Error> for SessionError {
482    fn from(_: Error) -> Self {
483        SessionError::Chacha
484    }
485}
486
487// TODO: not good, fix chacha error
488impl From<Error> for Ssu2Error {
489    fn from(_: Error) -> Self {
490        Ssu2Error::Chacha
491    }
492}
493
494impl From<RoutingError> for Error {
495    fn from(value: RoutingError) -> Self {
496        Error::Routing(value)
497    }
498}
499
500impl<T> From<thingbuf::mpsc::errors::TrySendError<T>> for ChannelError {
501    fn from(value: thingbuf::mpsc::errors::TrySendError<T>) -> Self {
502        match value {
503            thingbuf::mpsc::errors::TrySendError::Full(_) => ChannelError::Full,
504            thingbuf::mpsc::errors::TrySendError::Closed(_) => ChannelError::Closed,
505            _ => unreachable!(),
506        }
507    }
508}
509
510impl<T> From<thingbuf::mpsc::errors::TrySendError<T>> for Ssu2Error {
511    fn from(value: thingbuf::mpsc::errors::TrySendError<T>) -> Self {
512        match value {
513            thingbuf::mpsc::errors::TrySendError::Full(_) => Ssu2Error::Channel(ChannelError::Full),
514            thingbuf::mpsc::errors::TrySendError::Closed(_) =>
515                Ssu2Error::Channel(ChannelError::Closed),
516            _ => unreachable!(),
517        }
518    }
519}
520
521impl From<thingbuf::mpsc::errors::TrySendError<Message>> for RoutingError {
522    fn from(value: thingbuf::mpsc::errors::TrySendError<Message>) -> Self {
523        match value {
524            thingbuf::mpsc::errors::TrySendError::Full(message) =>
525                RoutingError::ChannelFull(message),
526            thingbuf::mpsc::errors::TrySendError::Closed(message) =>
527                RoutingError::ChannelClosed(message),
528            _ => unreachable!(),
529        }
530    }
531}