1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
//! Low-level protocol logic for the SCTP protocol
//!
//! sctp-proto contains a fully deterministic implementation of SCTP protocol logic. It contains
//! no networking code and does not get any relevant timestamps from the operating system. Most
//! users may want to use the futures-based sctp-async API instead.
//!
//! The sctp-proto API might be of interest if you want to use it from a C or C++ project
//! through C bindings or if you want to use a different event loop than the one tokio provides.
//!
//! The most important types are `Endpoint`, which conceptually represents the protocol state for
//! a single socket and mostly manages configuration and dispatches incoming datagrams to the
//! related `Association`. `Association` types contain the bulk of the protocol logic related to
//! managing a single association and all the related state (such as streams).
#![warn(rust_2018_idioms)]
#![allow(dead_code)]
#![allow(clippy::bool_to_int_with_if)]
use ::shared::EcnCodepoint;
use bytes::Bytes;
use std::time::Instant;
use std::{
fmt,
net::{IpAddr, SocketAddr},
ops,
};
mod association;
pub use crate::association::{
stats::AssociationStats,
stream::{ReliabilityType, Stream, StreamEvent, StreamId, StreamState},
timer::TimerConfig,
Association, AssociationError, Event,
};
pub(crate) mod chunk;
pub use crate::chunk::{
chunk_payload_data::{ChunkPayloadData, PayloadProtocolIdentifier},
ErrorCauseCode,
};
mod config;
pub use crate::config::{ClientConfig, EndpointConfig, ServerConfig, TransportConfig};
mod endpoint;
pub use crate::endpoint::{AssociationHandle, ConnectError, DatagramEvent, Endpoint};
mod packet;
mod shared;
pub use crate::shared::{AssociationEvent, AssociationId, EndpointEvent};
pub(crate) mod param;
pub(crate) mod queue;
pub use crate::queue::reassembly_queue::{Chunk, Chunks};
pub(crate) mod util;
/// Whether an endpoint was the initiator of an association
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Side {
/// The initiator of an association
#[default]
Client = 0,
/// The acceptor of an association
Server = 1,
}
impl fmt::Display for Side {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match *self {
Side::Client => "Client",
Side::Server => "Server",
};
write!(f, "{}", s)
}
}
impl Side {
#[inline]
/// Shorthand for `self == Side::Client`
pub fn is_client(self) -> bool {
self == Side::Client
}
#[inline]
/// Shorthand for `self == Side::Server`
pub fn is_server(self) -> bool {
self == Side::Server
}
}
impl ops::Not for Side {
type Output = Side;
fn not(self) -> Side {
match self {
Side::Client => Side::Server,
Side::Server => Side::Client,
}
}
}
use crate::packet::PartialDecode;
/// Payload in Incoming/outgoing Transmit
#[derive(Debug)]
pub enum Payload {
PartialDecode(PartialDecode),
RawEncode(Vec<Bytes>),
}
/// Incoming/outgoing Transmit
#[derive(Debug)]
pub struct Transmit {
/// Received/Sent time
pub now: Instant,
/// The socket this datagram should be sent to
pub remote: SocketAddr,
/// Explicit congestion notification bits to set on the packet
pub ecn: Option<EcnCodepoint>,
/// Optional local IP address for the datagram
pub local_ip: Option<IpAddr>,
/// Payload of the datagram
pub payload: Payload,
}