rtcp/
packet.rs

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