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 { 21 fn header(&self) -> Header; 22 fn destination_ssrc(&self) -> Vec<u32>; 23 fn raw_size(&self) -> usize; 24 fn as_any(&self) -> &(dyn Any + Send + Sync); 25 fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool; 26 fn cloned(&self) -> Box<dyn Packet + Send + Sync>; 27 } 28 29 impl PartialEq for dyn Packet + Send + Sync { 30 fn eq(&self, other: &Self) -> bool { 31 self.equal(other) 32 } 33 } 34 35 impl Clone for 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 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. 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. 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] 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] 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!(want, got, "Unmarshal(nil) err = {}, want {}", got, want); 214 } else { 215 panic!("want error"); 216 } 217 218 Ok(()) 219 } 220 221 #[test] 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 want, got, 234 "Unmarshal(invalid_header_length) err = {}, want {}", 235 got, want 236 ); 237 } else { 238 panic!("want error"); 239 } 240 241 Ok(()) 242 } 243 #[test] 244 fn test_packet_unmarshal_firefox() -> Result<()> { 245 // issue report from https://github.com/webrtc-rs/srtp/issues/7 246 let tests = vec![ 247 Bytes::from_static(&[ 248 143, 205, 0, 6, 65, 227, 184, 49, 118, 243, 78, 96, 42, 63, 0, 5, 12, 162, 166, 0, 249 32, 5, 200, 4, 0, 4, 0, 0, 250 ]), 251 Bytes::from_static(&[ 252 143, 205, 0, 9, 65, 227, 184, 49, 118, 243, 78, 96, 42, 68, 0, 17, 12, 162, 167, 1, 253 32, 17, 88, 0, 4, 0, 4, 8, 108, 0, 4, 0, 4, 12, 0, 4, 0, 4, 4, 0, 254 ]), 255 Bytes::from_static(&[ 256 143, 205, 0, 8, 65, 227, 184, 49, 118, 243, 78, 96, 42, 91, 0, 12, 12, 162, 168, 3, 257 32, 12, 220, 4, 0, 4, 0, 8, 128, 4, 0, 4, 0, 8, 0, 0, 258 ]), 259 Bytes::from_static(&[ 260 143, 205, 0, 7, 65, 227, 184, 49, 118, 243, 78, 96, 42, 103, 0, 8, 12, 162, 169, 4, 261 32, 8, 232, 4, 0, 4, 0, 4, 4, 0, 0, 0, 262 ]), 263 ]; 264 265 for mut test in tests { 266 unmarshal(&mut test)?; 267 } 268 269 Ok(()) 270 } 271 } 272