xref: /webrtc/rtcp/src/packet.rs (revision 5d8fe953)
1 use crate::error::Result;
2 use crate::{
3     error::Error, goodbye::*, header::*, payload_feedbacks::full_intra_request::*,
4     payload_feedbacks::picture_loss_indication::*,
5     payload_feedbacks::receiver_estimated_maximum_bitrate::*,
6     payload_feedbacks::slice_loss_indication::*, raw_packet::*, receiver_report::*,
7     sender_report::*, source_description::*,
8     transport_feedbacks::rapid_resynchronization_request::*,
9     transport_feedbacks::transport_layer_cc::*, transport_feedbacks::transport_layer_nack::*,
10 };
11 use util::marshal::{Marshal, Unmarshal};
12 
13 use crate::extended_report::ExtendedReport;
14 use bytes::{Buf, BufMut, Bytes, BytesMut};
15 use std::any::Any;
16 use std::fmt;
17 
18 /// Packet represents an RTCP packet, a protocol used for out-of-band statistics and
19 /// control information for an RTP session
20 pub trait Packet: Marshal + Unmarshal + fmt::Display + fmt::Debug {
header(&self) -> Header21     fn header(&self) -> Header;
destination_ssrc(&self) -> Vec<u32>22     fn destination_ssrc(&self) -> Vec<u32>;
raw_size(&self) -> usize23     fn raw_size(&self) -> usize;
as_any(&self) -> &(dyn Any + Send + Sync)24     fn as_any(&self) -> &(dyn Any + Send + Sync);
equal(&self, other: &(dyn Packet + Send + Sync)) -> bool25     fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool;
cloned(&self) -> Box<dyn Packet + Send + Sync>26     fn cloned(&self) -> Box<dyn Packet + Send + Sync>;
27 }
28 
29 impl PartialEq for dyn Packet + Send + Sync {
eq(&self, other: &Self) -> bool30     fn eq(&self, other: &Self) -> bool {
31         self.equal(other)
32     }
33 }
34 
35 impl Clone for Box<dyn Packet + Send + Sync> {
clone(&self) -> Box<dyn Packet + Send + Sync>36     fn clone(&self) -> Box<dyn Packet + Send + Sync> {
37         self.cloned()
38     }
39 }
40 
41 /// marshal takes an array of Packets and serializes them to a single buffer
marshal(packets: &[Box<dyn Packet + Send + Sync>]) -> Result<Bytes>42 pub fn marshal(packets: &[Box<dyn Packet + Send + Sync>]) -> Result<Bytes> {
43     let mut out = BytesMut::new();
44     for p in packets {
45         let data = p.marshal()?;
46         out.put(data);
47     }
48     Ok(out.freeze())
49 }
50 
51 /// Unmarshal takes an entire udp datagram (which may consist of multiple RTCP packets) and
52 /// returns the unmarshaled packets it contains.
53 ///
54 /// If this is a reduced-size RTCP packet a feedback packet (Goodbye, SliceLossIndication, etc)
55 /// will be returned. Otherwise, the underlying type of the returned packet will be
56 /// CompoundPacket.
unmarshal<B>(raw_data: &mut B) -> Result<Vec<Box<dyn Packet + Send + Sync>>> where B: Buf,57 pub fn unmarshal<B>(raw_data: &mut B) -> Result<Vec<Box<dyn Packet + Send + Sync>>>
58 where
59     B: Buf,
60 {
61     let mut packets = vec![];
62 
63     while raw_data.has_remaining() {
64         let p = unmarshaller(raw_data)?;
65         packets.push(p);
66     }
67 
68     match packets.len() {
69         // Empty Packet
70         0 => Err(Error::InvalidHeader),
71 
72         // Multiple Packet
73         _ => Ok(packets),
74     }
75 }
76 
77 /// unmarshaller is a factory which pulls the first RTCP packet from a bytestream,
78 /// and returns it's parsed representation, and the amount of data that was processed.
unmarshaller<B>(raw_data: &mut B) -> Result<Box<dyn Packet + Send + Sync>> where B: Buf,79 pub(crate) fn unmarshaller<B>(raw_data: &mut B) -> Result<Box<dyn Packet + Send + Sync>>
80 where
81     B: Buf,
82 {
83     let h = Header::unmarshal(raw_data)?;
84 
85     let length = (h.length as usize) * 4;
86     if length > raw_data.remaining() {
87         return Err(Error::PacketTooShort);
88     }
89 
90     let mut in_packet = h.marshal()?.chain(raw_data.take(length));
91 
92     let p: Box<dyn Packet + Send + Sync> = match h.packet_type {
93         PacketType::SenderReport => Box::new(SenderReport::unmarshal(&mut in_packet)?),
94         PacketType::ReceiverReport => Box::new(ReceiverReport::unmarshal(&mut in_packet)?),
95         PacketType::SourceDescription => Box::new(SourceDescription::unmarshal(&mut in_packet)?),
96         PacketType::Goodbye => Box::new(Goodbye::unmarshal(&mut in_packet)?),
97 
98         PacketType::TransportSpecificFeedback => match h.count {
99             FORMAT_TLN => Box::new(TransportLayerNack::unmarshal(&mut in_packet)?),
100             FORMAT_RRR => Box::new(RapidResynchronizationRequest::unmarshal(&mut in_packet)?),
101             FORMAT_TCC => Box::new(TransportLayerCc::unmarshal(&mut in_packet)?),
102             _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
103         },
104         PacketType::PayloadSpecificFeedback => match h.count {
105             FORMAT_PLI => Box::new(PictureLossIndication::unmarshal(&mut in_packet)?),
106             FORMAT_SLI => Box::new(SliceLossIndication::unmarshal(&mut in_packet)?),
107             FORMAT_REMB => Box::new(ReceiverEstimatedMaximumBitrate::unmarshal(&mut in_packet)?),
108             FORMAT_FIR => Box::new(FullIntraRequest::unmarshal(&mut in_packet)?),
109             _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
110         },
111         PacketType::ExtendedReport => Box::new(ExtendedReport::unmarshal(&mut in_packet)?),
112         _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
113     };
114 
115     Ok(p)
116 }
117 
118 #[cfg(test)]
119 mod test {
120     use super::*;
121     use crate::reception_report::*;
122     use bytes::Bytes;
123 
124     #[test]
test_packet_unmarshal()125     fn test_packet_unmarshal() {
126         let mut data = Bytes::from_static(&[
127             // Receiver Report (offset=0)
128             0x81, 0xc9, 0x0, 0x7, // v=2, p=0, count=1, RR, len=7
129             0x90, 0x2f, 0x9e, 0x2e, // ssrc=0x902f9e2e
130             0xbc, 0x5e, 0x9a, 0x40, // ssrc=0xbc5e9a40
131             0x0, 0x0, 0x0, 0x0, // fracLost=0, totalLost=0
132             0x0, 0x0, 0x46, 0xe1, // lastSeq=0x46e1
133             0x0, 0x0, 0x1, 0x11, // jitter=273
134             0x9, 0xf3, 0x64, 0x32, // lsr=0x9f36432
135             0x0, 0x2, 0x4a, 0x79, // delay=150137
136             // Source Description (offset=32)
137             0x81, 0xca, 0x0, 0xc, // v=2, p=0, count=1, SDES, len=12
138             0x90, 0x2f, 0x9e, 0x2e, // ssrc=0x902f9e2e
139             0x1, 0x26, // CNAME, len=38
140             0x7b, 0x39, 0x63, 0x30, 0x30, 0x65, 0x62, 0x39, 0x32, 0x2d, 0x31, 0x61, 0x66, 0x62,
141             0x2d, 0x39, 0x64, 0x34, 0x39, 0x2d, 0x61, 0x34, 0x37, 0x64, 0x2d, 0x39, 0x31, 0x66,
142             0x36, 0x34, 0x65, 0x65, 0x65, 0x36, 0x39, 0x66, 0x35,
143             0x7d, // text="{9c00eb92-1afb-9d49-a47d-91f64eee69f5}"
144             0x0, 0x0, 0x0, 0x0, // END + padding
145             // Goodbye (offset=84)
146             0x81, 0xcb, 0x0, 0x1, // v=2, p=0, count=1, BYE, len=1
147             0x90, 0x2f, 0x9e, 0x2e, // source=0x902f9e2e
148             0x81, 0xce, 0x0, 0x2, // Picture Loss Indication (offset=92)
149             0x90, 0x2f, 0x9e, 0x2e, // sender=0x902f9e2e
150             0x90, 0x2f, 0x9e, 0x2e, // media=0x902f9e2e
151             0x85, 0xcd, 0x0, 0x2, // RapidResynchronizationRequest (offset=104)
152             0x90, 0x2f, 0x9e, 0x2e, // sender=0x902f9e2e
153             0x90, 0x2f, 0x9e, 0x2e, // media=0x902f9e2e
154         ]);
155 
156         let packet = unmarshal(&mut data).expect("Error unmarshalling packets");
157 
158         let a = ReceiverReport {
159             ssrc: 0x902f9e2e,
160             reports: vec![ReceptionReport {
161                 ssrc: 0xbc5e9a40,
162                 fraction_lost: 0,
163                 total_lost: 0,
164                 last_sequence_number: 0x46e1,
165                 jitter: 273,
166                 last_sender_report: 0x9f36432,
167                 delay: 150137,
168             }],
169             ..Default::default()
170         };
171 
172         let b = SourceDescription {
173             chunks: vec![SourceDescriptionChunk {
174                 source: 0x902f9e2e,
175                 items: vec![SourceDescriptionItem {
176                     sdes_type: SdesType::SdesCname,
177                     text: Bytes::from_static(b"{9c00eb92-1afb-9d49-a47d-91f64eee69f5}"),
178                 }],
179             }],
180         };
181 
182         let c = Goodbye {
183             sources: vec![0x902f9e2e],
184             ..Default::default()
185         };
186 
187         let d = PictureLossIndication {
188             sender_ssrc: 0x902f9e2e,
189             media_ssrc: 0x902f9e2e,
190         };
191 
192         let e = RapidResynchronizationRequest {
193             sender_ssrc: 0x902f9e2e,
194             media_ssrc: 0x902f9e2e,
195         };
196 
197         let expected: Vec<Box<dyn Packet + Send + Sync>> = vec![
198             Box::new(a),
199             Box::new(b),
200             Box::new(c),
201             Box::new(d),
202             Box::new(e),
203         ];
204 
205         assert!(packet == expected, "Invalid packets");
206     }
207 
208     #[test]
test_packet_unmarshal_empty() -> Result<()>209     fn test_packet_unmarshal_empty() -> Result<()> {
210         let result = unmarshal(&mut Bytes::new());
211         if let Err(got) = result {
212             let want = Error::InvalidHeader;
213             assert_eq!(got, want, "Unmarshal(nil) err = {got}, want {want}");
214         } else {
215             panic!("want error");
216         }
217 
218         Ok(())
219     }
220 
221     #[test]
test_packet_invalid_header_length() -> Result<()>222     fn test_packet_invalid_header_length() -> Result<()> {
223         let mut data = Bytes::from_static(&[
224             // Goodbye (offset=84)
225             // v=2, p=0, count=1, BYE, len=100
226             0x81, 0xcb, 0x0, 0x64,
227         ]);
228 
229         let result = unmarshal(&mut data);
230         if let Err(got) = result {
231             let want = Error::PacketTooShort;
232             assert_eq!(
233                 got, want,
234                 "Unmarshal(invalid_header_length) err = {got}, want {want}"
235             );
236         } else {
237             panic!("want error");
238         }
239 
240         Ok(())
241     }
242     #[test]
test_packet_unmarshal_firefox() -> Result<()>243     fn test_packet_unmarshal_firefox() -> Result<()> {
244         // issue report from https://github.com/webrtc-rs/srtp/issues/7
245         let tests = vec![
246             Bytes::from_static(&[
247                 143, 205, 0, 6, 65, 227, 184, 49, 118, 243, 78, 96, 42, 63, 0, 5, 12, 162, 166, 0,
248                 32, 5, 200, 4, 0, 4, 0, 0,
249             ]),
250             Bytes::from_static(&[
251                 143, 205, 0, 9, 65, 227, 184, 49, 118, 243, 78, 96, 42, 68, 0, 17, 12, 162, 167, 1,
252                 32, 17, 88, 0, 4, 0, 4, 8, 108, 0, 4, 0, 4, 12, 0, 4, 0, 4, 4, 0,
253             ]),
254             Bytes::from_static(&[
255                 143, 205, 0, 8, 65, 227, 184, 49, 118, 243, 78, 96, 42, 91, 0, 12, 12, 162, 168, 3,
256                 32, 12, 220, 4, 0, 4, 0, 8, 128, 4, 0, 4, 0, 8, 0, 0,
257             ]),
258             Bytes::from_static(&[
259                 143, 205, 0, 7, 65, 227, 184, 49, 118, 243, 78, 96, 42, 103, 0, 8, 12, 162, 169, 4,
260                 32, 8, 232, 4, 0, 4, 0, 4, 4, 0, 0, 0,
261             ]),
262         ];
263 
264         for mut test in tests {
265             unmarshal(&mut test)?;
266         }
267 
268         Ok(())
269     }
270 }
271