xref: /webrtc/sctp/src/param/mod.rs (revision ffe74184)
1 #[cfg(test)]
2 mod param_test;
3 
4 pub(crate) mod param_chunk_list;
5 pub(crate) mod param_forward_tsn_supported;
6 pub(crate) mod param_header;
7 pub(crate) mod param_heartbeat_info;
8 pub(crate) mod param_outgoing_reset_request;
9 pub(crate) mod param_random;
10 pub(crate) mod param_reconfig_response;
11 pub(crate) mod param_requested_hmac_algorithm;
12 pub(crate) mod param_state_cookie;
13 pub(crate) mod param_supported_extensions;
14 pub(crate) mod param_type;
15 pub(crate) mod param_unknown;
16 pub(crate) mod param_unrecognized;
17 
18 use crate::error::{Error, Result};
19 use crate::param::{
20     param_chunk_list::ParamChunkList, param_forward_tsn_supported::ParamForwardTsnSupported,
21     param_heartbeat_info::ParamHeartbeatInfo,
22     param_outgoing_reset_request::ParamOutgoingResetRequest, param_random::ParamRandom,
23     param_reconfig_response::ParamReconfigResponse,
24     param_requested_hmac_algorithm::ParamRequestedHmacAlgorithm,
25     param_state_cookie::ParamStateCookie, param_supported_extensions::ParamSupportedExtensions,
26 };
27 use param_header::*;
28 use param_type::*;
29 
30 use crate::param::param_unknown::ParamUnknown;
31 use bytes::{Buf, Bytes, BytesMut};
32 use std::{any::Any, fmt};
33 
34 pub(crate) trait Param: fmt::Display + fmt::Debug {
header(&self) -> ParamHeader35     fn header(&self) -> ParamHeader;
unmarshal(raw: &Bytes) -> Result<Self> where Self: Sized36     fn unmarshal(raw: &Bytes) -> Result<Self>
37     where
38         Self: Sized;
marshal_to(&self, buf: &mut BytesMut) -> Result<usize>39     fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize>;
value_length(&self) -> usize40     fn value_length(&self) -> usize;
clone_to(&self) -> Box<dyn Param + Send + Sync>41     fn clone_to(&self) -> Box<dyn Param + Send + Sync>;
as_any(&self) -> &(dyn Any + Send + Sync)42     fn as_any(&self) -> &(dyn Any + Send + Sync);
43 
marshal(&self) -> Result<Bytes>44     fn marshal(&self) -> Result<Bytes> {
45         let capacity = PARAM_HEADER_LENGTH + self.value_length();
46         let mut buf = BytesMut::with_capacity(capacity);
47         self.marshal_to(&mut buf)?;
48         Ok(buf.freeze())
49     }
50 }
51 
52 impl Clone for Box<dyn Param + Send + Sync> {
clone(&self) -> Box<dyn Param + Send + Sync>53     fn clone(&self) -> Box<dyn Param + Send + Sync> {
54         self.clone_to()
55     }
56 }
57 
build_param(raw_param: &Bytes) -> Result<Box<dyn Param + Send + Sync>>58 pub(crate) fn build_param(raw_param: &Bytes) -> Result<Box<dyn Param + Send + Sync>> {
59     if raw_param.len() < PARAM_HEADER_LENGTH {
60         return Err(Error::ErrParamHeaderTooShort);
61     }
62     let reader = &mut raw_param.slice(..2);
63     let raw_type = reader.get_u16();
64     match raw_type.into() {
65         ParamType::ForwardTsnSupp => Ok(Box::new(ParamForwardTsnSupported::unmarshal(raw_param)?)),
66         ParamType::SupportedExt => Ok(Box::new(ParamSupportedExtensions::unmarshal(raw_param)?)),
67         ParamType::Random => Ok(Box::new(ParamRandom::unmarshal(raw_param)?)),
68         ParamType::ReqHmacAlgo => Ok(Box::new(ParamRequestedHmacAlgorithm::unmarshal(raw_param)?)),
69         ParamType::ChunkList => Ok(Box::new(ParamChunkList::unmarshal(raw_param)?)),
70         ParamType::StateCookie => Ok(Box::new(ParamStateCookie::unmarshal(raw_param)?)),
71         ParamType::HeartbeatInfo => Ok(Box::new(ParamHeartbeatInfo::unmarshal(raw_param)?)),
72         ParamType::OutSsnResetReq => Ok(Box::new(ParamOutgoingResetRequest::unmarshal(raw_param)?)),
73         ParamType::ReconfigResp => Ok(Box::new(ParamReconfigResponse::unmarshal(raw_param)?)),
74         _ => {
75             // According to RFC https://datatracker.ietf.org/doc/html/rfc4960#section-3.2.1
76             let stop_processing = ((raw_type >> 15) & 0x01) == 0;
77             if stop_processing {
78                 Err(Error::ErrParamTypeUnhandled { typ: raw_type })
79             } else {
80                 // We still might need to report this param as unrecognized.
81                 // This depends on the context though.
82                 Ok(Box::new(ParamUnknown::unmarshal(raw_param)?))
83             }
84         }
85     }
86 }
87