Replace BundleFilter with RtpDemuxer in RtpTransport.

BundleFilter is replaced by RtpDemuxer in RtpTransport for payload
type-based demuxing. RtpTransport will support MID-based demuxing later.

Each BaseChannel has its own RTP demuxing criteria and when connecting
to the RtpTransport, BaseChannel will register itself as a demuxer sink.

The inheritance model is changed. New inheritance chain:
DtlsSrtpTransport->SrtpTransport->RtpTranpsort

The JsepTransport2 is renamed to JsepTransport.

NOTE:
When RTCP packets are received, Call::DeliverRtcp will be called for
multiple times (webrtc:9035) which is an existing issue. With this CL,
it will become more of a problem and should be fixed.

Bug: webrtc:8587
Change-Id: Ibd880e7b744bd912336a691309950bc18e42cf62
Reviewed-on: https://webrtc-review.googlesource.com/65786
Commit-Queue: Zhi Huang <zhihuang@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Benjamin Wright <benwright@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22867}
diff --git a/pc/srtptransport.cc b/pc/srtptransport.cc
index 3e7b154..1fe0cc8 100644
--- a/pc/srtptransport.cc
+++ b/pc/srtptransport.cc
@@ -19,6 +19,7 @@
 #include "rtc_base/asyncpacketsocket.h"
 #include "rtc_base/base64.h"
 #include "rtc_base/copyonwritebuffer.h"
+#include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/ptr_util.h"
 #include "rtc_base/trace_event.h"
 #include "rtc_base/zero_memory.h"
@@ -26,31 +27,7 @@
 namespace webrtc {
 
 SrtpTransport::SrtpTransport(bool rtcp_mux_enabled)
-    : RtpTransportInternalAdapter(new RtpTransport(rtcp_mux_enabled)) {
-  // Own the raw pointer |transport| from the base class.
-  rtp_transport_.reset(static_cast<RtpTransport*>(transport_));
-  RTC_DCHECK(rtp_transport_);
-  ConnectToRtpTransport();
-}
-
-SrtpTransport::SrtpTransport(std::unique_ptr<RtpTransport> rtp_transport)
-    : RtpTransportInternalAdapter(rtp_transport.get()),
-      rtp_transport_(std::move(rtp_transport)) {
-  RTC_DCHECK(rtp_transport_);
-  ConnectToRtpTransport();
-}
-
-void SrtpTransport::ConnectToRtpTransport() {
-  rtp_transport_->SignalPacketReceived.connect(
-      this, &SrtpTransport::OnPacketReceived);
-  rtp_transport_->SignalReadyToSend.connect(this,
-                                            &SrtpTransport::OnReadyToSend);
-  rtp_transport_->SignalNetworkRouteChanged.connect(
-      this, &SrtpTransport::OnNetworkRouteChanged);
-  rtp_transport_->SignalWritableState.connect(this,
-                                              &SrtpTransport::OnWritableState);
-  rtp_transport_->SignalSentPacket.connect(this, &SrtpTransport::OnSentPacket);
-}
+    : RtpTransport(rtcp_mux_enabled) {}
 
 RTCError SrtpTransport::SetSrtpSendKey(const cricket::CryptoParams& params) {
   if (send_params_) {
@@ -135,125 +112,128 @@
 bool SrtpTransport::SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
                                   const rtc::PacketOptions& options,
                                   int flags) {
-  return SendPacket(false, packet, options, flags);
-}
-
-bool SrtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
-                                   const rtc::PacketOptions& options,
-                                   int flags) {
-  return SendPacket(true, packet, options, flags);
-}
-
-bool SrtpTransport::SendPacket(bool rtcp,
-                               rtc::CopyOnWriteBuffer* packet,
-                               const rtc::PacketOptions& options,
-                               int flags) {
   if (!IsSrtpActive()) {
     RTC_LOG(LS_ERROR)
         << "Failed to send the packet because SRTP transport is inactive.";
     return false;
   }
-
   rtc::PacketOptions updated_options = options;
-  rtc::CopyOnWriteBuffer cp = *packet;
   TRACE_EVENT0("webrtc", "SRTP Encode");
   bool res;
   uint8_t* data = packet->data();
-  int len = static_cast<int>(packet->size());
-  if (!rtcp) {
+  int len = rtc::checked_cast<int>(packet->size());
 // If ENABLE_EXTERNAL_AUTH flag is on then packet authentication is not done
 // inside libsrtp for a RTP packet. A external HMAC module will be writing
 // a fake HMAC value. This is ONLY done for a RTP packet.
 // Socket layer will update rtp sendtime extension header if present in
 // packet with current time before updating the HMAC.
 #if !defined(ENABLE_EXTERNAL_AUTH)
-    res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len);
+  res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len);
 #else
-    if (!IsExternalAuthActive()) {
-      res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len);
-    } else {
-      updated_options.packet_time_params.rtp_sendtime_extension_id =
-          rtp_abs_sendtime_extn_id_;
-      res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len,
-                       &updated_options.packet_time_params.srtp_packet_index);
-      // If protection succeeds, let's get auth params from srtp.
+  if (!IsExternalAuthActive()) {
+    res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len);
+  } else {
+    updated_options.packet_time_params.rtp_sendtime_extension_id =
+        rtp_abs_sendtime_extn_id_;
+    res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len,
+                     &updated_options.packet_time_params.srtp_packet_index);
+    // If protection succeeds, let's get auth params from srtp.
+    if (res) {
+      uint8_t* auth_key = nullptr;
+      int key_len = 0;
+      res = GetRtpAuthParams(
+          &auth_key, &key_len,
+          &updated_options.packet_time_params.srtp_auth_tag_len);
       if (res) {
-        uint8_t* auth_key = NULL;
-        int key_len;
-        res = GetRtpAuthParams(
-            &auth_key, &key_len,
-            &updated_options.packet_time_params.srtp_auth_tag_len);
-        if (res) {
-          updated_options.packet_time_params.srtp_auth_key.resize(key_len);
-          updated_options.packet_time_params.srtp_auth_key.assign(
-              auth_key, auth_key + key_len);
-        }
+        updated_options.packet_time_params.srtp_auth_key.resize(key_len);
+        updated_options.packet_time_params.srtp_auth_key.assign(
+            auth_key, auth_key + key_len);
       }
     }
+  }
 #endif
-    if (!res) {
-      int seq_num = -1;
-      uint32_t ssrc = 0;
-      cricket::GetRtpSeqNum(data, len, &seq_num);
-      cricket::GetRtpSsrc(data, len, &ssrc);
-      RTC_LOG(LS_ERROR) << "Failed to protect RTP packet: size=" << len
-                        << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
-      return false;
-    }
-  } else {
-    res = ProtectRtcp(data, len, static_cast<int>(packet->capacity()), &len);
-    if (!res) {
-      int type = -1;
-      cricket::GetRtcpType(data, len, &type);
-      RTC_LOG(LS_ERROR) << "Failed to protect RTCP packet: size=" << len
-                        << ", type=" << type;
-      return false;
-    }
+  if (!res) {
+    int seq_num = -1;
+    uint32_t ssrc = 0;
+    cricket::GetRtpSeqNum(data, len, &seq_num);
+    cricket::GetRtpSsrc(data, len, &ssrc);
+    RTC_LOG(LS_ERROR) << "Failed to protect RTP packet: size=" << len
+                      << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
+    return false;
   }
 
   // Update the length of the packet now that we've added the auth tag.
   packet->SetSize(len);
-  return rtcp ? rtp_transport_->SendRtcpPacket(packet, updated_options, flags)
-              : rtp_transport_->SendRtpPacket(packet, updated_options, flags);
+  return SendPacket(/*rtcp=*/false, packet, updated_options, flags);
 }
 
-void SrtpTransport::OnPacketReceived(bool rtcp,
-                                     rtc::CopyOnWriteBuffer* packet,
-                                     const rtc::PacketTime& packet_time) {
+bool SrtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
+                                   const rtc::PacketOptions& options,
+                                   int flags) {
+  if (!IsSrtpActive()) {
+    RTC_LOG(LS_ERROR)
+        << "Failed to send the packet because SRTP transport is inactive.";
+    return false;
+  }
+
+  TRACE_EVENT0("webrtc", "SRTP Encode");
+  uint8_t* data = packet->data();
+  int len = rtc::checked_cast<int>(packet->size());
+  if (!ProtectRtcp(data, len, static_cast<int>(packet->capacity()), &len)) {
+    int type = -1;
+    cricket::GetRtcpType(data, len, &type);
+    RTC_LOG(LS_ERROR) << "Failed to protect RTCP packet: size=" << len
+                      << ", type=" << type;
+    return false;
+  }
+  // Update the length of the packet now that we've added the auth tag.
+  packet->SetSize(len);
+
+  return SendPacket(/*rtcp=*/true, packet, options, flags);
+}
+
+void SrtpTransport::OnRtpPacketReceived(rtc::CopyOnWriteBuffer* packet,
+                                        const rtc::PacketTime& packet_time) {
   if (!IsSrtpActive()) {
     RTC_LOG(LS_WARNING)
-        << "Inactive SRTP transport received a packet. Drop it.";
+        << "Inactive SRTP transport received an RTP packet. Drop it.";
     return;
   }
-
   TRACE_EVENT0("webrtc", "SRTP Decode");
   char* data = packet->data<char>();
-  int len = static_cast<int>(packet->size());
-  bool res;
-  if (!rtcp) {
-    res = UnprotectRtp(data, len, &len);
-    if (!res) {
-      int seq_num = -1;
-      uint32_t ssrc = 0;
-      cricket::GetRtpSeqNum(data, len, &seq_num);
-      cricket::GetRtpSsrc(data, len, &ssrc);
-      RTC_LOG(LS_ERROR) << "Failed to unprotect RTP packet: size=" << len
-                        << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
-      return;
-    }
-  } else {
-    res = UnprotectRtcp(data, len, &len);
-    if (!res) {
-      int type = -1;
-      cricket::GetRtcpType(data, len, &type);
-      RTC_LOG(LS_ERROR) << "Failed to unprotect RTCP packet: size=" << len
-                        << ", type=" << type;
-      return;
-    }
+  int len = rtc::checked_cast<int>(packet->size());
+  if (!UnprotectRtp(data, len, &len)) {
+    int seq_num = -1;
+    uint32_t ssrc = 0;
+    cricket::GetRtpSeqNum(data, len, &seq_num);
+    cricket::GetRtpSsrc(data, len, &ssrc);
+    RTC_LOG(LS_ERROR) << "Failed to unprotect RTP packet: size=" << len
+                      << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
+    return;
   }
-
   packet->SetSize(len);
-  SignalPacketReceived(rtcp, packet, packet_time);
+  DemuxPacket(packet, packet_time);
+}
+
+void SrtpTransport::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
+                                         const rtc::PacketTime& packet_time) {
+  if (!IsSrtpActive()) {
+    RTC_LOG(LS_WARNING)
+        << "Inactive SRTP transport received an RTCP packet. Drop it.";
+    return;
+  }
+  TRACE_EVENT0("webrtc", "SRTP Decode");
+  char* data = packet->data<char>();
+  int len = rtc::checked_cast<int>(packet->size());
+  if (!UnprotectRtcp(data, len, &len)) {
+    int type = -1;
+    cricket::GetRtcpType(data, len, &type);
+    RTC_LOG(LS_ERROR) << "Failed to unprotect RTCP packet: size=" << len
+                      << ", type=" << type;
+    return;
+  }
+  packet->SetSize(len);
+  SignalRtcpPacketReceived(packet, packet_time);
 }
 
 void SrtpTransport::OnNetworkRouteChanged(
@@ -269,6 +249,11 @@
   SignalNetworkRouteChanged(network_route);
 }
 
+void SrtpTransport::OnWritableState(
+    rtc::PacketTransportInternal* packet_transport) {
+  SignalWritableState(IsWritable(/*rtcp=*/true) && IsWritable(/*rtcp=*/true));
+}
+
 bool SrtpTransport::SetRtpParams(int send_cs,
                                  const uint8_t* send_key,
                                  int send_key_len,
@@ -309,6 +294,7 @@
   RTC_LOG(LS_INFO) << "SRTP " << (new_sessions ? "activated" : "updated")
                    << " with negotiated parameters: send cipher_suite "
                    << send_cs << " recv cipher_suite " << recv_cs;
+  MaybeUpdateWritableState();
   return true;
 }
 
@@ -347,7 +333,7 @@
   RTC_LOG(LS_INFO) << "SRTCP activated with negotiated parameters:"
                       " send cipher_suite "
                    << send_cs << " recv cipher_suite " << recv_cs;
-
+  MaybeUpdateWritableState();
   return true;
 }
 
@@ -355,11 +341,16 @@
   return send_session_ && recv_session_;
 }
 
+bool SrtpTransport::IsWritable(bool rtcp) const {
+  return IsSrtpActive() && RtpTransport::IsWritable(rtcp);
+}
+
 void SrtpTransport::ResetParams() {
   send_session_ = nullptr;
   recv_session_ = nullptr;
   send_rtcp_session_ = nullptr;
   recv_rtcp_session_ = nullptr;
+  MaybeUpdateWritableState();
   RTC_LOG(LS_INFO) << "The params in SRTP transport are reset.";
 }
 
@@ -530,7 +521,15 @@
   if (recv_rtcp_session_) {
     recv_rtcp_session_->SetMetricsObserver(metrics_observer_);
   }
-  rtp_transport_->SetMetricsObserver(metrics_observer);
+}
+
+void SrtpTransport::MaybeUpdateWritableState() {
+  bool writable = IsWritable(/*rtcp=*/true) && IsWritable(/*rtcp=*/false);
+  // Only fire the signal if the writable state changes.
+  if (writable_ != writable) {
+    writable_ = writable;
+    SignalWritableState(writable_);
+  }
 }
 
 }  // namespace webrtc