rtc_dtls/record_layer/
record_layer_header.rs1use crate::content::*;
2
3use shared::error::*;
4
5use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
6use std::io::{Read, Write};
7
8pub const RECORD_LAYER_HEADER_SIZE: usize = 13;
9pub const MAX_SEQUENCE_NUMBER: u64 = 0x0000FFFFFFFFFFFF;
10
11pub const DTLS1_2MAJOR: u8 = 0xfe;
12pub const DTLS1_2MINOR: u8 = 0xfd;
13
14pub const DTLS1_0MAJOR: u8 = 0xfe;
15pub const DTLS1_0MINOR: u8 = 0xff;
16
17pub const VERSION_DTLS12: u16 = 0xfefd;
20
21pub const PROTOCOL_VERSION1_0: ProtocolVersion = ProtocolVersion {
22 major: DTLS1_0MAJOR,
23 minor: DTLS1_0MINOR,
24};
25pub const PROTOCOL_VERSION1_2: ProtocolVersion = ProtocolVersion {
26 major: DTLS1_2MAJOR,
27 minor: DTLS1_2MINOR,
28};
29
30#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
36pub struct ProtocolVersion {
37 pub major: u8,
38 pub minor: u8,
39}
40
41#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
42pub struct RecordLayerHeader {
43 pub content_type: ContentType,
44 pub protocol_version: ProtocolVersion,
45 pub epoch: u16,
46 pub sequence_number: u64, pub content_len: u16,
48}
49
50impl RecordLayerHeader {
51 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
52 if self.sequence_number > MAX_SEQUENCE_NUMBER {
53 return Err(Error::ErrSequenceNumberOverflow);
54 }
55
56 writer.write_u8(self.content_type as u8)?;
57 writer.write_u8(self.protocol_version.major)?;
58 writer.write_u8(self.protocol_version.minor)?;
59 writer.write_u16::<BigEndian>(self.epoch)?;
60
61 let be: [u8; 8] = self.sequence_number.to_be_bytes();
62 writer.write_all(&be[2..])?; writer.write_u16::<BigEndian>(self.content_len)?;
65
66 Ok(writer.flush()?)
67 }
68
69 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
70 let content_type = reader.read_u8()?.into();
71 let major = reader.read_u8()?;
72 let minor = reader.read_u8()?;
73 let epoch = reader.read_u16::<BigEndian>()?;
74
75 let mut be: [u8; 8] = [0u8; 8];
77 reader.read_exact(&mut be[2..])?;
78 let sequence_number = u64::from_be_bytes(be);
79
80 let protocol_version = ProtocolVersion { major, minor };
81 if protocol_version != PROTOCOL_VERSION1_0 && protocol_version != PROTOCOL_VERSION1_2 {
82 return Err(Error::ErrUnsupportedProtocolVersion);
83 }
84 let content_len = reader.read_u16::<BigEndian>()?;
85
86 Ok(RecordLayerHeader {
87 content_type,
88 protocol_version,
89 epoch,
90 sequence_number,
91 content_len,
92 })
93 }
94}