1 use super::{chunk_header::*, chunk_type::*, *}; 2 3 use bytes::{Bytes, BytesMut}; 4 use std::fmt; 5 6 /// CookieEcho represents an SCTP Chunk of type CookieEcho 7 /// 8 /// 0 1 2 3 9 /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 10 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11 /// | Type = 10 |Chunk Flags | Length | 12 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 13 /// | Cookie | 14 /// | | 15 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 16 #[derive(Default, Debug, Clone)] 17 pub(crate) struct ChunkCookieEcho { 18 pub(crate) cookie: Bytes, 19 } 20 21 /// makes ChunkCookieEcho printable 22 impl fmt::Display for ChunkCookieEcho { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 24 write!(f, "{}", self.header()) 25 } 26 } 27 28 impl Chunk for ChunkCookieEcho { header(&self) -> ChunkHeader29 fn header(&self) -> ChunkHeader { 30 ChunkHeader { 31 typ: CT_COOKIE_ECHO, 32 flags: 0, 33 value_length: self.value_length() as u16, 34 } 35 } 36 unmarshal(raw: &Bytes) -> Result<Self>37 fn unmarshal(raw: &Bytes) -> Result<Self> { 38 let header = ChunkHeader::unmarshal(raw)?; 39 40 if header.typ != CT_COOKIE_ECHO { 41 return Err(Error::ErrChunkTypeNotCookieEcho); 42 } 43 44 let cookie = raw.slice(CHUNK_HEADER_SIZE..CHUNK_HEADER_SIZE + header.value_length()); 45 Ok(ChunkCookieEcho { cookie }) 46 } 47 marshal_to(&self, buf: &mut BytesMut) -> Result<usize>48 fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize> { 49 self.header().marshal_to(buf)?; 50 buf.extend(self.cookie.clone()); 51 Ok(buf.len()) 52 } 53 check(&self) -> Result<()>54 fn check(&self) -> Result<()> { 55 Ok(()) 56 } 57 value_length(&self) -> usize58 fn value_length(&self) -> usize { 59 self.cookie.len() 60 } 61 as_any(&self) -> &(dyn Any + Send + Sync)62 fn as_any(&self) -> &(dyn Any + Send + Sync) { 63 self 64 } 65 } 66