| // 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 "quic/qbone/qbone_server_session.h" | |
| #include <string> | |
| #include <utility> | |
| #include "absl/strings/string_view.h" | |
| #include "quic/core/quic_connection_id.h" | |
| #include "quic/core/quic_types.h" | |
| #include "quic/core/quic_utils.h" | |
| #include "quic/qbone/qbone_constants.h" | |
| #include "common/platform/api/quiche_command_line_flags.h" | |
| DEFINE_QUICHE_COMMAND_LINE_FLAG( | |
| bool, qbone_server_defer_control_stream_creation, true, | |
| "If true, control stream in QBONE server session is created after " | |
| "encryption established."); | |
| namespace quic { | |
| bool QboneCryptoServerStreamHelper::CanAcceptClientHello( | |
| const CryptoHandshakeMessage& chlo, | |
| const QuicSocketAddress& client_address, | |
| const QuicSocketAddress& peer_address, | |
| const QuicSocketAddress& self_address, | |
| std::string* error_details) const { | |
| absl::string_view alpn; | |
| chlo.GetStringPiece(quic::kALPN, &alpn); | |
| if (alpn != QboneConstants::kQboneAlpn) { | |
| *error_details = "ALPN-indicated protocol is not qbone"; | |
| return false; | |
| } | |
| return true; | |
| } | |
| QboneServerSession::QboneServerSession( | |
| const quic::ParsedQuicVersionVector& supported_versions, | |
| QuicConnection* connection, | |
| Visitor* owner, | |
| const QuicConfig& config, | |
| const QuicCryptoServerConfig* quic_crypto_server_config, | |
| QuicCompressedCertsCache* compressed_certs_cache, | |
| QbonePacketWriter* writer, | |
| QuicIpAddress self_ip, | |
| QuicIpAddress client_ip, | |
| size_t client_ip_subnet_length, | |
| QboneServerControlStream::Handler* handler) | |
| : QboneSessionBase(connection, owner, config, supported_versions, writer), | |
| processor_(self_ip, client_ip, client_ip_subnet_length, this, this), | |
| quic_crypto_server_config_(quic_crypto_server_config), | |
| compressed_certs_cache_(compressed_certs_cache), | |
| handler_(handler) {} | |
| QboneServerSession::~QboneServerSession() {} | |
| std::unique_ptr<QuicCryptoStream> QboneServerSession::CreateCryptoStream() { | |
| return CreateCryptoServerStream(quic_crypto_server_config_, | |
| compressed_certs_cache_, this, | |
| &stream_helper_); | |
| } | |
| void QboneServerSession::CreateControlStream() { | |
| if (control_stream_ != nullptr) { | |
| return; | |
| } | |
| // Register the reserved control stream. | |
| auto control_stream = | |
| std::make_unique<QboneServerControlStream>(this, handler_); | |
| control_stream_ = control_stream.get(); | |
| ActivateStream(std::move(control_stream)); | |
| } | |
| QuicStream* QboneServerSession::CreateControlStreamFromPendingStream( | |
| PendingStream* pending) { | |
| QUICHE_DCHECK(control_stream_ == nullptr); | |
| // Register the reserved control stream. | |
| auto control_stream = | |
| std::make_unique<QboneServerControlStream>(pending, this, handler_); | |
| control_stream_ = control_stream.get(); | |
| ActivateStream(std::move(control_stream)); | |
| return control_stream_; | |
| } | |
| void QboneServerSession::Initialize() { | |
| QboneSessionBase::Initialize(); | |
| if (!GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation)) { | |
| CreateControlStream(); | |
| } | |
| } | |
| void QboneServerSession::SetDefaultEncryptionLevel( | |
| quic::EncryptionLevel level) { | |
| QboneSessionBase::SetDefaultEncryptionLevel(level); | |
| if (GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation) && | |
| level == quic::ENCRYPTION_FORWARD_SECURE) { | |
| CreateControlStream(); | |
| } | |
| } | |
| bool QboneServerSession::SendClientRequest(const QboneClientRequest& request) { | |
| if (!control_stream_) { | |
| QUIC_BUG(quic_bug_11026_1) | |
| << "Cannot send client request before control stream is created."; | |
| return false; | |
| } | |
| return control_stream_->SendRequest(request); | |
| } | |
| void QboneServerSession::ProcessPacketFromNetwork(absl::string_view packet) { | |
| std::string buffer = std::string(packet); | |
| processor_.ProcessPacket(&buffer, | |
| QbonePacketProcessor::Direction::FROM_NETWORK); | |
| } | |
| void QboneServerSession::ProcessPacketFromPeer(absl::string_view packet) { | |
| std::string buffer = std::string(packet); | |
| processor_.ProcessPacket(&buffer, | |
| QbonePacketProcessor::Direction::FROM_OFF_NETWORK); | |
| } | |
| void QboneServerSession::SendPacketToClient(absl::string_view packet) { | |
| SendPacketToPeer(packet); | |
| } | |
| void QboneServerSession::SendPacketToNetwork(absl::string_view packet) { | |
| QUICHE_DCHECK(writer_ != nullptr); | |
| writer_->WritePacketToNetwork(packet.data(), packet.size()); | |
| } | |
| } // namespace quic |