Apply rustfmt-0.99.4
parent
88b02115fc
commit
4cbba5358c
|
@ -6,37 +6,48 @@ extern crate trackable;
|
||||||
extern crate rtp;
|
extern crate rtp;
|
||||||
|
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use fibers::{Spawn, Executor, InPlaceExecutor};
|
|
||||||
use fibers::net::UdpSocket;
|
|
||||||
use fibers::net::futures::RecvFrom;
|
use fibers::net::futures::RecvFrom;
|
||||||
use futures::{Future, Poll, Async};
|
use fibers::net::UdpSocket;
|
||||||
use trackable::error::ErrorKindExt;
|
use fibers::{Executor, InPlaceExecutor, Spawn};
|
||||||
use rtp::{Error, ErrorKind};
|
use futures::{Async, Future, Poll};
|
||||||
use rtp::traits::ReadPacket;
|
|
||||||
use rtp::rfc3550::RtpPacketReader;
|
use rtp::rfc3550::RtpPacketReader;
|
||||||
use rtp::rfc3711::{SrtpPacketReader, SrtpContext};
|
use rtp::rfc3711::{SrtpContext, SrtpPacketReader};
|
||||||
|
use rtp::traits::ReadPacket;
|
||||||
|
use rtp::{Error, ErrorKind};
|
||||||
|
use trackable::error::ErrorKindExt;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("srtpsrv")
|
let matches = App::new("srtpsrv")
|
||||||
.arg(Arg::with_name("PORT").short("p").takes_value(true).default_value("6000"))
|
.arg(
|
||||||
.arg(Arg::with_name("MASTER_KEY").short("k").takes_value(true)
|
Arg::with_name("PORT")
|
||||||
.default_value("d34d74f37d74e75f3bdb4f76f1bdf477"))
|
.short("p")
|
||||||
.arg(Arg::with_name("MASTER_SALT").short("s").takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("7f1fe35d78f77e75e79f7beb5f7a"))
|
.default_value("6000"),
|
||||||
.get_matches();
|
).arg(
|
||||||
|
Arg::with_name("MASTER_KEY")
|
||||||
|
.short("k")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("d34d74f37d74e75f3bdb4f76f1bdf477"),
|
||||||
|
).arg(
|
||||||
|
Arg::with_name("MASTER_SALT")
|
||||||
|
.short("s")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("7f1fe35d78f77e75e79f7beb5f7a"),
|
||||||
|
).get_matches();
|
||||||
let port = matches.value_of("PORT").unwrap();
|
let port = matches.value_of("PORT").unwrap();
|
||||||
let addr = format!("0.0.0.0:{}", port).parse().unwrap();
|
let addr = format!("0.0.0.0:{}", port).parse().unwrap();
|
||||||
|
|
||||||
let master_key = hex_str_to_bytes(matches.value_of("MASTER_KEY").unwrap());
|
let master_key = hex_str_to_bytes(matches.value_of("MASTER_KEY").unwrap());
|
||||||
let master_salt = hex_str_to_bytes(matches.value_of("MASTER_SALT").unwrap());
|
let master_salt = hex_str_to_bytes(matches.value_of("MASTER_SALT").unwrap());
|
||||||
let context = SrtpContext::new(&master_key, &master_salt);
|
let context = SrtpContext::new(&master_key, &master_salt);
|
||||||
let future = track_err!(UdpSocket::bind(addr)).and_then(move |socket| {
|
let future = track_err!(UdpSocket::bind(addr))
|
||||||
SrtpRecvLoop::new(socket, context)
|
.and_then(move |socket| SrtpRecvLoop::new(socket, context));
|
||||||
});
|
|
||||||
|
|
||||||
let mut executor = InPlaceExecutor::new().unwrap();
|
let mut executor = InPlaceExecutor::new().unwrap();
|
||||||
let monitor = executor.spawn_monitor(future);
|
let monitor = executor.spawn_monitor(future);
|
||||||
let result = executor.run_fiber(monitor).unwrap()
|
let result = executor
|
||||||
|
.run_fiber(monitor)
|
||||||
|
.unwrap()
|
||||||
.map_err(|e| e.unwrap_or_else(|| ErrorKind::Other.cause("disconnected")));
|
.map_err(|e| e.unwrap_or_else(|| ErrorKind::Other.cause("disconnected")));
|
||||||
track_try_unwrap!(result);
|
track_try_unwrap!(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
use trackable::error::{TrackableError, IntoTrackableError};
|
|
||||||
use trackable::error::{ErrorKind as TrackableErrorKind, ErrorKindExt};
|
use trackable::error::{ErrorKind as TrackableErrorKind, ErrorKindExt};
|
||||||
|
use trackable::error::{IntoTrackableError, TrackableError};
|
||||||
|
|
||||||
pub type Error = TrackableError<ErrorKind>;
|
pub type Error = TrackableError<ErrorKind>;
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate trackable;
|
extern crate trackable;
|
||||||
extern crate handy_async;
|
|
||||||
extern crate crypto;
|
extern crate crypto;
|
||||||
|
extern crate handy_async;
|
||||||
extern crate num;
|
extern crate num;
|
||||||
extern crate splay_tree;
|
extern crate splay_tree;
|
||||||
|
|
||||||
pub use error::{Error, ErrorKind};
|
pub use error::{Error, ErrorKind};
|
||||||
|
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod traits;
|
|
||||||
pub mod rfc3550;
|
pub mod rfc3550;
|
||||||
pub mod rfc3711;
|
pub mod rfc3711;
|
||||||
pub mod rfc4585;
|
pub mod rfc4585;
|
||||||
pub mod rfc5761;
|
pub mod rfc5761;
|
||||||
|
pub mod traits;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
pub use self::rtp::{RtpPacket, RtpFixedHeader, RtpHeaderExtension, RtpPacketReader};
|
pub use self::rtp::{RtpFixedHeader, RtpHeaderExtension, RtpPacket, RtpPacketReader};
|
||||||
|
|
||||||
pub use self::rtcp::{RtcpPacket, RtcpSenderReport, RtcpReceiverReport, RtcpPacketReader};
|
pub use self::rtcp::{ReceptionReport, RtcpCompoundPacket, SdesChunk, SdesItem};
|
||||||
pub use self::rtcp::{RtcpSourceDescription, RtcpGoodbye, RtcpApplicationDefined};
|
pub use self::rtcp::{RtcpApplicationDefined, RtcpGoodbye, RtcpSourceDescription};
|
||||||
pub use self::rtcp::{RtcpCompoundPacket, ReceptionReport, SdesChunk, SdesItem};
|
pub use self::rtcp::{RtcpPacket, RtcpPacketReader, RtcpReceiverReport, RtcpSenderReport};
|
||||||
|
|
||||||
pub use self::rtcp::{RTCP_PACKET_TYPE_SR, RTCP_PACKET_TYPE_RR, RTCP_PACKET_TYPE_SDES};
|
pub use self::rtcp::{RTCP_PACKET_TYPE_APP, RTCP_PACKET_TYPE_BYE};
|
||||||
pub use self::rtcp::{RTCP_PACKET_TYPE_BYE, RTCP_PACKET_TYPE_APP};
|
pub use self::rtcp::{RTCP_PACKET_TYPE_RR, RTCP_PACKET_TYPE_SDES, RTCP_PACKET_TYPE_SR};
|
||||||
pub use self::rtcp::{SDES_ITEM_TYPE_END, SDES_ITEM_TYPE_CNAME, SDES_ITEM_TYPE_NAME};
|
pub use self::rtcp::{SDES_ITEM_TYPE_CNAME, SDES_ITEM_TYPE_END, SDES_ITEM_TYPE_NAME};
|
||||||
pub use self::rtcp::{SDES_ITEM_TYPE_EMAIL, SDES_ITEM_TYPE_PHONE, SDES_ITEM_TYPE_LOC};
|
pub use self::rtcp::{SDES_ITEM_TYPE_EMAIL, SDES_ITEM_TYPE_LOC, SDES_ITEM_TYPE_PHONE};
|
||||||
pub use self::rtcp::{SDES_ITEM_TYPE_TOOL, SDES_ITEM_TYPE_NOTE, SDES_ITEM_TYPE_PRIV};
|
pub use self::rtcp::{SDES_ITEM_TYPE_NOTE, SDES_ITEM_TYPE_PRIV, SDES_ITEM_TYPE_TOOL};
|
||||||
|
|
||||||
mod rtp;
|
|
||||||
mod rtcp;
|
mod rtcp;
|
||||||
|
mod rtp;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::io::{Read, Write};
|
|
||||||
use handy_async::sync_io::{ReadExt, WriteExt};
|
use handy_async::sync_io::{ReadExt, WriteExt};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use {Result, ErrorKind};
|
use constants::RTP_VERSION;
|
||||||
use io::{ReadFrom, WriteTo};
|
use io::{ReadFrom, WriteTo};
|
||||||
use traits::{self, Packet};
|
use traits::{self, Packet};
|
||||||
use types::{U5, U24, RtpTimestamp, NtpTimestamp, NtpMiddleTimetamp, Ssrc, SsrcOrCsrc};
|
use types::{NtpMiddleTimetamp, NtpTimestamp, RtpTimestamp, Ssrc, SsrcOrCsrc, U24, U5};
|
||||||
use constants::RTP_VERSION;
|
use {ErrorKind, Result};
|
||||||
|
|
||||||
pub const RTCP_PACKET_TYPE_SR: u8 = 200;
|
pub const RTCP_PACKET_TYPE_SR: u8 = 200;
|
||||||
pub const RTCP_PACKET_TYPE_RR: u8 = 201;
|
pub const RTCP_PACKET_TYPE_RR: u8 = 201;
|
||||||
|
@ -40,11 +40,11 @@ impl traits::ReadPacket for RtcpPacketReader {
|
||||||
}
|
}
|
||||||
fn supports_type(&self, ty: u8) -> bool {
|
fn supports_type(&self, ty: u8) -> bool {
|
||||||
match ty {
|
match ty {
|
||||||
RTCP_PACKET_TYPE_SR |
|
RTCP_PACKET_TYPE_SR
|
||||||
RTCP_PACKET_TYPE_RR |
|
| RTCP_PACKET_TYPE_RR
|
||||||
RTCP_PACKET_TYPE_SDES |
|
| RTCP_PACKET_TYPE_SDES
|
||||||
RTCP_PACKET_TYPE_BYE |
|
| RTCP_PACKET_TYPE_BYE
|
||||||
RTCP_PACKET_TYPE_APP => true,
|
| RTCP_PACKET_TYPE_APP => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,11 +103,11 @@ impl ReadFrom for RtcpPacket {
|
||||||
RTCP_PACKET_TYPE_APP => {
|
RTCP_PACKET_TYPE_APP => {
|
||||||
track_err!(RtcpApplicationDefined::read_from(reader).map(From::from))
|
track_err!(RtcpApplicationDefined::read_from(reader).map(From::from))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => track_panic!(
|
||||||
track_panic!(ErrorKind::Unsupported,
|
ErrorKind::Unsupported,
|
||||||
"Unknown packet type: {}",
|
"Unknown packet type: {}",
|
||||||
packet_type)
|
packet_type
|
||||||
}
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,21 +150,25 @@ impl From<RtcpApplicationDefined> for RtcpPacket {
|
||||||
|
|
||||||
fn read_sctp<R: Read>(reader: &mut R, expected_type: u8) -> Result<(U5, Vec<u8>)> {
|
fn read_sctp<R: Read>(reader: &mut R, expected_type: u8) -> Result<(U5, Vec<u8>)> {
|
||||||
let b = track_try!(reader.read_u8());
|
let b = track_try!(reader.read_u8());
|
||||||
track_assert_eq!(b >> 6,
|
track_assert_eq!(
|
||||||
|
b >> 6,
|
||||||
RTP_VERSION,
|
RTP_VERSION,
|
||||||
ErrorKind::Unsupported,
|
ErrorKind::Unsupported,
|
||||||
"Unsupported RTP version: {}",
|
"Unsupported RTP version: {}",
|
||||||
b >> 6);
|
b >> 6
|
||||||
|
);
|
||||||
let padding = (b & 0b0010_0000) != 0;
|
let padding = (b & 0b0010_0000) != 0;
|
||||||
let packet_specific = b & 0b0001_1111;
|
let packet_specific = b & 0b0001_1111;
|
||||||
|
|
||||||
let packet_type = track_try!(reader.read_u8());
|
let packet_type = track_try!(reader.read_u8());
|
||||||
track_assert_eq!(packet_type,
|
track_assert_eq!(
|
||||||
|
packet_type,
|
||||||
expected_type,
|
expected_type,
|
||||||
ErrorKind::Invalid,
|
ErrorKind::Invalid,
|
||||||
"Unexpected SCTP packet type: actual={}, expected={}",
|
"Unexpected SCTP packet type: actual={}, expected={}",
|
||||||
packet_type,
|
packet_type,
|
||||||
expected_type);
|
expected_type
|
||||||
|
);
|
||||||
|
|
||||||
let word_count = track_try!(reader.read_u16be()) as usize;
|
let word_count = track_try!(reader.read_u16be()) as usize;
|
||||||
let mut payload = track_try!(reader.read_bytes(word_count * 4));
|
let mut payload = track_try!(reader.read_bytes(word_count * 4));
|
||||||
|
@ -183,11 +187,12 @@ fn read_sctp<R: Read>(reader: &mut R, expected_type: u8) -> Result<(U5, Vec<u8>)
|
||||||
Ok((packet_specific, payload))
|
Ok((packet_specific, payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_sctp<W: Write>(writer: &mut W,
|
fn write_sctp<W: Write>(
|
||||||
|
writer: &mut W,
|
||||||
packet_type: u8,
|
packet_type: u8,
|
||||||
packet_specific: U5,
|
packet_specific: U5,
|
||||||
payload: &[u8])
|
payload: &[u8],
|
||||||
-> Result<()> {
|
) -> Result<()> {
|
||||||
track_assert_eq!(payload.len() % 4, 0, ErrorKind::Invalid);
|
track_assert_eq!(payload.len() % 4, 0, ErrorKind::Invalid);
|
||||||
|
|
||||||
track_try!(writer.write_u8(RTP_VERSION << 6 | packet_specific));
|
track_try!(writer.write_u8(RTP_VERSION << 6 | packet_specific));
|
||||||
|
@ -270,12 +275,16 @@ impl WriteTo for RtcpSenderReport {
|
||||||
}
|
}
|
||||||
payload.extend(&self.extensions);
|
payload.extend(&self.extensions);
|
||||||
|
|
||||||
track_assert!(self.reception_reports.len() <= 0x0001_1111,
|
track_assert!(
|
||||||
ErrorKind::Invalid);
|
self.reception_reports.len() <= 0x0001_1111,
|
||||||
track_try!(write_sctp(writer,
|
ErrorKind::Invalid
|
||||||
|
);
|
||||||
|
track_try!(write_sctp(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_SR,
|
RTCP_PACKET_TYPE_SR,
|
||||||
self.reception_reports.len() as u8,
|
self.reception_reports.len() as u8,
|
||||||
&payload));
|
&payload
|
||||||
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,12 +396,16 @@ impl WriteTo for RtcpReceiverReport {
|
||||||
}
|
}
|
||||||
payload.extend(&self.extensions);
|
payload.extend(&self.extensions);
|
||||||
|
|
||||||
track_assert!(self.reception_reports.len() <= 0b0001_1111,
|
track_assert!(
|
||||||
ErrorKind::Invalid);
|
self.reception_reports.len() <= 0b0001_1111,
|
||||||
track_try!(write_sctp(writer,
|
ErrorKind::Invalid
|
||||||
|
);
|
||||||
|
track_try!(write_sctp(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_RR,
|
RTCP_PACKET_TYPE_RR,
|
||||||
self.reception_reports.len() as u8,
|
self.reception_reports.len() as u8,
|
||||||
&payload));
|
&payload
|
||||||
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,7 +426,11 @@ impl ReadFrom for RtcpSourceDescription {
|
||||||
let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SDES));
|
let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SDES));
|
||||||
let reader = &mut &payload[..];
|
let reader = &mut &payload[..];
|
||||||
|
|
||||||
let chunks = track_try!((0..source_count).map(|_| SdesChunk::read_from(reader)).collect());
|
let chunks = track_try!(
|
||||||
|
(0..source_count)
|
||||||
|
.map(|_| SdesChunk::read_from(reader))
|
||||||
|
.collect()
|
||||||
|
);
|
||||||
Ok(RtcpSourceDescription { chunks: chunks })
|
Ok(RtcpSourceDescription { chunks: chunks })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,10 +442,12 @@ impl WriteTo for RtcpSourceDescription {
|
||||||
}
|
}
|
||||||
|
|
||||||
track_assert!(self.chunks.len() <= 0b0001_1111, ErrorKind::Invalid);
|
track_assert!(self.chunks.len() <= 0b0001_1111, ErrorKind::Invalid);
|
||||||
track_try!(write_sctp(writer,
|
track_try!(write_sctp(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_SDES,
|
RTCP_PACKET_TYPE_SDES,
|
||||||
self.chunks.len() as u8,
|
self.chunks.len() as u8,
|
||||||
&payload));
|
&payload
|
||||||
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -594,10 +613,12 @@ impl WriteTo for RtcpGoodbye {
|
||||||
}
|
}
|
||||||
|
|
||||||
track_assert!(self.ssrc_csrc_list.len() <= 0b0001_1111, ErrorKind::Invalid);
|
track_assert!(self.ssrc_csrc_list.len() <= 0b0001_1111, ErrorKind::Invalid);
|
||||||
track_try!(write_sctp(writer,
|
track_try!(write_sctp(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_BYE,
|
RTCP_PACKET_TYPE_BYE,
|
||||||
self.ssrc_csrc_list.len() as u8,
|
self.ssrc_csrc_list.len() as u8,
|
||||||
&payload));
|
&payload
|
||||||
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -636,7 +657,12 @@ impl WriteTo for RtcpApplicationDefined {
|
||||||
payload.extend(&self.data);
|
payload.extend(&self.data);
|
||||||
|
|
||||||
track_assert!(self.subtype <= 0b0001_1111, ErrorKind::Invalid);
|
track_assert!(self.subtype <= 0b0001_1111, ErrorKind::Invalid);
|
||||||
track_try!(write_sctp(writer, RTCP_PACKET_TYPE_APP, self.subtype, &payload));
|
track_try!(write_sctp(
|
||||||
|
writer,
|
||||||
|
RTCP_PACKET_TYPE_APP,
|
||||||
|
self.subtype,
|
||||||
|
&payload
|
||||||
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::io::{Read, Write};
|
|
||||||
use handy_async::sync_io::{ReadExt, WriteExt};
|
use handy_async::sync_io::{ReadExt, WriteExt};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use {Result, ErrorKind};
|
use constants::RTP_VERSION;
|
||||||
use io::{ReadFrom, WriteTo};
|
use io::{ReadFrom, WriteTo};
|
||||||
use traits::{self, Packet};
|
use traits::{self, Packet};
|
||||||
use types::{U7, RtpTimestamp, Ssrc, Csrc};
|
use types::{Csrc, RtpTimestamp, Ssrc, U7};
|
||||||
use constants::RTP_VERSION;
|
use {ErrorKind, Result};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct RtpPacketReader;
|
pub struct RtpPacketReader;
|
||||||
|
@ -62,13 +62,17 @@ impl WriteTo for RtpPacket {
|
||||||
track_try!(self.header.write_to(writer));
|
track_try!(self.header.write_to(writer));
|
||||||
track_try!(writer.write_all(&self.payload));
|
track_try!(writer.write_all(&self.payload));
|
||||||
|
|
||||||
track_assert_ne!(self.header.padding,
|
track_assert_ne!(
|
||||||
|
self.header.padding,
|
||||||
self.padding.is_empty(),
|
self.padding.is_empty(),
|
||||||
ErrorKind::Invalid);
|
ErrorKind::Invalid
|
||||||
|
);
|
||||||
if !self.padding.is_empty() {
|
if !self.padding.is_empty() {
|
||||||
track_assert_eq!(*self.padding.last().unwrap() as usize,
|
track_assert_eq!(
|
||||||
|
*self.padding.last().unwrap() as usize,
|
||||||
self.padding.len(),
|
self.padding.len(),
|
||||||
ErrorKind::Invalid);
|
ErrorKind::Invalid
|
||||||
|
);
|
||||||
track_try!(writer.write_all(&self.padding));
|
track_try!(writer.write_all(&self.padding));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -89,11 +93,13 @@ pub struct RtpFixedHeader {
|
||||||
impl ReadFrom for RtpFixedHeader {
|
impl ReadFrom for RtpFixedHeader {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let b = track_try!(reader.read_u8());
|
let b = track_try!(reader.read_u8());
|
||||||
track_assert_eq!(b >> 6,
|
track_assert_eq!(
|
||||||
|
b >> 6,
|
||||||
RTP_VERSION,
|
RTP_VERSION,
|
||||||
ErrorKind::Unsupported,
|
ErrorKind::Unsupported,
|
||||||
"Unsupported RTP version: {}",
|
"Unsupported RTP version: {}",
|
||||||
b >> 6);
|
b >> 6
|
||||||
|
);
|
||||||
let padding = (b & 0b0010_0000) != 0;
|
let padding = (b & 0b0010_0000) != 0;
|
||||||
let extension = (b & 0b0001_0000) != 0;
|
let extension = (b & 0b0001_0000) != 0;
|
||||||
let csrc_count = b & 0b0000_1111;
|
let csrc_count = b & 0b0000_1111;
|
||||||
|
|
142
src/rfc3711.rs
142
src/rfc3711.rs
|
@ -1,14 +1,14 @@
|
||||||
use std::io::Read;
|
|
||||||
use crypto;
|
use crypto;
|
||||||
|
use handy_async::sync_io::{ReadExt, WriteExt};
|
||||||
use num::BigUint;
|
use num::BigUint;
|
||||||
use splay_tree::SplaySet;
|
use splay_tree::SplaySet;
|
||||||
use handy_async::sync_io::{ReadExt, WriteExt};
|
use std::io::Read;
|
||||||
|
|
||||||
use {Result, ErrorKind};
|
|
||||||
use io::{ReadFrom, WriteTo};
|
use io::{ReadFrom, WriteTo};
|
||||||
use types::U48;
|
|
||||||
use traits::{ReadPacket, RtpPacket, RtcpPacket};
|
|
||||||
use rfc3550;
|
use rfc3550;
|
||||||
|
use traits::{ReadPacket, RtcpPacket, RtpPacket};
|
||||||
|
use types::U48;
|
||||||
|
use {ErrorKind, Result};
|
||||||
|
|
||||||
pub type PacketIndex = U48;
|
pub type PacketIndex = U48;
|
||||||
|
|
||||||
|
@ -64,15 +64,21 @@ impl SrtpContext {
|
||||||
let salt_key_id = BigUint::from_bytes_be(&[2, 0, 0, 0, 0, 0, 0]) + index.clone();
|
let salt_key_id = BigUint::from_bytes_be(&[2, 0, 0, 0, 0, 0, 0]) + index.clone();
|
||||||
let master_salt = BigUint::from_bytes_be(&self.master_salt);
|
let master_salt = BigUint::from_bytes_be(&self.master_salt);
|
||||||
|
|
||||||
self.session_encr_key = prf_n(&self.master_key,
|
self.session_encr_key = prf_n(
|
||||||
|
&self.master_key,
|
||||||
enc_key_id ^ master_salt.clone(),
|
enc_key_id ^ master_salt.clone(),
|
||||||
self.session_encr_key.len());
|
self.session_encr_key.len(),
|
||||||
self.session_auth_key = prf_n(&self.master_key,
|
);
|
||||||
|
self.session_auth_key = prf_n(
|
||||||
|
&self.master_key,
|
||||||
auth_key_id ^ master_salt.clone(),
|
auth_key_id ^ master_salt.clone(),
|
||||||
self.session_auth_key.len());
|
self.session_auth_key.len(),
|
||||||
self.session_salt_key = prf_n(&self.master_key,
|
);
|
||||||
|
self.session_salt_key = prf_n(
|
||||||
|
&self.master_key,
|
||||||
salt_key_id ^ master_salt.clone(),
|
salt_key_id ^ master_salt.clone(),
|
||||||
self.session_salt_key.len());
|
self.session_salt_key.len(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
pub fn authenticate(&self, packet: &[u8]) -> Result<()> {
|
pub fn authenticate(&self, packet: &[u8]) -> Result<()> {
|
||||||
let auth_portion = &packet[..packet.len() - self.auth_tag_len];
|
let auth_portion = &packet[..packet.len() - self.auth_tag_len];
|
||||||
|
@ -151,15 +157,21 @@ impl SrtcpContext {
|
||||||
let salt_key_id = BigUint::from_bytes_be(&[5, 0, 0, 0, 0, 0, 0]) + index.clone();
|
let salt_key_id = BigUint::from_bytes_be(&[5, 0, 0, 0, 0, 0, 0]) + index.clone();
|
||||||
let master_salt = BigUint::from_bytes_be(&self.master_salt);
|
let master_salt = BigUint::from_bytes_be(&self.master_salt);
|
||||||
|
|
||||||
self.session_encr_key = prf_n(&self.master_key,
|
self.session_encr_key = prf_n(
|
||||||
|
&self.master_key,
|
||||||
enc_key_id ^ master_salt.clone(),
|
enc_key_id ^ master_salt.clone(),
|
||||||
self.session_encr_key.len());
|
self.session_encr_key.len(),
|
||||||
self.session_auth_key = prf_n(&self.master_key,
|
);
|
||||||
|
self.session_auth_key = prf_n(
|
||||||
|
&self.master_key,
|
||||||
auth_key_id ^ master_salt.clone(),
|
auth_key_id ^ master_salt.clone(),
|
||||||
self.session_auth_key.len());
|
self.session_auth_key.len(),
|
||||||
self.session_salt_key = prf_n(&self.master_key,
|
);
|
||||||
|
self.session_salt_key = prf_n(
|
||||||
|
&self.master_key,
|
||||||
salt_key_id ^ master_salt.clone(),
|
salt_key_id ^ master_salt.clone(),
|
||||||
self.session_salt_key.len());
|
self.session_salt_key.len(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
pub fn authenticate(&self, packet: &[u8]) -> Result<()> {
|
pub fn authenticate(&self, packet: &[u8]) -> Result<()> {
|
||||||
let auth_portion = &packet[..packet.len() - self.auth_tag_len];
|
let auth_portion = &packet[..packet.len() - self.auth_tag_len];
|
||||||
|
@ -209,8 +221,9 @@ pub struct SrtpPacketReader<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
}
|
}
|
||||||
impl<T> SrtpPacketReader<T>
|
impl<T> SrtpPacketReader<T>
|
||||||
where T: ReadPacket,
|
where
|
||||||
T::Packet: RtpPacket
|
T: ReadPacket,
|
||||||
|
T::Packet: RtpPacket,
|
||||||
{
|
{
|
||||||
pub fn new(mut context: SrtpContext, inner: T) -> Self {
|
pub fn new(mut context: SrtpContext, inner: T) -> Self {
|
||||||
context.update_session_keys();
|
context.update_session_keys();
|
||||||
|
@ -221,8 +234,9 @@ impl<T> SrtpPacketReader<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> ReadPacket for SrtpPacketReader<T>
|
impl<T> ReadPacket for SrtpPacketReader<T>
|
||||||
where T: ReadPacket,
|
where
|
||||||
T::Packet: RtpPacket
|
T: ReadPacket,
|
||||||
|
T::Packet: RtpPacket,
|
||||||
{
|
{
|
||||||
type Packet = T::Packet;
|
type Packet = T::Packet;
|
||||||
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||||
|
@ -243,8 +257,9 @@ pub struct SrtcpPacketReader<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
}
|
}
|
||||||
impl<T> SrtcpPacketReader<T>
|
impl<T> SrtcpPacketReader<T>
|
||||||
where T: ReadPacket,
|
where
|
||||||
T::Packet: RtcpPacket
|
T: ReadPacket,
|
||||||
|
T::Packet: RtcpPacket,
|
||||||
{
|
{
|
||||||
pub fn new(mut context: SrtcpContext, inner: T) -> Self {
|
pub fn new(mut context: SrtcpContext, inner: T) -> Self {
|
||||||
context.update_session_keys();
|
context.update_session_keys();
|
||||||
|
@ -255,8 +270,9 @@ impl<T> SrtcpPacketReader<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> ReadPacket for SrtcpPacketReader<T>
|
impl<T> ReadPacket for SrtcpPacketReader<T>
|
||||||
where T: ReadPacket,
|
where
|
||||||
T::Packet: RtcpPacket
|
T: ReadPacket,
|
||||||
|
T::Packet: RtcpPacket,
|
||||||
{
|
{
|
||||||
type Packet = T::Packet;
|
type Packet = T::Packet;
|
||||||
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||||
|
@ -281,9 +297,11 @@ fn hmac_hash_sha1(key: &[u8], data: &[u8]) -> Vec<u8> {
|
||||||
fn prf_n(master_key: &[u8], x: BigUint, n: usize) -> Vec<u8> {
|
fn prf_n(master_key: &[u8], x: BigUint, n: usize) -> Vec<u8> {
|
||||||
// https://tools.ietf.org/html/rfc3711#section-4.1.1
|
// https://tools.ietf.org/html/rfc3711#section-4.1.1
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
let mut ctr = crypto::aes::ctr(crypto::aes::KeySize::KeySize128,
|
let mut ctr = crypto::aes::ctr(
|
||||||
|
crypto::aes::KeySize::KeySize128,
|
||||||
master_key,
|
master_key,
|
||||||
&(x << 16).to_bytes_be());
|
&(x << 16).to_bytes_be(),
|
||||||
|
);
|
||||||
for i in 0.. {
|
for i in 0.. {
|
||||||
let old_len = output.len();
|
let old_len = output.len();
|
||||||
let new_len = output.len() + 16;
|
let new_len = output.len() + 16;
|
||||||
|
@ -302,50 +320,64 @@ fn prf_n(master_key: &[u8], x: BigUint, n: usize) -> Vec<u8> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use super::*;
|
||||||
use rfc3550;
|
use rfc3550;
|
||||||
use rfc4585;
|
use rfc4585;
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rtp_decryption_works() {
|
fn rtp_decryption_works() {
|
||||||
let master_key = [211, 77, 116, 243, 125, 116, 231, 95, 59, 219, 79, 118, 241, 189, 244,
|
let master_key = [
|
||||||
119];
|
211, 77, 116, 243, 125, 116, 231, 95, 59, 219, 79, 118, 241, 189, 244, 119,
|
||||||
let master_salt = [127, 31, 227, 93, 120, 247, 126, 117, 231, 159, 123, 235, 95, 122];
|
];
|
||||||
|
let master_salt = [
|
||||||
|
127, 31, 227, 93, 120, 247, 126, 117, 231, 159, 123, 235, 95, 122,
|
||||||
|
];
|
||||||
|
|
||||||
let packet = [128, 0, 3, 92, 222, 161, 6, 76, 26, 163, 115, 130, 222, 0, 143, 87, 0, 227,
|
let packet = [
|
||||||
123, 91, 200, 238, 141, 220, 9, 191, 52, 111, 100, 62, 220, 158, 211, 79,
|
128, 0, 3, 92, 222, 161, 6, 76, 26, 163, 115, 130, 222, 0, 143, 87, 0, 227, 123, 91,
|
||||||
184, 199, 79, 182, 9, 248, 170, 82, 125, 152, 143, 206, 8, 152, 80, 207, 27,
|
200, 238, 141, 220, 9, 191, 52, 111, 100, 62, 220, 158, 211, 79, 184, 199, 79, 182, 9,
|
||||||
183, 141, 77, 33, 60, 101, 180, 210, 146, 139, 170, 149, 13, 99, 75, 223,
|
248, 170, 82, 125, 152, 143, 206, 8, 152, 80, 207, 27, 183, 141, 77, 33, 60, 101, 180,
|
||||||
156, 79, 71, 84, 119, 68, 236, 244, 163, 198, 175, 219, 160, 255, 9, 82,
|
210, 146, 139, 170, 149, 13, 99, 75, 223, 156, 79, 71, 84, 119, 68, 236, 244, 163, 198,
|
||||||
169, 64, 112, 106, 4, 0, 246, 39, 29, 88, 15, 62, 174, 21, 253, 171, 198,
|
175, 219, 160, 255, 9, 82, 169, 64, 112, 106, 4, 0, 246, 39, 29, 88, 15, 62, 174, 21,
|
||||||
128, 61, 23, 43, 143, 255, 176, 125, 223, 23, 188, 90, 103, 139, 223, 56,
|
253, 171, 198, 128, 61, 23, 43, 143, 255, 176, 125, 223, 23, 188, 90, 103, 139, 223,
|
||||||
162, 35, 27, 225, 117, 243, 138, 163, 35, 79, 221, 201, 149, 154, 203, 255,
|
56, 162, 35, 27, 225, 117, 243, 138, 163, 35, 79, 221, 201, 149, 154, 203, 255, 2, 23,
|
||||||
2, 23, 184, 184, 169, 32, 1, 138, 172, 60, 70, 240, 53, 11, 54, 81, 172,
|
184, 184, 169, 32, 1, 138, 172, 60, 70, 240, 53, 11, 54, 81, 172, 214, 34, 136, 39,
|
||||||
214, 34, 136, 39, 152, 17, 247, 126, 199, 200, 184, 70, 7, 52, 191, 129,
|
152, 17, 247, 126, 199, 200, 184, 70, 7, 52, 191, 129, 239, 86, 78, 172, 229, 178, 112,
|
||||||
239, 86, 78, 172, 229, 178, 112, 22, 125, 191, 164, 17, 193, 24, 152, 197,
|
22, 125, 191, 164, 17, 193, 24, 152, 197, 146, 94, 74, 156, 171, 245, 239, 220, 205,
|
||||||
146, 94, 74, 156, 171, 245, 239, 220, 205, 145, 206];
|
145, 206,
|
||||||
|
];
|
||||||
|
|
||||||
let context = SrtpContext::new(&master_key, &master_salt);
|
let context = SrtpContext::new(&master_key, &master_salt);
|
||||||
let mut rtp_reader = SrtpPacketReader::new(context, rfc3550::RtpPacketReader);
|
let mut rtp_reader = SrtpPacketReader::new(context, rfc3550::RtpPacketReader);
|
||||||
let packet = rtp_reader.read_packet(&mut &packet[..]).unwrap();
|
let packet = rtp_reader.read_packet(&mut &packet[..]).unwrap();
|
||||||
|
|
||||||
let expected_prefix = [0xbe, 0x9c, 0x8c, 0x86, 0x81, 0x80, 0x81, 0x86, 0x8d, 0x9c, 0xfd,
|
let expected_prefix = [
|
||||||
0x1b, 0x0d, 0x05, 0x01, 0x00, 0x01, 0x05, 0x0d, 0x1b, 0xff, 0x9b,
|
0xbe, 0x9c, 0x8c, 0x86, 0x81, 0x80, 0x81, 0x86, 0x8d, 0x9c, 0xfd, 0x1b, 0x0d, 0x05,
|
||||||
0x8d, 0x85, 0x81, 0x80, 0x81, 0x85, 0x8d, 0x9b, 0xff, 0x1b];
|
0x01, 0x00, 0x01, 0x05, 0x0d, 0x1b, 0xff, 0x9b, 0x8d, 0x85, 0x81, 0x80, 0x81, 0x85,
|
||||||
|
0x8d, 0x9b, 0xff, 0x1b,
|
||||||
|
];
|
||||||
|
|
||||||
assert_eq!(&packet.payload[..expected_prefix.len()],
|
assert_eq!(
|
||||||
&expected_prefix[..]);
|
&packet.payload[..expected_prefix.len()],
|
||||||
|
&expected_prefix[..]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rtcp_decryption_works() {
|
fn rtcp_decryption_works() {
|
||||||
let master_key = [254, 123, 44, 240, 174, 252, 53, 54, 2, 213, 123, 106, 85, 165, 5, 13];
|
let master_key = [
|
||||||
let master_salt = [77, 202, 202, 112, 81, 101, 219, 232, 143, 131, 160, 89, 15, 141];
|
254, 123, 44, 240, 174, 252, 53, 54, 2, 213, 123, 106, 85, 165, 5, 13,
|
||||||
let packet = [128, 201, 0, 1, 194, 242, 138, 93, 67, 38, 193, 233, 60, 78, 188, 195, 230,
|
];
|
||||||
90, 19, 196, 152, 235, 136, 164, 15, 177, 174, 217, 207, 115, 148, 223, 109,
|
let master_salt = [
|
||||||
112, 71, 245, 16, 214, 216, 232, 87, 153, 5, 238, 72, 201, 223, 43, 69, 99,
|
77, 202, 202, 112, 81, 101, 219, 232, 143, 131, 160, 89, 15, 141,
|
||||||
54, 211, 118, 28, 227, 100, 161, 216, 90, 203, 99, 167, 215, 130, 151, 16,
|
];
|
||||||
128, 138, 128, 0, 0, 1, 126, 39, 201, 236, 161, 194, 6, 232, 194, 230];
|
let packet = [
|
||||||
|
128, 201, 0, 1, 194, 242, 138, 93, 67, 38, 193, 233, 60, 78, 188, 195, 230, 90, 19,
|
||||||
|
196, 152, 235, 136, 164, 15, 177, 174, 217, 207, 115, 148, 223, 109, 112, 71, 245, 16,
|
||||||
|
214, 216, 232, 87, 153, 5, 238, 72, 201, 223, 43, 69, 99, 54, 211, 118, 28, 227, 100,
|
||||||
|
161, 216, 90, 203, 99, 167, 215, 130, 151, 16, 128, 138, 128, 0, 0, 1, 126, 39, 201,
|
||||||
|
236, 161, 194, 6, 232, 194, 230,
|
||||||
|
];
|
||||||
|
|
||||||
let context = SrtcpContext::new(&master_key, &master_salt);
|
let context = SrtcpContext::new(&master_key, &master_salt);
|
||||||
let mut rtcp_reader = SrtcpPacketReader::new(context, rfc4585::RtcpPacketReader);
|
let mut rtcp_reader = SrtcpPacketReader::new(context, rfc4585::RtcpPacketReader);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use std::io::{Read, Write};
|
|
||||||
use handy_async::sync_io::{ReadExt, WriteExt};
|
use handy_async::sync_io::{ReadExt, WriteExt};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use {Result, ErrorKind};
|
|
||||||
use io::{ReadFrom, WriteTo};
|
|
||||||
use traits::{self, Packet};
|
|
||||||
use types::{U5, U6, U7, U13, Ssrc};
|
|
||||||
use constants::RTP_VERSION;
|
use constants::RTP_VERSION;
|
||||||
|
use io::{ReadFrom, WriteTo};
|
||||||
use rfc3550;
|
use rfc3550;
|
||||||
|
use traits::{self, Packet};
|
||||||
|
use types::{Ssrc, U13, U5, U6, U7};
|
||||||
|
use {ErrorKind, Result};
|
||||||
|
|
||||||
pub const RTCP_PACKET_TYPE_RTPFB: u8 = 205;
|
pub const RTCP_PACKET_TYPE_RTPFB: u8 = 205;
|
||||||
pub const RTCP_PACKET_TYPE_PSFB: u8 = 206;
|
pub const RTCP_PACKET_TYPE_PSFB: u8 = 206;
|
||||||
|
@ -35,13 +35,13 @@ impl traits::ReadPacket for RtcpPacketReader {
|
||||||
}
|
}
|
||||||
fn supports_type(&self, ty: u8) -> bool {
|
fn supports_type(&self, ty: u8) -> bool {
|
||||||
match ty {
|
match ty {
|
||||||
rfc3550::RTCP_PACKET_TYPE_SR |
|
rfc3550::RTCP_PACKET_TYPE_SR
|
||||||
rfc3550::RTCP_PACKET_TYPE_RR |
|
| rfc3550::RTCP_PACKET_TYPE_RR
|
||||||
rfc3550::RTCP_PACKET_TYPE_SDES |
|
| rfc3550::RTCP_PACKET_TYPE_SDES
|
||||||
rfc3550::RTCP_PACKET_TYPE_BYE |
|
| rfc3550::RTCP_PACKET_TYPE_BYE
|
||||||
rfc3550::RTCP_PACKET_TYPE_APP |
|
| rfc3550::RTCP_PACKET_TYPE_APP
|
||||||
RTCP_PACKET_TYPE_RTPFB |
|
| RTCP_PACKET_TYPE_RTPFB
|
||||||
RTCP_PACKET_TYPE_PSFB => true,
|
| RTCP_PACKET_TYPE_PSFB => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,9 +102,11 @@ impl ReadFrom for RtcpPacket {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
track_assert_eq!(buf[0] >> 6, RTP_VERSION, ErrorKind::Invalid);
|
track_assert_eq!(buf[0] >> 6, RTP_VERSION, ErrorKind::Invalid);
|
||||||
track_panic!(ErrorKind::Unsupported,
|
track_panic!(
|
||||||
|
ErrorKind::Unsupported,
|
||||||
"Unknown packet type: {}",
|
"Unknown packet type: {}",
|
||||||
packet_type)
|
packet_type
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,11 +173,11 @@ impl ReadFrom for RtcpTransportLayerFeedback {
|
||||||
RTPFB_MESSAGE_TYPE_NACK => {
|
RTPFB_MESSAGE_TYPE_NACK => {
|
||||||
track_err!(GenericNack::read_from(&mut &rest[..])).map(From::from)
|
track_err!(GenericNack::read_from(&mut &rest[..])).map(From::from)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => track_panic!(
|
||||||
track_panic!(ErrorKind::Unsupported,
|
ErrorKind::Unsupported,
|
||||||
"Unknown feedback type: {}",
|
"Unknown feedback type: {}",
|
||||||
fb_message_type)
|
fb_message_type
|
||||||
}
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,10 +186,12 @@ impl WriteTo for RtcpTransportLayerFeedback {
|
||||||
match *self {
|
match *self {
|
||||||
RtcpTransportLayerFeedback::Nack(ref f) => {
|
RtcpTransportLayerFeedback::Nack(ref f) => {
|
||||||
let payload = track_try!(f.to_bytes());
|
let payload = track_try!(f.to_bytes());
|
||||||
track_err!(write_common(writer,
|
track_err!(write_common(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_RTPFB,
|
RTCP_PACKET_TYPE_RTPFB,
|
||||||
RTPFB_MESSAGE_TYPE_NACK,
|
RTPFB_MESSAGE_TYPE_NACK,
|
||||||
&payload))
|
&payload
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,11 +228,11 @@ impl ReadFrom for RtcpPayloadSpecificFeedback {
|
||||||
PSFB_MESSAGE_TYPE_AFB => {
|
PSFB_MESSAGE_TYPE_AFB => {
|
||||||
track_err!(ApplicationLayerFeedback::read_from(reader).map(From::from))
|
track_err!(ApplicationLayerFeedback::read_from(reader).map(From::from))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => track_panic!(
|
||||||
track_panic!(ErrorKind::Unsupported,
|
ErrorKind::Unsupported,
|
||||||
"Unknown feedback type: {}",
|
"Unknown feedback type: {}",
|
||||||
fb_message_type)
|
fb_message_type
|
||||||
}
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,31 +241,39 @@ impl WriteTo for RtcpPayloadSpecificFeedback {
|
||||||
match *self {
|
match *self {
|
||||||
RtcpPayloadSpecificFeedback::Pli(ref f) => {
|
RtcpPayloadSpecificFeedback::Pli(ref f) => {
|
||||||
let payload = track_try!(f.to_bytes());
|
let payload = track_try!(f.to_bytes());
|
||||||
track_err!(write_common(writer,
|
track_err!(write_common(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_PSFB,
|
RTCP_PACKET_TYPE_PSFB,
|
||||||
PSFB_MESSAGE_TYPE_PLI,
|
PSFB_MESSAGE_TYPE_PLI,
|
||||||
&payload))
|
&payload
|
||||||
|
))
|
||||||
}
|
}
|
||||||
RtcpPayloadSpecificFeedback::Sli(ref f) => {
|
RtcpPayloadSpecificFeedback::Sli(ref f) => {
|
||||||
let payload = track_try!(f.to_bytes());
|
let payload = track_try!(f.to_bytes());
|
||||||
track_err!(write_common(writer,
|
track_err!(write_common(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_PSFB,
|
RTCP_PACKET_TYPE_PSFB,
|
||||||
PSFB_MESSAGE_TYPE_SLI,
|
PSFB_MESSAGE_TYPE_SLI,
|
||||||
&payload))
|
&payload
|
||||||
|
))
|
||||||
}
|
}
|
||||||
RtcpPayloadSpecificFeedback::Rpsi(ref f) => {
|
RtcpPayloadSpecificFeedback::Rpsi(ref f) => {
|
||||||
let payload = track_try!(f.to_bytes());
|
let payload = track_try!(f.to_bytes());
|
||||||
track_err!(write_common(writer,
|
track_err!(write_common(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_PSFB,
|
RTCP_PACKET_TYPE_PSFB,
|
||||||
PSFB_MESSAGE_TYPE_RPSI,
|
PSFB_MESSAGE_TYPE_RPSI,
|
||||||
&payload))
|
&payload
|
||||||
|
))
|
||||||
}
|
}
|
||||||
RtcpPayloadSpecificFeedback::Afb(ref f) => {
|
RtcpPayloadSpecificFeedback::Afb(ref f) => {
|
||||||
let payload = track_try!(f.to_bytes());
|
let payload = track_try!(f.to_bytes());
|
||||||
track_err!(write_common(writer,
|
track_err!(write_common(
|
||||||
|
writer,
|
||||||
RTCP_PACKET_TYPE_PSFB,
|
RTCP_PACKET_TYPE_PSFB,
|
||||||
PSFB_MESSAGE_TYPE_AFB,
|
PSFB_MESSAGE_TYPE_AFB,
|
||||||
&payload))
|
&payload
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,11 +299,12 @@ impl From<ApplicationLayerFeedback> for RtcpPayloadSpecificFeedback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_common<W: Write>(writer: &mut W,
|
fn write_common<W: Write>(
|
||||||
|
writer: &mut W,
|
||||||
packet_type: u8,
|
packet_type: u8,
|
||||||
fb_message_type: U5,
|
fb_message_type: U5,
|
||||||
payload: &[u8])
|
payload: &[u8],
|
||||||
-> Result<()> {
|
) -> Result<()> {
|
||||||
track_assert_eq!(payload.len() % 4, 0, ErrorKind::Invalid);
|
track_assert_eq!(payload.len() % 4, 0, ErrorKind::Invalid);
|
||||||
|
|
||||||
track_try!(writer.write_u8(RTP_VERSION << 6 | fb_message_type));
|
track_try!(writer.write_u8(RTP_VERSION << 6 | fb_message_type));
|
||||||
|
@ -308,21 +321,25 @@ fn write_common<W: Write>(writer: &mut W,
|
||||||
|
|
||||||
fn read_common<R: Read>(reader: &mut R, expected_type: u8) -> Result<(U5, Vec<u8>)> {
|
fn read_common<R: Read>(reader: &mut R, expected_type: u8) -> Result<(U5, Vec<u8>)> {
|
||||||
let b = track_try!(reader.read_u8());
|
let b = track_try!(reader.read_u8());
|
||||||
track_assert_eq!(b >> 6,
|
track_assert_eq!(
|
||||||
|
b >> 6,
|
||||||
RTP_VERSION,
|
RTP_VERSION,
|
||||||
ErrorKind::Unsupported,
|
ErrorKind::Unsupported,
|
||||||
"Unsupported RTP version: {}",
|
"Unsupported RTP version: {}",
|
||||||
b >> 6);
|
b >> 6
|
||||||
|
);
|
||||||
let padding = (b & 0b0010_0000) != 0;
|
let padding = (b & 0b0010_0000) != 0;
|
||||||
let fb_message_type = b & 0b0001_1111;
|
let fb_message_type = b & 0b0001_1111;
|
||||||
|
|
||||||
let packet_type = track_try!(reader.read_u8());
|
let packet_type = track_try!(reader.read_u8());
|
||||||
track_assert_eq!(packet_type,
|
track_assert_eq!(
|
||||||
|
packet_type,
|
||||||
expected_type,
|
expected_type,
|
||||||
ErrorKind::Invalid,
|
ErrorKind::Invalid,
|
||||||
"Unexpected SCTP packet type: actual={}, expected={}",
|
"Unexpected SCTP packet type: actual={}, expected={}",
|
||||||
packet_type,
|
packet_type,
|
||||||
expected_type);
|
expected_type
|
||||||
|
);
|
||||||
|
|
||||||
let word_count = track_try!(reader.read_u16be()) as usize;
|
let word_count = track_try!(reader.read_u16be()) as usize;
|
||||||
let mut payload = track_try!(reader.read_bytes(word_count * 4));
|
let mut payload = track_try!(reader.read_bytes(word_count * 4));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
use traits::{Packet, ReadPacket, RtcpPacket, RtpPacket, WritePacket};
|
||||||
use Result;
|
use Result;
|
||||||
use traits::{ReadPacket, WritePacket, RtpPacket, RtcpPacket, Packet};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MuxPacketReader<T, U> {
|
pub struct MuxPacketReader<T, U> {
|
||||||
|
@ -9,10 +9,11 @@ pub struct MuxPacketReader<T, U> {
|
||||||
rtcp_reader: U,
|
rtcp_reader: U,
|
||||||
}
|
}
|
||||||
impl<T, U> MuxPacketReader<T, U>
|
impl<T, U> MuxPacketReader<T, U>
|
||||||
where T: ReadPacket,
|
where
|
||||||
|
T: ReadPacket,
|
||||||
T::Packet: RtpPacket,
|
T::Packet: RtpPacket,
|
||||||
U: ReadPacket,
|
U: ReadPacket,
|
||||||
U::Packet: RtcpPacket
|
U::Packet: RtcpPacket,
|
||||||
{
|
{
|
||||||
pub fn new(rtp_reader: T, rtcp_reader: U) -> Self {
|
pub fn new(rtp_reader: T, rtcp_reader: U) -> Self {
|
||||||
MuxPacketReader {
|
MuxPacketReader {
|
||||||
|
@ -22,10 +23,11 @@ impl<T, U> MuxPacketReader<T, U>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T, U> ReadPacket for MuxPacketReader<T, U>
|
impl<T, U> ReadPacket for MuxPacketReader<T, U>
|
||||||
where T: ReadPacket,
|
where
|
||||||
|
T: ReadPacket,
|
||||||
T::Packet: RtpPacket,
|
T::Packet: RtpPacket,
|
||||||
U: ReadPacket,
|
U: ReadPacket,
|
||||||
U::Packet: RtcpPacket
|
U::Packet: RtcpPacket,
|
||||||
{
|
{
|
||||||
type Packet = MuxedPacket<T::Packet, U::Packet>;
|
type Packet = MuxedPacket<T::Packet, U::Packet>;
|
||||||
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||||
|
@ -52,10 +54,11 @@ pub struct MuxPacketWriter<T, U> {
|
||||||
rtcp_writer: U,
|
rtcp_writer: U,
|
||||||
}
|
}
|
||||||
impl<T, U> MuxPacketWriter<T, U>
|
impl<T, U> MuxPacketWriter<T, U>
|
||||||
where T: WritePacket,
|
where
|
||||||
|
T: WritePacket,
|
||||||
T::Packet: RtpPacket,
|
T::Packet: RtpPacket,
|
||||||
U: WritePacket,
|
U: WritePacket,
|
||||||
U::Packet: RtcpPacket
|
U::Packet: RtcpPacket,
|
||||||
{
|
{
|
||||||
pub fn new(rtp_writer: T, rtcp_writer: U) -> Self {
|
pub fn new(rtp_writer: T, rtcp_writer: U) -> Self {
|
||||||
MuxPacketWriter {
|
MuxPacketWriter {
|
||||||
|
@ -65,10 +68,11 @@ impl<T, U> MuxPacketWriter<T, U>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T, U> WritePacket for MuxPacketWriter<T, U>
|
impl<T, U> WritePacket for MuxPacketWriter<T, U>
|
||||||
where T: WritePacket,
|
where
|
||||||
|
T: WritePacket,
|
||||||
T::Packet: RtpPacket,
|
T::Packet: RtpPacket,
|
||||||
U: WritePacket,
|
U: WritePacket,
|
||||||
U::Packet: RtcpPacket
|
U::Packet: RtcpPacket,
|
||||||
{
|
{
|
||||||
type Packet = MuxedPacket<T::Packet, U::Packet>;
|
type Packet = MuxedPacket<T::Packet, U::Packet>;
|
||||||
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
||||||
|
@ -85,7 +89,8 @@ pub enum MuxedPacket<T, U> {
|
||||||
Rtcp(U),
|
Rtcp(U),
|
||||||
}
|
}
|
||||||
impl<T, U> Packet for MuxedPacket<T, U>
|
impl<T, U> Packet for MuxedPacket<T, U>
|
||||||
where T: RtpPacket,
|
where
|
||||||
U: RtcpPacket
|
T: RtpPacket,
|
||||||
|
U: RtcpPacket,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue