diff options
Diffstat (limited to 'webrtc/p2p/base/dtlstransportchannel.cc')
-rw-r--r-- | webrtc/p2p/base/dtlstransportchannel.cc | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/webrtc/p2p/base/dtlstransportchannel.cc b/webrtc/p2p/base/dtlstransportchannel.cc index 0c063e0323..d6b5bce723 100644 --- a/webrtc/p2p/base/dtlstransportchannel.cc +++ b/webrtc/p2p/base/dtlstransportchannel.cc @@ -8,6 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include <utility> + #include "webrtc/p2p/base/dtlstransportchannel.h" #include "webrtc/p2p/base/common.h" @@ -95,7 +97,7 @@ DtlsTransportChannelWrapper::DtlsTransportChannelWrapper( channel_(channel), downward_(NULL), ssl_role_(rtc::SSL_CLIENT), - ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10) { + ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_12) { channel_->SignalWritableState.connect(this, &DtlsTransportChannelWrapper::OnWritableState); channel_->SignalReadPacket.connect(this, @@ -199,6 +201,8 @@ bool DtlsTransportChannelWrapper::SetRemoteFingerprint( size_t digest_len) { rtc::Buffer remote_fingerprint_value(digest, digest_len); + // Once we have the local certificate, the same remote fingerprint can be set + // multiple times. if (dtls_active_ && remote_fingerprint_value_ == remote_fingerprint_value && !digest_alg.empty()) { // This may happen during renegotiation. @@ -206,28 +210,36 @@ bool DtlsTransportChannelWrapper::SetRemoteFingerprint( return true; } - // Allow SetRemoteFingerprint with a NULL digest even if SetLocalCertificate - // hasn't been called. - if (dtls_ || (!dtls_active_ && !digest_alg.empty())) { - LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; - return false; - } - + // If the other side doesn't support DTLS, turn off |dtls_active_|. if (digest_alg.empty()) { + RTC_DCHECK(!digest_len); LOG_J(LS_INFO, this) << "Other side didn't support DTLS."; dtls_active_ = false; return true; } + // Otherwise, we must have a local certificate before setting remote + // fingerprint. + if (!dtls_active_) { + LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; + return false; + } + // At this point we know we are doing DTLS - remote_fingerprint_value_ = remote_fingerprint_value.Pass(); + remote_fingerprint_value_ = std::move(remote_fingerprint_value); remote_fingerprint_algorithm_ = digest_alg; + bool reconnect = dtls_; + if (!SetupDtls()) { set_dtls_state(DTLS_TRANSPORT_FAILED); return false; } + if (reconnect) { + Reconnect(); + } + return true; } @@ -267,7 +279,7 @@ bool DtlsTransportChannelWrapper::SetupDtls() { // Set up DTLS-SRTP, if it's been enabled. if (!srtp_ciphers_.empty()) { - if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) { + if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) { LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; return false; } @@ -279,11 +291,10 @@ bool DtlsTransportChannelWrapper::SetupDtls() { return true; } -bool DtlsTransportChannelWrapper::SetSrtpCiphers( - const std::vector<std::string>& ciphers) { - if (srtp_ciphers_ == ciphers) { +bool DtlsTransportChannelWrapper::SetSrtpCryptoSuites( + const std::vector<int>& ciphers) { + if (srtp_ciphers_ == ciphers) return true; - } if (dtls_state() == DTLS_TRANSPORT_CONNECTING) { LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating"; @@ -294,18 +305,18 @@ bool DtlsTransportChannelWrapper::SetSrtpCiphers( // We don't support DTLS renegotiation currently. If new set of srtp ciphers // are different than what's being used currently, we will not use it. // So for now, let's be happy (or sad) with a warning message. - std::string current_srtp_cipher; - if (!dtls_->GetDtlsSrtpCipher(¤t_srtp_cipher)) { + int current_srtp_cipher; + if (!dtls_->GetDtlsSrtpCryptoSuite(¤t_srtp_cipher)) { LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel"; return false; } - const std::vector<std::string>::const_iterator iter = + const std::vector<int>::const_iterator iter = std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher); if (iter == ciphers.end()) { std::string requested_str; for (size_t i = 0; i < ciphers.size(); ++i) { requested_str.append(" "); - requested_str.append(ciphers[i]); + requested_str.append(rtc::SrtpCryptoSuiteToName(ciphers[i])); requested_str.append(" "); } LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS " @@ -324,12 +335,12 @@ bool DtlsTransportChannelWrapper::SetSrtpCiphers( return true; } -bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(std::string* cipher) { +bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(int* cipher) { if (dtls_state() != DTLS_TRANSPORT_CONNECTED) { return false; } - return dtls_->GetDtlsSrtpCipher(cipher); + return dtls_->GetDtlsSrtpCryptoSuite(cipher); } @@ -617,4 +628,12 @@ void DtlsTransportChannelWrapper::OnConnectionRemoved( SignalConnectionRemoved(this); } +void DtlsTransportChannelWrapper::Reconnect() { + set_dtls_state(DTLS_TRANSPORT_NEW); + set_writable(false); + if (channel_->writable()) { + OnWritableState(channel_); + } +} + } // namespace cricket |