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)]
37pub struct RecordLayer {
38 pub record_layer_header: RecordLayerHeader,
39 pub content: Content,
40}
41
42impl RecordLayer {
43 pub fn new(protocol_version: ProtocolVersion, epoch: u16, content: Content) -> Self {
44 RecordLayer {
45 record_layer_header: RecordLayerHeader {
46 content_type: content.content_type(),
47 protocol_version,
48 epoch,
49 sequence_number: 0,
50 content_len: content.size() as u16,
51 },
52 content,
53 }
54 }
55
56 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
57 self.record_layer_header.marshal(writer)?;
58 self.content.marshal(writer)?;
59 Ok(())
60 }
61
62 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
63 let record_layer_header = RecordLayerHeader::unmarshal(reader)?;
64 let content = match record_layer_header.content_type {
65 ContentType::Alert => Content::Alert(Alert::unmarshal(reader)?),
66 ContentType::ApplicationData => {
67 Content::ApplicationData(ApplicationData::unmarshal(reader)?)
68 }
69 ContentType::ChangeCipherSpec => {
70 Content::ChangeCipherSpec(ChangeCipherSpec::unmarshal(reader)?)
71 }
72 ContentType::Handshake => Content::Handshake(Handshake::unmarshal(reader)?),
73 _ => return Err(Error::Other("Invalid Content Type".to_owned())),
74 };
75
76 Ok(RecordLayer {
77 record_layer_header,
78 content,
79 })
80 }
81}
82
83pub(crate) fn unpack_datagram(buf: &[u8]) -> Result<Vec<Vec<u8>>> {
90 let mut out = vec![];
91
92 let mut offset = 0;
93 while buf.len() != offset {
94 if buf.len() - offset <= RECORD_LAYER_HEADER_SIZE {
95 return Err(Error::ErrInvalidPacketLength);
96 }
97
98 let pkt_len = RECORD_LAYER_HEADER_SIZE
99 + (((buf[offset + RECORD_LAYER_HEADER_SIZE - 2] as usize) << 8)
100 | buf[offset + RECORD_LAYER_HEADER_SIZE - 1] as usize);
101 if offset + pkt_len > buf.len() {
102 return Err(Error::ErrInvalidPacketLength);
103 }
104
105 out.push(buf[offset..offset + pkt_len].to_vec());
106 offset += pkt_len
107 }
108
109 Ok(out)
110}