| Index: webrtc/pc/srtpfilter_unittest.cc
|
| diff --git a/webrtc/pc/srtpfilter_unittest.cc b/webrtc/pc/srtpfilter_unittest.cc
|
| index af8b69f73e334496ef4e2bc80224a66ecd85d6f8..33ff2e31bb9ea124ed278d5b9c52ef6990aca67b 100644
|
| --- a/webrtc/pc/srtpfilter_unittest.cc
|
| +++ b/webrtc/pc/srtpfilter_unittest.cc
|
| @@ -8,6 +8,8 @@
|
| * be found in the AUTHORS file in the root of the source tree.
|
| */
|
|
|
| +#include <algorithm>
|
| +
|
| #include "webrtc/pc/srtpfilter.h"
|
|
|
| #include "third_party/libsrtp/include/srtp.h"
|
| @@ -67,6 +69,8 @@ static const cricket::CryptoParams kTestCryptoParamsGcm3(
|
| 1, "AEAD_AES_128_GCM", kTestKeyParamsGcm3, "");
|
| static const cricket::CryptoParams kTestCryptoParamsGcm4(
|
| 1, "AEAD_AES_128_GCM", kTestKeyParamsGcm4, "");
|
| +static const char kDummyExtensionUri1[] = "dummy-extension-uri-1";
|
| +static const char kDummyExtensionUri4[] = "dummy-extension-uri-4";
|
|
|
| static int rtp_auth_tag_len(const std::string& cs) {
|
| if (cs == CS_AES_CM_128_HMAC_SHA1_32) {
|
| @@ -193,6 +197,99 @@ class SrtpFilterTest : public testing::Test {
|
| EXPECT_EQ(rtcp_len, out_len);
|
| EXPECT_EQ(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
|
| }
|
| + // This expects both packets to be based on kPcmuFrameWithExtensions.
|
| + // Header extensions with an id in "encrypted_headers" are expected to be
|
| + // different in the packets unless "expect_equal" is set to "true".
|
| + void CompareHeaderExtensions(const char* packet1, const char* packet2,
|
| + const std::vector<int> encrypted_headers,
|
| + bool expect_equal) {
|
| + // RTP header + extension header are the same.
|
| + EXPECT_EQ(0, memcmp(packet1, packet2, 12 + 4));
|
| + // Check for one-byte header extensions.
|
| + EXPECT_EQ('\xBE', packet1[12]);
|
| + EXPECT_EQ('\xDE', packet1[13]);
|
| + // Determine position and size of extension headers.
|
| + size_t extension_words = packet1[14] << 8 | packet1[15];
|
| + const char* extension_data1 = packet1 + 12 + 4;
|
| + const char* extension_end1 = extension_data1 + extension_words * 4;
|
| + const char* extension_data2 = packet2 + 12 + 4;
|
| + while (extension_data1 < extension_end1) {
|
| + uint8_t id = (*extension_data1 & 0xf0) >> 4;
|
| + uint8_t len = (*extension_data1 & 0x0f) +1;
|
| + extension_data1++;
|
| + extension_data2++;
|
| + EXPECT_LE(extension_data1, extension_end1);
|
| + if (id == 15) {
|
| + // Finished parsing.
|
| + break;
|
| + }
|
| +
|
| + // The header extension doesn't get encrypted if the id not in the list
|
| + // of header extensions to encrypt.
|
| + if (expect_equal ||
|
| + std::find(encrypted_headers.begin(), encrypted_headers.end(), id) ==
|
| + encrypted_headers.end()) {
|
| + EXPECT_EQ(0, memcmp(extension_data1, extension_data2, len));
|
| + } else {
|
| + EXPECT_NE(0, memcmp(extension_data1, extension_data2, len));
|
| + }
|
| +
|
| + extension_data1 += len;
|
| + extension_data2 += len;
|
| + // Skip padding.
|
| + while (extension_data1 < extension_end1 && *extension_data1 == 0) {
|
| + extension_data1++;
|
| + extension_data2++;
|
| + }
|
| + }
|
| + }
|
| + void TestProtectUnprotectHeaderEncryption(const std::string& cs1,
|
| + const std::string& cs2,
|
| + const std::vector<webrtc::RtpExtension>& encrypted_headers) {
|
| + rtc::Buffer rtp_buffer(sizeof(kPcmuFrameWithExtensions) +
|
| + rtp_auth_tag_len(cs1));
|
| + char* rtp_packet = rtp_buffer.data<char>();
|
| + char original_rtp_packet[sizeof(kPcmuFrameWithExtensions)];
|
| + int rtp_len = sizeof(kPcmuFrameWithExtensions), out_len;
|
| + memcpy(rtp_packet, kPcmuFrameWithExtensions, rtp_len);
|
| + // In order to be able to run this test function multiple times we can not
|
| + // use the same sequence number twice. Increase the sequence number by one.
|
| + rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet) + 2,
|
| + ++sequence_number_);
|
| + memcpy(original_rtp_packet, rtp_packet, rtp_len);
|
| +
|
| + std::vector<int> encrypted_header_ids;
|
| + for (const webrtc::RtpExtension& extension : encrypted_headers) {
|
| + EXPECT_TRUE(extension.encrypt);
|
| + encrypted_header_ids.push_back(extension.id);
|
| + }
|
| +
|
| + EXPECT_TRUE(f1_.ProtectRtp(rtp_packet, rtp_len,
|
| + static_cast<int>(rtp_buffer.size()),
|
| + &out_len));
|
| + EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs1));
|
| + EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
|
| + CompareHeaderExtensions(rtp_packet, original_rtp_packet,
|
| + encrypted_header_ids, false);
|
| + EXPECT_TRUE(f2_.UnprotectRtp(rtp_packet, out_len, &out_len));
|
| + EXPECT_EQ(rtp_len, out_len);
|
| + EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
|
| + CompareHeaderExtensions(rtp_packet, original_rtp_packet,
|
| + encrypted_header_ids, true);
|
| +
|
| + EXPECT_TRUE(f2_.ProtectRtp(rtp_packet, rtp_len,
|
| + static_cast<int>(rtp_buffer.size()),
|
| + &out_len));
|
| + EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs2));
|
| + EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
|
| + CompareHeaderExtensions(rtp_packet, original_rtp_packet,
|
| + encrypted_header_ids, false);
|
| + EXPECT_TRUE(f1_.UnprotectRtp(rtp_packet, out_len, &out_len));
|
| + EXPECT_EQ(rtp_len, out_len);
|
| + EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
|
| + CompareHeaderExtensions(rtp_packet, original_rtp_packet,
|
| + encrypted_header_ids, true);
|
| + }
|
| void TestProtectSetParamsDirect(bool enable_external_auth, int cs,
|
| const uint8_t* key1, int key1_len, const uint8_t* key2, int key2_len,
|
| const std::string& cs_name) {
|
| @@ -217,6 +314,29 @@ class SrtpFilterTest : public testing::Test {
|
| }
|
| TestProtectUnprotect(cs_name, cs_name);
|
| }
|
| + void TestProtectSetParamsDirectHeaderEncryption(int cs,
|
| + const uint8_t* key1, int key1_len, const uint8_t* key2, int key2_len,
|
| + const std::string& cs_name) {
|
| + std::vector<webrtc::RtpExtension> encrypted_headers;
|
| + encrypted_headers.push_back(
|
| + webrtc::RtpExtension(kDummyExtensionUri1, 1, true));
|
| + // Don't encrypt header ids 2 and 3.
|
| + encrypted_headers.push_back(
|
| + webrtc::RtpExtension(kDummyExtensionUri4, 4, true));
|
| + EXPECT_EQ(key1_len, key2_len);
|
| + EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs));
|
| + f1_.SetEncryptedHeaderExtensions(CS_LOCAL, encrypted_headers);
|
| + f1_.SetEncryptedHeaderExtensions(CS_REMOTE, encrypted_headers);
|
| + f2_.SetEncryptedHeaderExtensions(CS_LOCAL, encrypted_headers);
|
| + f2_.SetEncryptedHeaderExtensions(CS_REMOTE, encrypted_headers);
|
| + EXPECT_TRUE(f1_.SetRtpParams(cs, key1, key1_len, cs, key2, key2_len));
|
| + EXPECT_TRUE(f2_.SetRtpParams(cs, key2, key2_len, cs, key1, key1_len));
|
| + EXPECT_TRUE(f1_.IsActive());
|
| + EXPECT_TRUE(f2_.IsActive());
|
| + EXPECT_FALSE(f1_.IsExternalAuthActive());
|
| + EXPECT_FALSE(f2_.IsExternalAuthActive());
|
| + TestProtectUnprotectHeaderEncryption(cs_name, cs_name, encrypted_headers);
|
| + }
|
| cricket::SrtpFilter f1_;
|
| cricket::SrtpFilter f2_;
|
| int sequence_number_;
|
| @@ -619,6 +739,13 @@ TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_80) {
|
| CS_AES_CM_128_HMAC_SHA1_80);
|
| }
|
|
|
| +TEST_F(SrtpFilterTest,
|
| + TestProtectSetParamsDirectHeaderEncryption_AES_CM_128_HMAC_SHA1_80) {
|
| + TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AES128_CM_SHA1_80,
|
| + kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen,
|
| + CS_AES_CM_128_HMAC_SHA1_80);
|
| +}
|
| +
|
| // Test directly setting the params with AES_CM_128_HMAC_SHA1_32.
|
| TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_32) {
|
| bool enable_external_auth = GetParam();
|
| @@ -627,6 +754,13 @@ TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_32) {
|
| CS_AES_CM_128_HMAC_SHA1_32);
|
| }
|
|
|
| +TEST_F(SrtpFilterTest,
|
| + TestProtectSetParamsDirectHeaderEncryption_AES_CM_128_HMAC_SHA1_32) {
|
| + TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AES128_CM_SHA1_32,
|
| + kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen,
|
| + CS_AES_CM_128_HMAC_SHA1_32);
|
| +}
|
| +
|
| // Test directly setting the params with SRTP_AEAD_AES_128_GCM.
|
| TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_128_GCM) {
|
| bool enable_external_auth = GetParam();
|
| @@ -635,6 +769,13 @@ TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_128_GCM) {
|
| CS_AEAD_AES_128_GCM);
|
| }
|
|
|
| +TEST_F(SrtpFilterTest,
|
| + TestProtectSetParamsDirectHeaderEncryption_SRTP_AEAD_AES_128_GCM) {
|
| + TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AEAD_AES_128_GCM,
|
| + kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2, kTestKeyGcm128Len,
|
| + CS_AEAD_AES_128_GCM);
|
| +}
|
| +
|
| // Test directly setting the params with SRTP_AEAD_AES_256_GCM.
|
| TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_256_GCM) {
|
| bool enable_external_auth = GetParam();
|
| @@ -643,6 +784,13 @@ TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_256_GCM) {
|
| CS_AEAD_AES_256_GCM);
|
| }
|
|
|
| +TEST_F(SrtpFilterTest,
|
| + TestProtectSetParamsDirectHeaderEncryption_SRTP_AEAD_AES_256_GCM) {
|
| + TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AEAD_AES_256_GCM,
|
| + kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2, kTestKeyGcm256Len,
|
| + CS_AEAD_AES_256_GCM);
|
| +}
|
| +
|
| // Run all tests both with and without external auth enabled.
|
| INSTANTIATE_TEST_CASE_P(ExternalAuth,
|
| SrtpFilterProtectSetParamsDirectTest,
|
| @@ -704,30 +852,44 @@ class SrtpSessionTest : public testing::Test {
|
|
|
| // Test that we can set up the session and keys properly.
|
| TEST_F(SrtpSessionTest, TestGoodSetup) {
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| - EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| + std::vector<int> no_encrypted_headers;
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| + EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| }
|
|
|
| // Test that we can't change the keys once set.
|
| TEST_F(SrtpSessionTest, TestBadSetup) {
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| - EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| + std::vector<int> no_encrypted_headers;
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| + EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| EXPECT_FALSE(
|
| - s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey2, kTestKeyLen));
|
| + s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey2, kTestKeyLen,
|
| + no_encrypted_headers));
|
| EXPECT_FALSE(
|
| - s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey2, kTestKeyLen));
|
| + s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey2, kTestKeyLen,
|
| + no_encrypted_headers));
|
| }
|
|
|
| // Test that we fail keys of the wrong length.
|
| TEST_F(SrtpSessionTest, TestKeysTooShort) {
|
| - EXPECT_FALSE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, 1));
|
| - EXPECT_FALSE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, 1));
|
| + std::vector<int> no_encrypted_headers;
|
| + EXPECT_FALSE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, 1,
|
| + no_encrypted_headers));
|
| + EXPECT_FALSE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, 1,
|
| + no_encrypted_headers));
|
| }
|
|
|
| // Test that we can encrypt and decrypt RTP/RTCP using AES_CM_128_HMAC_SHA1_80.
|
| TEST_F(SrtpSessionTest, TestProtect_AES_CM_128_HMAC_SHA1_80) {
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| - EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| + std::vector<int> no_encrypted_headers;
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| + EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_80);
|
| TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_80);
|
| TestUnprotectRtp(CS_AES_CM_128_HMAC_SHA1_80);
|
| @@ -736,8 +898,11 @@ TEST_F(SrtpSessionTest, TestProtect_AES_CM_128_HMAC_SHA1_80) {
|
|
|
| // Test that we can encrypt and decrypt RTP/RTCP using AES_CM_128_HMAC_SHA1_32.
|
| TEST_F(SrtpSessionTest, TestProtect_AES_CM_128_HMAC_SHA1_32) {
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen));
|
| - EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen));
|
| + std::vector<int> no_encrypted_headers;
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| + EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_32);
|
| TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_32);
|
| TestUnprotectRtp(CS_AES_CM_128_HMAC_SHA1_32);
|
| @@ -745,7 +910,9 @@ TEST_F(SrtpSessionTest, TestProtect_AES_CM_128_HMAC_SHA1_32) {
|
| }
|
|
|
| TEST_F(SrtpSessionTest, TestGetSendStreamPacketIndex) {
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen));
|
| + std::vector<int> no_encrypted_headers;
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| int64_t index;
|
| int out_len = 0;
|
| EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_,
|
| @@ -757,9 +924,12 @@ TEST_F(SrtpSessionTest, TestGetSendStreamPacketIndex) {
|
|
|
| // Test that we fail to unprotect if someone tampers with the RTP/RTCP paylaods.
|
| TEST_F(SrtpSessionTest, TestTamperReject) {
|
| + std::vector<int> no_encrypted_headers;
|
| int out_len;
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| - EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| + EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_80);
|
| TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_80);
|
| rtp_packet_[0] = 0x12;
|
| @@ -770,17 +940,22 @@ TEST_F(SrtpSessionTest, TestTamperReject) {
|
|
|
| // Test that we fail to unprotect if the payloads are not authenticated.
|
| TEST_F(SrtpSessionTest, TestUnencryptReject) {
|
| + std::vector<int> no_encrypted_headers;
|
| int out_len;
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| - EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| + EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| EXPECT_FALSE(s2_.UnprotectRtp(rtp_packet_, rtp_len_, &out_len));
|
| EXPECT_FALSE(s2_.UnprotectRtcp(rtcp_packet_, rtcp_len_, &out_len));
|
| }
|
|
|
| // Test that we fail when using buffers that are too small.
|
| TEST_F(SrtpSessionTest, TestBuffersTooSmall) {
|
| + std::vector<int> no_encrypted_headers;
|
| int out_len;
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| EXPECT_FALSE(s1_.ProtectRtp(rtp_packet_, rtp_len_,
|
| sizeof(rtp_packet_) - 10, &out_len));
|
| EXPECT_FALSE(s1_.ProtectRtcp(rtcp_packet_, rtcp_len_,
|
| @@ -788,14 +963,17 @@ TEST_F(SrtpSessionTest, TestBuffersTooSmall) {
|
| }
|
|
|
| TEST_F(SrtpSessionTest, TestReplay) {
|
| + std::vector<int> no_encrypted_headers;
|
| static const uint16_t kMaxSeqnum = static_cast<uint16_t>(-1);
|
| static const uint16_t seqnum_big = 62275;
|
| static const uint16_t seqnum_small = 10;
|
| static const uint16_t replay_window = 1024;
|
| int out_len;
|
|
|
| - EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| - EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen));
|
| + EXPECT_TRUE(s1_.SetSend(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
| + EXPECT_TRUE(s2_.SetRecv(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
|
| + no_encrypted_headers));
|
|
|
| // Initial sequence number.
|
| rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2, seqnum_big);
|
|
|