rtc_dtls/application_data.rs
1use bytes::{Bytes, BytesMut};
2use std::io::{Read, Write};
3
4use super::content::*;
5use shared::error::Result;
6
7// Application data messages are carried by the record layer and are
8// fragmented, compressed, and encrypted based on the current connection
9// state. The messages are treated as transparent data to the record
10// layer.
11/// ## Specifications
12///
13/// * [RFC 5246 §10]
14///
15/// [RFC 5246 §10]: https://tools.ietf.org/html/rfc5246#section-10
16#[derive(Clone, PartialEq, Eq, Debug)]
17pub struct ApplicationData {
18 /// The application payload.
19 pub data: BytesMut,
20}
21
22impl ApplicationData {
23 /// The record content type this message is carried in.
24 pub fn content_type(&self) -> ContentType {
25 ContentType::ApplicationData
26 }
27
28 /// The encoded size of this message in bytes.
29 pub fn size(&self) -> usize {
30 self.data.len()
31 }
32
33 /// Encodes this message to `writer`.
34 ///
35 /// # Errors
36 ///
37 /// Fails on a write error, or if a field exceeds the length its wire format allows.
38 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
39 writer.write_all(&self.data)?;
40
41 Ok(writer.flush()?)
42 }
43
44 /// Decodes one of these messages from `reader`.
45 ///
46 /// # Errors
47 ///
48 /// Fails if `reader` is truncated or its contents are not a valid encoding.
49 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
50 // Read straight into the BytesMut-backed Vec instead of staging in a
51 // temporary Vec and copying the whole payload a second time.
52 let mut data: Vec<u8> = vec![];
53 reader.read_to_end(&mut data)?;
54
55 // `Bytes::from(Vec)` is zero-copy and the buffer is uniquely owned
56 // here, so `try_into_mut` succeeds without the second full-payload
57 // copy the old `BytesMut::from(&data[..])` performed.
58 Ok(ApplicationData {
59 data: Bytes::from(data)
60 .try_into_mut()
61 .unwrap_or_else(|b| BytesMut::from(&b[..])),
62 })
63 }
64}