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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 // fingerprint. | 231 // fingerprint. |
232 if (!dtls_active_) { | 232 if (!dtls_active_) { |
233 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; | 233 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; |
234 return false; | 234 return false; |
235 } | 235 } |
236 | 236 |
237 // At this point we know we are doing DTLS | 237 // At this point we know we are doing DTLS |
238 remote_fingerprint_value_ = std::move(remote_fingerprint_value); | 238 remote_fingerprint_value_ = std::move(remote_fingerprint_value); |
239 remote_fingerprint_algorithm_ = digest_alg; | 239 remote_fingerprint_algorithm_ = digest_alg; |
240 | 240 |
241 bool reconnect = (dtls_ != nullptr); | 241 if (dtls_) { |
| 242 // If the fingerprint is changing, we'll tear down the DTLS association and |
| 243 // create a new one, resetting our state. |
| 244 dtls_.reset(nullptr); |
| 245 set_dtls_state(DTLS_TRANSPORT_NEW); |
| 246 set_writable(false); |
| 247 } |
242 | 248 |
243 if (!SetupDtls()) { | 249 if (!SetupDtls()) { |
244 set_dtls_state(DTLS_TRANSPORT_FAILED); | 250 set_dtls_state(DTLS_TRANSPORT_FAILED); |
245 return false; | 251 return false; |
246 } | 252 } |
247 | 253 |
248 if (reconnect) { | |
249 Reconnect(); | |
250 } | |
251 | |
252 return true; | 254 return true; |
253 } | 255 } |
254 | 256 |
255 std::unique_ptr<rtc::SSLCertificate> | 257 std::unique_ptr<rtc::SSLCertificate> |
256 DtlsTransportChannelWrapper::GetRemoteSSLCertificate() const { | 258 DtlsTransportChannelWrapper::GetRemoteSSLCertificate() const { |
257 if (!dtls_) { | 259 if (!dtls_) { |
258 return nullptr; | 260 return nullptr; |
259 } | 261 } |
260 | 262 |
261 return dtls_->GetPeerCertificate(); | 263 return dtls_->GetPeerCertificate(); |
(...skipping 28 matching lines...) Expand all Loading... |
290 if (!srtp_ciphers_.empty()) { | 292 if (!srtp_ciphers_.empty()) { |
291 if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) { | 293 if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) { |
292 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; | 294 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; |
293 return false; | 295 return false; |
294 } | 296 } |
295 } else { | 297 } else { |
296 LOG_J(LS_INFO, this) << "Not using DTLS-SRTP."; | 298 LOG_J(LS_INFO, this) << "Not using DTLS-SRTP."; |
297 } | 299 } |
298 | 300 |
299 LOG_J(LS_INFO, this) << "DTLS setup complete."; | 301 LOG_J(LS_INFO, this) << "DTLS setup complete."; |
| 302 |
| 303 // If the underlying channel is already writable at this point, we may be |
| 304 // able to start DTLS right away. |
| 305 MaybeStartDtls(); |
300 return true; | 306 return true; |
301 } | 307 } |
302 | 308 |
303 bool DtlsTransportChannelWrapper::SetSrtpCryptoSuites( | 309 bool DtlsTransportChannelWrapper::SetSrtpCryptoSuites( |
304 const std::vector<int>& ciphers) { | 310 const std::vector<int>& ciphers) { |
305 if (srtp_ciphers_ == ciphers) | 311 if (srtp_ciphers_ == ciphers) |
306 return true; | 312 return true; |
307 | 313 |
308 if (dtls_state() == DTLS_TRANSPORT_CONNECTING) { | 314 if (dtls_state() == DTLS_TRANSPORT_CONNECTING) { |
309 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating"; | 315 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating"; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 | 418 |
413 if (!dtls_active_) { | 419 if (!dtls_active_) { |
414 // Not doing DTLS. | 420 // Not doing DTLS. |
415 // Note: SignalWritableState fired by set_writable. | 421 // Note: SignalWritableState fired by set_writable. |
416 set_writable(channel_->writable()); | 422 set_writable(channel_->writable()); |
417 return; | 423 return; |
418 } | 424 } |
419 | 425 |
420 switch (dtls_state()) { | 426 switch (dtls_state()) { |
421 case DTLS_TRANSPORT_NEW: | 427 case DTLS_TRANSPORT_NEW: |
422 // This should never fail: | 428 MaybeStartDtls(); |
423 // Because we are operating in a nonblocking mode and all | |
424 // incoming packets come in via OnReadPacket(), which rejects | |
425 // packets in this state, the incoming queue must be empty. We | |
426 // ignore write errors, thus any errors must be because of | |
427 // configuration and therefore are our fault. | |
428 // Note that in non-debug configurations, failure in | |
429 // MaybeStartDtls() changes the state to DTLS_TRANSPORT_FAILED. | |
430 VERIFY(MaybeStartDtls()); | |
431 break; | 429 break; |
432 case DTLS_TRANSPORT_CONNECTED: | 430 case DTLS_TRANSPORT_CONNECTED: |
433 // Note: SignalWritableState fired by set_writable. | 431 // Note: SignalWritableState fired by set_writable. |
434 set_writable(channel_->writable()); | 432 set_writable(channel_->writable()); |
435 break; | 433 break; |
436 case DTLS_TRANSPORT_CONNECTING: | 434 case DTLS_TRANSPORT_CONNECTING: |
437 // Do nothing. | 435 // Do nothing. |
438 break; | 436 break; |
439 case DTLS_TRANSPORT_FAILED: | 437 case DTLS_TRANSPORT_FAILED: |
440 case DTLS_TRANSPORT_CLOSED: | 438 case DTLS_TRANSPORT_CLOSED: |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 if (!err) { | 562 if (!err) { |
565 LOG_J(LS_INFO, this) << "DTLS channel closed"; | 563 LOG_J(LS_INFO, this) << "DTLS channel closed"; |
566 set_dtls_state(DTLS_TRANSPORT_CLOSED); | 564 set_dtls_state(DTLS_TRANSPORT_CLOSED); |
567 } else { | 565 } else { |
568 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; | 566 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; |
569 set_dtls_state(DTLS_TRANSPORT_FAILED); | 567 set_dtls_state(DTLS_TRANSPORT_FAILED); |
570 } | 568 } |
571 } | 569 } |
572 } | 570 } |
573 | 571 |
574 bool DtlsTransportChannelWrapper::MaybeStartDtls() { | 572 void DtlsTransportChannelWrapper::MaybeStartDtls() { |
575 if (dtls_ && channel_->writable()) { | 573 if (dtls_ && channel_->writable()) { |
576 if (dtls_->StartSSLWithPeer()) { | 574 if (dtls_->StartSSLWithPeer()) { |
| 575 // This should never fail: |
| 576 // Because we are operating in a nonblocking mode and all |
| 577 // incoming packets come in via OnReadPacket(), which rejects |
| 578 // packets in this state, the incoming queue must be empty. We |
| 579 // ignore write errors, thus any errors must be because of |
| 580 // configuration and therefore are our fault. |
| 581 RTC_DCHECK(false) << "StartSSLWithPeer failed."; |
577 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; | 582 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; |
578 set_dtls_state(DTLS_TRANSPORT_FAILED); | 583 set_dtls_state(DTLS_TRANSPORT_FAILED); |
579 return false; | 584 return; |
580 } | 585 } |
581 LOG_J(LS_INFO, this) | 586 LOG_J(LS_INFO, this) |
582 << "DtlsTransportChannelWrapper: Started DTLS handshake"; | 587 << "DtlsTransportChannelWrapper: Started DTLS handshake"; |
583 set_dtls_state(DTLS_TRANSPORT_CONNECTING); | 588 set_dtls_state(DTLS_TRANSPORT_CONNECTING); |
584 // Now that the handshake has started, we can process a cached ClientHello | 589 // Now that the handshake has started, we can process a cached ClientHello |
585 // (if one exists). | 590 // (if one exists). |
586 if (cached_client_hello_.size()) { | 591 if (cached_client_hello_.size()) { |
587 if (ssl_role_ == rtc::SSL_SERVER) { | 592 if (ssl_role_ == rtc::SSL_SERVER) { |
588 LOG_J(LS_INFO, this) << "Handling cached DTLS ClientHello packet."; | 593 LOG_J(LS_INFO, this) << "Handling cached DTLS ClientHello packet."; |
589 if (!HandleDtlsPacket(cached_client_hello_.data<char>(), | 594 if (!HandleDtlsPacket(cached_client_hello_.data<char>(), |
590 cached_client_hello_.size())) { | 595 cached_client_hello_.size())) { |
591 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; | 596 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; |
592 } | 597 } |
593 } else { | 598 } else { |
594 LOG_J(LS_WARNING, this) << "Discarding cached DTLS ClientHello packet " | 599 LOG_J(LS_WARNING, this) << "Discarding cached DTLS ClientHello packet " |
595 << "because we don't have the server role."; | 600 << "because we don't have the server role."; |
596 } | 601 } |
597 cached_client_hello_.Clear(); | 602 cached_client_hello_.Clear(); |
598 } | 603 } |
599 } | 604 } |
600 return true; | |
601 } | 605 } |
602 | 606 |
603 // Called from OnReadPacket when a DTLS packet is received. | 607 // Called from OnReadPacket when a DTLS packet is received. |
604 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, | 608 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, |
605 size_t size) { | 609 size_t size) { |
606 // Sanity check we're not passing junk that | 610 // Sanity check we're not passing junk that |
607 // just looks like DTLS. | 611 // just looks like DTLS. |
608 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data); | 612 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data); |
609 size_t tmp_size = size; | 613 size_t tmp_size = size; |
610 while (tmp_size > 0) { | 614 while (tmp_size > 0) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 SignalSelectedCandidatePairChanged(this, selected_candidate_pair, | 669 SignalSelectedCandidatePairChanged(this, selected_candidate_pair, |
666 last_sent_packet_id, ready_to_send); | 670 last_sent_packet_id, ready_to_send); |
667 } | 671 } |
668 | 672 |
669 void DtlsTransportChannelWrapper::OnChannelStateChanged( | 673 void DtlsTransportChannelWrapper::OnChannelStateChanged( |
670 TransportChannelImpl* channel) { | 674 TransportChannelImpl* channel) { |
671 ASSERT(channel == channel_); | 675 ASSERT(channel == channel_); |
672 SignalStateChanged(this); | 676 SignalStateChanged(this); |
673 } | 677 } |
674 | 678 |
675 void DtlsTransportChannelWrapper::Reconnect() { | |
676 set_dtls_state(DTLS_TRANSPORT_NEW); | |
677 set_writable(false); | |
678 if (channel_->writable()) { | |
679 OnWritableState(channel_); | |
680 } | |
681 } | |
682 | |
683 } // namespace cricket | 679 } // namespace cricket |
OLD | NEW |