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 18 matching lines...) Expand all Loading... |
29 static const size_t kMinRtpPacketLen = 12; | 29 static const size_t kMinRtpPacketLen = 12; |
30 | 30 |
31 // Maximum number of pending packets in the queue. Packets are read immediately | 31 // Maximum number of pending packets in the queue. Packets are read immediately |
32 // after they have been written, so a capacity of "1" is sufficient. | 32 // after they have been written, so a capacity of "1" is sufficient. |
33 static const size_t kMaxPendingPackets = 1; | 33 static const size_t kMaxPendingPackets = 1; |
34 | 34 |
35 static bool IsDtlsPacket(const char* data, size_t len) { | 35 static bool IsDtlsPacket(const char* data, size_t len) { |
36 const uint8_t* u = reinterpret_cast<const uint8_t*>(data); | 36 const uint8_t* u = reinterpret_cast<const uint8_t*>(data); |
37 return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64)); | 37 return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64)); |
38 } | 38 } |
| 39 static bool IsDtlsClientHelloPacket(const char* data, size_t len) { |
| 40 if (!IsDtlsPacket(data, len)) { |
| 41 return false; |
| 42 } |
| 43 const uint8_t* u = reinterpret_cast<const uint8_t*>(data); |
| 44 return len > 17 && u[0] == 22 && u[13] == 1; |
| 45 } |
39 static bool IsRtpPacket(const char* data, size_t len) { | 46 static bool IsRtpPacket(const char* data, size_t len) { |
40 const uint8_t* u = reinterpret_cast<const uint8_t*>(data); | 47 const uint8_t* u = reinterpret_cast<const uint8_t*>(data); |
41 return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80); | 48 return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80); |
42 } | 49 } |
43 | 50 |
44 StreamInterfaceChannel::StreamInterfaceChannel(TransportChannel* channel) | 51 StreamInterfaceChannel::StreamInterfaceChannel(TransportChannel* channel) |
45 : channel_(channel), | 52 : channel_(channel), |
46 state_(rtc::SS_OPEN), | 53 state_(rtc::SS_OPEN), |
47 packets_(kMaxPendingPackets, kMaxDtlsPacketLen) { | 54 packets_(kMaxPendingPackets, kMaxDtlsPacketLen) { |
48 } | 55 } |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 | 469 |
463 if (!dtls_active_) { | 470 if (!dtls_active_) { |
464 // Not doing DTLS. | 471 // Not doing DTLS. |
465 SignalReadPacket(this, data, size, packet_time, 0); | 472 SignalReadPacket(this, data, size, packet_time, 0); |
466 return; | 473 return; |
467 } | 474 } |
468 | 475 |
469 switch (dtls_state()) { | 476 switch (dtls_state()) { |
470 case DTLS_TRANSPORT_NEW: | 477 case DTLS_TRANSPORT_NEW: |
471 if (dtls_) { | 478 if (dtls_) { |
472 // Drop packets received before DTLS has actually started. | 479 LOG_J(LS_INFO, this) << "Packet received before DTLS started."; |
473 LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started."; | |
474 } else { | 480 } else { |
475 // Currently drop the packet, but we might in future | 481 LOG_J(LS_WARNING, this) << "Packet received before we know if we are " |
476 // decide to take this as evidence that the other | 482 << "doing DTLS or not."; |
477 // side is ready to do DTLS and start the handshake | 483 } |
478 // on our end. | 484 // Cache a client hello packet received before DTLS has actually started. |
479 LOG_J(LS_WARNING, this) << "Received packet before we know if we are " | 485 if (IsDtlsClientHelloPacket(data, size)) { |
480 << "doing DTLS or not; dropping."; | 486 LOG_J(LS_INFO, this) << "Caching DTLS ClientHello packet until DTLS is " |
| 487 << "started."; |
| 488 cached_client_hello_.SetData(data, size); |
| 489 } else { |
| 490 LOG_J(LS_INFO, this) << "Not a DTLS ClientHello packet; dropping."; |
481 } | 491 } |
482 break; | 492 break; |
483 | 493 |
484 case DTLS_TRANSPORT_CONNECTING: | 494 case DTLS_TRANSPORT_CONNECTING: |
485 case DTLS_TRANSPORT_CONNECTED: | 495 case DTLS_TRANSPORT_CONNECTED: |
486 // We should only get DTLS or SRTP packets; STUN's already been demuxed. | 496 // We should only get DTLS or SRTP packets; STUN's already been demuxed. |
487 // Is this potentially a DTLS packet? | 497 // Is this potentially a DTLS packet? |
488 if (IsDtlsPacket(data, size)) { | 498 if (IsDtlsPacket(data, size)) { |
489 if (!HandleDtlsPacket(data, size)) { | 499 if (!HandleDtlsPacket(data, size)) { |
490 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; | 500 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 bool DtlsTransportChannelWrapper::MaybeStartDtls() { | 579 bool DtlsTransportChannelWrapper::MaybeStartDtls() { |
570 if (dtls_ && channel_->writable()) { | 580 if (dtls_ && channel_->writable()) { |
571 if (dtls_->StartSSLWithPeer()) { | 581 if (dtls_->StartSSLWithPeer()) { |
572 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; | 582 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; |
573 set_dtls_state(DTLS_TRANSPORT_FAILED); | 583 set_dtls_state(DTLS_TRANSPORT_FAILED); |
574 return false; | 584 return false; |
575 } | 585 } |
576 LOG_J(LS_INFO, this) | 586 LOG_J(LS_INFO, this) |
577 << "DtlsTransportChannelWrapper: Started DTLS handshake"; | 587 << "DtlsTransportChannelWrapper: Started DTLS handshake"; |
578 set_dtls_state(DTLS_TRANSPORT_CONNECTING); | 588 set_dtls_state(DTLS_TRANSPORT_CONNECTING); |
| 589 // Now that the handshake has started, we can process a cached ClientHello |
| 590 // (if one exists). |
| 591 if (cached_client_hello_.size()) { |
| 592 if (ssl_role_ == rtc::SSL_SERVER) { |
| 593 LOG_J(LS_INFO, this) << "Handling cached DTLS ClientHello packet."; |
| 594 if (!HandleDtlsPacket(cached_client_hello_.data<char>(), |
| 595 cached_client_hello_.size())) { |
| 596 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; |
| 597 } |
| 598 } else { |
| 599 LOG_J(LS_WARNING, this) << "Discarding cached DTLS ClientHello packet " |
| 600 << "because we don't have the server role."; |
| 601 } |
| 602 cached_client_hello_.Clear(); |
| 603 } |
579 } | 604 } |
580 return true; | 605 return true; |
581 } | 606 } |
582 | 607 |
583 // Called from OnReadPacket when a DTLS packet is received. | 608 // Called from OnReadPacket when a DTLS packet is received. |
584 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, | 609 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, |
585 size_t size) { | 610 size_t size) { |
586 // Sanity check we're not passing junk that | 611 // Sanity check we're not passing junk that |
587 // just looks like DTLS. | 612 // just looks like DTLS. |
588 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data); | 613 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 | 678 |
654 void DtlsTransportChannelWrapper::Reconnect() { | 679 void DtlsTransportChannelWrapper::Reconnect() { |
655 set_dtls_state(DTLS_TRANSPORT_NEW); | 680 set_dtls_state(DTLS_TRANSPORT_NEW); |
656 set_writable(false); | 681 set_writable(false); |
657 if (channel_->writable()) { | 682 if (channel_->writable()) { |
658 OnWritableState(channel_); | 683 OnWritableState(channel_); |
659 } | 684 } |
660 } | 685 } |
661 | 686 |
662 } // namespace cricket | 687 } // namespace cricket |
OLD | NEW |