hopr_protocol_session/
lib.rs

1//! Contains implementation of a `Session` message protocol.
2//!
3//! The implementation in this crate follows
4//! the HOPR [`RFC-0007`](https://github.com/hoprnet/rfc/tree/main/rfcs/RFC-0007-session-protocol).
5//!
6//! # What is `Session` protocol?
7//! `Session` protocol is a simple protocol for unreliable networks that implements
8//! basic TCP-like features, such as segmentation, retransmission and acknowledgement.
9//!
10//! The goal of this protocol is to establish a read-write session between two parties,
11//! where one is a message sender and the other one is the receiver. The messages are called
12//! *frames* which are split and are delivered as *segments* from the sender to the recipient.
13//! The session has some reliability guarantees given by the retransmission and acknowledgement
14//! capabilities of individual segments.
15//!
16//! The [`UnreliableSocket`] acts as an unreliable Session protocol socket, taking care only of
17//! segmentation, reassembly and sequencing.
18//!
19//! The [`ReliableSocket`] has (in addition to segmentation, reassembly and sequencing) an
20//! internal state that allows acknowledging frames, retransmit unacknowledged frames and/or
21//! requesting of missing frame segments. It therefore offers data some delivery guarantees
22//! up to the pre-defined frame expiration time.
23//!
24//! The above sockets can be constructed on top of any transport that implements
25//! [`futures::io::AsyncRead`] and [`futures::io::AsyncWrite`],
26//! also using the [extension](SessionSocketExt) methods.
27//!
28//! ## Overview of the crate
29//! - Protocol messages are defined in the `protocol` submodule.
30//! - Socket-like Session interface is defined in `socket` submodule.
31//! - Frames and segments are defined in the `frames` module.
32//! - Segmentation, reassembly and sequencing are defined in the `processing` submodule.
33
34/// Contains errors thrown from this module.
35pub mod errors;
36#[allow(dead_code)]
37mod processing;
38mod protocol;
39mod socket;
40pub(crate) mod utils;
41
42pub use socket::{
43    SessionSocket, SessionSocketConfig,
44    ack_state::{AcknowledgementMode, AcknowledgementState, AcknowledgementStateConfig},
45    state::{SocketState, Stateless},
46};
47
48// Enable exports of additional Session protocol types
49#[cfg(feature = "session-types")]
50pub mod types {
51    pub use super::protocol::*;
52}
53
54/// Represents a stateless (and therefore unreliable) socket.
55pub type UnreliableSocket<const C: usize> = SessionSocket<C, Stateless<C>>;
56
57/// Represents a socket with reliable delivery.
58pub type ReliableSocket<const C: usize> = SessionSocket<C, AcknowledgementState<C>>;
59
60/// Computes the Session Socket MTU, given the MTU `C` of the underlying socket.
61pub const fn session_socket_mtu<const C: usize>() -> usize {
62    C - protocol::SessionMessage::<C>::SEGMENT_OVERHEAD
63}
64
65/// Adaptors for [`futures::io::AsyncRead`] + [`futures::io::AsyncWrite`] transport to use Session protocol.
66///
67/// Use `compat` first when the underlying transport is Tokio-based.
68pub trait SessionSocketExt: futures::io::AsyncRead + futures::io::AsyncWrite + Send + Unpin {
69    /// Runs a [reliable](ReliableSocket) Session protocol on self.
70    fn reliable_session<const MTU: usize>(
71        self,
72        ack: AcknowledgementState<MTU>,
73        cfg: SessionSocketConfig,
74    ) -> errors::Result<ReliableSocket<MTU>>
75    where
76        Self: Sized + 'static,
77    {
78        SessionSocket::new(self, ack, cfg)
79    }
80
81    /// Runs [unreliable](UnreliableSocket) Session protocol on self.
82    fn unreliable_session<const MTU: usize>(
83        self,
84        id: &str,
85        cfg: SessionSocketConfig,
86    ) -> errors::Result<UnreliableSocket<MTU>>
87    where
88        Self: Sized + 'static,
89    {
90        SessionSocket::new_stateless(id, self, cfg)
91    }
92}
93
94impl<T: ?Sized> SessionSocketExt for T where T: futures::io::AsyncRead + futures::io::AsyncWrite + Send + Unpin {}