blob: e6ca1f3c6d58245d703601bf241479965d362f28 [file] [log] [blame]
// 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