Chromium Code Reviews| Index: webrtc/p2p/base/dtlstransportchannel.cc |
| diff --git a/webrtc/p2p/base/dtlstransportchannel.cc b/webrtc/p2p/base/dtlstransportchannel.cc |
| index fff24f30b81617e39475f5e804902f6782d979c2..656f2ae7c563150321acf5aed70897a40b5a55c4 100644 |
| --- a/webrtc/p2p/base/dtlstransportchannel.cc |
| +++ b/webrtc/p2p/base/dtlstransportchannel.cc |
| @@ -199,6 +199,8 @@ bool DtlsTransportChannelWrapper::SetRemoteFingerprint( |
| size_t digest_len) { |
| rtc::Buffer remote_fingerprint_value(digest, digest_len); |
| + // Once we have local certificate, the same remote fingerprint can be set |
| + // multiple times. |
|
pthatcher1
2015/12/01 23:29:35
have local certificate => have the local certifica
|
| if (dtls_active_ && remote_fingerprint_value_ == remote_fingerprint_value && |
| !digest_alg.empty()) { |
| // This may happen during renegotiation. |
| @@ -206,28 +208,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_algorithm_ = digest_alg; |
| + bool reconnect = dtls_; |
| + |
| if (!SetupDtls()) { |
| set_dtls_state(DTLS_TRANSPORT_FAILED); |
| return false; |
| } |
| + if (reconnect) { |
| + Reconnect(); |
| + } |
| + |
| return true; |
| } |
| @@ -530,8 +540,13 @@ void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls, |
| if (sig & rtc::SE_READ) { |
| char buf[kMaxDtlsPacketLen]; |
| size_t read; |
| - if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) { |
| + rtc::StreamResult result = dtls_->Read(buf, sizeof(buf), &read, NULL); |
| + if (result == rtc::SR_SUCCESS) { |
| SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); |
| + } else if (result == rtc::SR_EOS) { |
| + // If the SSL stream has closed remotely, reset the |sig| to be SE_CLOSE |
| + // so it could be handled below. |
| + sig = rtc::SE_CLOSE; |
| } |
| } |
| if (sig & rtc::SE_CLOSE) { |
| @@ -616,4 +631,14 @@ void DtlsTransportChannelWrapper::OnConnectionRemoved( |
| SignalConnectionRemoved(this); |
| } |
| +void DtlsTransportChannelWrapper::Reconnect() { |
| + set_dtls_state(DTLS_TRANSPORT_NEW); |
| + set_writable(false); |
| + if (channel_->writable()) { |
| + OnWritableState(channel_); |
| + } else { |
| + channel_->Connect(); |
| + } |
| +} |
| + |
| } // namespace cricket |