OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 192 |
193 return dtls_->GetSslCipherSuite(cipher); | 193 return dtls_->GetSslCipherSuite(cipher); |
194 } | 194 } |
195 | 195 |
196 bool DtlsTransportChannelWrapper::SetRemoteFingerprint( | 196 bool DtlsTransportChannelWrapper::SetRemoteFingerprint( |
197 const std::string& digest_alg, | 197 const std::string& digest_alg, |
198 const uint8_t* digest, | 198 const uint8_t* digest, |
199 size_t digest_len) { | 199 size_t digest_len) { |
200 rtc::Buffer remote_fingerprint_value(digest, digest_len); | 200 rtc::Buffer remote_fingerprint_value(digest, digest_len); |
201 | 201 |
202 // Once we have the local certificate, the same remote fingerprint can be set | |
203 // multiple times. | |
204 if (dtls_active_ && remote_fingerprint_value_ == remote_fingerprint_value && | 202 if (dtls_active_ && remote_fingerprint_value_ == remote_fingerprint_value && |
205 !digest_alg.empty()) { | 203 !digest_alg.empty()) { |
206 // This may happen during renegotiation. | 204 // This may happen during renegotiation. |
207 LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint"; | 205 LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint"; |
208 return true; | 206 return true; |
209 } | 207 } |
210 | 208 |
211 // If the other side doesn't support DTLS, turn off |dtls_active_|. | 209 // Allow SetRemoteFingerprint with a NULL digest even if SetLocalCertificate |
| 210 // hasn't been called. |
| 211 if (dtls_ || (!dtls_active_ && !digest_alg.empty())) { |
| 212 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; |
| 213 return false; |
| 214 } |
| 215 |
212 if (digest_alg.empty()) { | 216 if (digest_alg.empty()) { |
213 RTC_DCHECK(!digest_len); | |
214 LOG_J(LS_INFO, this) << "Other side didn't support DTLS."; | 217 LOG_J(LS_INFO, this) << "Other side didn't support DTLS."; |
215 dtls_active_ = false; | 218 dtls_active_ = false; |
216 return true; | 219 return true; |
217 } | 220 } |
218 | 221 |
219 // Otherwise, we must have a local certificate before setting remote | |
220 // fingerprint. | |
221 if (!dtls_active_) { | |
222 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; | |
223 return false; | |
224 } | |
225 | |
226 // At this point we know we are doing DTLS | 222 // At this point we know we are doing DTLS |
227 remote_fingerprint_value_ = remote_fingerprint_value.Pass(); | 223 remote_fingerprint_value_ = remote_fingerprint_value.Pass(); |
228 remote_fingerprint_algorithm_ = digest_alg; | 224 remote_fingerprint_algorithm_ = digest_alg; |
229 | 225 |
230 bool reconnect = dtls_; | |
231 | |
232 if (!SetupDtls()) { | 226 if (!SetupDtls()) { |
233 set_dtls_state(DTLS_TRANSPORT_FAILED); | 227 set_dtls_state(DTLS_TRANSPORT_FAILED); |
234 return false; | 228 return false; |
235 } | 229 } |
236 | 230 |
237 if (reconnect) { | |
238 Reconnect(); | |
239 } | |
240 | |
241 return true; | 231 return true; |
242 } | 232 } |
243 | 233 |
244 bool DtlsTransportChannelWrapper::GetRemoteSSLCertificate( | 234 bool DtlsTransportChannelWrapper::GetRemoteSSLCertificate( |
245 rtc::SSLCertificate** cert) const { | 235 rtc::SSLCertificate** cert) const { |
246 if (!dtls_) { | 236 if (!dtls_) { |
247 return false; | 237 return false; |
248 } | 238 } |
249 | 239 |
250 return dtls_->GetPeerCertificate(cert); | 240 return dtls_->GetPeerCertificate(cert); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 if (dtls_->GetState() == rtc::SS_OPEN) { | 523 if (dtls_->GetState() == rtc::SS_OPEN) { |
534 // The check for OPEN shouldn't be necessary but let's make | 524 // The check for OPEN shouldn't be necessary but let's make |
535 // sure we don't accidentally frob the state if it's closed. | 525 // sure we don't accidentally frob the state if it's closed. |
536 set_dtls_state(DTLS_TRANSPORT_CONNECTED); | 526 set_dtls_state(DTLS_TRANSPORT_CONNECTED); |
537 set_writable(true); | 527 set_writable(true); |
538 } | 528 } |
539 } | 529 } |
540 if (sig & rtc::SE_READ) { | 530 if (sig & rtc::SE_READ) { |
541 char buf[kMaxDtlsPacketLen]; | 531 char buf[kMaxDtlsPacketLen]; |
542 size_t read; | 532 size_t read; |
543 rtc::StreamResult result = dtls_->Read(buf, sizeof(buf), &read, NULL); | 533 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) { |
544 if (result == rtc::SR_SUCCESS) { | |
545 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); | 534 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); |
546 } else if (result == rtc::SR_EOS) { | |
547 // If the SSL stream has closed remotely, reset the |sig| to be SE_CLOSE | |
548 // so it could be handled below. | |
549 sig = rtc::SE_CLOSE; | |
550 } | 535 } |
551 } | 536 } |
552 if (sig & rtc::SE_CLOSE) { | 537 if (sig & rtc::SE_CLOSE) { |
553 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. | 538 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. |
554 set_writable(false); | 539 set_writable(false); |
555 if (!err) { | 540 if (!err) { |
556 LOG_J(LS_INFO, this) << "DTLS channel closed"; | 541 LOG_J(LS_INFO, this) << "DTLS channel closed"; |
557 set_dtls_state(DTLS_TRANSPORT_CLOSED); | 542 set_dtls_state(DTLS_TRANSPORT_CLOSED); |
558 } else { | 543 } else { |
559 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; | 544 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 ASSERT(channel == channel_); | 609 ASSERT(channel == channel_); |
625 SignalRouteChange(this, candidate); | 610 SignalRouteChange(this, candidate); |
626 } | 611 } |
627 | 612 |
628 void DtlsTransportChannelWrapper::OnConnectionRemoved( | 613 void DtlsTransportChannelWrapper::OnConnectionRemoved( |
629 TransportChannelImpl* channel) { | 614 TransportChannelImpl* channel) { |
630 ASSERT(channel == channel_); | 615 ASSERT(channel == channel_); |
631 SignalConnectionRemoved(this); | 616 SignalConnectionRemoved(this); |
632 } | 617 } |
633 | 618 |
634 void DtlsTransportChannelWrapper::Reconnect() { | |
635 set_dtls_state(DTLS_TRANSPORT_NEW); | |
636 set_writable(false); | |
637 if (channel_->writable()) { | |
638 OnWritableState(channel_); | |
639 } | |
640 } | |
641 | |
642 } // namespace cricket | 619 } // namespace cricket |
OLD | NEW |