Skip to content
File

Blob: firmware/vendor/sctp-proto/src/chunk/chunk_heartbeat.rs

rust94 lines
1use super::{chunk_header::*, chunk_type::*, *};
2use crate::param::{param_header::*, param_type::*, *};
3 
4///chunkHeartbeat represents an SCTP Chunk of type HEARTBEAT
5///
6///An endpoint should send this chunk to its peer endpoint to probe the
7///reachability of a particular destination transport address defined in
8///the present association.
9///
10///The parameter field contains the Heartbeat Information, which is a
11///variable-length opaque data structure understood only by the sender.
12///
13///
14/// 0 1 2 3
15/// 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
16///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17///| Type = 4 | Chunk Flags | Heartbeat Length |
18///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19///| |
20///| Heartbeat Information TLV (Variable-Length) |
21///| |
22///+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23///
24///Defined as a variable-length parameter using the format described
25///in Section 3.2.1, i.e.:
26///
27///Variable Parameters Status Type Value
28///-------------------------------------------------------------
29///heartbeat Info Mandatory 1
30#[derive(Default, Debug)]
31pub(crate) struct ChunkHeartbeat {
32 pub(crate) params: Vec<Box<dyn Param + Send + Sync>>,
33}
34 
35/// makes ChunkHeartbeat printable
36impl fmt::Display for ChunkHeartbeat {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(f, "{}", self.header())
39 }
40}
41 
42impl Chunk for ChunkHeartbeat {
43 fn header(&self) -> ChunkHeader {
44 ChunkHeader {
45 typ: CT_HEARTBEAT,
46 flags: 0,
47 value_length: self.value_length() as u16,
48 }
49 }
50 
51 fn unmarshal(raw: &Bytes) -> Result<Self> {
52 let header = ChunkHeader::unmarshal(raw)?;
53 
54 if header.typ != CT_HEARTBEAT {
55 return Err(Error::ErrChunkTypeNotHeartbeat);
56 }
57 
58 if header.value_length() < PARAM_HEADER_LENGTH {
59 return Err(Error::ErrHeartbeatNotLongEnoughInfo);
60 }
61 
62 let p =
63 build_param(&raw.slice(CHUNK_HEADER_SIZE..CHUNK_HEADER_SIZE + header.value_length()))?;
64 if p.header().typ != ParamType::HeartbeatInfo {
65 return Err(Error::ErrHeartbeatParam);
66 }
67 let params = vec![p];
68 
69 Ok(ChunkHeartbeat { params })
70 }
71 
72 fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize> {
73 self.header().marshal_to(buf)?;
74 for p in &self.params {
75 buf.extend(p.marshal()?);
76 }
77 Ok(buf.len())
78 }
79 
80 fn check(&self) -> Result<()> {
81 Ok(())
82 }
83 
84 fn value_length(&self) -> usize {
85 self.params.iter().fold(0, |length, p| {
86 length + PARAM_HEADER_LENGTH + p.value_length()
87 })
88 }
89 
90 fn as_any(&self) -> &(dyn Any + Send + Sync) {
91 self
92 }
93}