1use 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#[derive(Debug, PartialEq, Eq)]
33pub enum Ssu2Error {
34 Chacha,
36
37 Channel(ChannelError),
39
40 InvalidVersion,
42
43 Malformed,
45
46 NotEnoughBytes,
48
49 SessionTerminated(TerminationReason),
51
52 UnexpectedMessage,
54
55 TokenMismatch,
57
58 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#[derive(Debug, PartialEq, Eq)]
80pub enum SessionError {
81 SessionTerminated,
83
84 UnknownTag,
86
87 Malformed,
89
90 Chacha,
92
93 InvalidState,
95
96 InvalidKey,
98
99 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#[derive(Debug, PartialEq, Eq)]
119pub enum ConnectionError {
120 SocketClosed,
122
123 BindFailure,
125
126 KeepAliveTimeout,
128
129 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#[derive(Debug, PartialEq, Eq)]
146pub enum I2cpError {
147 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#[derive(Debug, PartialEq, Eq, Clone, Copy)]
161pub enum QueryError {
162 NoFloodfills,
164
165 Timeout,
167
168 ValueNotFound,
170
171 Malformed,
173
174 RetryFailure,
176
177 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#[derive(Debug, PartialEq, Eq)]
196pub enum StreamingError {
197 StreamIdMismatch(u32, u32),
199
200 SignatureMissing,
202
203 DestinationMissing,
205
206 VerifyingKeyMissing,
208
209 ReplayProtectionCheckFailed,
213
214 InvalidSignature,
216
217 Malformed(PacketParseError),
219
220 ListenerMismatch,
225
226 Closed,
228
229 ReceiveWindowFull,
231
232 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#[derive(Debug, PartialEq, Eq)]
268pub enum ChannelError {
269 Full,
271
272 Closed,
274
275 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#[derive(Debug, PartialEq, Eq)]
291pub enum RejectionReason {
292 NotSupported,
294
295 InvalidChecksum,
297}
298
299#[derive(Debug, PartialEq, Eq)]
301pub enum TunnelError {
302 TunnelDoesntExist(TunnelId),
304
305 InvalidHop,
307
308 TooManyHops(usize),
310
311 NotEnoughHops(usize),
313
314 InvalidMessage,
316
317 TunnelRejected(u8),
319
320 RecordNotFound,
322
323 MessageRejected(RejectionReason),
327
328 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#[derive(Debug, PartialEq, Eq)]
352pub enum RouteKind {
353 Tunnel(TunnelId),
355
356 #[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#[derive(Debug)]
372pub enum RoutingError {
373 #[allow(unused)]
375 RouteNotFound(Message, RouteKind),
376
377 #[allow(unused)]
381 FailedToParseRoute(Message),
382
383 #[allow(unused)]
385 ChannelFull(Message),
386
387 #[allow(unused)]
389 ChannelClosed(Message),
390
391 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
480impl From<Error> for SessionError {
482 fn from(_: Error) -> Self {
483 SessionError::Chacha
484 }
485}
486
487impl 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}