Chromium Code Reviews| Index: talk/session/media/channel.cc |
| diff --git a/talk/session/media/channel.cc b/talk/session/media/channel.cc |
| index ef26704f1a4f0058d895e7fb3d539030c7a300e3..56df76ef6fe4c6c20ddc43888e46637b95f9701c 100644 |
| --- a/talk/session/media/channel.cc |
| +++ b/talk/session/media/channel.cc |
| @@ -249,6 +249,12 @@ bool BaseChannel::SetTransport_w(const std::string& transport_name) { |
| return true; |
| } |
| + // For DTLS/SRTP case, the SrtpFilter should be set up by the certificate |
|
pthatcher1
2015/12/01 23:29:35
Would be more clear as:
"When using DTLS-SRTP, we
|
| + // associated with the TransportChannel, reset the |srtp_filter_|. |
| + if (ShouldSetupDtlsSrtp()) { |
| + srtp_filter_.ResetParams(); |
| + } |
| + |
| set_transport_channel(transport_controller_->CreateTransportChannel_w( |
| transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP)); |
| if (!transport_channel()) { |
| @@ -318,6 +324,9 @@ void BaseChannel::set_rtcp_transport_channel(TransportChannel* new_tc) { |
| rtcp_transport_channel_ = new_tc; |
| if (new_tc) { |
| + RTC_CHECK(!(ShouldSetupDtlsSrtp() && srtp_filter_.IsActive())) |
| + << "setting RTCP for DTLS/SRTP after SrtpFilter is active " |
|
pthatcher1
2015/12/01 23:29:35
setting => Setting
|
| + << "should never happen."; |
| ConnectToTransportChannel(new_tc); |
| for (const auto& pair : rtcp_socket_options_) { |
| new_tc->SetOption(pair.first, pair.second); |
| @@ -336,6 +345,7 @@ void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { |
| tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
| tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); |
| tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); |
| + tc->SignalDtlsState.connect(this, &BaseChannel::OnDtlsState); |
| } |
| void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) { |
| @@ -344,6 +354,7 @@ void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) { |
| tc->SignalWritableState.disconnect(this); |
| tc->SignalReadPacket.disconnect(this); |
| tc->SignalReadyToSend.disconnect(this); |
| + tc->SignalDtlsState.disconnect(this); |
| } |
| bool BaseChannel::Enable(bool enable) { |
| @@ -416,10 +427,10 @@ bool BaseChannel::IsReadyToReceive() const { |
| bool BaseChannel::IsReadyToSend() const { |
| // Send outgoing data if we are enabled, have local and remote content, |
| // and we have had some form of connectivity. |
| - return enabled() && |
| - IsReceiveContentDirection(remote_content_direction_) && |
| + return enabled() && IsReceiveContentDirection(remote_content_direction_) && |
| IsSendContentDirection(local_content_direction_) && |
| - was_ever_writable(); |
| + was_ever_writable() && |
| + (srtp_filter_.IsActive() || !ShouldSetupDtlsSrtp()); |
| } |
| bool BaseChannel::SendPacket(rtc::Buffer* packet, |
| @@ -474,6 +485,22 @@ void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
| SetReadyToSend(channel == rtcp_transport_channel_, true); |
| } |
| +void BaseChannel::OnDtlsState(TransportChannel* channel, |
| + DtlsTransportState state) { |
| + if (!ShouldSetupDtlsSrtp()) { |
| + return; |
| + } |
| + |
| + // Reset the srtp filter if it's not the CONNECTED state. For CONNECTED |
|
pthatcher1
2015/12/01 23:29:35
For CONNECTED state => For the CONNECTED state
|
| + // state, setting up DTLS-SRTP context is deferred to ChannelWritable_w to |
| + // cover other scenarios like the whole channel is writable (not just this |
| + // TransportChannel) or when TransportChannel is attached after DTLS is |
| + // negotiated. |
| + if (state != DTLS_TRANSPORT_CONNECTED) { |
| + srtp_filter_.ResetParams(); |
| + } |
| +} |
| + |
| void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { |
| if (rtcp) { |
| rtcp_ready_to_send_ = ready; |
| @@ -761,8 +788,9 @@ void BaseChannel::UpdateWritableState_w() { |
| void BaseChannel::ChannelWritable_w() { |
| ASSERT(worker_thread_ == rtc::Thread::Current()); |
| - if (writable_) |
| + if (writable_) { |
| return; |
| + } |
| LOG(LS_INFO) << "Channel writable (" << content_name_ << ")" |
| << (was_ever_writable_ ? "" : " for the first time"); |
| @@ -778,22 +806,8 @@ void BaseChannel::ChannelWritable_w() { |
| } |
| } |
| - // If we're doing DTLS-SRTP, now is the time. |
| - if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) { |
| - if (!SetupDtlsSrtp(false)) { |
| - SignalDtlsSetupFailure_w(false); |
| - return; |
| - } |
| - |
| - if (rtcp_transport_channel_) { |
| - if (!SetupDtlsSrtp(true)) { |
| - SignalDtlsSetupFailure_w(true); |
| - return; |
| - } |
| - } |
| - } |
| - |
| was_ever_writable_ = true; |
| + MaybeSetupDtlsSrtp_w(); |
| writable_ = true; |
| ChangeState(); |
| } |
| @@ -822,7 +836,8 @@ bool BaseChannel::SetDtlsSrtpCryptoSuites(TransportChannel* tc, bool rtcp) { |
| } |
| bool BaseChannel::ShouldSetupDtlsSrtp() const { |
| - return true; |
| + // Since DTLS is applied to all channels, checking RTP should be enough. |
| + return transport_channel_ && transport_channel_->IsDtlsActive(); |
| } |
| // This function returns true if either DTLS-SRTP is not in use |
| @@ -915,6 +930,28 @@ bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { |
| return ret; |
| } |
| +void BaseChannel::MaybeSetupDtlsSrtp_w() { |
| + if (srtp_filter_.IsActive()) { |
| + return; |
| + } |
| + |
| + if (!ShouldSetupDtlsSrtp()) { |
| + return; |
| + } |
| + |
| + if (!SetupDtlsSrtp(false)) { |
| + SignalDtlsSetupFailure_w(false); |
| + return; |
| + } |
| + |
| + if (rtcp_transport_channel_) { |
| + if (!SetupDtlsSrtp(true)) { |
| + SignalDtlsSetupFailure_w(true); |
| + return; |
| + } |
| + } |
| +} |
| + |
| void BaseChannel::ChannelNotWritable_w() { |
| ASSERT(worker_thread_ == rtc::Thread::Current()); |
| if (!writable_) |
| @@ -2275,7 +2312,7 @@ void DataChannel::GetSrtpCryptoSuites(std::vector<int>* crypto_suites) const { |
| } |
| bool DataChannel::ShouldSetupDtlsSrtp() const { |
| - return (data_channel_type_ == DCT_RTP); |
| + return (data_channel_type_ == DCT_RTP) && BaseChannel::ShouldSetupDtlsSrtp(); |
| } |
| void DataChannel::OnStreamClosedRemotely(uint32_t sid) { |