rtc_dtls/record_layer/
mod.rs1pub mod record_layer_header;
2
3#[cfg(test)]
4mod record_layer_test;
5
6use super::content::*;
7use crate::alert::Alert;
8use crate::application_data::ApplicationData;
9use crate::change_cipher_spec::ChangeCipherSpec;
10use crate::handshake::Handshake;
11use record_layer_header::*;
12use shared::error::*;
13
14use std::io::{Read, Write};
15
16#[derive(Debug, Clone, PartialEq)]
33pub struct RecordLayer {
34 pub record_layer_header: RecordLayerHeader,
35 pub content: Content,
36}
37
38impl RecordLayer {
39 pub fn new(protocol_version: ProtocolVersion, epoch: u16, content: Content) -> Self {
40 RecordLayer {
41 record_layer_header: RecordLayerHeader {
42 content_type: content.content_type(),
43 protocol_version,
44 epoch,
45 sequence_number: 0,
46 content_len: content.size() as u16,
47 },
48 content,
49 }
50 }
51
52 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
53 self.record_layer_header.marshal(writer)?;
54 self.content.marshal(writer)?;
55 Ok(())
56 }
57
58 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
59 let record_layer_header = RecordLayerHeader::unmarshal(reader)?;
60 let content = match record_layer_header.content_type {
61 ContentType::Alert => Content::Alert(Alert::unmarshal(reader)?),
62 ContentType::ApplicationData => {
63 Content::ApplicationData(ApplicationData::unmarshal(reader)?)
64 }
65 ContentType::ChangeCipherSpec => {
66 Content::ChangeCipherSpec(ChangeCipherSpec::unmarshal(reader)?)
67 }
68 ContentType::Handshake => Content::Handshake(Handshake::unmarshal(reader)?),
69 _ => return Err(Error::Other("Invalid Content Type".to_owned())),
70 };
71
72 Ok(RecordLayer {
73 record_layer_header,
74 content,
75 })
76 }
77}
78
79pub(crate) fn unpack_datagram(buf: &[u8]) -> Result<Vec<Vec<u8>>> {
86 let mut out = vec![];
87
88 let mut offset = 0;
89 while buf.len() != offset {
90 if buf.len() - offset <= RECORD_LAYER_HEADER_SIZE {
91 return Err(Error::ErrInvalidPacketLength);
92 }
93
94 let pkt_len = RECORD_LAYER_HEADER_SIZE
95 + (((buf[offset + RECORD_LAYER_HEADER_SIZE - 2] as usize) << 8)
96 | buf[offset + RECORD_LAYER_HEADER_SIZE - 1] as usize);
97 if offset + pkt_len > buf.len() {
98 return Err(Error::ErrInvalidPacketLength);
99 }
100
101 out.push(buf[offset..offset + pkt_len].to_vec());
102 offset += pkt_len
103 }
104
105 Ok(out)
106}