webrtc_sctp/
error_cause.rs1use std::fmt;
2
3use bytes::{Buf, BufMut, Bytes, BytesMut};
4
5use crate::error::{Error, Result};
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
9pub(crate) struct ErrorCauseCode(pub(crate) u16);
10
11pub(crate) const INVALID_STREAM_IDENTIFIER: ErrorCauseCode = ErrorCauseCode(1);
12pub(crate) const MISSING_MANDATORY_PARAMETER: ErrorCauseCode = ErrorCauseCode(2);
13pub(crate) const STALE_COOKIE_ERROR: ErrorCauseCode = ErrorCauseCode(3);
14pub(crate) const OUT_OF_RESOURCE: ErrorCauseCode = ErrorCauseCode(4);
15pub(crate) const UNRESOLVABLE_ADDRESS: ErrorCauseCode = ErrorCauseCode(5);
16pub(crate) const UNRECOGNIZED_CHUNK_TYPE: ErrorCauseCode = ErrorCauseCode(6);
17pub(crate) const INVALID_MANDATORY_PARAMETER: ErrorCauseCode = ErrorCauseCode(7);
18pub(crate) const UNRECOGNIZED_PARAMETERS: ErrorCauseCode = ErrorCauseCode(8);
19pub(crate) const NO_USER_DATA: ErrorCauseCode = ErrorCauseCode(9);
20pub(crate) const COOKIE_RECEIVED_WHILE_SHUTTING_DOWN: ErrorCauseCode = ErrorCauseCode(10);
21pub(crate) const RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESSES: ErrorCauseCode = ErrorCauseCode(11);
22pub(crate) const USER_INITIATED_ABORT: ErrorCauseCode = ErrorCauseCode(12);
23pub(crate) const PROTOCOL_VIOLATION: ErrorCauseCode = ErrorCauseCode(13);
24
25impl fmt::Display for ErrorCauseCode {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 let others = format!("Unknown CauseCode: {}", self.0);
28 let s = match *self {
29 INVALID_STREAM_IDENTIFIER => "Invalid Stream Identifier",
30 MISSING_MANDATORY_PARAMETER => "Missing Mandatory Parameter",
31 STALE_COOKIE_ERROR => "Stale Cookie Error",
32 OUT_OF_RESOURCE => "Out Of Resource",
33 UNRESOLVABLE_ADDRESS => "Unresolvable IP",
34 UNRECOGNIZED_CHUNK_TYPE => "Unrecognized Chunk Type",
35 INVALID_MANDATORY_PARAMETER => "Invalid Mandatory Parameter",
36 UNRECOGNIZED_PARAMETERS => "Unrecognized Parameters",
37 NO_USER_DATA => "No User Data",
38 COOKIE_RECEIVED_WHILE_SHUTTING_DOWN => "Cookie Received While Shutting Down",
39 RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESSES => {
40 "Restart Of An Association With New Addresses"
41 }
42 USER_INITIATED_ABORT => "User Initiated Abort",
43 PROTOCOL_VIOLATION => "Protocol Violation",
44 _ => others.as_str(),
45 };
46 write!(f, "{s}")
47 }
48}
49
50#[derive(Debug, Clone, Default)]
52pub(crate) struct ErrorCause {
53 pub(crate) code: ErrorCauseCode,
54 pub(crate) raw: Bytes,
55}
56
57pub(crate) type ErrorCauseInvalidMandatoryParameter = ErrorCause;
59
60pub(crate) type ErrorCauseUnrecognizedChunkType = ErrorCause;
62
63pub(crate) type ErrorCauseProtocolViolation = ErrorCause;
80
81pub(crate) const ERROR_CAUSE_HEADER_LENGTH: usize = 4;
82
83impl fmt::Display for ErrorCause {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 write!(f, "{}", self.code)
87 }
88}
89
90impl ErrorCause {
91 pub(crate) fn unmarshal(buf: &Bytes) -> Result<Self> {
92 if buf.len() < ERROR_CAUSE_HEADER_LENGTH {
93 return Err(Error::ErrErrorCauseTooSmall);
94 }
95
96 let reader = &mut buf.clone();
97
98 let code = ErrorCauseCode(reader.get_u16());
99 let len = reader.get_u16();
100
101 if len < ERROR_CAUSE_HEADER_LENGTH as u16 {
102 return Err(Error::ErrErrorCauseTooSmall);
103 }
104 if buf.len() < len as usize {
105 return Err(Error::ErrErrorCauseTooSmall);
106 }
107
108 let value_length = len as usize - ERROR_CAUSE_HEADER_LENGTH;
109
110 let raw = buf.slice(ERROR_CAUSE_HEADER_LENGTH..ERROR_CAUSE_HEADER_LENGTH + value_length);
111
112 Ok(ErrorCause { code, raw })
113 }
114
115 pub(crate) fn marshal(&self) -> Bytes {
116 let mut buf = BytesMut::with_capacity(self.length());
117 let _ = self.marshal_to(&mut buf);
118 buf.freeze()
119 }
120
121 pub(crate) fn marshal_to(&self, writer: &mut BytesMut) -> usize {
122 let len = self.raw.len() + ERROR_CAUSE_HEADER_LENGTH;
123 writer.put_u16(self.code.0);
124 writer.put_u16(len as u16);
125 writer.extend(self.raw.clone());
126 writer.len()
127 }
128
129 pub(crate) fn length(&self) -> usize {
130 self.raw.len() + ERROR_CAUSE_HEADER_LENGTH
131 }
132
133 pub(crate) fn error_cause_code(&self) -> ErrorCauseCode {
134 self.code
135 }
136}