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

Unified Diff: pc/channel.cc

Issue 3012953002: Created the DtlsSrtpTransport.
Patch Set: Resolved the comments. 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
Index: pc/channel.cc
diff --git a/pc/channel.cc b/pc/channel.cc
index 7ddf5de7dd91bf304bf5b0e2dc10f5c55d7dcc57..11bf78261630c7dbbc715df3c6cb60123273707d 100644
--- a/pc/channel.cc
+++ b/pc/channel.cc
@@ -63,9 +63,6 @@ enum {
MSG_FIRSTPACKETRECEIVED,
};
-// Value specified in RFC 5764.
-static const char kDtlsSrtpExporterLabel[] = "EXTRACTOR-dtls_srtp";
-
static const int kAgcMinus10db = -10;
static void SafeSetError(const std::string& message, std::string* error_desc) {
@@ -155,18 +152,7 @@ BaseChannel::BaseChannel(rtc::Thread* worker_thread,
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();
-#endif
- } else {
- rtp_transport_ = rtc::MakeUnique<webrtc::RtpTransport>(rtcp_mux_required);
- srtp_transport_ = nullptr;
- }
+ rtp_transport_ = rtc::MakeUnique<webrtc::RtpTransport>(rtcp_mux_required);
rtp_transport_->SignalReadyToSend.connect(
this, &BaseChannel::OnTransportReadyToSend);
// TODO(zstein): RtpTransport::SignalPacketReceived will probably be replaced
@@ -318,9 +304,8 @@ void BaseChannel::SetTransports_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();
+ if (dtls_srtp_transport_) {
+ dtls_srtp_transport_->ResetParams();
}
}
@@ -384,6 +369,10 @@ void BaseChannel::SetTransport_n(
if (new_dtls_transport) {
ConnectToDtlsTransport(new_dtls_transport);
+ if (dtls_srtp_transport_) {
+ rtcp ? dtls_srtp_transport_->SetRtcpDtlsTransport(new_dtls_transport)
+ : dtls_srtp_transport_->SetRtpDtlsTransport(new_dtls_transport);
+ }
} else {
ConnectToPacketTransport(new_packet_transport);
}
@@ -587,9 +576,8 @@ void BaseChannel::OnDtlsState(DtlsTransportInternal* transport,
// TransportChannel) or when TransportChannel is attached after DTLS is
// negotiated.
if (state != DTLS_TRANSPORT_CONNECTED) {
- dtls_active_ = false;
- if (srtp_transport_) {
- srtp_transport_->ResetParams();
+ if (dtls_srtp_transport_) {
+ dtls_srtp_transport_->ResetParams();
}
}
}
@@ -683,11 +671,22 @@ bool BaseChannel::SendPacket(bool rtcp,
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());
+
+ if (dtls_srtp_transport_) {
+ RTC_DCHECK(!sdes_transport_);
+ RTC_DCHECK(dtls_srtp_transport_->IsActive());
+ // Bon voyage.
+ return rtcp ? dtls_srtp_transport_->SendRtcpPacket(packet, options,
+ PF_SRTP_BYPASS)
+ : dtls_srtp_transport_->SendRtpPacket(packet, options,
+ PF_SRTP_BYPASS);
+ }
+
+ RTC_DCHECK(sdes_transport_);
+ RTC_DCHECK(sdes_transport_->IsActive());
// Bon voyage.
- return rtcp ? srtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
- : srtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
+ return rtcp ? sdes_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
+ : sdes_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
}
bool BaseChannel::HandlesPayloadType(int packet_type) const {
@@ -811,102 +810,6 @@ bool BaseChannel::ShouldSetupDtlsSrtp_n() const {
return rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
}
-// This function returns true if either DTLS-SRTP is not in use
-// *or* DTLS-SRTP is successfully set up.
-bool BaseChannel::SetupDtlsSrtp_n(bool rtcp) {
- RTC_DCHECK(network_thread_->IsCurrent());
- bool ret = false;
-
- DtlsTransportInternal* transport =
- rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
- RTC_DCHECK(transport);
- RTC_DCHECK(transport->IsDtlsActive());
-
- int selected_crypto_suite;
-
- if (!transport->GetSrtpCryptoSuite(&selected_crypto_suite)) {
- LOG(LS_ERROR) << "No DTLS-SRTP selected crypto suite";
- return false;
- }
-
- LOG(LS_INFO) << "Installing keys from DTLS-SRTP on " << content_name() << " "
- << RtpRtcpStringLiteral(rtcp);
-
- int key_len;
- int salt_len;
- if (!rtc::GetSrtpKeyAndSaltLengths(selected_crypto_suite, &key_len,
- &salt_len)) {
- LOG(LS_ERROR) << "Unknown DTLS-SRTP crypto suite" << selected_crypto_suite;
- return false;
- }
-
- // OK, we're now doing DTLS (RFC 5764)
- std::vector<unsigned char> dtls_buffer(key_len * 2 + salt_len * 2);
-
- // RFC 5705 exporter using the RFC 5764 parameters
- if (!transport->ExportKeyingMaterial(kDtlsSrtpExporterLabel, NULL, 0, false,
- &dtls_buffer[0], dtls_buffer.size())) {
- LOG(LS_WARNING) << "DTLS-SRTP key export failed";
- RTC_NOTREACHED(); // This should never happen
- return false;
- }
-
- // Sync up the keys with the DTLS-SRTP interface
- std::vector<unsigned char> client_write_key(key_len + salt_len);
- std::vector<unsigned char> server_write_key(key_len + salt_len);
- size_t offset = 0;
- memcpy(&client_write_key[0], &dtls_buffer[offset], key_len);
- offset += key_len;
- memcpy(&server_write_key[0], &dtls_buffer[offset], key_len);
- offset += key_len;
- memcpy(&client_write_key[key_len], &dtls_buffer[offset], salt_len);
- offset += salt_len;
- memcpy(&server_write_key[key_len], &dtls_buffer[offset], salt_len);
-
- std::vector<unsigned char> *send_key, *recv_key;
- rtc::SSLRole role;
- if (!transport->GetSslRole(&role)) {
- LOG(LS_WARNING) << "GetSslRole failed";
- return false;
- }
-
- if (role == rtc::SSL_SERVER) {
- send_key = &server_write_key;
- recv_key = &client_write_key;
- } else {
- send_key = &client_write_key;
- 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()));
- } 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;
- }
- } 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 (!ret) {
- LOG(LS_WARNING) << "DTLS-SRTP key installation failed";
- } else {
- UpdateTransportOverhead();
- }
- return ret;
-}
-
void BaseChannel::MaybeSetupDtlsSrtp_n() {
if (dtls_active()) {
return;
@@ -916,17 +819,17 @@ void BaseChannel::MaybeSetupDtlsSrtp_n() {
return;
}
- if (!srtp_transport_) {
- EnableSrtpTransport_n();
+ if (!dtls_srtp_transport_) {
+ EnableDtlsSrtp_n();
}
- if (!SetupDtlsSrtp_n(false)) {
+ if (!dtls_srtp_transport_->SetupDtlsSrtp(false)) {
SignalDtlsSrtpSetupFailure_n(false);
return;
}
if (rtcp_dtls_transport_) {
- if (!SetupDtlsSrtp_n(true)) {
+ if (!dtls_srtp_transport_->SetupDtlsSrtp(true)) {
SignalDtlsSrtpSetupFailure_n(true);
return;
}
@@ -1003,21 +906,72 @@ bool BaseChannel::CheckSrtpConfig_n(const std::vector<CryptoParams>& cryptos,
return true;
}
-void BaseChannel::EnableSrtpTransport_n() {
- if (srtp_transport_ == nullptr) {
- rtp_transport_->SignalReadyToSend.disconnect(this);
- rtp_transport_->SignalPacketReceived.disconnect(this);
+void BaseChannel::EnableSdes_n() {
+ if (sdes_transport_) {
+ return;
+ }
+ // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
+ // time.
+ RTC_DCHECK(!dtls_srtp_transport_);
+ rtp_transport_->SignalReadyToSend.disconnect(this);
+ rtp_transport_->SignalPacketReceived.disconnect(this);
+
+ auto transport = rtc::MakeUnique<webrtc::SrtpTransport>(
+ std::move(rtp_transport_), content_name_);
+ sdes_transport_ = transport.get();
+#if defined(ENABLE_EXTERNAL_AUTH)
+ sdes_transport_->EnableExternalAuth();
+#endif
+ 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.";
+}
+
+void BaseChannel::EnableDtlsSrtp_n() {
+ if (dtls_srtp_transport_) {
+ return;
+ }
+ // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
+ // time.
+ RTC_DCHECK(!sdes_transport_);
+ rtp_transport_->SignalReadyToSend.disconnect(this);
+ rtp_transport_->SignalPacketReceived.disconnect(this);
+
+ std::unique_ptr<webrtc::SrtpTransport> srtp_transport =
+ rtc::MakeUnique<webrtc::SrtpTransport>(std::move(rtp_transport_),
+ content_name_);
+ srtp_transport->SetSendEncryptedHeaderExtensionIds(
+ send_encrypted_header_extension_ids_);
+ srtp_transport->SetRecvEncryptedHeaderExtensionIds(
+ recv_encrypted_header_extension_ids_);
+#if defined(ENABLE_EXTERNAL_AUTH)
+ srtp_transport->EnableExternalAuth();
+#endif
+ std::unique_ptr<webrtc::DtlsSrtpTransport> transport =
+ rtc::MakeUnique<webrtc::DtlsSrtpTransport>(std::move(srtp_transport));
+ dtls_srtp_transport_ = transport.get();
+ dtls_srtp_transport_->SetRtcpDtlsTransport(rtcp_dtls_transport_);
+ dtls_srtp_transport_->SetRtpDtlsTransport(rtp_dtls_transport_);
- auto transport = rtc::MakeUnique<webrtc::SrtpTransport>(
- std::move(rtp_transport_), content_name_);
- srtp_transport_ = transport.get();
- rtp_transport_ = std::move(transport);
+ rtp_transport_ = std::move(transport);
+ rtp_transport_->SignalReadyToSend.connect(
+ this, &BaseChannel::OnTransportReadyToSend);
+ rtp_transport_->SignalPacketReceived.connect(this,
+ &BaseChannel::OnPacketReceived);
+ LOG(LS_INFO) << "Wrapping SrtpTransport in DtlsSrtpTransport.";
+}
- rtp_transport_->SignalReadyToSend.connect(
- this, &BaseChannel::OnTransportReadyToSend);
- rtp_transport_->SignalPacketReceived.connect(
- this, &BaseChannel::OnPacketReceived);
- LOG(LS_INFO) << "Wrapping RtpTransport in SrtpTransport.";
+void BaseChannel::CacheEncryptedHeaderExtensionIds(
+ cricket::ContentSource source,
+ const std::vector<int>& extension_ids) {
+ if (source == cricket::CS_LOCAL) {
+ recv_encrypted_header_extension_ids_ = extension_ids;
+ } else {
+ send_encrypted_header_extension_ids_ = extension_ids;
}
}
@@ -1037,37 +991,56 @@ bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
if (!ret) {
return false;
}
+ // Cache the encrypted extension ids. |SetSrtp_n| could happen before the
+ // certficate is ready and the |rtp_dtls_transport_| is active. The
Taylor Brandstetter 2017/09/27 23:54:48 certificate
+ // |dtls_srtp_transport_| is not enabled until the |rtp_dtls_transport_| is
+ // active.
+ CacheEncryptedHeaderExtensionIds(src, encrypted_extension_ids);
+
+ if (!dtls) {
+ ret = SetSdesSrtp_n(cryptos, action, src, encrypted_extension_ids);
+ } else {
+ ret = SetDtlsSrtp_n(src, encrypted_extension_ids);
+ }
+
+ if (!ret) {
+ SafeSetError("Failed to setup SRTP.", error_desc);
+ return false;
+ }
+ return true;
+}
+bool BaseChannel::SetSdesSrtp_n(
+ const std::vector<CryptoParams>& cryptos,
+ ContentAction action,
+ ContentSource src,
+ const std::vector<int>& encrypted_extension_ids) {
+ if (cryptos.empty()) {
+ return true;
+ }
// 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 (!sdes_transport_) {
+ EnableSdes_n();
}
- if (srtp_transport_) {
- srtp_transport_->SetEncryptedHeaderExtensionIds(src,
- encrypted_extension_ids);
+ if (sdes_transport_) {
+ src == cricket::CS_LOCAL
+ ? sdes_transport_->SetRecvEncryptedHeaderExtensionIds(
+ encrypted_extension_ids)
+ : sdes_transport_->SetSendEncryptedHeaderExtensionIds(
+ encrypted_extension_ids);
}
+
+ bool ret = true;
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 = sdes_negotiator_.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 = sdes_negotiator_.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 = sdes_negotiator_.SetAnswer(cryptos, src);
break;
default:
break;
@@ -1075,10 +1048,10 @@ bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
// If setting an SDES answer succeeded, apply the negotiated parameters
// to the SRTP transport.
- if ((action == CA_PRANSWER || action == CA_ANSWER) && !dtls && ret) {
+ if ((action == CA_PRANSWER || action == CA_ANSWER) && ret) {
if (sdes_negotiator_.send_cipher_suite() &&
sdes_negotiator_.recv_cipher_suite()) {
- ret = srtp_transport_->SetRtpParams(
+ ret = sdes_transport_->SetRtpParams(
*(sdes_negotiator_.send_cipher_suite()),
sdes_negotiator_.send_key().data(),
static_cast<int>(sdes_negotiator_.send_key().size()),
@@ -1087,28 +1060,41 @@ bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
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
+ if (action == CA_ANSWER && sdes_transport_) {
+ // Explicitly reset the |sdes_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();
+ sdes_transport_->ResetParams();
}
}
}
+ return ret;
+}
- // 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_ &&
- rtp_dtls_transport_->dtls_state() == DTLS_TRANSPORT_CONNECTED) {
+bool BaseChannel::SetDtlsSrtp_n(
+ ContentSource src,
+ const std::vector<int>& encrypted_extension_ids) {
+ bool ret = true;
+ if (!dtls_srtp_transport_) {
+ EnableDtlsSrtp_n();
+ }
+ // Update the DtlsSrtpTransport if using DTLS.
+ // TODO(zhihuang): Only update if encrypted extension ids have changed.
+ else {
+ src == cricket::CS_LOCAL
+ ? dtls_srtp_transport_->SetRecvEncryptedHeaderExtensionIds(
+ encrypted_extension_ids)
+ : dtls_srtp_transport_->SetSendEncryptedHeaderExtensionIds(
+ encrypted_extension_ids);
+ }
+
+ if (dtls_active() && dtls_srtp_transport_->rtp_dtls_transport() &&
+ dtls_srtp_transport_->rtp_dtls_transport()->dtls_state() ==
+ DTLS_TRANSPORT_CONNECTED) {
bool rtcp = false;
- ret = SetupDtlsSrtp_n(rtcp);
- }
- if (!ret) {
- SafeSetError("Failed to setup SRTP filter.", error_desc);
- return false;
+ ret = dtls_srtp_transport_->SetupDtlsSrtp(rtcp);
}
- return true;
+ return ret;
}
bool BaseChannel::SetRtcpMux_n(bool enable,
@@ -1371,8 +1357,8 @@ void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension_w(
void BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n(
int rtp_abs_sendtime_extn_id) {
- if (srtp_transport_) {
- srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
+ if (sdes_transport_) {
+ sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
rtp_abs_sendtime_extn_id);
} else {
LOG(LS_WARNING) << "Trying to cache the Absolute Send Time extension id "
@@ -1663,7 +1649,7 @@ int BaseChannel::GetTransportOverheadPerPacket() const {
if (sdes_active()) {
int srtp_overhead = 0;
- if (srtp_transport_->GetSrtpOverhead(&srtp_overhead))
+ if (sdes_transport_->GetSrtpOverhead(&srtp_overhead))
transport_overhead_per_packet += srtp_overhead;
}

Powered by Google App Engine
This is Rietveld 408576698