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