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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
//! 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 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},
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 error;
pub use crate::error::Error;
mod packet;
mod shared;
pub use crate::shared::{AssociationEvent, AssociationId, EcnCodepoint, 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(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
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,
}
#[cfg(test)]
mod test {
use std::sync::Arc;
use super::*;
#[test]
fn ensure_send_sync() {
fn is_send_sync(_a: impl Send + Sync) {}
let c = EndpointConfig::new();
let e = Endpoint::new(Arc::new(c), None);
is_send_sync(e);
let a = Association::default();
is_send_sync(a);
}
}