warn about #30

This commit is contained in:
Scott Lamb 2021-08-31 13:27:13 -07:00
parent 3a15ddcab5
commit ffaa831c54
3 changed files with 50 additions and 0 deletions

View File

@ -1,3 +1,7 @@
## unreleased
* warn when connecting via TCP to a known-broken live555 server version.
## `v0.3.0` (2021-08-31) ## `v0.3.0` (2021-08-31)
* BREAKING CHANGE: [#30](https://github.com/scottlamb/retina/issues/30): * BREAKING CHANGE: [#30](https://github.com/scottlamb/retina/issues/30):

View File

@ -216,6 +216,9 @@ pub struct Presentation {
base_url: Url, base_url: Url,
pub control: Url, pub control: Url,
pub accept_dynamic_rate: bool, pub accept_dynamic_rate: bool,
/// Session-level `a:tool` from SDP.
tool: Option<Box<str>>,
} }
/// Information about a stream offered within a presentation. /// Information about a stream offered within a presentation.
@ -908,6 +911,17 @@ impl Session<Described> {
"must SETUP before PLAY".into() "must SETUP before PLAY".into()
)) ))
})?; })?;
if let Some(tool) = inner.presentation.tool.as_deref() {
if matches!(inner.options.transport, Transport::Tcp) && has_live555_tcp_bug(tool) {
warn!(
"Connecting via TCP to known-broken RTSP server {:?}. \
See <https://github.com/scottlamb/retina/issues/17>. \
Consider using UDP instead!",
tool
);
}
}
trace!("PLAY with channel mappings: {:#?}", &inner.conn.channels); trace!("PLAY with channel mappings: {:#?}", &inner.conn.channels);
let (msg_ctx, cseq, response) = inner let (msg_ctx, cseq, response) = inner
.conn .conn
@ -1022,6 +1036,17 @@ impl Session<Described> {
} }
} }
/// Checks if the `tool` entry refers to a live555 version affected by
/// [#17](https://github.com/scottlamb/retina/issues/17).
fn has_live555_tcp_bug(tool: &str) -> bool {
const PREFIX: &str = "LIVE555 Streaming Media v";
if !tool.starts_with(PREFIX) {
return false;
}
let version = &tool[PREFIX.len()..];
version > "0000.00.00" && version < "2017.06.04"
}
/// Sends dummy RTP and RTCP packets to punch a hole in connection-tracking /// Sends dummy RTP and RTCP packets to punch a hole in connection-tracking
/// firewalls. /// firewalls.
/// ///
@ -1748,4 +1773,13 @@ mod tests {
println!("{:-40} {:4}", name, size); println!("{:-40} {:4}", name, size);
} }
} }
#[test]
fn check_live555_tcp_bug() {
assert!(!has_live555_tcp_bug("not live555"));
assert!(!has_live555_tcp_bug("LIVE555 Streaming Media v"));
assert!(has_live555_tcp_bug("LIVE555 Streaming Media v2013.04.08"));
assert!(!has_live555_tcp_bug("LIVE555 Streaming Media v2017.06.04"));
assert!(!has_live555_tcp_bug("LIVE555 Streaming Media v2020.01.01"));
}
} }

View File

@ -417,6 +417,7 @@ pub(crate) fn parse_describe(
.unwrap_or(Ok(request_url.clone()))?; .unwrap_or(Ok(request_url.clone()))?;
let mut control = None; let mut control = None;
let mut tool = None;
for a in &sdp.attributes { for a in &sdp.attributes {
if a.key == "control" { if a.key == "control" {
control = a control = a
@ -425,6 +426,8 @@ pub(crate) fn parse_describe(
.map(|c| join_control(&base_url, c)) .map(|c| join_control(&base_url, c))
.transpose()?; .transpose()?;
break; break;
} else if a.key == "tool" {
tool = a.value.as_deref().map(Into::into);
} }
} }
let control = control.unwrap_or(request_url); let control = control.unwrap_or(request_url);
@ -447,6 +450,7 @@ pub(crate) fn parse_describe(
base_url, base_url,
control, control,
accept_dynamic_rate, accept_dynamic_rate,
tool,
}) })
} }
@ -825,6 +829,10 @@ mod tests {
let base = "rtsp://192.168.5.206/h264Preview_01_main/"; let base = "rtsp://192.168.5.206/h264Preview_01_main/";
assert_eq!(p.control.as_str(), base); assert_eq!(p.control.as_str(), base);
assert!(!p.accept_dynamic_rate); assert!(!p.accept_dynamic_rate);
assert_eq!(
p.tool.as_deref(),
Some("LIVE555 Streaming Media v2013.04.08")
);
assert_eq!(p.streams.len(), 2); assert_eq!(p.streams.len(), 2);
@ -967,6 +975,10 @@ mod tests {
let p = parse_describe(prefix, include_bytes!("testdata/foscam_describe.txt")).unwrap(); let p = parse_describe(prefix, include_bytes!("testdata/foscam_describe.txt")).unwrap();
assert_eq!(p.control.as_str(), &(prefix.to_string() + "/")); assert_eq!(p.control.as_str(), &(prefix.to_string() + "/"));
assert!(!p.accept_dynamic_rate); assert!(!p.accept_dynamic_rate);
assert_eq!(
p.tool.as_deref(),
Some("LIVE555 Streaming Media v2014.02.10")
);
assert_eq!(p.streams.len(), 2); assert_eq!(p.streams.len(), 2);