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_i_forward_tsn;
13pub(crate) mod chunk_init;
14pub mod chunk_payload_data;
15pub(crate) mod chunk_reconfig;
16pub(crate) mod chunk_selective_ack;
17pub(crate) mod chunk_shutdown;
18pub(crate) mod chunk_shutdown_ack;
19pub(crate) mod chunk_shutdown_complete;
20pub(crate) mod chunk_type;
21
22use crate::error::{Error, Result};
23use chunk_header::*;
24
25use alloc::boxed::Box;
26use alloc::string::String;
27use alloc::vec;
28use alloc::vec::Vec;
29use bytes::{Buf, BufMut, Bytes, BytesMut};
30use core::{any::Any, fmt};
31
32pub(crate) trait Chunk: fmt::Display + fmt::Debug {
33 fn header(&self) -> ChunkHeader;
34 fn unmarshal(raw: &Bytes) -> Result<Self>
35 where
36 Self: Sized;
37 fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize>;
38 fn check(&self) -> Result<()>;
39 fn value_length(&self) -> usize;
40 fn as_any(&self) -> &(dyn Any + Send + Sync);
41
42 fn marshal(&self) -> Result<Bytes> {
43 let capacity = CHUNK_HEADER_SIZE + self.value_length();
44 let mut buf = BytesMut::with_capacity(capacity);
45 self.marshal_to(&mut buf)?;
46 Ok(buf.freeze())
47 }
48}
49
50#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
52pub struct ErrorCauseCode(pub(crate) u16);
53
54pub(crate) const INVALID_STREAM_IDENTIFIER: ErrorCauseCode = ErrorCauseCode(1);
55pub(crate) const MISSING_MANDATORY_PARAMETER: ErrorCauseCode = ErrorCauseCode(2);
56pub(crate) const STALE_COOKIE_ERROR: ErrorCauseCode = ErrorCauseCode(3);
57pub(crate) const OUT_OF_RESOURCE: ErrorCauseCode = ErrorCauseCode(4);
58pub(crate) const UNRESOLVABLE_ADDRESS: ErrorCauseCode = ErrorCauseCode(5);
59pub(crate) const UNRECOGNIZED_CHUNK_TYPE: ErrorCauseCode = ErrorCauseCode(6);
60pub(crate) const INVALID_MANDATORY_PARAMETER: ErrorCauseCode = ErrorCauseCode(7);
61pub(crate) const UNRECOGNIZED_PARAMETERS: ErrorCauseCode = ErrorCauseCode(8);
62pub(crate) const NO_USER_DATA: ErrorCauseCode = ErrorCauseCode(9);
63pub(crate) const COOKIE_RECEIVED_WHILE_SHUTTING_DOWN: ErrorCauseCode = ErrorCauseCode(10);
64pub(crate) const RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESSES: ErrorCauseCode = ErrorCauseCode(11);
65pub(crate) const USER_INITIATED_ABORT: ErrorCauseCode = ErrorCauseCode(12);
66pub(crate) const PROTOCOL_VIOLATION: ErrorCauseCode = ErrorCauseCode(13);
67
68impl fmt::Display for ErrorCauseCode {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 let others = format!("Unknown CauseCode: {}", self.0);
71 let s = match *self {
72 INVALID_STREAM_IDENTIFIER => "Invalid Stream Identifier",
73 MISSING_MANDATORY_PARAMETER => "Missing Mandatory Parameter",
74 STALE_COOKIE_ERROR => "Stale Cookie Error",
75 OUT_OF_RESOURCE => "Out Of Resource",
76 UNRESOLVABLE_ADDRESS => "Unresolvable IP",
77 UNRECOGNIZED_CHUNK_TYPE => "Unrecognized Chunk Type",
78 INVALID_MANDATORY_PARAMETER => "Invalid Mandatory Parameter",
79 UNRECOGNIZED_PARAMETERS => "Unrecognized Parameters",
80 NO_USER_DATA => "No User Data",
81 COOKIE_RECEIVED_WHILE_SHUTTING_DOWN => "Cookie Received While Shutting Down",
82 RESTART_OF_AN_ASSOCIATION_WITH_NEW_ADDRESSES => {
83 "Restart Of An Association With New Addresses"
84 }
85 USER_INITIATED_ABORT => "User Initiated Abort",
86 PROTOCOL_VIOLATION => "Protocol Violation",
87 _ => others.as_str(),
88 };
89 write!(f, "{}", s)
90 }
91}
92
93impl From<u16> for ErrorCauseCode {
94 fn from(v: u16) -> Self {
95 ErrorCauseCode(v)
96 }
97}
98
99#[derive(Debug, Clone, Default)]
101pub(crate) struct ErrorCause {
102 pub(crate) code: ErrorCauseCode,
103 pub(crate) raw: Bytes,
104}
105
106pub(crate) type ErrorCauseInvalidMandatoryParameter = ErrorCause;
108
109pub(crate) type ErrorCauseUnrecognizedChunkType = ErrorCause;
111
112pub(crate) type ErrorCauseProtocolViolation = ErrorCause;
129
130pub(crate) const ERROR_CAUSE_HEADER_LENGTH: usize = 4;
131
132impl fmt::Display for ErrorCause {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 write!(f, "{}", self.code)
136 }
137}
138
139impl ErrorCause {
140 pub(crate) fn unmarshal(buf: &Bytes) -> Result<Self> {
141 if buf.len() < ERROR_CAUSE_HEADER_LENGTH {
142 return Err(Error::ErrErrorCauseTooSmall);
143 }
144
145 let reader = &mut buf.clone();
146
147 let code = ErrorCauseCode(reader.get_u16());
148 let len = reader.get_u16();
149
150 if len < ERROR_CAUSE_HEADER_LENGTH as u16 {
151 return Err(Error::ErrErrorCauseTooSmall);
152 }
153
154 let value_length = len as usize - ERROR_CAUSE_HEADER_LENGTH;
155 if buf.len() < ERROR_CAUSE_HEADER_LENGTH + value_length {
156 return Err(Error::ErrErrorCauseTooSmall);
157 }
158 let raw = buf.slice(ERROR_CAUSE_HEADER_LENGTH..ERROR_CAUSE_HEADER_LENGTH + value_length);
159
160 Ok(ErrorCause { code, raw })
161 }
162
163 pub(crate) fn marshal(&self) -> Bytes {
164 let mut buf = BytesMut::with_capacity(self.length());
165 let _ = self.marshal_to(&mut buf);
166 buf.freeze()
167 }
168
169 pub(crate) fn marshal_to(&self, writer: &mut BytesMut) -> usize {
170 let len = self.raw.len() + ERROR_CAUSE_HEADER_LENGTH;
171 writer.put_u16(self.code.0);
172 writer.put_u16(len as u16);
173 writer.extend(self.raw.clone());
174 writer.len()
175 }
176
177 pub(crate) fn length(&self) -> usize {
178 self.raw.len() + ERROR_CAUSE_HEADER_LENGTH
179 }
180
181 pub(crate) fn error_cause_code(&self) -> ErrorCauseCode {
182 self.code
183 }
184}