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