rtc_sctp/chunk/
mod.rs

1#[cfg(test)]
2mod chunk_test;
3
4pub(crate) mod chunk_abort;
5pub(crate) mod chunk_cookie_ack;
6pub(crate) mod chunk_cookie_echo;
7pub(crate) mod chunk_error;
8pub(crate) mod chunk_forward_tsn;
9pub(crate) mod chunk_header;
10pub(crate) mod chunk_heartbeat;
11pub(crate) mod chunk_heartbeat_ack;
12pub(crate) mod chunk_init;
13pub mod chunk_payload_data;
14pub(crate) mod chunk_reconfig;
15pub(crate) mod chunk_selective_ack;
16pub(crate) mod chunk_shutdown;
17pub(crate) mod chunk_shutdown_ack;
18pub(crate) mod chunk_shutdown_complete;
19pub(crate) mod chunk_type;
20
21use chunk_header::*;
22use shared::error::{Error, Result};
23
24use bytes::{Buf, BufMut, Bytes, BytesMut};
25use std::marker::Sized;
26use std::{any::Any, fmt};
27
28pub(crate) trait Chunk: fmt::Display + fmt::Debug {
29    fn header(&self) -> ChunkHeader;
30    fn unmarshal(raw: &Bytes) -> Result<Self>
31    where
32        Self: Sized;
33    fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize>;
34    fn check(&self) -> Result<()>;
35    fn value_length(&self) -> usize;
36    fn as_any(&self) -> &(dyn Any);
37
38    fn marshal(&self) -> Result<Bytes> {
39        let capacity = CHUNK_HEADER_SIZE + self.value_length();
40        let mut buf = BytesMut::with_capacity(capacity);
41        self.marshal_to(&mut buf)?;
42        Ok(buf.freeze())
43    }
44}
45
46/// ErrorCauseCode is a cause code that appears in either a ERROR or ABORT chunk
47#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
48pub struct ErrorCauseCode(pub(crate) u16);
49
50pub(crate) const INVALID_STREAM_IDENTIFIER: ErrorCauseCode = ErrorCauseCode(1);
51pub(crate) const MISSING_MANDATORY_PARAMETER: ErrorCauseCode = ErrorCauseCode(2);
52pub(crate) const STALE_COOKIE_ERROR: ErrorCauseCode = ErrorCauseCode(3);
53pub(crate) const OUT_OF_RESOURCE: ErrorCauseCode = ErrorCauseCode(4);
54pub(crate) const UNRESOLVABLE_ADDRESS: ErrorCauseCode = ErrorCauseCode(5);
55pub(crate) const UNRECOGNIZED_CHUNK_TYPE: ErrorCauseCode = ErrorCauseCode(6);
56pub(crate) const INVALID_MANDATORY_PARAMETER: ErrorCauseCode = ErrorCauseCode(7);
57pub(crate) const UNRECOGNIZED_PARAMETERS: ErrorCauseCode = ErrorCauseCode(8);
58pub(crate) const NO_USER_DATA: ErrorCauseCode = ErrorCauseCode(9);
59pub(crate) const COOKIE_RECEIVED_WHILE_SHUTTING_DOWN: ErrorCauseCode = ErrorCauseCode(10);
60pub(crate) const RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESSES: ErrorCauseCode = ErrorCauseCode(11);
61pub(crate) const USER_INITIATED_ABORT: ErrorCauseCode = ErrorCauseCode(12);
62pub(crate) const PROTOCOL_VIOLATION: ErrorCauseCode = ErrorCauseCode(13);
63
64impl fmt::Display for ErrorCauseCode {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        let others = format!("Unknown CauseCode: {}", self.0);
67        let s = match *self {
68            INVALID_STREAM_IDENTIFIER => "Invalid Stream Identifier",
69            MISSING_MANDATORY_PARAMETER => "Missing Mandatory Parameter",
70            STALE_COOKIE_ERROR => "Stale Cookie Error",
71            OUT_OF_RESOURCE => "Out Of Resource",
72            UNRESOLVABLE_ADDRESS => "Unresolvable IP",
73            UNRECOGNIZED_CHUNK_TYPE => "Unrecognized Chunk Type",
74            INVALID_MANDATORY_PARAMETER => "Invalid Mandatory Parameter",
75            UNRECOGNIZED_PARAMETERS => "Unrecognized Parameters",
76            NO_USER_DATA => "No User Data",
77            COOKIE_RECEIVED_WHILE_SHUTTING_DOWN => "Cookie Received While Shutting Down",
78            RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESSES => {
79                "Restart Of An Association With New Addresses"
80            }
81            USER_INITIATED_ABORT => "User Initiated Abort",
82            PROTOCOL_VIOLATION => "Protocol Violation",
83            _ => others.as_str(),
84        };
85        write!(f, "{}", s)
86    }
87}
88
89impl From<u16> for ErrorCauseCode {
90    fn from(v: u16) -> Self {
91        ErrorCauseCode(v)
92    }
93}
94
95/// ErrorCauseHeader represents the shared header that is shared by all error causes
96#[derive(Debug, Clone, Default)]
97pub(crate) struct ErrorCause {
98    pub(crate) code: ErrorCauseCode,
99    pub(crate) raw: Bytes,
100}
101
102/// ErrorCauseInvalidMandatoryParameter represents an SCTP error cause
103pub(crate) type ErrorCauseInvalidMandatoryParameter = ErrorCause;
104
105/// ErrorCauseUnrecognizedChunkType represents an SCTP error cause
106pub(crate) type ErrorCauseUnrecognizedChunkType = ErrorCause;
107
108///
109/// This error cause MAY be included in ABORT chunks that are sent
110/// because an SCTP endpoint detects a protocol violation of the peer
111/// that is not covered by the error causes described in Section 3.3.10.1
112/// to Section 3.3.10.12.  An implementation MAY provide additional
113/// information specifying what kind of protocol violation has been
114/// detected.
115///      0                   1                   2                   3
116///      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
117///     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118///     |         Cause Code=13         |      Cause Length=Variable    |
119///     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120///     /                    Additional Information                     /
121///     \                                                               \
122///     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123///
124pub(crate) type ErrorCauseProtocolViolation = ErrorCause;
125
126pub(crate) const ERROR_CAUSE_HEADER_LENGTH: usize = 4;
127
128/// makes ErrorCauseHeader printable
129impl fmt::Display for ErrorCause {
130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131        write!(f, "{}", self.code)
132    }
133}
134
135impl ErrorCause {
136    pub(crate) fn unmarshal(buf: &Bytes) -> Result<Self> {
137        if buf.len() < ERROR_CAUSE_HEADER_LENGTH {
138            return Err(Error::ErrErrorCauseTooSmall);
139        }
140
141        let reader = &mut buf.clone();
142
143        let code = ErrorCauseCode(reader.get_u16());
144        let len = reader.get_u16();
145
146        if len < ERROR_CAUSE_HEADER_LENGTH as u16 {
147            return Err(Error::ErrErrorCauseTooSmall);
148        }
149
150        let value_length = len as usize - ERROR_CAUSE_HEADER_LENGTH;
151        let raw = buf.slice(ERROR_CAUSE_HEADER_LENGTH..ERROR_CAUSE_HEADER_LENGTH + value_length);
152
153        Ok(ErrorCause { code, raw })
154    }
155
156    pub(crate) fn marshal(&self) -> Bytes {
157        let mut buf = BytesMut::with_capacity(self.length());
158        let _ = self.marshal_to(&mut buf);
159        buf.freeze()
160    }
161
162    pub(crate) fn marshal_to(&self, writer: &mut BytesMut) -> usize {
163        let len = self.raw.len() + ERROR_CAUSE_HEADER_LENGTH;
164        writer.put_u16(self.code.0);
165        writer.put_u16(len as u16);
166        writer.extend(self.raw.clone());
167        writer.len()
168    }
169
170    pub(crate) fn length(&self) -> usize {
171        self.raw.len() + ERROR_CAUSE_HEADER_LENGTH
172    }
173
174    pub(crate) fn error_cause_code(&self) -> ErrorCauseCode {
175        self.code
176    }
177}