/*
 *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "pc/dtls_srtp_transport.h"

#include <string.h>
#include <cstdint>
#include <memory>
#include <set>

#include "absl/memory/memory.h"
#include "call/rtp_demuxer.h"
#include "media/base/fake_rtp.h"
#include "p2p/base/dtls_transport_internal.h"
#include "p2p/base/fake_dtls_transport.h"
#include "p2p/base/fake_ice_transport.h"
#include "p2p/base/p2p_constants.h"
#include "pc/rtp_transport.h"
#include "pc/test/rtp_transport_test_util.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/byte_order.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/ssl_identity.h"
#include "test/gtest.h"

using cricket::FakeDtlsTransport;
using cricket::FakeIceTransport;
using webrtc::DtlsSrtpTransport;
using webrtc::SrtpTransport;
using webrtc::RtpTransport;

const int kRtpAuthTagLen = 10;

class DtlsSrtpTransportTest : public testing::Test,
                              public sigslot::has_slots<> {
 protected:
  DtlsSrtpTransportTest() {}

  ~DtlsSrtpTransportTest() {
    if (dtls_srtp_transport1_) {
      dtls_srtp_transport1_->UnregisterRtpDemuxerSink(&transport_observer1_);
    }
    if (dtls_srtp_transport2_) {
      dtls_srtp_transport2_->UnregisterRtpDemuxerSink(&transport_observer2_);
    }
  }

  std::unique_ptr<DtlsSrtpTransport> MakeDtlsSrtpTransport(
      FakeDtlsTransport* rtp_dtls,
      FakeDtlsTransport* rtcp_dtls,
      bool rtcp_mux_enabled) {
    auto dtls_srtp_transport =
        absl::make_unique<DtlsSrtpTransport>(rtcp_mux_enabled);

    dtls_srtp_transport->SetDtlsTransports(rtp_dtls, rtcp_dtls);

    return dtls_srtp_transport;
  }

  void MakeDtlsSrtpTransports(FakeDtlsTransport* rtp_dtls1,
                              FakeDtlsTransport* rtcp_dtls1,
                              FakeDtlsTransport* rtp_dtls2,
                              FakeDtlsTransport* rtcp_dtls2,
                              bool rtcp_mux_enabled) {
    dtls_srtp_transport1_ =
        MakeDtlsSrtpTransport(rtp_dtls1, rtcp_dtls1, rtcp_mux_enabled);
    dtls_srtp_transport2_ =
        MakeDtlsSrtpTransport(rtp_dtls2, rtcp_dtls2, rtcp_mux_enabled);

    dtls_srtp_transport1_->SignalRtcpPacketReceived.connect(
        &transport_observer1_,
        &webrtc::TransportObserver::OnRtcpPacketReceived);
    dtls_srtp_transport1_->SignalReadyToSend.connect(
        &transport_observer1_, &webrtc::TransportObserver::OnReadyToSend);

    dtls_srtp_transport2_->SignalRtcpPacketReceived.connect(
        &transport_observer2_,
        &webrtc::TransportObserver::OnRtcpPacketReceived);
    dtls_srtp_transport2_->SignalReadyToSend.connect(
        &transport_observer2_, &webrtc::TransportObserver::OnReadyToSend);
    webrtc::RtpDemuxerCriteria demuxer_criteria;
    // 0x00 is the payload type used in kPcmuFrame.
    demuxer_criteria.payload_types = {0x00};
    dtls_srtp_transport1_->RegisterRtpDemuxerSink(demuxer_criteria,
                                                  &transport_observer1_);
    dtls_srtp_transport2_->RegisterRtpDemuxerSink(demuxer_criteria,
                                                  &transport_observer2_);
  }

  void CompleteDtlsHandshake(FakeDtlsTransport* fake_dtls1,
                             FakeDtlsTransport* fake_dtls2) {
    auto cert1 = rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
        rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
    fake_dtls1->SetLocalCertificate(cert1);
    auto cert2 = rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
        rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
    fake_dtls2->SetLocalCertificate(cert2);
    fake_dtls1->SetDestination(fake_dtls2);
  }

  void SendRecvRtpPackets() {
    ASSERT_TRUE(dtls_srtp_transport1_);
    ASSERT_TRUE(dtls_srtp_transport2_);
    ASSERT_TRUE(dtls_srtp_transport1_->IsSrtpActive());
    ASSERT_TRUE(dtls_srtp_transport2_->IsSrtpActive());

    size_t rtp_len = sizeof(kPcmuFrame);
    size_t packet_size = rtp_len + kRtpAuthTagLen;
    rtc::Buffer rtp_packet_buffer(packet_size);
    char* rtp_packet_data = rtp_packet_buffer.data<char>();
    memcpy(rtp_packet_data, kPcmuFrame, 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_data) + 2,
                 ++sequence_number_);
    rtc::CopyOnWriteBuffer rtp_packet1to2(rtp_packet_data, rtp_len,
                                          packet_size);
    rtc::CopyOnWriteBuffer rtp_packet2to1(rtp_packet_data, rtp_len,
                                          packet_size);

    rtc::PacketOptions options;
    // Send a packet from |srtp_transport1_| to |srtp_transport2_| and verify
    // that the packet can be successfully received and decrypted.
    int prev_received_packets = transport_observer2_.rtp_count();
    ASSERT_TRUE(dtls_srtp_transport1_->SendRtpPacket(&rtp_packet1to2, options,
                                                     cricket::PF_SRTP_BYPASS));
    ASSERT_TRUE(transport_observer2_.last_recv_rtp_packet().data());
    EXPECT_EQ(0, memcmp(transport_observer2_.last_recv_rtp_packet().data(),
                        kPcmuFrame, rtp_len));
    EXPECT_EQ(prev_received_packets + 1, transport_observer2_.rtp_count());

    prev_received_packets = transport_observer1_.rtp_count();
    ASSERT_TRUE(dtls_srtp_transport2_->SendRtpPacket(&rtp_packet2to1, options,
                                                     cricket::PF_SRTP_BYPASS));
    ASSERT_TRUE(transport_observer1_.last_recv_rtp_packet().data());
    EXPECT_EQ(0, memcmp(transport_observer1_.last_recv_rtp_packet().data(),
                        kPcmuFrame, rtp_len));
    EXPECT_EQ(prev_received_packets + 1, transport_observer1_.rtp_count());
  }

  void SendRecvRtcpPackets() {
    size_t rtcp_len = sizeof(kRtcpReport);
    size_t packet_size = rtcp_len + 4 + kRtpAuthTagLen;
    rtc::Buffer rtcp_packet_buffer(packet_size);

    // TODO(zhihuang): Remove the extra copy when the SendRtpPacket method
    // doesn't take the CopyOnWriteBuffer by pointer.
    rtc::CopyOnWriteBuffer rtcp_packet1to2(kRtcpReport, rtcp_len, packet_size);
    rtc::CopyOnWriteBuffer rtcp_packet2to1(kRtcpReport, rtcp_len, packet_size);

    rtc::PacketOptions options;
    // Send a packet from |srtp_transport1_| to |srtp_transport2_| and verify
    // that the packet can be successfully received and decrypted.
    int prev_received_packets = transport_observer2_.rtcp_count();
    ASSERT_TRUE(dtls_srtp_transport1_->SendRtcpPacket(&rtcp_packet1to2, options,
                                                      cricket::PF_SRTP_BYPASS));
    ASSERT_TRUE(transport_observer2_.last_recv_rtcp_packet().data());
    EXPECT_EQ(0, memcmp(transport_observer2_.last_recv_rtcp_packet().data(),
                        kRtcpReport, rtcp_len));
    EXPECT_EQ(prev_received_packets + 1, transport_observer2_.rtcp_count());

    // Do the same thing in the opposite direction;
    prev_received_packets = transport_observer1_.rtcp_count();
    ASSERT_TRUE(dtls_srtp_transport2_->SendRtcpPacket(&rtcp_packet2to1, options,
                                                      cricket::PF_SRTP_BYPASS));
    ASSERT_TRUE(transport_observer1_.last_recv_rtcp_packet().data());
    EXPECT_EQ(0, memcmp(transport_observer1_.last_recv_rtcp_packet().data(),
                        kRtcpReport, rtcp_len));
    EXPECT_EQ(prev_received_packets + 1, transport_observer1_.rtcp_count());
  }

  void SendRecvRtpPacketsWithHeaderExtension(
      const std::vector<int>& encrypted_header_ids) {
    ASSERT_TRUE(dtls_srtp_transport1_);
    ASSERT_TRUE(dtls_srtp_transport2_);
    ASSERT_TRUE(dtls_srtp_transport1_->IsSrtpActive());
    ASSERT_TRUE(dtls_srtp_transport2_->IsSrtpActive());

    size_t rtp_len = sizeof(kPcmuFrameWithExtensions);
    size_t packet_size = rtp_len + kRtpAuthTagLen;
    rtc::Buffer rtp_packet_buffer(packet_size);
    char* rtp_packet_data = rtp_packet_buffer.data<char>();
    memcpy(rtp_packet_data, 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_data) + 2,
                 ++sequence_number_);
    rtc::CopyOnWriteBuffer rtp_packet1to2(rtp_packet_data, rtp_len,
                                          packet_size);
    rtc::CopyOnWriteBuffer rtp_packet2to1(rtp_packet_data, rtp_len,
                                          packet_size);

    char original_rtp_data[sizeof(kPcmuFrameWithExtensions)];
    memcpy(original_rtp_data, rtp_packet_data, rtp_len);

    rtc::PacketOptions options;
    // Send a packet from |srtp_transport1_| to |srtp_transport2_| and verify
    // that the packet can be successfully received and decrypted.
    ASSERT_TRUE(dtls_srtp_transport1_->SendRtpPacket(&rtp_packet1to2, options,
                                                     cricket::PF_SRTP_BYPASS));
    ASSERT_TRUE(transport_observer2_.last_recv_rtp_packet().data());
    EXPECT_EQ(0, memcmp(transport_observer2_.last_recv_rtp_packet().data(),
                        original_rtp_data, rtp_len));
    // Get the encrypted packet from underneath packet transport and verify the
    // data and header extension are actually encrypted.
    auto fake_dtls_transport = static_cast<FakeDtlsTransport*>(
        dtls_srtp_transport1_->rtp_packet_transport());
    auto fake_ice_transport =
        static_cast<FakeIceTransport*>(fake_dtls_transport->ice_transport());
    EXPECT_NE(0, memcmp(fake_ice_transport->last_sent_packet().data(),
                        original_rtp_data, rtp_len));
    CompareHeaderExtensions(reinterpret_cast<const char*>(
                                fake_ice_transport->last_sent_packet().data()),
                            fake_ice_transport->last_sent_packet().size(),
                            original_rtp_data, rtp_len, encrypted_header_ids,
                            false);

    // Do the same thing in the opposite direction.
    ASSERT_TRUE(dtls_srtp_transport2_->SendRtpPacket(&rtp_packet2to1, options,
                                                     cricket::PF_SRTP_BYPASS));
    ASSERT_TRUE(transport_observer1_.last_recv_rtp_packet().data());
    EXPECT_EQ(0, memcmp(transport_observer1_.last_recv_rtp_packet().data(),
                        original_rtp_data, rtp_len));
    // Get the encrypted packet from underneath packet transport and verify the
    // data and header extension are actually encrypted.
    fake_dtls_transport = static_cast<FakeDtlsTransport*>(
        dtls_srtp_transport2_->rtp_packet_transport());
    fake_ice_transport =
        static_cast<FakeIceTransport*>(fake_dtls_transport->ice_transport());
    EXPECT_NE(0, memcmp(fake_ice_transport->last_sent_packet().data(),
                        original_rtp_data, rtp_len));
    CompareHeaderExtensions(reinterpret_cast<const char*>(
                                fake_ice_transport->last_sent_packet().data()),
                            fake_ice_transport->last_sent_packet().size(),
                            original_rtp_data, rtp_len, encrypted_header_ids,
                            false);
  }

  void SendRecvPackets() {
    SendRecvRtpPackets();
    SendRecvRtcpPackets();
  }

  std::unique_ptr<DtlsSrtpTransport> dtls_srtp_transport1_;
  std::unique_ptr<DtlsSrtpTransport> dtls_srtp_transport2_;
  webrtc::TransportObserver transport_observer1_;
  webrtc::TransportObserver transport_observer2_;

  int sequence_number_ = 0;
};

// Tests that if RTCP muxing is enabled and transports are set after RTP
// transport finished the handshake, SRTP is set up.
TEST_F(DtlsSrtpTransportTest, SetTransportsAfterHandshakeCompleteWithRtcpMux) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "video", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "video", cricket::ICE_CANDIDATE_COMPONENT_RTP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), nullptr, rtp_dtls2.get(), nullptr,
                         /*rtcp_mux_enabled=*/true);

  auto rtp_dtls3 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtp_dtls4 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);

  CompleteDtlsHandshake(rtp_dtls3.get(), rtp_dtls4.get());

  dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls3.get(), nullptr);
  dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls4.get(), nullptr);

  SendRecvPackets();
}

// Tests that if RTCP muxing is not enabled and transports are set after both
// RTP and RTCP transports finished the handshake, SRTP is set up.
TEST_F(DtlsSrtpTransportTest,
       SetTransportsAfterHandshakeCompleteWithoutRtcpMux) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "video", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "video", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "video", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "video", cricket::ICE_CANDIDATE_COMPONENT_RTCP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
                         rtcp_dtls2.get(), /*rtcp_mux_enabled=*/false);

  auto rtp_dtls3 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls3 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  auto rtp_dtls4 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls4 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  CompleteDtlsHandshake(rtp_dtls3.get(), rtp_dtls4.get());
  CompleteDtlsHandshake(rtcp_dtls3.get(), rtcp_dtls4.get());

  dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls3.get(), rtcp_dtls3.get());
  dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls4.get(), rtcp_dtls4.get());

  SendRecvPackets();
}

// Tests if RTCP muxing is enabled, SRTP is set up as soon as the RTP DTLS
// handshake is finished.
TEST_F(DtlsSrtpTransportTest, SetTransportsBeforeHandshakeCompleteWithRtcpMux) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
                         rtcp_dtls2.get(),
                         /*rtcp_mux_enabled=*/false);

  dtls_srtp_transport1_->SetRtcpMuxEnabled(true);
  dtls_srtp_transport2_->SetRtcpMuxEnabled(true);
  CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
  SendRecvPackets();
}

// Tests if RTCP muxing is not enabled, SRTP is set up when both the RTP and
// RTCP DTLS handshake are finished.
TEST_F(DtlsSrtpTransportTest,
       SetTransportsBeforeHandshakeCompleteWithoutRtcpMux) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
                         rtcp_dtls2.get(), /*rtcp_mux_enabled=*/false);

  CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
  EXPECT_FALSE(dtls_srtp_transport1_->IsSrtpActive());
  EXPECT_FALSE(dtls_srtp_transport2_->IsSrtpActive());
  CompleteDtlsHandshake(rtcp_dtls1.get(), rtcp_dtls2.get());
  SendRecvPackets();
}

// Tests that if the DtlsTransport underneath is changed, the previous DTLS-SRTP
// context will be reset and will be re-setup once the new transports' handshake
// complete.
TEST_F(DtlsSrtpTransportTest, DtlsSrtpResetAfterDtlsTransportChange) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), nullptr, rtp_dtls2.get(), nullptr,
                         /*rtcp_mux_enabled=*/true);

  CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
  EXPECT_TRUE(dtls_srtp_transport1_->IsSrtpActive());
  EXPECT_TRUE(dtls_srtp_transport2_->IsSrtpActive());

  auto rtp_dtls3 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtp_dtls4 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);

  // The previous context is reset.
  dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls3.get(), nullptr);
  dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls4.get(), nullptr);
  EXPECT_FALSE(dtls_srtp_transport1_->IsSrtpActive());
  EXPECT_FALSE(dtls_srtp_transport2_->IsSrtpActive());

  // Re-setup.
  CompleteDtlsHandshake(rtp_dtls3.get(), rtp_dtls4.get());
  SendRecvPackets();
}

// Tests if only the RTP DTLS handshake complete, and then RTCP muxing is
// enabled, SRTP is set up.
TEST_F(DtlsSrtpTransportTest,
       RtcpMuxEnabledAfterRtpTransportHandshakeComplete) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
                         rtcp_dtls2.get(), /*rtcp_mux_enabled=*/false);

  CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
  // Inactive because the RTCP transport handshake didn't complete.
  EXPECT_FALSE(dtls_srtp_transport1_->IsSrtpActive());
  EXPECT_FALSE(dtls_srtp_transport2_->IsSrtpActive());

  dtls_srtp_transport1_->SetRtcpMuxEnabled(true);
  dtls_srtp_transport2_->SetRtcpMuxEnabled(true);
  // The transports should be active and be able to send packets when the
  // RTCP muxing is enabled.
  SendRecvPackets();
}

// Tests that when SetSend/RecvEncryptedHeaderExtensionIds is called, the SRTP
// sessions are updated with new encryped header extension IDs immediately.
TEST_F(DtlsSrtpTransportTest, EncryptedHeaderExtensionIdUpdated) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), nullptr, rtp_dtls2.get(), nullptr,
                         /*rtcp_mux_enabled=*/true);
  CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());

  std::vector<int> encrypted_headers;
  encrypted_headers.push_back(kHeaderExtensionIDs[0]);
  encrypted_headers.push_back(kHeaderExtensionIDs[1]);

  dtls_srtp_transport1_->UpdateSendEncryptedHeaderExtensionIds(
      encrypted_headers);
  dtls_srtp_transport1_->UpdateRecvEncryptedHeaderExtensionIds(
      encrypted_headers);
  dtls_srtp_transport2_->UpdateSendEncryptedHeaderExtensionIds(
      encrypted_headers);
  dtls_srtp_transport2_->UpdateRecvEncryptedHeaderExtensionIds(
      encrypted_headers);
}

// Tests if RTCP muxing is enabled. DtlsSrtpTransport is ready to send once the
// RTP DtlsTransport is ready.
TEST_F(DtlsSrtpTransportTest, SignalReadyToSendFiredWithRtcpMux) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), nullptr, rtp_dtls2.get(), nullptr,
                         /*rtcp_mux_enabled=*/true);

  rtp_dtls1->SetDestination(rtp_dtls2.get());
  EXPECT_TRUE(transport_observer1_.ready_to_send());
  EXPECT_TRUE(transport_observer2_.ready_to_send());
}

// Tests if RTCP muxing is not enabled. DtlsSrtpTransport is ready to send once
// both the RTP and RTCP DtlsTransport are ready.
TEST_F(DtlsSrtpTransportTest, SignalReadyToSendFiredWithoutRtcpMux) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
                         rtcp_dtls2.get(), /*rtcp_mux_enabled=*/false);

  rtp_dtls1->SetDestination(rtp_dtls2.get());
  EXPECT_FALSE(transport_observer1_.ready_to_send());
  EXPECT_FALSE(transport_observer2_.ready_to_send());

  rtcp_dtls1->SetDestination(rtcp_dtls2.get());
  EXPECT_TRUE(transport_observer1_.ready_to_send());
  EXPECT_TRUE(transport_observer2_.ready_to_send());
}

// Test that if an endpoint "fully" enables RTCP mux, setting the RTCP
// transport to null, it *doesn't* reset its SRTP context. That would cause the
// ROC and SRTCP index to be reset, causing replay detection and other errors
// when attempting to unprotect packets.
// Regression test for bugs.webrtc.org/8996
TEST_F(DtlsSrtpTransportTest, SrtpSessionNotResetWhenRtcpTransportRemoved) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
                         rtcp_dtls2.get(), /*rtcp_mux_enabled=*/true);
  CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
  CompleteDtlsHandshake(rtcp_dtls1.get(), rtcp_dtls2.get());

  // Send some RTCP packets, causing the SRTCP index to be incremented.
  SendRecvRtcpPackets();

  // Set RTCP transport to null, which previously would trigger this problem.
  dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls1.get(), nullptr);

  // Attempt to send more RTCP packets. If the issue occurred, one side would
  // reset its context while the other would not, causing replay detection
  // errors when a packet with a duplicate SRTCP index is received.
  SendRecvRtcpPackets();
}

// Tests that RTCP packets can be sent and received if both sides actively reset
// the SRTP parameters with the |active_reset_srtp_params_| flag.
TEST_F(DtlsSrtpTransportTest, ActivelyResetSrtpParams) {
  auto rtp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls1 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
  auto rtp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
  auto rtcp_dtls2 = absl::make_unique<FakeDtlsTransport>(
      "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);

  MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
                         rtcp_dtls2.get(), /*rtcp_mux_enabled=*/true);
  CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
  CompleteDtlsHandshake(rtcp_dtls1.get(), rtcp_dtls2.get());

  // Send some RTCP packets, causing the SRTCP index to be incremented.
  SendRecvRtcpPackets();

  // Only set the |active_reset_srtp_params_| flag to be true one side.
  dtls_srtp_transport1_->SetActiveResetSrtpParams(true);
  // Set RTCP transport to null to trigger the SRTP parameters update.
  dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls1.get(), nullptr);
  dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls2.get(), nullptr);

  // Sending some RTCP packets.
  size_t rtcp_len = sizeof(kRtcpReport);
  size_t packet_size = rtcp_len + 4 + kRtpAuthTagLen;
  rtc::Buffer rtcp_packet_buffer(packet_size);
  rtc::CopyOnWriteBuffer rtcp_packet(kRtcpReport, rtcp_len, packet_size);
  int prev_received_packets = transport_observer2_.rtcp_count();
  ASSERT_TRUE(dtls_srtp_transport1_->SendRtcpPacket(
      &rtcp_packet, rtc::PacketOptions(), cricket::PF_SRTP_BYPASS));
  // The RTCP packet is not exepected to be received because the SRTP parameters
  // are only reset on one side and the SRTCP index is out of sync.
  EXPECT_EQ(prev_received_packets, transport_observer2_.rtcp_count());

  // Set the flag to be true on the other side.
  dtls_srtp_transport2_->SetActiveResetSrtpParams(true);
  // Set RTCP transport to null to trigger the SRTP parameters update.
  dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls1.get(), nullptr);
  dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls2.get(), nullptr);

  // RTCP packets flow is expected to work just fine.
  SendRecvRtcpPackets();
}
