Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 return net::QUIC_SUCCESS; | 116 return net::QUIC_SUCCESS; |
| 117 } | 117 } |
| 118 }; | 118 }; |
| 119 | 119 |
| 120 } // namespace | 120 } // namespace |
| 121 | 121 |
| 122 namespace cricket { | 122 namespace cricket { |
| 123 | 123 |
| 124 QuicTransportChannel::QuicTransportChannel(TransportChannelImpl* channel) | 124 QuicTransportChannel::QuicTransportChannel(TransportChannelImpl* channel) |
| 125 : TransportChannelImpl(channel->transport_name(), channel->component()), | 125 : TransportChannelImpl(channel->transport_name(), channel->component()), |
| 126 Transport("", nullptr), | |
|
pthatcher1
2016/03/30 20:34:50
Why not use channel->transport_name() for the tran
mikescarlett
2016/04/05 19:58:53
Transport isn't subclassed anymore
| |
| 126 worker_thread_(rtc::Thread::Current()), | 127 worker_thread_(rtc::Thread::Current()), |
| 127 channel_(channel), | 128 channel_(channel), |
| 128 helper_(worker_thread_) { | 129 helper_(worker_thread_) { |
| 129 channel_->SignalWritableState.connect(this, | 130 channel_->SignalWritableState.connect(this, |
| 130 &QuicTransportChannel::OnWritableState); | 131 &QuicTransportChannel::OnWritableState); |
| 131 channel_->SignalReadPacket.connect(this, &QuicTransportChannel::OnReadPacket); | 132 channel_->SignalReadPacket.connect(this, &QuicTransportChannel::OnReadPacket); |
| 132 channel_->SignalSentPacket.connect(this, &QuicTransportChannel::OnSentPacket); | 133 channel_->SignalSentPacket.connect(this, &QuicTransportChannel::OnSentPacket); |
| 133 channel_->SignalReadyToSend.connect(this, | 134 channel_->SignalReadyToSend.connect(this, |
| 134 &QuicTransportChannel::OnReadyToSend); | 135 &QuicTransportChannel::OnReadyToSend); |
| 135 channel_->SignalGatheringState.connect( | 136 channel_->SignalGatheringState.connect( |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 146 this, &QuicTransportChannel::OnConnectionRemoved); | 147 this, &QuicTransportChannel::OnConnectionRemoved); |
| 147 channel_->SignalReceivingState.connect( | 148 channel_->SignalReceivingState.connect( |
| 148 this, &QuicTransportChannel::OnReceivingState); | 149 this, &QuicTransportChannel::OnReceivingState); |
| 149 | 150 |
| 150 // Set the QUIC connection timeout. | 151 // Set the QUIC connection timeout. |
| 151 config_.SetIdleConnectionStateLifetime( | 152 config_.SetIdleConnectionStateLifetime( |
| 152 net::QuicTime::Delta::FromSeconds(kIdleConnectionStateLifetime), | 153 net::QuicTime::Delta::FromSeconds(kIdleConnectionStateLifetime), |
| 153 net::QuicTime::Delta::FromSeconds(kIdleConnectionStateLifetime)); | 154 net::QuicTime::Delta::FromSeconds(kIdleConnectionStateLifetime)); |
| 154 // Set the bytes reserved for the QUIC connection ID to zero. | 155 // Set the bytes reserved for the QUIC connection ID to zero. |
| 155 config_.SetBytesForConnectionIdToSend(0); | 156 config_.SetBytesForConnectionIdToSend(0); |
| 157 // Provide the Transport base class with a pointer to this channel by | |
| 158 // implicitly triggering Transport::CreateTransportChannel. | |
| 159 Transport::CreateChannel(0); | |
| 156 } | 160 } |
| 157 | 161 |
| 158 QuicTransportChannel::~QuicTransportChannel() {} | 162 QuicTransportChannel::~QuicTransportChannel() { |
| 163 // Required to avoid assertion error in Transport::~Transport(). | |
| 164 Transport::DestroyAllChannels(); | |
| 165 } | |
| 159 | 166 |
| 160 bool QuicTransportChannel::SetLocalCertificate( | 167 bool QuicTransportChannel::SetLocalCertificate( |
| 161 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { | 168 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
| 162 if (!certificate) { | 169 if (!certificate) { |
| 163 LOG_J(LS_ERROR, this) | 170 LOG_J(LS_ERROR, this) |
| 164 << "No local certificate was supplied. Not doing QUIC."; | 171 << "No local certificate was supplied. Not doing QUIC."; |
| 165 return false; | 172 return false; |
| 166 } | 173 } |
| 167 if (!local_certificate_) { | 174 if (!local_certificate_) { |
| 168 local_certificate_ = certificate; | 175 local_certificate_ = certificate; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 : net::Perspective::IS_SERVER; | 441 : net::Perspective::IS_SERVER; |
| 435 bool owns_writer = false; | 442 bool owns_writer = false; |
| 436 rtc::scoped_ptr<net::QuicConnection> connection(new net::QuicConnection( | 443 rtc::scoped_ptr<net::QuicConnection> connection(new net::QuicConnection( |
| 437 kConnectionId, kConnectionIpEndpoint, &helper_, this, owns_writer, | 444 kConnectionId, kConnectionIpEndpoint, &helper_, this, owns_writer, |
| 438 perspective, net::QuicSupportedVersions())); | 445 perspective, net::QuicSupportedVersions())); |
| 439 quic_.reset(new QuicSession(std::move(connection), config_)); | 446 quic_.reset(new QuicSession(std::move(connection), config_)); |
| 440 quic_->SignalHandshakeComplete.connect( | 447 quic_->SignalHandshakeComplete.connect( |
| 441 this, &QuicTransportChannel::OnHandshakeComplete); | 448 this, &QuicTransportChannel::OnHandshakeComplete); |
| 442 quic_->SignalConnectionClosed.connect( | 449 quic_->SignalConnectionClosed.connect( |
| 443 this, &QuicTransportChannel::OnConnectionClosed); | 450 this, &QuicTransportChannel::OnConnectionClosed); |
| 451 quic_->SignalIncomingStream.connect(this, | |
| 452 &QuicTransportChannel::OnIncomingStream); | |
| 444 return true; | 453 return true; |
| 445 } | 454 } |
| 446 | 455 |
| 447 bool QuicTransportChannel::StartQuicHandshake() { | 456 bool QuicTransportChannel::StartQuicHandshake() { |
| 448 if (*ssl_role_ == rtc::SSL_CLIENT) { | 457 if (*ssl_role_ == rtc::SSL_CLIENT) { |
| 449 // Unique identifier for remote peer. | 458 // Unique identifier for remote peer. |
| 450 net::QuicServerId server_id(remote_fingerprint_->value, kQuicServerPort); | 459 net::QuicServerId server_id(remote_fingerprint_->value, kQuicServerPort); |
| 451 // Perform authentication of remote peer; owned by QuicCryptoClientConfig. | 460 // Perform authentication of remote peer; owned by QuicCryptoClientConfig. |
| 452 // TODO(mikescarlett): Actually verify proof. | 461 // TODO(mikescarlett): Actually verify proof. |
| 453 net::ProofVerifier* proof_verifier = new InsecureProofVerifier(); | 462 net::ProofVerifier* proof_verifier = new InsecureProofVerifier(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 | 541 |
| 533 void QuicTransportChannel::OnConnectionClosed(net::QuicErrorCode error, | 542 void QuicTransportChannel::OnConnectionClosed(net::QuicErrorCode error, |
| 534 bool from_peer) { | 543 bool from_peer) { |
| 535 LOG_J(LS_INFO, this) << "Connection closed by " | 544 LOG_J(LS_INFO, this) << "Connection closed by " |
| 536 << (from_peer ? "other" : "this") << " peer " | 545 << (from_peer ? "other" : "this") << " peer " |
| 537 << "with QUIC error " << error; | 546 << "with QUIC error " << error; |
| 538 // TODO(mikescarlett): Allow the QUIC session to be reset when the connection | 547 // TODO(mikescarlett): Allow the QUIC session to be reset when the connection |
| 539 // does not close due to failure. | 548 // does not close due to failure. |
| 540 set_quic_state(QUIC_TRANSPORT_CLOSED); | 549 set_quic_state(QUIC_TRANSPORT_CLOSED); |
| 541 set_writable(false); | 550 set_writable(false); |
| 551 SignalClosed(); | |
| 542 } | 552 } |
| 543 | 553 |
| 544 void QuicTransportChannel::OnProofValid( | 554 void QuicTransportChannel::OnProofValid( |
| 545 const net::QuicCryptoClientConfig::CachedState& cached) { | 555 const net::QuicCryptoClientConfig::CachedState& cached) { |
| 546 LOG_J(LS_INFO, this) << "Cached proof marked valid"; | 556 LOG_J(LS_INFO, this) << "Cached proof marked valid"; |
| 547 } | 557 } |
| 548 | 558 |
| 549 void QuicTransportChannel::OnProofVerifyDetailsAvailable( | 559 void QuicTransportChannel::OnProofVerifyDetailsAvailable( |
| 550 const net::ProofVerifyDetails& verify_details) { | 560 const net::ProofVerifyDetails& verify_details) { |
| 551 LOG_J(LS_INFO, this) << "Proof verify details available from" | 561 LOG_J(LS_INFO, this) << "Proof verify details available from" |
| 552 << " QuicCryptoClientStream"; | 562 << " QuicCryptoClientStream"; |
| 553 } | 563 } |
| 554 | 564 |
| 555 bool QuicTransportChannel::HasDataToWrite() const { | 565 bool QuicTransportChannel::HasDataToWrite() const { |
| 556 return quic_ && quic_->HasDataToWrite(); | 566 return quic_ && quic_->HasDataToWrite(); |
| 557 } | 567 } |
| 558 | 568 |
| 559 void QuicTransportChannel::OnCanWrite() { | 569 void QuicTransportChannel::OnCanWrite() { |
| 560 RTC_DCHECK(quic_ != nullptr); | 570 RTC_DCHECK(quic_ != nullptr); |
| 561 quic_->connection()->OnCanWrite(); | 571 quic_->connection()->OnCanWrite(); |
| 562 } | 572 } |
| 563 | 573 |
| 564 void QuicTransportChannel::set_quic_state(QuicTransportState state) { | 574 void QuicTransportChannel::set_quic_state(QuicTransportState state) { |
| 565 LOG_J(LS_VERBOSE, this) << "set_quic_state from:" << quic_state_ << " to " | 575 LOG_J(LS_VERBOSE, this) << "set_quic_state from:" << quic_state_ << " to " |
| 566 << state; | 576 << state; |
| 567 quic_state_ = state; | 577 quic_state_ = state; |
| 568 } | 578 } |
| 569 | 579 |
| 580 bool QuicTransportChannel::NegotiateTransportDescription( | |
| 581 ContentAction local_role, | |
| 582 std::string* error_desc) { | |
| 583 if (!local_description() || !remote_description()) { | |
| 584 const std::string msg = | |
| 585 "Local and Remote description must be set before " | |
| 586 "transport descriptions are negotiated"; | |
| 587 return BadTransportDescription(msg, error_desc); | |
| 588 } | |
| 589 | |
| 590 rtc::SSLFingerprint* remote_fp = | |
| 591 remote_description()->identity_fingerprint.get(); | |
| 592 | |
| 593 if (remote_fp) { | |
| 594 if (!SetRemoteFingerprint( | |
| 595 remote_fp->algorithm, | |
| 596 reinterpret_cast<const uint8_t*>(remote_fp->digest.data()), | |
| 597 remote_fp->digest.size())) { | |
| 598 return BadTransportDescription("Failed to apply remote fingerprint.", | |
| 599 error_desc); | |
| 600 } | |
| 601 } else { | |
| 602 return BadTransportDescription( | |
| 603 "Local fingerprint supplied when caller didn't offer DTLS.", | |
| 604 error_desc); | |
| 605 } | |
| 606 | |
| 607 // From RFC 4145, section-4.1, The following are the values that the | |
| 608 // 'setup' attribute can take in an offer/answer exchange: | |
| 609 // Offer Answer | |
| 610 // ________________ | |
| 611 // active passive / holdconn | |
| 612 // passive active / holdconn | |
| 613 // actpass active / passive / holdconn | |
| 614 // holdconn holdconn | |
| 615 // | |
| 616 // Set the role that is most conformant with RFC 5763, Section 5, bullet 1 | |
| 617 // The endpoint MUST use the setup attribute defined in [RFC4145]. | |
| 618 // The endpoint that is the offerer MUST use the setup attribute | |
| 619 // value of setup:actpass and be prepared to receive a client_hello | |
| 620 // before it receives the answer. The answerer MUST use either a | |
| 621 // setup attribute value of setup:active or setup:passive. Note that | |
| 622 // if the answerer uses setup:passive, then the DTLS handshake will | |
| 623 // not begin until the answerer is received, which adds additional | |
| 624 // latency. setup:active allows the answer and the DTLS handshake to | |
| 625 // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever | |
| 626 // party is active MUST initiate a DTLS handshake by sending a | |
| 627 // ClientHello over each flow (host/port quartet). | |
| 628 // IOW - actpass and passive modes should be treated as server and | |
| 629 // active as client. | |
|
pthatcher1
2016/03/30 20:34:50
Can you just delete this whole comment and write t
mikescarlett
2016/04/05 19:58:53
Done. See QuicTransport in https://codereview.webr
| |
| 630 ConnectionRole local_connection_role = local_description()->connection_role; | |
| 631 ConnectionRole remote_connection_role = remote_description()->connection_role; | |
| 632 | |
| 633 bool is_remote_server = false; | |
| 634 if (local_role == CA_OFFER) { | |
| 635 if (local_connection_role != CONNECTIONROLE_ACTPASS) { | |
| 636 return BadTransportDescription( | |
| 637 "Offerer must use actpass value for setup attribute.", error_desc); | |
| 638 } | |
| 639 | |
| 640 if (remote_connection_role == CONNECTIONROLE_ACTIVE || | |
| 641 remote_connection_role == CONNECTIONROLE_PASSIVE || | |
| 642 remote_connection_role == CONNECTIONROLE_NONE) { | |
| 643 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE); | |
| 644 } else { | |
| 645 const std::string msg = | |
| 646 "Answerer must use either active or passive value " | |
| 647 "for setup attribute."; | |
| 648 return BadTransportDescription(msg, error_desc); | |
| 649 } | |
| 650 // If remote is NONE or ACTIVE it will act as client. | |
| 651 } else { | |
| 652 if (remote_connection_role != CONNECTIONROLE_ACTPASS && | |
| 653 remote_connection_role != CONNECTIONROLE_NONE) { | |
| 654 return BadTransportDescription( | |
| 655 "Offerer must use actpass value for setup attribute.", error_desc); | |
| 656 } | |
| 657 | |
| 658 if (local_connection_role == CONNECTIONROLE_ACTIVE || | |
| 659 local_connection_role == CONNECTIONROLE_PASSIVE) { | |
| 660 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE); | |
| 661 } else { | |
| 662 const std::string msg = | |
| 663 "Answerer must use either active or passive value " | |
| 664 "for setup attribute."; | |
| 665 return BadTransportDescription(msg, error_desc); | |
| 666 } | |
| 667 | |
| 668 // If local is passive, local will act as server. | |
| 669 } | |
| 670 | |
| 671 rtc::SSLRole ssl_role = is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER; | |
| 672 if (!SetSslRole(ssl_role)) { | |
| 673 return BadTransportDescription("Failed to set ssl role for the channel.", | |
| 674 error_desc); | |
| 675 } | |
| 676 | |
| 677 // Now run the negotiation for the base class. | |
| 678 return Transport::NegotiateTransportDescription(local_role, error_desc); | |
| 679 } | |
| 680 | |
| 681 ReliableQuicStream* QuicTransportChannel::CreateQuicStream() { | |
|
pthatcher1
2016/03/30 20:34:50
Can you make it clear that the 0 here is the prior
mikescarlett
2016/04/05 19:58:53
Done.
| |
| 682 if (quic_) { | |
| 683 return quic_->CreateOutgoingDynamicStream(0); | |
| 684 } | |
| 685 return nullptr; | |
| 686 } | |
| 687 | |
| 688 void QuicTransportChannel::OnIncomingStream(ReliableQuicStream* stream) { | |
| 689 SignalIncomingStream(stream); | |
| 690 } | |
| 691 | |
| 570 } // namespace cricket | 692 } // namespace cricket |
| OLD | NEW |