| // Copyright (c) 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "quiche/quic/qbone/qbone_client_session.h" |
| |
| #include <utility> |
| |
| #include "absl/strings/string_view.h" |
| #include "quiche/quic/core/quic_types.h" |
| #include "quiche/quic/qbone/qbone_constants.h" |
| #include "quiche/common/platform/api/quiche_command_line_flags.h" |
| |
| DEFINE_QUICHE_COMMAND_LINE_FLAG( |
| bool, qbone_client_defer_control_stream_creation, true, |
| "If true, control stream in QBONE client session is created after " |
| "encryption established."); |
| |
| namespace quic { |
| |
| QboneClientSession::QboneClientSession( |
| QuicConnection* connection, |
| QuicCryptoClientConfig* quic_crypto_client_config, |
| QuicSession::Visitor* owner, const QuicConfig& config, |
| const ParsedQuicVersionVector& supported_versions, |
| const QuicServerId& server_id, QbonePacketWriter* writer, |
| QboneClientControlStream::Handler* handler) |
| : QboneSessionBase(connection, owner, config, supported_versions, writer), |
| server_id_(server_id), |
| quic_crypto_client_config_(quic_crypto_client_config), |
| handler_(handler) {} |
| |
| QboneClientSession::~QboneClientSession() {} |
| |
| std::unique_ptr<QuicCryptoStream> QboneClientSession::CreateCryptoStream() { |
| return std::make_unique<QuicCryptoClientStream>( |
| server_id_, this, nullptr, quic_crypto_client_config_, this, |
| /*has_application_state = */ true); |
| } |
| |
| void QboneClientSession::CreateControlStream() { |
| if (control_stream_ != nullptr) { |
| return; |
| } |
| // Register the reserved control stream. |
| QuicStreamId next_id = GetNextOutgoingBidirectionalStreamId(); |
| QUICHE_DCHECK_EQ(next_id, |
| QboneConstants::GetControlStreamId(transport_version())); |
| auto control_stream = |
| std::make_unique<QboneClientControlStream>(this, handler_); |
| control_stream_ = control_stream.get(); |
| ActivateStream(std::move(control_stream)); |
| } |
| |
| void QboneClientSession::Initialize() { |
| // Initialize must be called first, as that's what generates the crypto |
| // stream. |
| QboneSessionBase::Initialize(); |
| static_cast<QuicCryptoClientStreamBase*>(GetMutableCryptoStream()) |
| ->CryptoConnect(); |
| if (!quiche::GetQuicheCommandLineFlag( |
| FLAGS_qbone_client_defer_control_stream_creation)) { |
| CreateControlStream(); |
| } |
| } |
| |
| void QboneClientSession::SetDefaultEncryptionLevel( |
| quic::EncryptionLevel level) { |
| QboneSessionBase::SetDefaultEncryptionLevel(level); |
| if (quiche::GetQuicheCommandLineFlag( |
| FLAGS_qbone_client_defer_control_stream_creation) && |
| level == quic::ENCRYPTION_FORWARD_SECURE) { |
| CreateControlStream(); |
| } |
| } |
| |
| int QboneClientSession::GetNumSentClientHellos() const { |
| return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream()) |
| ->num_sent_client_hellos(); |
| } |
| |
| bool QboneClientSession::EarlyDataAccepted() const { |
| return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream()) |
| ->EarlyDataAccepted(); |
| } |
| |
| bool QboneClientSession::ReceivedInchoateReject() const { |
| return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream()) |
| ->ReceivedInchoateReject(); |
| } |
| |
| int QboneClientSession::GetNumReceivedServerConfigUpdates() const { |
| return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream()) |
| ->num_scup_messages_received(); |
| } |
| |
| bool QboneClientSession::SendServerRequest(const QboneServerRequest& request) { |
| if (!control_stream_) { |
| QUIC_BUG(quic_bug_11056_1) |
| << "Cannot send server request before control stream is created."; |
| return false; |
| } |
| return control_stream_->SendRequest(request); |
| } |
| |
| void QboneClientSession::ProcessPacketFromNetwork(absl::string_view packet) { |
| SendPacketToPeer(packet); |
| } |
| |
| void QboneClientSession::ProcessPacketFromPeer(absl::string_view packet) { |
| writer_->WritePacketToNetwork(packet.data(), packet.size()); |
| } |
| |
| void QboneClientSession::OnProofValid( |
| const QuicCryptoClientConfig::CachedState& cached) {} |
| |
| void QboneClientSession::OnProofVerifyDetailsAvailable( |
| const ProofVerifyDetails& verify_details) {} |
| |
| bool QboneClientSession::HasActiveRequests() const { |
| return GetNumActiveStreams() + num_draining_streams() > 0; |
| } |
| |
| } // namespace quic |