Fix RTP header extension encryption
Previously, RTP header extensions with encryption had been filtered if the encryption had been activated (not the other way around) which was likely an unintended logic inversion. In addition, it ensures that encrypted RTP header extensions are only negotiated if RTP header extension encryption is turned on. Formerly, which extensions had been negotiated depended on the order in which they were inserted, regardless of whether or not header encryption was actually enabled, leading to no extensions being sent on the wire. Further changes: - If RTP header encryption enabled, prefer encrypted extensions over non-encrypted extensions - Add most extensions to list of extensions supported for encryption - Discard encrypted extensions in a session description in case encryption is not supported for that extension Note that this depends on https://github.com/cisco/libsrtp/pull/491 to get into libwebrtc (cherry-pick or bump libsrtp version). Otherwise, two-byte header extensions will prevent any RTP packets being sent/received. Bug: webrtc:11713 Change-Id: Ia0779453d342fa11e06996d9bc2d3c826f3466d3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/177980 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Taylor <deadbeef@webrtc.org> Commit-Queue: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33723}
This commit is contained in:

committed by
Commit Bot

parent
84ba1643c2
commit
a743303211
@ -23,28 +23,249 @@ static const RtpExtension kExtension1(kExtensionUri1, 1);
|
||||
static const RtpExtension kExtension1Encrypted(kExtensionUri1, 10, true);
|
||||
static const RtpExtension kExtension2(kExtensionUri2, 2);
|
||||
|
||||
TEST(RtpExtensionTest, FilterDuplicateNonEncrypted) {
|
||||
TEST(RtpExtensionTest, DeduplicateHeaderExtensions) {
|
||||
std::vector<RtpExtension> extensions;
|
||||
std::vector<RtpExtension> filtered;
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
filtered = RtpExtension::FilterDuplicateNonEncrypted(extensions);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
|
||||
EXPECT_EQ(1u, filtered.size());
|
||||
EXPECT_EQ(std::vector<RtpExtension>{kExtension1}, filtered);
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kPreferEncryptedExtension);
|
||||
EXPECT_EQ(1u, filtered.size());
|
||||
EXPECT_EQ(std::vector<RtpExtension>{kExtension1Encrypted}, filtered);
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kRequireEncryptedExtension);
|
||||
EXPECT_EQ(1u, filtered.size());
|
||||
EXPECT_EQ(std::vector<RtpExtension>{kExtension1Encrypted}, filtered);
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
extensions.push_back(kExtension1);
|
||||
filtered = RtpExtension::FilterDuplicateNonEncrypted(extensions);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
|
||||
EXPECT_EQ(1u, filtered.size());
|
||||
EXPECT_EQ(std::vector<RtpExtension>{kExtension1}, filtered);
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
extensions.push_back(kExtension1);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kPreferEncryptedExtension);
|
||||
EXPECT_EQ(1u, filtered.size());
|
||||
EXPECT_EQ(std::vector<RtpExtension>{kExtension1Encrypted}, filtered);
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
extensions.push_back(kExtension1);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kRequireEncryptedExtension);
|
||||
EXPECT_EQ(1u, filtered.size());
|
||||
EXPECT_EQ(std::vector<RtpExtension>{kExtension1Encrypted}, filtered);
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension2);
|
||||
filtered = RtpExtension::FilterDuplicateNonEncrypted(extensions);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
|
||||
EXPECT_EQ(2u, filtered.size());
|
||||
EXPECT_EQ(extensions, filtered);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kPreferEncryptedExtension);
|
||||
EXPECT_EQ(2u, filtered.size());
|
||||
EXPECT_EQ(extensions, filtered);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kRequireEncryptedExtension);
|
||||
EXPECT_EQ(0u, filtered.size());
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension2);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
|
||||
EXPECT_EQ(2u, filtered.size());
|
||||
EXPECT_EQ((std::vector<RtpExtension>{kExtension1, kExtension2}), filtered);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kPreferEncryptedExtension);
|
||||
EXPECT_EQ(2u, filtered.size());
|
||||
EXPECT_EQ((std::vector<RtpExtension>{kExtension1Encrypted, kExtension2}),
|
||||
filtered);
|
||||
filtered = RtpExtension::DeduplicateHeaderExtensions(
|
||||
extensions, RtpExtension::Filter::kRequireEncryptedExtension);
|
||||
EXPECT_EQ(1u, filtered.size());
|
||||
EXPECT_EQ((std::vector<RtpExtension>{kExtension1Encrypted}), filtered);
|
||||
}
|
||||
|
||||
TEST(RtpExtensionTest, FindHeaderExtensionByUriAndEncryption) {
|
||||
std::vector<RtpExtension> extensions;
|
||||
|
||||
extensions.clear();
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUriAndEncryption(
|
||||
extensions, kExtensionUri1, false));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUriAndEncryption(
|
||||
extensions, kExtensionUri1, false));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUriAndEncryption(
|
||||
extensions, kExtensionUri1, true));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUriAndEncryption(
|
||||
extensions, kExtensionUri2, false));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension2);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUriAndEncryption(
|
||||
extensions, kExtensionUri1, false));
|
||||
EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUriAndEncryption(
|
||||
extensions, kExtensionUri2, false));
|
||||
EXPECT_EQ(kExtension1Encrypted,
|
||||
*RtpExtension::FindHeaderExtensionByUriAndEncryption(
|
||||
extensions, kExtensionUri1, true));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUriAndEncryption(
|
||||
extensions, kExtensionUri2, true));
|
||||
}
|
||||
|
||||
TEST(RtpExtensionTest, FindHeaderExtensionByUri) {
|
||||
std::vector<RtpExtension> extensions;
|
||||
|
||||
extensions.clear();
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
EXPECT_EQ(kExtension1Encrypted,
|
||||
*RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
EXPECT_EQ(kExtension1Encrypted,
|
||||
*RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
extensions.push_back(kExtension1);
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
extensions.push_back(kExtension1);
|
||||
EXPECT_EQ(kExtension1Encrypted,
|
||||
*RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
extensions.push_back(kExtension1);
|
||||
EXPECT_EQ(kExtension1Encrypted,
|
||||
*RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension2);
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
|
||||
extensions.clear();
|
||||
extensions.push_back(kExtension1);
|
||||
extensions.push_back(kExtension2);
|
||||
extensions.push_back(kExtension1Encrypted);
|
||||
EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
EXPECT_EQ(kExtension1Encrypted,
|
||||
*RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
EXPECT_EQ(kExtension1Encrypted,
|
||||
*RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri1,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kDiscardEncryptedExtension));
|
||||
EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kPreferEncryptedExtension));
|
||||
EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
|
||||
extensions, kExtensionUri2,
|
||||
RtpExtension::Filter::kRequireEncryptedExtension));
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
Reference in New Issue
Block a user