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