| // Copyright 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 "net/third_party/quiche/src/quic/masque/masque_server_session.h" |
| |
| namespace quic { |
| |
| MasqueServerSession::MasqueServerSession( |
| const QuicConfig& config, |
| const ParsedQuicVersionVector& supported_versions, |
| QuicConnection* connection, |
| QuicSession::Visitor* visitor, |
| Visitor* owner, |
| QuicCryptoServerStreamBase::Helper* helper, |
| const QuicCryptoServerConfig* crypto_config, |
| QuicCompressedCertsCache* compressed_certs_cache, |
| MasqueServerBackend* masque_server_backend) |
| : QuicSimpleServerSession(config, |
| supported_versions, |
| connection, |
| visitor, |
| helper, |
| crypto_config, |
| compressed_certs_cache, |
| masque_server_backend), |
| masque_server_backend_(masque_server_backend), |
| owner_(owner), |
| compression_engine_(this) { |
| masque_server_backend_->RegisterBackendClient(connection_id(), this); |
| } |
| |
| void MasqueServerSession::OnMessageReceived(absl::string_view message) { |
| QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length(); |
| |
| QuicConnectionId client_connection_id, server_connection_id; |
| QuicSocketAddress server_address; |
| std::vector<char> packet; |
| bool version_present; |
| if (!compression_engine_.DecompressDatagram( |
| message, &client_connection_id, &server_connection_id, |
| &server_address, &packet, &version_present)) { |
| return; |
| } |
| |
| QUIC_DVLOG(1) << "Received packet of length " << packet.size() << " for " |
| << server_address << " client " << client_connection_id; |
| |
| if (version_present) { |
| if (client_connection_id.length() != kQuicDefaultConnectionIdLength) { |
| QUIC_DLOG(ERROR) |
| << "Dropping long header with invalid client_connection_id " |
| << client_connection_id; |
| return; |
| } |
| owner_->RegisterClientConnectionId(client_connection_id, this); |
| } |
| |
| WriteResult write_result = connection()->writer()->WritePacket( |
| packet.data(), packet.size(), connection()->self_address().host(), |
| server_address, nullptr); |
| QUIC_DVLOG(1) << "Got " << write_result << " for " << packet.size() |
| << " bytes to " << server_address; |
| } |
| |
| void MasqueServerSession::OnMessageAcked(QuicMessageId message_id, |
| QuicTime /*receive_timestamp*/) { |
| QUIC_DVLOG(1) << "Received ack for DATAGRAM frame " << message_id; |
| } |
| |
| void MasqueServerSession::OnMessageLost(QuicMessageId message_id) { |
| QUIC_DVLOG(1) << "We believe DATAGRAM frame " << message_id << " was lost"; |
| } |
| |
| void MasqueServerSession::OnConnectionClosed( |
| const QuicConnectionCloseFrame& /*frame*/, |
| ConnectionCloseSource /*source*/) { |
| QUIC_DLOG(INFO) << "Closing connection for " << connection_id(); |
| masque_server_backend_->RemoveBackendClient(connection_id()); |
| } |
| |
| std::unique_ptr<QuicBackendResponse> MasqueServerSession::HandleMasqueRequest( |
| const std::string& masque_path, |
| const spdy::Http2HeaderBlock& /*request_headers*/, |
| const std::string& request_body, |
| QuicSimpleServerBackend::RequestHandler* /*request_handler*/) { |
| QUIC_DLOG(INFO) << "MasqueServerSession handling MASQUE request"; |
| |
| if (masque_path == "init") { |
| if (masque_initialized_) { |
| QUIC_DLOG(ERROR) << "Got second MASQUE init request"; |
| return nullptr; |
| } |
| masque_initialized_ = true; |
| } else if (masque_path == "unregister") { |
| QuicConnectionId connection_id(request_body.data(), request_body.length()); |
| QUIC_DLOG(INFO) << "Received MASQUE request to unregister " |
| << connection_id; |
| owner_->UnregisterClientConnectionId(connection_id); |
| compression_engine_.UnregisterClientConnectionId(connection_id); |
| } else { |
| if (!masque_initialized_) { |
| QUIC_DLOG(ERROR) << "Got MASQUE request before init"; |
| return nullptr; |
| } |
| } |
| |
| // TODO(dschinazi) implement binary protocol sent in response body. |
| const std::string response_body = ""; |
| spdy::Http2HeaderBlock response_headers; |
| response_headers[":status"] = "200"; |
| auto response = std::make_unique<QuicBackendResponse>(); |
| response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE); |
| response->set_headers(std::move(response_headers)); |
| response->set_body(response_body); |
| |
| return response; |
| } |
| |
| void MasqueServerSession::HandlePacketFromServer( |
| const ReceivedPacketInfo& packet_info) { |
| QUIC_DVLOG(1) << "MasqueServerSession received " << packet_info; |
| compression_engine_.CompressAndSendPacket( |
| packet_info.packet.AsStringPiece(), packet_info.destination_connection_id, |
| packet_info.source_connection_id, packet_info.peer_address); |
| } |
| |
| } // namespace quic |