rtc_dtls/record_layer/
record_layer_header.rs1use crate::content::*;
11
12use shared::error::*;
13
14use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
15use std::io::{Read, Write};
16
17pub const RECORD_LAYER_HEADER_SIZE: usize = 13;
19pub const MAX_SEQUENCE_NUMBER: u64 = 0x0000FFFFFFFFFFFF;
21
22pub const DTLS1_2MAJOR: u8 = 0xfe;
24pub const DTLS1_2MINOR: u8 = 0xfd;
26
27pub const DTLS1_0MAJOR: u8 = 0xfe;
29pub const DTLS1_0MINOR: u8 = 0xff;
31
32pub const VERSION_DTLS12: u16 = 0xfefd;
36
37pub const PROTOCOL_VERSION1_0: ProtocolVersion = ProtocolVersion {
39 major: DTLS1_0MAJOR,
40 minor: DTLS1_0MINOR,
41};
42pub const PROTOCOL_VERSION1_2: ProtocolVersion = ProtocolVersion {
44 major: DTLS1_2MAJOR,
45 minor: DTLS1_2MINOR,
46};
47
48#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
54pub struct ProtocolVersion {
55 pub major: u8,
57 pub minor: u8,
59}
60
61#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
62pub struct RecordLayerHeader {
64 pub content_type: ContentType,
66 pub protocol_version: ProtocolVersion,
68 pub epoch: u16,
70 pub sequence_number: u64, pub content_len: u16,
74}
75
76impl RecordLayerHeader {
77 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
83 if self.sequence_number > MAX_SEQUENCE_NUMBER {
84 return Err(Error::ErrSequenceNumberOverflow);
85 }
86
87 writer.write_u8(self.content_type as u8)?;
88 writer.write_u8(self.protocol_version.major)?;
89 writer.write_u8(self.protocol_version.minor)?;
90 writer.write_u16::<BigEndian>(self.epoch)?;
91
92 let be: [u8; 8] = self.sequence_number.to_be_bytes();
93 writer.write_all(&be[2..])?; writer.write_u16::<BigEndian>(self.content_len)?;
96
97 Ok(writer.flush()?)
98 }
99
100 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
106 let content_type = reader.read_u8()?.into();
107 let major = reader.read_u8()?;
108 let minor = reader.read_u8()?;
109 let epoch = reader.read_u16::<BigEndian>()?;
110
111 let mut be: [u8; 8] = [0u8; 8];
113 reader.read_exact(&mut be[2..])?;
114 let sequence_number = u64::from_be_bytes(be);
115
116 let protocol_version = ProtocolVersion { major, minor };
117 if protocol_version != PROTOCOL_VERSION1_0 && protocol_version != PROTOCOL_VERSION1_2 {
118 return Err(Error::ErrUnsupportedProtocolVersion);
119 }
120 let content_len = reader.read_u16::<BigEndian>()?;
121
122 Ok(RecordLayerHeader {
123 content_type,
124 protocol_version,
125 epoch,
126 sequence_number,
127 content_len,
128 })
129 }
130}