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