rtc_dtls/record_layer/
mod.rs1pub mod record_layer_header;
3
4#[cfg(test)]
5mod record_layer_test;
6
7use super::content::*;
8use crate::alert::Alert;
9use crate::application_data::ApplicationData;
10use crate::change_cipher_spec::ChangeCipherSpec;
11use crate::handshake::Handshake;
12use record_layer_header::*;
13use shared::error::*;
14
15use std::io::{Read, Write};
16
17#[derive(Debug, Clone, PartialEq)]
38pub struct RecordLayer {
39 pub record_layer_header: RecordLayerHeader,
41 pub content: Content,
43}
44
45impl RecordLayer {
46 pub fn new(protocol_version: ProtocolVersion, epoch: u16, content: Content) -> Self {
48 RecordLayer {
49 record_layer_header: RecordLayerHeader {
50 content_type: content.content_type(),
51 protocol_version,
52 epoch,
53 sequence_number: 0,
54 content_len: content.size() as u16,
55 },
56 content,
57 }
58 }
59
60 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
66 self.record_layer_header.marshal(writer)?;
67 self.content.marshal(writer)?;
68 Ok(())
69 }
70
71 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
77 let record_layer_header = RecordLayerHeader::unmarshal(reader)?;
78 let content = match record_layer_header.content_type {
79 ContentType::Alert => Content::Alert(Alert::unmarshal(reader)?),
80 ContentType::ApplicationData => {
81 Content::ApplicationData(ApplicationData::unmarshal(reader)?)
82 }
83 ContentType::ChangeCipherSpec => {
84 Content::ChangeCipherSpec(ChangeCipherSpec::unmarshal(reader)?)
85 }
86 ContentType::Handshake => Content::Handshake(Handshake::unmarshal(reader)?),
87 _ => return Err(Error::Other("Invalid Content Type".to_owned())),
88 };
89
90 Ok(RecordLayer {
91 record_layer_header,
92 content,
93 })
94 }
95}
96
97pub(crate) fn unpack_datagram(buf: &[u8]) -> Result<Vec<Vec<u8>>> {
104 let mut out = vec![];
105
106 let mut offset = 0;
107 while buf.len() != offset {
108 if buf.len() - offset <= RECORD_LAYER_HEADER_SIZE {
109 return Err(Error::ErrInvalidPacketLength);
110 }
111
112 let pkt_len = RECORD_LAYER_HEADER_SIZE
113 + (((buf[offset + RECORD_LAYER_HEADER_SIZE - 2] as usize) << 8)
114 | buf[offset + RECORD_LAYER_HEADER_SIZE - 1] as usize);
115 if offset + pkt_len > buf.len() {
116 return Err(Error::ErrInvalidPacketLength);
117 }
118
119 out.push(buf[offset..offset + pkt_len].to_vec());
120 offset += pkt_len
121 }
122
123 Ok(out)
124}