Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Unified Diff: webrtc/pc/channel.cc

Issue 3012333003: Revert of Completed the functionalities of SrtpTransport. (Closed)
Patch Set: Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/pc/channel.h ('k') | webrtc/pc/channel_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/pc/channel.cc
diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc
index d99a1058683f0e6c51a00e862463edfcce6f9c05..59f0869431ae59aef1e26b3dbc555b0c897e7e14 100644
--- a/webrtc/pc/channel.cc
+++ b/webrtc/pc/channel.cc
@@ -158,22 +158,18 @@
signaling_thread_(signaling_thread),
content_name_(content_name),
rtcp_mux_required_(rtcp_mux_required),
+ rtp_transport_(
+ srtp_required
+ ? rtc::WrapUnique<webrtc::RtpTransportInternal>(
+ new webrtc::SrtpTransport(rtcp_mux_required, content_name))
+ : rtc::MakeUnique<webrtc::RtpTransport>(rtcp_mux_required)),
srtp_required_(srtp_required),
media_channel_(media_channel),
selected_candidate_pair_(nullptr) {
RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
- if (srtp_required) {
- auto transport =
- rtc::MakeUnique<webrtc::SrtpTransport>(rtcp_mux_required, content_name);
- srtp_transport_ = transport.get();
- rtp_transport_ = std::move(transport);
#if defined(ENABLE_EXTERNAL_AUTH)
- srtp_transport_->EnableExternalAuth();
+ srtp_filter_.EnableExternalAuth();
#endif
- } else {
- rtp_transport_ = rtc::MakeUnique<webrtc::RtpTransport>(rtcp_mux_required);
- srtp_transport_ = nullptr;
- }
rtp_transport_->SignalReadyToSend.connect(
this, &BaseChannel::OnTransportReadyToSend);
// TODO(zstein): RtpTransport::SignalPacketReceived will probably be replaced
@@ -318,17 +314,14 @@
return;
}
- // When using DTLS-SRTP, we must reset the SrtpTransport every time the
- // DtlsTransport changes and wait until the DTLS handshake is complete to set
- // the newly negotiated parameters.
+ // When using DTLS-SRTP, we must reset the SrtpFilter every time the transport
+ // changes and wait until the DTLS handshake is complete to set the newly
+ // negotiated parameters.
if (ShouldSetupDtlsSrtp_n()) {
// Set |writable_| to false such that UpdateWritableState_w can set up
// DTLS-SRTP when |writable_| becomes true again.
writable_ = false;
- dtls_active_ = false;
- if (srtp_transport_) {
- srtp_transport_->ResetParams();
- }
+ srtp_filter_.ResetParams();
}
// If this BaseChannel doesn't require RTCP mux and we haven't fully
@@ -384,8 +377,8 @@
}
if (rtcp && new_dtls_transport) {
- RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_active()))
- << "Setting RTCP for DTLS/SRTP after the DTLS is active "
+ RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_filter_.IsActive()))
+ << "Setting RTCP for DTLS/SRTP after SrtpFilter is active "
<< "should never happen.";
}
@@ -536,7 +529,8 @@
// and we have had some form of connectivity.
return enabled() && IsReceiveContentDirection(remote_content_direction_) &&
IsSendContentDirection(local_content_direction_) &&
- was_ever_writable() && (srtp_active() || !ShouldSetupDtlsSrtp_n());
+ was_ever_writable() &&
+ (srtp_filter_.IsActive() || !ShouldSetupDtlsSrtp_n());
}
bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
@@ -588,16 +582,13 @@
return;
}
- // Reset the SrtpTransport if it's not the CONNECTED state. For the CONNECTED
+ // Reset the srtp filter if it's not the CONNECTED state. For the CONNECTED
// state, setting up DTLS-SRTP context is deferred to ChannelWritable_w to
// cover other scenarios like the whole transport is writable (not just this
// TransportChannel) or when TransportChannel is attached after DTLS is
// negotiated.
if (state != DTLS_TRANSPORT_CONNECTED) {
- dtls_active_ = false;
- if (srtp_transport_) {
- srtp_transport_->ResetParams();
- }
+ srtp_filter_.ResetParams();
}
}
@@ -671,30 +662,91 @@
return false;
}
- if (!srtp_active()) {
- if (srtp_required_) {
- // The audio/video engines may attempt to send RTCP packets as soon as the
- // streams are created, so don't treat this as an error for RTCP.
- // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
- if (rtcp) {
+ rtc::PacketOptions updated_options;
+ updated_options = options;
+ // Protect if needed.
+ if (srtp_filter_.IsActive()) {
+ TRACE_EVENT0("webrtc", "SRTP Encode");
+ bool res;
+ uint8_t* data = packet->data();
+ int len = static_cast<int>(packet->size());
+ if (!rtcp) {
+ // 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 = srtp_filter_.ProtectRtp(
+ data, len, static_cast<int>(packet->capacity()), &len);
+#else
+ if (!srtp_filter_.IsExternalAuthActive()) {
+ res = srtp_filter_.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 = srtp_filter_.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 = NULL;
+ int key_len;
+ res = srtp_filter_.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);
+ }
+ }
+ }
+#endif
+ if (!res) {
+ int seq_num = -1;
+ uint32_t ssrc = 0;
+ GetRtpSeqNum(data, len, &seq_num);
+ GetRtpSsrc(data, len, &ssrc);
+ LOG(LS_ERROR) << "Failed to protect " << content_name_
+ << " RTP packet: size=" << len
+ << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
return false;
}
- // However, there shouldn't be any RTP packets sent before SRTP is set up
- // (and SetSend(true) is called).
- LOG(LS_ERROR) << "Can't send outgoing RTP packet when SRTP is inactive"
- << " and crypto is required";
- RTC_NOTREACHED();
+ } else {
+ res = srtp_filter_.ProtectRtcp(data, len,
+ static_cast<int>(packet->capacity()),
+ &len);
+ if (!res) {
+ int type = -1;
+ GetRtcpType(data, len, &type);
+ LOG(LS_ERROR) << "Failed to protect " << content_name_
+ << " 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);
+ } else if (srtp_required_) {
+ // The audio/video engines may attempt to send RTCP packets as soon as the
+ // streams are created, so don't treat this as an error for RTCP.
+ // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
+ if (rtcp) {
return false;
}
- // Bon voyage.
- return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_NORMAL)
- : rtp_transport_->SendRtpPacket(packet, options, PF_NORMAL);
- }
- RTC_DCHECK(srtp_transport_);
- RTC_DCHECK(srtp_transport_->IsActive());
+ // However, there shouldn't be any RTP packets sent before SRTP is set up
+ // (and SetSend(true) is called).
+ LOG(LS_ERROR) << "Can't send outgoing RTP packet when SRTP is inactive"
+ << " and crypto is required";
+ RTC_NOTREACHED();
+ return false;
+ }
+
// Bon voyage.
- return rtcp ? srtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
- : srtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
+ int flags = (secure() && secure_dtls()) ? PF_SRTP_BYPASS : PF_NORMAL;
+ return rtp_transport_->SendPacket(rtcp, packet, updated_options, flags);
}
bool BaseChannel::HandlesPayloadType(int packet_type) const {
@@ -709,7 +761,37 @@
signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
}
- if (!srtp_active() && srtp_required_) {
+ // Unprotect the packet, if needed.
+ if (srtp_filter_.IsActive()) {
+ TRACE_EVENT0("webrtc", "SRTP Decode");
+ char* data = packet->data<char>();
+ int len = static_cast<int>(packet->size());
+ bool res;
+ if (!rtcp) {
+ res = srtp_filter_.UnprotectRtp(data, len, &len);
+ if (!res) {
+ int seq_num = -1;
+ uint32_t ssrc = 0;
+ GetRtpSeqNum(data, len, &seq_num);
+ GetRtpSsrc(data, len, &ssrc);
+ LOG(LS_ERROR) << "Failed to unprotect " << content_name_
+ << " RTP packet: size=" << len << ", seqnum=" << seq_num
+ << ", SSRC=" << ssrc;
+ return;
+ }
+ } else {
+ res = srtp_filter_.UnprotectRtcp(data, len, &len);
+ if (!res) {
+ int type = -1;
+ GetRtcpType(data, len, &type);
+ LOG(LS_ERROR) << "Failed to unprotect " << content_name_
+ << " RTCP packet: size=" << len << ", type=" << type;
+ return;
+ }
+ }
+
+ packet->SetSize(len);
+ } else if (srtp_required_) {
// Our session description indicates that SRTP is required, but we got a
// packet before our SRTP filter is active. This means either that
// a) we got SRTP packets before we received the SDES keys, in which case
@@ -913,46 +995,48 @@
recv_key = &server_write_key;
}
- if (rtcp) {
- if (!dtls_active()) {
- RTC_DCHECK(srtp_transport_);
- ret = srtp_transport_->SetRtcpParams(
- selected_crypto_suite, &(*send_key)[0],
- static_cast<int>(send_key->size()), selected_crypto_suite,
- &(*recv_key)[0], static_cast<int>(recv_key->size()));
+ if (!srtp_filter_.IsActive()) {
+ if (rtcp) {
+ ret = srtp_filter_.SetRtcpParams(selected_crypto_suite, &(*send_key)[0],
+ static_cast<int>(send_key->size()),
+ selected_crypto_suite, &(*recv_key)[0],
+ static_cast<int>(recv_key->size()));
} else {
- // RTCP doesn't need to call SetRtpParam because it is only used
- // to make the updated encrypted RTP header extension IDs take effect.
- ret = true;
+ ret = srtp_filter_.SetRtpParams(selected_crypto_suite, &(*send_key)[0],
+ static_cast<int>(send_key->size()),
+ selected_crypto_suite, &(*recv_key)[0],
+ static_cast<int>(recv_key->size()));
}
} else {
- RTC_DCHECK(srtp_transport_);
- ret = srtp_transport_->SetRtpParams(selected_crypto_suite, &(*send_key)[0],
- static_cast<int>(send_key->size()),
- selected_crypto_suite, &(*recv_key)[0],
- static_cast<int>(recv_key->size()));
- dtls_active_ = ret;
+ if (rtcp) {
+ // RTCP doesn't need to be updated because UpdateRtpParams is only used
+ // to update the set of encrypted RTP header extension IDs.
+ ret = true;
+ } else {
+ ret = srtp_filter_.UpdateRtpParams(
+ selected_crypto_suite,
+ &(*send_key)[0], static_cast<int>(send_key->size()),
+ selected_crypto_suite,
+ &(*recv_key)[0], static_cast<int>(recv_key->size()));
+ }
}
if (!ret) {
LOG(LS_WARNING) << "DTLS-SRTP key installation failed";
} else {
+ dtls_keyed_ = true;
UpdateTransportOverhead();
}
return ret;
}
void BaseChannel::MaybeSetupDtlsSrtp_n() {
- if (dtls_active()) {
+ if (srtp_filter_.IsActive()) {
return;
}
if (!ShouldSetupDtlsSrtp_n()) {
return;
- }
-
- if (!srtp_transport_) {
- EnableSrtpTransport_n();
}
if (!SetupDtlsSrtp_n(false)) {
@@ -1038,24 +1122,6 @@
return true;
}
-void BaseChannel::EnableSrtpTransport_n() {
- if (srtp_transport_ == nullptr) {
- rtp_transport_->SignalReadyToSend.disconnect(this);
- rtp_transport_->SignalPacketReceived.disconnect(this);
-
- auto transport = rtc::MakeUnique<webrtc::SrtpTransport>(
- std::move(rtp_transport_), content_name_);
- srtp_transport_ = transport.get();
- rtp_transport_ = std::move(transport);
-
- rtp_transport_->SignalReadyToSend.connect(
- this, &BaseChannel::OnTransportReadyToSend);
- rtp_transport_->SignalPacketReceived.connect(
- this, &BaseChannel::OnPacketReceived);
- LOG(LS_INFO) << "Wrapping RtpTransport in SrtpTransport.";
- }
-}
-
bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
ContentAction action,
ContentSource src,
@@ -1072,69 +1138,36 @@
if (!ret) {
return false;
}
-
- // If SRTP was not required, but we're setting a description that uses SDES,
- // we need to upgrade to an SrtpTransport.
- if (!srtp_transport_ && !dtls && !cryptos.empty()) {
- EnableSrtpTransport_n();
- }
- if (srtp_transport_) {
- srtp_transport_->SetEncryptedHeaderExtensionIds(src,
- encrypted_extension_ids);
- }
+ srtp_filter_.SetEncryptedHeaderExtensionIds(src, encrypted_extension_ids);
switch (action) {
case CA_OFFER:
// If DTLS is already active on the channel, we could be renegotiating
// here. We don't update the srtp filter.
if (!dtls) {
- ret = sdes_negotiator_.SetOffer(cryptos, src);
+ ret = srtp_filter_.SetOffer(cryptos, src);
}
break;
case CA_PRANSWER:
// If we're doing DTLS-SRTP, we don't want to update the filter
// with an answer, because we already have SRTP parameters.
if (!dtls) {
- ret = sdes_negotiator_.SetProvisionalAnswer(cryptos, src);
+ ret = srtp_filter_.SetProvisionalAnswer(cryptos, src);
}
break;
case CA_ANSWER:
// If we're doing DTLS-SRTP, we don't want to update the filter
// with an answer, because we already have SRTP parameters.
if (!dtls) {
- ret = sdes_negotiator_.SetAnswer(cryptos, src);
+ ret = srtp_filter_.SetAnswer(cryptos, src);
}
break;
default:
break;
}
-
- // If setting an SDES answer succeeded, apply the negotiated parameters
- // to the SRTP transport.
- if ((action == CA_PRANSWER || action == CA_ANSWER) && !dtls && ret) {
- if (sdes_negotiator_.send_cipher_suite() &&
- sdes_negotiator_.recv_cipher_suite()) {
- ret = srtp_transport_->SetRtpParams(
- *(sdes_negotiator_.send_cipher_suite()),
- sdes_negotiator_.send_key().data(),
- static_cast<int>(sdes_negotiator_.send_key().size()),
- *(sdes_negotiator_.recv_cipher_suite()),
- sdes_negotiator_.recv_key().data(),
- static_cast<int>(sdes_negotiator_.recv_key().size()));
- } else {
- LOG(LS_INFO) << "No crypto keys are provided for SDES.";
- if (action == CA_ANSWER && srtp_transport_) {
- // Explicitly reset the |srtp_transport_| if no crypto param is
- // provided in the answer. No need to call |ResetParams()| for
- // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
- srtp_transport_->ResetParams();
- }
- }
- }
-
// Only update SRTP filter if using DTLS. SDES is handled internally
// by the SRTP filter.
// TODO(jbauch): Only update if encrypted extension ids have changed.
- if (ret && dtls_active() && rtp_dtls_transport_ &&
+ if (ret && dtls_keyed_ && rtp_dtls_transport_ &&
rtp_dtls_transport_->dtls_state() == DTLS_TRANSPORT_CONNECTED) {
bool rtcp = false;
ret = SetupDtlsSrtp_n(rtcp);
@@ -1178,6 +1211,7 @@
transport_name_.empty()
? rtp_transport_->rtp_packet_transport()->debug_name()
: transport_name_;
+ ;
LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name()
<< "; no longer need RTCP transport for " << debug_name;
if (rtp_transport_->rtcp_packet_transport()) {
@@ -1406,13 +1440,7 @@
void BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n(
int rtp_abs_sendtime_extn_id) {
- if (srtp_transport_) {
- srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
- rtp_abs_sendtime_extn_id);
- } else {
- LOG(LS_WARNING) << "Trying to cache the Absolute Send Time extension id "
- "but the SRTP is not active.";
- }
+ rtp_abs_sendtime_extn_id_ = rtp_abs_sendtime_extn_id;
}
void BaseChannel::OnMessage(rtc::Message *pmsg) {
@@ -1696,9 +1724,9 @@
? kTcpOverhaed
: kUdpOverhaed;
- if (sdes_active()) {
+ if (secure()) {
int srtp_overhead = 0;
- if (srtp_transport_->GetSrtpOverhead(&srtp_overhead))
+ if (srtp_filter_.GetSrtpOverhead(&srtp_overhead))
transport_overhead_per_packet += srtp_overhead;
}
« no previous file with comments | « webrtc/pc/channel.h ('k') | webrtc/pc/channel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698