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#[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#[derive(Debug, Clone, Default)]
97pub(crate) struct ErrorCause {
98 pub(crate) code: ErrorCauseCode,
99 pub(crate) raw: Bytes,
100}
101
102pub(crate) type ErrorCauseInvalidMandatoryParameter = ErrorCause;
104
105pub(crate) type ErrorCauseUnrecognizedChunkType = ErrorCause;
107
108pub(crate) type ErrorCauseProtocolViolation = ErrorCause;
125
126pub(crate) const ERROR_CAUSE_HEADER_LENGTH: usize = 4;
127
128impl 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}