Remove legacy MASQUE mode
This CL deletes the implementation of the earliest MASQUE draft. Since we are moving forward with a new design, this will reduce complexity. This CL is not flag protected because MASQUE is not yet used in production.
PiperOrigin-RevId: 442372570
diff --git a/quiche/quic/masque/masque_client_bin.cc b/quiche/quic/masque/masque_client_bin.cc
index 8fd5e52..f973227 100644
--- a/quiche/quic/masque/masque_client_bin.cc
+++ b/quiche/quic/masque/masque_client_bin.cc
@@ -29,9 +29,9 @@
bool, disable_certificate_verification, false,
"If true, don't verify the server certificate.");
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
- "Allows setting MASQUE mode, valid values are "
- "open and legacy. Defaults to open.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, masque_mode, "",
+ "Allows setting MASQUE mode, currently only valid value is \"open\".");
namespace quic {
@@ -83,9 +83,7 @@
}
MasqueMode masque_mode = MasqueMode::kOpen;
std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
- if (mode_string == "legacy") {
- masque_mode = MasqueMode::kLegacy;
- } else if (!mode_string.empty() && mode_string != "open") {
+ if (!mode_string.empty() && mode_string != "open") {
std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
return 1;
}
diff --git a/quiche/quic/masque/masque_client_session.cc b/quiche/quic/masque/masque_client_session.cc
index 9a69dad..b053659 100644
--- a/quiche/quic/masque/masque_client_session.cc
+++ b/quiche/quic/masque/masque_client_session.cc
@@ -30,42 +30,7 @@
crypto_config, push_promise_index),
masque_mode_(masque_mode),
uri_template_(uri_template),
- owner_(owner),
- compression_engine_(this) {}
-
-void MasqueClientSession::OnMessageReceived(absl::string_view message) {
- if (masque_mode_ == MasqueMode::kLegacy) {
- QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length();
- QuicConnectionId client_connection_id, server_connection_id;
- QuicSocketAddress target_server_address;
- std::vector<char> packet;
- bool version_present;
- if (!compression_engine_.DecompressDatagram(
- message, &client_connection_id, &server_connection_id,
- &target_server_address, &packet, &version_present)) {
- return;
- }
-
- auto connection_id_registration =
- client_connection_id_registrations_.find(client_connection_id);
- if (connection_id_registration ==
- client_connection_id_registrations_.end()) {
- QUIC_DLOG(ERROR) << "MasqueClientSession failed to dispatch "
- << client_connection_id;
- return;
- }
- EncapsulatedClientSession* encapsulated_client_session =
- connection_id_registration->second;
- encapsulated_client_session->ProcessPacket(
- absl::string_view(packet.data(), packet.size()), target_server_address);
-
- QUIC_DVLOG(1) << "Sent " << packet.size() << " bytes to connection for "
- << client_connection_id;
- return;
- }
- QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
- QuicSpdySession::OnMessageReceived(message);
-}
+ owner_(owner) {}
void MasqueClientSession::OnMessageAcked(QuicMessageId message_id,
QuicTime /*receive_timestamp*/) {
@@ -174,16 +139,8 @@
}
void MasqueClientSession::SendPacket(
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id, absl::string_view packet,
- const QuicSocketAddress& target_server_address,
+ absl::string_view packet, const QuicSocketAddress& target_server_address,
EncapsulatedClientSession* encapsulated_client_session) {
- if (masque_mode_ == MasqueMode::kLegacy) {
- compression_engine_.CompressAndSendPacket(packet, client_connection_id,
- server_connection_id,
- target_server_address);
- return;
- }
const ConnectUdpClientState* connect_udp = GetOrCreateConnectUdpClientState(
target_server_address, encapsulated_client_session);
if (connect_udp == nullptr) {
@@ -200,34 +157,8 @@
<< MessageStatusToString(message_status);
}
-void MasqueClientSession::RegisterConnectionId(
- QuicConnectionId client_connection_id,
+void MasqueClientSession::CloseConnectUdpStream(
EncapsulatedClientSession* encapsulated_client_session) {
- QUIC_DLOG(INFO) << "Registering " << client_connection_id
- << " to encapsulated client";
- QUICHE_DCHECK(
- client_connection_id_registrations_.find(client_connection_id) ==
- client_connection_id_registrations_.end() ||
- client_connection_id_registrations_[client_connection_id] ==
- encapsulated_client_session);
- client_connection_id_registrations_[client_connection_id] =
- encapsulated_client_session;
-}
-
-void MasqueClientSession::UnregisterConnectionId(
- QuicConnectionId client_connection_id,
- EncapsulatedClientSession* encapsulated_client_session) {
- QUIC_DLOG(INFO) << "Unregistering " << client_connection_id;
- if (masque_mode_ == MasqueMode::kLegacy) {
- if (client_connection_id_registrations_.find(client_connection_id) !=
- client_connection_id_registrations_.end()) {
- client_connection_id_registrations_.erase(client_connection_id);
- owner_->UnregisterClientConnectionId(client_connection_id);
- compression_engine_.UnregisterClientConnectionId(client_connection_id);
- }
- return;
- }
-
for (auto it = connect_udp_client_states_.begin();
it != connect_udp_client_states_.end();) {
if (it->encapsulated_client_session() == encapsulated_client_session) {
diff --git a/quiche/quic/masque/masque_client_session.h b/quiche/quic/masque/masque_client_session.h
index 6e469b2..05162b5 100644
--- a/quiche/quic/masque/masque_client_session.h
+++ b/quiche/quic/masque/masque_client_session.h
@@ -10,7 +10,6 @@
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/http/quic_spdy_client_session.h"
-#include "quiche/quic/masque/masque_compression_engine.h"
#include "quiche/quic/masque/masque_utils.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
@@ -30,10 +29,6 @@
public:
virtual ~Owner() {}
- // Notifies the owner that the client connection ID is no longer in use.
- virtual void UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) = 0;
-
// Notifies the owner that a settings frame has been received.
virtual void OnSettingsReceived() = 0;
};
@@ -70,7 +65,6 @@
MasqueClientSession& operator=(const MasqueClientSession&) = delete;
// From QuicSession.
- void OnMessageReceived(absl::string_view message) override;
void OnMessageAcked(QuicMessageId message_id,
QuicTime receive_timestamp) override;
void OnMessageLost(QuicMessageId message_id) override;
@@ -82,26 +76,12 @@
bool OnSettingsFrame(const SettingsFrame& frame) override;
// Send encapsulated packet.
- void SendPacket(QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- absl::string_view packet,
+ void SendPacket(absl::string_view packet,
const QuicSocketAddress& target_server_address,
EncapsulatedClientSession* encapsulated_client_session);
- // Register encapsulated client. This allows clients that are encapsulated
- // within this MASQUE session to indicate they own a given client connection
- // ID so incoming packets with that connection ID are routed back to them.
- // Callers must not register a second different |encapsulated_client_session|
- // with the same |client_connection_id|. Every call must be matched with a
- // call to UnregisterConnectionId.
- void RegisterConnectionId(
- QuicConnectionId client_connection_id,
- EncapsulatedClientSession* encapsulated_client_session);
-
- // Unregister encapsulated client. |client_connection_id| must match a
- // value previously passed to RegisterConnectionId.
- void UnregisterConnectionId(
- QuicConnectionId client_connection_id,
+ // Close CONNECT-UDP stream tied to this encapsulated client session.
+ void CloseConnectUdpStream(
EncapsulatedClientSession* encapsulated_client_session);
private:
@@ -155,11 +135,7 @@
MasqueMode masque_mode_;
std::string uri_template_;
std::list<ConnectUdpClientState> connect_udp_client_states_;
- absl::flat_hash_map<QuicConnectionId, EncapsulatedClientSession*,
- QuicConnectionIdHash>
- client_connection_id_registrations_;
Owner* owner_; // Unowned;
- MasqueCompressionEngine compression_engine_;
};
} // namespace quic
diff --git a/quiche/quic/masque/masque_compression_engine.cc b/quiche/quic/masque/masque_compression_engine.cc
deleted file mode 100644
index 3d05740..0000000
--- a/quiche/quic/masque/masque_compression_engine.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-// 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 "quiche/quic/masque/masque_compression_engine.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quiche/quic/core/quic_data_reader.h"
-#include "quiche/quic/core/quic_data_writer.h"
-#include "quiche/quic/core/quic_framer.h"
-#include "quiche/quic/core/quic_session.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/core/quic_versions.h"
-#include "quiche/quic/platform/api/quic_containers.h"
-#include "quiche/common/platform/api/quiche_mem_slice.h"
-#include "quiche/common/quiche_buffer_allocator.h"
-#include "quiche/common/quiche_text_utils.h"
-
-namespace quic {
-
-namespace {
-// |kFlowId0| is used to indicate creation of a new compression context.
-const QuicDatagramStreamId kFlowId0 = 0;
-
-enum MasqueAddressFamily : uint8_t {
- MasqueAddressFamilyIPv4 = 4,
- MasqueAddressFamilyIPv6 = 6,
-};
-
-} // namespace
-
-MasqueCompressionEngine::MasqueCompressionEngine(
- QuicSpdySession* masque_session)
- : masque_session_(masque_session),
- next_available_flow_id_(
- masque_session_->perspective() == Perspective::IS_CLIENT ? 0 : 1) {}
-
-QuicDatagramStreamId MasqueCompressionEngine::FindOrCreateCompressionContext(
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address, bool client_connection_id_present,
- bool server_connection_id_present, bool* validated) {
- QuicDatagramStreamId flow_id = kFlowId0;
- *validated = false;
- for (const auto& kv : contexts_) {
- const MasqueCompressionContext& context = kv.second;
- if (context.server_address != server_address) {
- continue;
- }
- if (client_connection_id_present &&
- context.client_connection_id != client_connection_id) {
- continue;
- }
- if (server_connection_id_present &&
- context.server_connection_id != server_connection_id) {
- continue;
- }
-
- flow_id = kv.first;
- QUICHE_DCHECK_NE(flow_id, kFlowId0);
- *validated = context.validated;
- QUIC_DVLOG(1) << "Compressing using " << (*validated ? "" : "un")
- << "validated flow_id " << flow_id << " to "
- << context.server_address << " client "
- << context.client_connection_id << " server "
- << context.server_connection_id;
- break;
- }
-
- if (flow_id != kFlowId0) {
- // Found a compression context, use it.
- return flow_id;
- }
-
- // Create new compression context.
- next_available_flow_id_ += 2;
- flow_id = next_available_flow_id_;
- QUIC_DVLOG(1) << "Compression assigning new flow_id " << flow_id << " to "
- << server_address << " client " << client_connection_id
- << " server " << server_connection_id;
- MasqueCompressionContext context;
- context.client_connection_id = client_connection_id;
- context.server_connection_id = server_connection_id;
- context.server_address = server_address;
- contexts_[flow_id] = context;
-
- return flow_id;
-}
-
-bool MasqueCompressionEngine::WriteCompressedPacketToSlice(
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address,
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id, QuicDatagramStreamId flow_id,
- bool validated, uint8_t first_byte, bool long_header,
- QuicDataReader* reader, QuicDataWriter* writer) {
- if (validated) {
- QUIC_DVLOG(1) << "Compressing using validated flow_id " << flow_id;
- if (!writer->WriteVarInt62(flow_id)) {
- QUIC_BUG(quic_bug_10981_1) << "Failed to write flow_id";
- return false;
- }
- } else {
- QUIC_DVLOG(1) << "Compressing using unvalidated flow_id " << flow_id;
- if (!writer->WriteVarInt62(kFlowId0)) {
- QUIC_BUG(quic_bug_10981_2) << "Failed to write kFlowId0";
- return false;
- }
- if (!writer->WriteVarInt62(flow_id)) {
- QUIC_BUG(quic_bug_10981_3) << "Failed to write flow_id";
- return false;
- }
- if (!writer->WriteLengthPrefixedConnectionId(client_connection_id)) {
- QUIC_BUG(quic_bug_10981_4) << "Failed to write client_connection_id";
- return false;
- }
- if (!writer->WriteLengthPrefixedConnectionId(server_connection_id)) {
- QUIC_BUG(quic_bug_10981_5) << "Failed to write server_connection_id";
- return false;
- }
- if (!writer->WriteUInt16(server_address.port())) {
- QUIC_BUG(quic_bug_10981_6) << "Failed to write port";
- return false;
- }
- QuicIpAddress peer_ip = server_address.host();
- QUICHE_DCHECK(peer_ip.IsInitialized());
- std::string peer_ip_bytes = peer_ip.ToPackedString();
- QUICHE_DCHECK(!peer_ip_bytes.empty());
- uint8_t address_id;
- if (peer_ip.address_family() == IpAddressFamily::IP_V6) {
- address_id = MasqueAddressFamilyIPv6;
- if (peer_ip_bytes.length() != QuicIpAddress::kIPv6AddressSize) {
- QUIC_BUG(quic_bug_10981_7) << "Bad IPv6 length " << server_address;
- return false;
- }
- } else if (peer_ip.address_family() == IpAddressFamily::IP_V4) {
- address_id = MasqueAddressFamilyIPv4;
- if (peer_ip_bytes.length() != QuicIpAddress::kIPv4AddressSize) {
- QUIC_BUG(quic_bug_10981_8) << "Bad IPv4 length " << server_address;
- return false;
- }
- } else {
- QUIC_BUG(quic_bug_10981_9)
- << "Unexpected server_address " << server_address;
- return false;
- }
- if (!writer->WriteUInt8(address_id)) {
- QUIC_BUG(quic_bug_10981_10) << "Failed to write address_id";
- return false;
- }
- if (!writer->WriteStringPiece(peer_ip_bytes)) {
- QUIC_BUG(quic_bug_10981_11) << "Failed to write IP address";
- return false;
- }
- }
- if (!writer->WriteUInt8(first_byte)) {
- QUIC_BUG(quic_bug_10981_12) << "Failed to write first_byte";
- return false;
- }
- if (long_header) {
- QuicVersionLabel version_label;
- if (!reader->ReadUInt32(&version_label)) {
- QUIC_DLOG(ERROR) << "Failed to read version";
- return false;
- }
- if (!writer->WriteUInt32(version_label)) {
- QUIC_BUG(quic_bug_10981_13) << "Failed to write version";
- return false;
- }
- QuicConnectionId packet_destination_connection_id,
- packet_source_connection_id;
- if (!reader->ReadLengthPrefixedConnectionId(
- &packet_destination_connection_id) ||
- !reader->ReadLengthPrefixedConnectionId(&packet_source_connection_id)) {
- QUIC_DLOG(ERROR) << "Failed to parse long header connection IDs";
- return false;
- }
- if (packet_destination_connection_id != destination_connection_id) {
- QUIC_DLOG(ERROR) << "Long header packet's destination_connection_id "
- << packet_destination_connection_id
- << " does not match expected "
- << destination_connection_id;
- return false;
- }
- if (packet_source_connection_id != source_connection_id) {
- QUIC_DLOG(ERROR) << "Long header packet's source_connection_id "
- << packet_source_connection_id
- << " does not match expected " << source_connection_id;
- return false;
- }
- } else {
- QuicConnectionId packet_destination_connection_id;
- if (!reader->ReadConnectionId(&packet_destination_connection_id,
- destination_connection_id.length())) {
- QUIC_DLOG(ERROR)
- << "Failed to read short header packet's destination_connection_id";
- return false;
- }
- if (packet_destination_connection_id != destination_connection_id) {
- QUIC_DLOG(ERROR) << "Short header packet's destination_connection_id "
- << packet_destination_connection_id
- << " does not match expected "
- << destination_connection_id;
- return false;
- }
- }
- absl::string_view packet_payload = reader->ReadRemainingPayload();
- if (!writer->WriteStringPiece(packet_payload)) {
- QUIC_BUG(quic_bug_10981_14) << "Failed to write packet_payload";
- return false;
- }
- return true;
-}
-
-void MasqueCompressionEngine::CompressAndSendPacket(
- absl::string_view packet, QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address) {
- QUIC_DVLOG(2) << "Compressing client " << client_connection_id << " server "
- << server_connection_id << "\n"
- << quiche::QuicheTextUtils::HexDump(packet);
- QUICHE_DCHECK(server_address.IsInitialized());
- if (packet.empty()) {
- QUIC_BUG(quic_bug_10981_15) << "Tried to send empty packet";
- return;
- }
- QuicDataReader reader(packet.data(), packet.length());
- uint8_t first_byte;
- if (!reader.ReadUInt8(&first_byte)) {
- QUIC_BUG(quic_bug_10981_16) << "Failed to read first_byte";
- return;
- }
- const bool long_header = (first_byte & FLAGS_LONG_HEADER) != 0;
- bool client_connection_id_present = true, server_connection_id_present = true;
- QuicConnectionId destination_connection_id, source_connection_id;
- if (masque_session_->perspective() == Perspective::IS_SERVER) {
- destination_connection_id = client_connection_id;
- source_connection_id = server_connection_id;
- if (!long_header) {
- server_connection_id_present = false;
- }
- } else {
- destination_connection_id = server_connection_id;
- source_connection_id = client_connection_id;
- if (!long_header) {
- client_connection_id_present = false;
- }
- }
-
- bool validated = false;
- QuicDatagramStreamId flow_id = FindOrCreateCompressionContext(
- client_connection_id, server_connection_id, server_address,
- client_connection_id_present, server_connection_id_present, &validated);
-
- size_t slice_length = packet.length() - destination_connection_id.length();
- if (long_header) {
- slice_length -= sizeof(uint8_t) * 2 + source_connection_id.length();
- }
- if (validated) {
- slice_length += QuicDataWriter::GetVarInt62Len(flow_id);
- } else {
- slice_length += QuicDataWriter::GetVarInt62Len(kFlowId0) +
- QuicDataWriter::GetVarInt62Len(flow_id) + sizeof(uint8_t) +
- client_connection_id.length() + sizeof(uint8_t) +
- server_connection_id.length() +
- sizeof(server_address.port()) + sizeof(uint8_t) +
- server_address.host().ToPackedString().length();
- }
- quiche::QuicheBuffer buffer(
- masque_session_->connection()->helper()->GetStreamSendBufferAllocator(),
- slice_length);
- QuicDataWriter writer(buffer.size(), buffer.data());
-
- if (!WriteCompressedPacketToSlice(
- client_connection_id, server_connection_id, server_address,
- destination_connection_id, source_connection_id, flow_id, validated,
- first_byte, long_header, &reader, &writer)) {
- return;
- }
-
- MessageResult message_result =
- masque_session_->SendMessage(quiche::QuicheMemSlice(std::move(buffer)));
-
- QUIC_DVLOG(1) << "Sent packet compressed with flow ID " << flow_id
- << " and got message result " << message_result;
-}
-
-bool MasqueCompressionEngine::ParseCompressionContext(
- QuicDataReader* reader, MasqueCompressionContext* context) {
- QuicDatagramStreamId new_flow_id;
- if (!reader->ReadVarInt62(&new_flow_id)) {
- QUIC_DLOG(ERROR) << "Could not read new_flow_id";
- return false;
- }
- QuicConnectionId new_client_connection_id;
- if (!reader->ReadLengthPrefixedConnectionId(&new_client_connection_id)) {
- QUIC_DLOG(ERROR) << "Could not read new_client_connection_id";
- return false;
- }
- QuicConnectionId new_server_connection_id;
- if (!reader->ReadLengthPrefixedConnectionId(&new_server_connection_id)) {
- QUIC_DLOG(ERROR) << "Could not read new_server_connection_id";
- return false;
- }
- uint16_t port;
- if (!reader->ReadUInt16(&port)) {
- QUIC_DLOG(ERROR) << "Could not read port";
- return false;
- }
- uint8_t address_id;
- if (!reader->ReadUInt8(&address_id)) {
- QUIC_DLOG(ERROR) << "Could not read address_id";
- return false;
- }
- size_t ip_bytes_length;
- if (address_id == MasqueAddressFamilyIPv6) {
- ip_bytes_length = QuicIpAddress::kIPv6AddressSize;
- } else if (address_id == MasqueAddressFamilyIPv4) {
- ip_bytes_length = QuicIpAddress::kIPv4AddressSize;
- } else {
- QUIC_DLOG(ERROR) << "Unknown address_id " << static_cast<int>(address_id);
- return false;
- }
- char ip_bytes[QuicIpAddress::kMaxAddressSize];
- if (!reader->ReadBytes(ip_bytes, ip_bytes_length)) {
- QUIC_DLOG(ERROR) << "Could not read IP address";
- return false;
- }
- QuicIpAddress ip_address;
- ip_address.FromPackedString(ip_bytes, ip_bytes_length);
- if (!ip_address.IsInitialized()) {
- QUIC_BUG(quic_bug_10981_17) << "Failed to parse IP address";
- return false;
- }
- QuicSocketAddress new_server_address = QuicSocketAddress(ip_address, port);
- auto context_pair = contexts_.find(new_flow_id);
- if (context_pair == contexts_.end()) {
- context->client_connection_id = new_client_connection_id;
- context->server_connection_id = new_server_connection_id;
- context->server_address = new_server_address;
- context->validated = true;
- contexts_[new_flow_id] = *context;
- QUIC_DVLOG(1) << "Registered new flow_id " << new_flow_id << " to "
- << new_server_address << " client "
- << new_client_connection_id << " server "
- << new_server_connection_id;
- } else {
- *context = context_pair->second;
- if (context->client_connection_id != new_client_connection_id) {
- QUIC_LOG(ERROR)
- << "Received incorrect context registration for existing flow_id "
- << new_flow_id << " mismatched client "
- << context->client_connection_id << " " << new_client_connection_id;
- return false;
- }
- if (context->server_connection_id != new_server_connection_id) {
- QUIC_LOG(ERROR)
- << "Received incorrect context registration for existing flow_id "
- << new_flow_id << " mismatched server "
- << context->server_connection_id << " " << new_server_connection_id;
- return false;
- }
- if (context->server_address != new_server_address) {
- QUIC_LOG(ERROR)
- << "Received incorrect context registration for existing flow_id "
- << new_flow_id << " mismatched server " << context->server_address
- << " " << new_server_address;
- return false;
- }
- if (!context->validated) {
- context->validated = true;
- contexts_[new_flow_id] = *context;
- QUIC_DLOG(INFO) << "Successfully validated remotely-unvalidated flow_id "
- << new_flow_id << " to " << new_server_address
- << " client " << new_client_connection_id << " server "
- << new_server_connection_id;
- } else {
- QUIC_DVLOG(1) << "Decompressing using incoming locally-validated "
- "remotely-unvalidated flow_id "
- << new_flow_id << " to " << new_server_address << " client "
- << new_client_connection_id << " server "
- << new_server_connection_id;
- }
- }
- return true;
-}
-
-bool MasqueCompressionEngine::WriteDecompressedPacket(
- QuicDataReader* reader, const MasqueCompressionContext& context,
- std::vector<char>* packet, bool* version_present) {
- QuicConnectionId destination_connection_id, source_connection_id;
- if (masque_session_->perspective() == Perspective::IS_SERVER) {
- destination_connection_id = context.server_connection_id;
- source_connection_id = context.client_connection_id;
- } else {
- destination_connection_id = context.client_connection_id;
- source_connection_id = context.server_connection_id;
- }
-
- size_t packet_length =
- reader->BytesRemaining() + destination_connection_id.length();
- uint8_t first_byte;
- if (!reader->ReadUInt8(&first_byte)) {
- QUIC_DLOG(ERROR) << "Failed to read first_byte";
- return false;
- }
- *version_present = (first_byte & FLAGS_LONG_HEADER) != 0;
- if (*version_present) {
- packet_length += sizeof(uint8_t) * 2 + source_connection_id.length();
- }
- *packet = std::vector<char>(packet_length);
- QuicDataWriter writer(packet->size(), packet->data());
- if (!writer.WriteUInt8(first_byte)) {
- QUIC_BUG(quic_bug_10981_18) << "Failed to write first_byte";
- return false;
- }
- if (*version_present) {
- QuicVersionLabel version_label;
- if (!reader->ReadUInt32(&version_label)) {
- QUIC_DLOG(ERROR) << "Failed to read version";
- return false;
- }
- if (!writer.WriteUInt32(version_label)) {
- QUIC_BUG(quic_bug_10981_19) << "Failed to write version";
- return false;
- }
- if (!writer.WriteLengthPrefixedConnectionId(destination_connection_id)) {
- QUIC_BUG(quic_bug_10981_20)
- << "Failed to write long header destination_connection_id";
- return false;
- }
- if (!writer.WriteLengthPrefixedConnectionId(source_connection_id)) {
- QUIC_BUG(quic_bug_10981_21)
- << "Failed to write long header source_connection_id";
- return false;
- }
- } else {
- if (!writer.WriteConnectionId(destination_connection_id)) {
- QUIC_BUG(quic_bug_10981_22)
- << "Failed to write short header destination_connection_id";
- return false;
- }
- }
- absl::string_view payload = reader->ReadRemainingPayload();
- if (!writer.WriteStringPiece(payload)) {
- QUIC_BUG(quic_bug_10981_23) << "Failed to write payload";
- return false;
- }
- return true;
-}
-
-bool MasqueCompressionEngine::DecompressDatagram(
- absl::string_view datagram, QuicConnectionId* client_connection_id,
- QuicConnectionId* server_connection_id, QuicSocketAddress* server_address,
- std::vector<char>* packet, bool* version_present) {
- QUIC_DVLOG(1) << "Decompressing DATAGRAM frame of length "
- << datagram.length();
- QuicDataReader reader(datagram);
- QuicDatagramStreamId flow_id;
- if (!reader.ReadVarInt62(&flow_id)) {
- QUIC_DLOG(ERROR) << "Could not read flow_id";
- return false;
- }
- MasqueCompressionContext context;
- if (flow_id == kFlowId0) {
- if (!ParseCompressionContext(&reader, &context)) {
- return false;
- }
- } else {
- auto context_pair = contexts_.find(flow_id);
- if (context_pair == contexts_.end()) {
- QUIC_DLOG(ERROR) << "Received unknown flow_id " << flow_id;
- return false;
- }
- context = context_pair->second;
-
- if (!context.validated) {
- context.validated = true;
- contexts_[flow_id] = context;
- QUIC_DLOG(INFO) << "Successfully validated remotely-validated flow_id "
- << flow_id << " to " << context.server_address
- << " client " << context.client_connection_id
- << " server " << context.server_connection_id;
- } else {
- QUIC_DVLOG(1) << "Decompressing using incoming locally-validated "
- "remotely-validated flow_id "
- << flow_id << " to " << context.server_address << " client "
- << context.client_connection_id << " server "
- << context.server_connection_id;
- }
- }
-
- if (!WriteDecompressedPacket(&reader, context, packet, version_present)) {
- return false;
- }
-
- *server_address = context.server_address;
- *client_connection_id = context.client_connection_id;
- *server_connection_id = context.server_connection_id;
-
- QUIC_DVLOG(2) << "Decompressed client " << context.client_connection_id
- << " server " << context.server_connection_id << "\n"
- << quiche::QuicheTextUtils::HexDump(
- absl::string_view(packet->data(), packet->size()));
-
- return true;
-}
-
-void MasqueCompressionEngine::UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) {
- std::vector<QuicDatagramStreamId> flow_ids_to_remove;
- for (const auto& kv : contexts_) {
- const MasqueCompressionContext& context = kv.second;
- if (context.client_connection_id == client_connection_id) {
- flow_ids_to_remove.push_back(kv.first);
- }
- }
- for (QuicDatagramStreamId flow_id : flow_ids_to_remove) {
- contexts_.erase(flow_id);
- }
-}
-
-} // namespace quic
diff --git a/quiche/quic/masque/masque_compression_engine.h b/quiche/quic/masque/masque_compression_engine.h
deleted file mode 100644
index 8c09de2..0000000
--- a/quiche/quic/masque/masque_compression_engine.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_COMPRESSION_ENGINE_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_COMPRESSION_ENGINE_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quiche/quic/core/http/quic_spdy_session.h"
-#include "quiche/quic/core/quic_connection_id.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/platform/api/quic_containers.h"
-#include "quiche/quic/platform/api/quic_export.h"
-#include "quiche/quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// MASQUE compression engine used by client and servers.
-// This class allows converting QUIC packets into a compressed form suitable
-// for sending over QUIC DATAGRAM frames. It leverages a flow identifier at the
-// start of each datagram to indicate which compression context was used to
-// compress this packet, or to create new compression contexts.
-// Compression contexts contain client and server connection IDs and the
-// server's IP and port. This allows compressing that information in most
-// packets without requiring access to the cryptographic keys of the end-to-end
-// encapsulated session. When the flow identifier is 0, the DATAGRAM contains
-// all the contents of the compression context. When the flow identifier is
-// non-zero, those fields are removed so the encapsulated QUIC packet is
-// transmitted without connection IDs and reassembled by the peer on
-// decompression. This only needs to contain the HTTP server's IP address since
-// the client's IP address is not visible to the HTTP server.
-
-class QUIC_NO_EXPORT MasqueCompressionEngine {
- public:
- // Caller must ensure that |masque_session| has a lifetime longer than the
- // newly constructed MasqueCompressionEngine.
- explicit MasqueCompressionEngine(QuicSpdySession* masque_session);
-
- // Disallow copy and assign.
- MasqueCompressionEngine(const MasqueCompressionEngine&) = delete;
- MasqueCompressionEngine& operator=(const MasqueCompressionEngine&) = delete;
-
- // Compresses packet and sends it in a DATAGRAM frame over a MASQUE session.
- // When used from MASQUE client to MASQUE server, the MASQUE server will then
- // send the packet to the provided |server_address|.
- // When used from MASQUE server to MASQUE client, the MASQUE client will then
- // hand off the uncompressed packet to an encapsulated session that will treat
- // it as having come from the provided |server_address|.
- // The connection IDs are the one used by the encapsulated |packet|.
- void CompressAndSendPacket(absl::string_view packet,
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address);
-
- // Decompresses received DATAGRAM frame contents from |datagram| and places
- // them in |packet|. Reverses the transformation from CompressAndSendPacket.
- // The connection IDs are the one used by the encapsulated |packet|.
- // |server_address| will be filled with the |server_address| passed to
- // CompressAndSendPacket. |version_present| will contain whether the
- // encapsulated |packet| contains a Version field.
- bool DecompressDatagram(absl::string_view datagram,
- QuicConnectionId* client_connection_id,
- QuicConnectionId* server_connection_id,
- QuicSocketAddress* server_address,
- std::vector<char>* packet, bool* version_present);
-
- // Clears all entries referencing |client_connection_id| from the
- // compression table.
- void UnregisterClientConnectionId(QuicConnectionId client_connection_id);
-
- private:
- struct QUIC_NO_EXPORT MasqueCompressionContext {
- QuicConnectionId client_connection_id;
- QuicConnectionId server_connection_id;
- QuicSocketAddress server_address;
- bool validated = false;
- };
-
- // Finds or creates a new compression context to use during compression.
- // |client_connection_id_present| and |server_connection_id_present| indicate
- // whether the corresponding connection ID is present in the current packet.
- // |validated| will contain whether the compression context that matches
- // these arguments is currently validated or not.
- QuicDatagramStreamId FindOrCreateCompressionContext(
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address,
- bool client_connection_id_present, bool server_connection_id_present,
- bool* validated);
-
- // Writes compressed packet to |slice| during compression.
- bool WriteCompressedPacketToSlice(QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address,
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- QuicDatagramStreamId flow_id,
- bool validated, uint8_t first_byte,
- bool long_header, QuicDataReader* reader,
- QuicDataWriter* writer);
-
- // Parses compression context from flow ID 0 during decompression.
- bool ParseCompressionContext(QuicDataReader* reader,
- MasqueCompressionContext* context);
-
- // Writes decompressed packet to |packet| during decompression.
- bool WriteDecompressedPacket(QuicDataReader* reader,
- const MasqueCompressionContext& context,
- std::vector<char>* packet,
- bool* version_present);
-
- QuicSpdySession* masque_session_; // Unowned.
- absl::flat_hash_map<QuicDatagramStreamId, MasqueCompressionContext> contexts_;
- QuicDatagramStreamId next_available_flow_id_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_COMPRESSION_ENGINE_H_
diff --git a/quiche/quic/masque/masque_dispatcher.cc b/quiche/quic/masque/masque_dispatcher.cc
index 6db6f8c..d0440a6 100644
--- a/quiche/quic/masque/masque_dispatcher.cc
+++ b/quiche/quic/masque/masque_dispatcher.cc
@@ -38,50 +38,11 @@
ParsedQuicVersionVector{version});
auto session = std::make_unique<MasqueServerSession>(
- masque_mode_, config(), GetSupportedVersions(), connection, this, this,
+ masque_mode_, config(), GetSupportedVersions(), connection, this,
epoll_server_, session_helper(), crypto_config(),
compressed_certs_cache(), masque_server_backend_);
session->Initialize();
return session;
}
-bool MasqueDispatcher::OnFailedToDispatchPacket(
- const ReceivedPacketInfo& packet_info) {
- auto connection_id_registration = client_connection_id_registrations_.find(
- packet_info.destination_connection_id);
- if (connection_id_registration == client_connection_id_registrations_.end()) {
- QUIC_DLOG(INFO) << "MasqueDispatcher failed to dispatch " << packet_info;
- return false;
- }
- MasqueServerSession* masque_server_session =
- connection_id_registration->second;
- masque_server_session->HandlePacketFromServer(packet_info);
- return true;
-}
-
-void MasqueDispatcher::RegisterClientConnectionId(
- QuicConnectionId client_connection_id,
- MasqueServerSession* masque_server_session) {
- QUIC_DLOG(INFO) << "Registering encapsulated " << client_connection_id
- << " to MASQUE session "
- << masque_server_session->connection_id();
-
- // Make sure we don't try to overwrite an existing registration with a
- // different session.
- QUIC_BUG_IF(quic_bug_12013_1,
- client_connection_id_registrations_.find(client_connection_id) !=
- client_connection_id_registrations_.end() &&
- client_connection_id_registrations_[client_connection_id] !=
- masque_server_session)
- << "Overwriting existing registration for " << client_connection_id;
- client_connection_id_registrations_[client_connection_id] =
- masque_server_session;
-}
-
-void MasqueDispatcher::UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) {
- QUIC_DLOG(INFO) << "Unregistering " << client_connection_id;
- client_connection_id_registrations_.erase(client_connection_id);
-}
-
} // namespace quic
diff --git a/quiche/quic/masque/masque_dispatcher.h b/quiche/quic/masque/masque_dispatcher.h
index 90d319c..b5ef5bb 100644
--- a/quiche/quic/masque/masque_dispatcher.h
+++ b/quiche/quic/masque/masque_dispatcher.h
@@ -17,8 +17,7 @@
// QUIC dispatcher that handles new MASQUE connections and can proxy traffic
// between MASQUE clients and QUIC servers.
-class QUIC_NO_EXPORT MasqueDispatcher : public QuicSimpleDispatcher,
- public MasqueServerSession::Visitor {
+class QUIC_NO_EXPORT MasqueDispatcher : public QuicSimpleDispatcher {
public:
explicit MasqueDispatcher(
MasqueMode masque_mode, const QuicConfig* config,
@@ -41,25 +40,10 @@
const ParsedQuicVersion& version,
const quic::ParsedClientHello& parsed_chlo) override;
- bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info) override;
-
- // From MasqueServerSession::Visitor.
- void RegisterClientConnectionId(
- QuicConnectionId client_connection_id,
- MasqueServerSession* masque_server_session) override;
-
- void UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) override;
-
private:
MasqueMode masque_mode_;
QuicEpollServer* epoll_server_; // Unowned.
MasqueServerBackend* masque_server_backend_; // Unowned.
- // Mapping from client connection IDs to server sessions, allows routing
- // incoming packets to the right MASQUE connection.
- absl::flat_hash_map<QuicConnectionId, MasqueServerSession*,
- QuicConnectionIdHash>
- client_connection_id_registrations_;
};
} // namespace quic
diff --git a/quiche/quic/masque/masque_encapsulated_client_session.cc b/quiche/quic/masque/masque_encapsulated_client_session.cc
index 988b511..077430f 100644
--- a/quiche/quic/masque/masque_encapsulated_client_session.cc
+++ b/quiche/quic/masque/masque_encapsulated_client_session.cc
@@ -33,8 +33,7 @@
void MasqueEncapsulatedClientSession::OnConnectionClosed(
const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
QuicSpdyClientSession::OnConnectionClosed(frame, source);
- masque_client_session_->UnregisterConnectionId(
- connection()->client_connection_id(), this);
+ masque_client_session_->CloseConnectUdpStream(this);
}
} // namespace quic
diff --git a/quiche/quic/masque/masque_encapsulated_epoll_client.cc b/quiche/quic/masque/masque_encapsulated_epoll_client.cc
index 41dde4e..242d265 100644
--- a/quiche/quic/masque/masque_encapsulated_epoll_client.cc
+++ b/quiche/quic/masque/masque_encapsulated_epoll_client.cc
@@ -29,9 +29,7 @@
<< " bytes to " << peer_address;
absl::string_view packet(buffer, buf_len);
client_->masque_client()->masque_client_session()->SendPacket(
- client_->session()->connection()->client_connection_id(),
- client_->session()->connection()->connection_id(), packet, peer_address,
- client_->masque_encapsulated_client_session());
+ packet, peer_address, client_->masque_encapsulated_client_session());
return WriteResult(WRITE_STATUS_OK, buf_len);
}
@@ -93,8 +91,8 @@
masque_client_(masque_client) {}
MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
- masque_client_->masque_client_session()->UnregisterConnectionId(
- client_connection_id_, masque_encapsulated_client_session());
+ masque_client_->masque_client_session()->CloseConnectUdpStream(
+ masque_encapsulated_client_session());
}
std::unique_ptr<QuicSession>
@@ -113,13 +111,4 @@
return static_cast<MasqueEncapsulatedClientSession*>(QuicClient::session());
}
-QuicConnectionId MasqueEncapsulatedEpollClient::GetClientConnectionId() {
- if (client_connection_id_.IsEmpty()) {
- client_connection_id_ = QuicUtils::CreateRandomConnectionId();
- masque_client_->masque_client_session()->RegisterConnectionId(
- client_connection_id_, masque_encapsulated_client_session());
- }
- return client_connection_id_;
-}
-
} // namespace quic
diff --git a/quiche/quic/masque/masque_encapsulated_epoll_client.h b/quiche/quic/masque/masque_encapsulated_epoll_client.h
index cbe1bcd..2b98652 100644
--- a/quiche/quic/masque/masque_encapsulated_epoll_client.h
+++ b/quiche/quic/masque/masque_encapsulated_epoll_client.h
@@ -32,8 +32,6 @@
const ParsedQuicVersionVector& supported_versions,
QuicConnection* connection) override;
- QuicConnectionId GetClientConnectionId() override;
-
// MASQUE client that this client is encapsulated in.
MasqueEpollClient* masque_client() { return masque_client_; }
@@ -42,7 +40,6 @@
private:
MasqueEpollClient* masque_client_; // Unowned.
- QuicConnectionId client_connection_id_;
};
} // namespace quic
diff --git a/quiche/quic/masque/masque_epoll_client.cc b/quiche/quic/masque/masque_epoll_client.cc
index 6d6470b..705ea15 100644
--- a/quiche/quic/masque/masque_epoll_client.cc
+++ b/quiche/quic/masque/masque_epoll_client.cc
@@ -91,36 +91,6 @@
return nullptr;
}
- if (masque_client->masque_mode() == MasqueMode::kLegacy) {
- // Construct the legacy mode init request.
- spdy::Http2HeaderBlock header_block;
- header_block[":method"] = "POST";
- header_block[":scheme"] = "https";
- header_block[":authority"] = masque_client->authority();
- header_block[":path"] = "/.well-known/masque/init";
- std::string body = "foo";
-
- // Make sure to store the response, for later output.
- masque_client->set_store_response(true);
-
- // Send the MASQUE init command.
- masque_client->SendRequestAndWaitForResponse(header_block, body,
- /*fin=*/true);
-
- if (!masque_client->connected()) {
- QUIC_LOG(ERROR)
- << "MASQUE init request caused connection failure. Error: "
- << QuicErrorCodeToString(masque_client->session()->error());
- return nullptr;
- }
-
- const int response_code = masque_client->latest_response_code();
- if (response_code != 200) {
- QUIC_LOG(ERROR) << "MASQUE init request failed with HTTP response code "
- << response_code;
- return nullptr;
- }
- }
return masque_client;
}
@@ -133,22 +103,4 @@
return connected() && settings_received_;
}
-void MasqueEpollClient::UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) {
- std::string body(client_connection_id.data(), client_connection_id.length());
-
- // Construct a GET or POST request for supplied URL.
- spdy::Http2HeaderBlock header_block;
- header_block[":method"] = "POST";
- header_block[":scheme"] = "https";
- header_block[":authority"] = authority();
- header_block[":path"] = "/.well-known/masque/unregister";
-
- // Make sure to store the response, for later output.
- set_store_response(true);
-
- // Send the MASQUE unregister command.
- SendRequest(header_block, body, /*fin=*/true);
-}
-
} // namespace quic
diff --git a/quiche/quic/masque/masque_epoll_client.h b/quiche/quic/masque/masque_epoll_client.h
index 7b36bf6..7eff270 100644
--- a/quiche/quic/masque/masque_epoll_client.h
+++ b/quiche/quic/masque/masque_epoll_client.h
@@ -38,9 +38,6 @@
// From MasqueClientSession::Owner.
void OnSettingsReceived() override;
- // Send a MASQUE client connection ID unregister command to the server.
- void UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) override;
MasqueMode masque_mode() const { return masque_mode_; }
diff --git a/quiche/quic/masque/masque_server_backend.cc b/quiche/quic/masque/masque_server_backend.cc
index 8dfe8b8..8e74e16 100644
--- a/quiche/quic/masque/masque_server_backend.cc
+++ b/quiche/quic/masque/masque_server_backend.cc
@@ -20,7 +20,6 @@
bool MasqueServerBackend::MaybeHandleMasqueRequest(
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) {
auto method_pair = request_headers.find(":method");
if (method_pair == request_headers.end()) {
@@ -29,34 +28,11 @@
}
absl::string_view method = method_pair->second;
std::string masque_path = "";
- if (masque_mode_ == MasqueMode::kLegacy) {
- auto path_pair = request_headers.find(":path");
- auto scheme_pair = request_headers.find(":scheme");
- if (path_pair == request_headers.end() ||
- scheme_pair == request_headers.end()) {
- // This request is missing required headers.
- return false;
- }
- absl::string_view path = path_pair->second;
- absl::string_view scheme = scheme_pair->second;
- if (scheme != "https" || method != "POST" || request_body.empty()) {
- // MASQUE requests MUST be a non-empty https POST.
- return false;
- }
-
- if (path.rfind("/.well-known/masque/", 0) != 0) {
- // This request is not a MASQUE path.
- return false;
- }
- masque_path = std::string(path.substr(sizeof("/.well-known/masque/") - 1));
- } else {
- QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
- auto protocol_pair = request_headers.find(":protocol");
- if (method != "CONNECT" || protocol_pair == request_headers.end() ||
- protocol_pair->second != "connect-udp") {
- // This is not a MASQUE request.
- return false;
- }
+ auto protocol_pair = request_headers.find(":protocol");
+ if (method != "CONNECT" || protocol_pair == request_headers.end() ||
+ protocol_pair->second != "connect-udp") {
+ // This is not a MASQUE request.
+ return false;
}
if (!server_authority_.empty()) {
@@ -82,8 +58,7 @@
BackendClient* backend_client = it->second.backend_client;
std::unique_ptr<QuicBackendResponse> response =
- backend_client->HandleMasqueRequest(masque_path, request_headers,
- request_body, request_handler);
+ backend_client->HandleMasqueRequest(request_headers, request_handler);
if (response == nullptr) {
QUIC_LOG(ERROR) << "Backend client did not process request for "
<< masque_path << request_headers.DebugString();
@@ -103,8 +78,7 @@
const spdy::Http2HeaderBlock& request_headers,
const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) {
- if (MaybeHandleMasqueRequest(request_headers, request_body,
- request_handler)) {
+ if (MaybeHandleMasqueRequest(request_headers, request_handler)) {
// Request was handled as a MASQUE request.
return;
}
diff --git a/quiche/quic/masque/masque_server_backend.h b/quiche/quic/masque/masque_server_backend.h
index 7480a86..8f35c3b 100644
--- a/quiche/quic/masque/masque_server_backend.h
+++ b/quiche/quic/masque/masque_server_backend.h
@@ -21,9 +21,7 @@
class QUIC_NO_EXPORT BackendClient {
public:
virtual std::unique_ptr<QuicBackendResponse> HandleMasqueRequest(
- const std::string& masque_path,
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) = 0;
virtual ~BackendClient() = default;
};
@@ -56,7 +54,6 @@
// Handle MASQUE request.
bool MaybeHandleMasqueRequest(
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler);
MasqueMode masque_mode_;
diff --git a/quiche/quic/masque/masque_server_bin.cc b/quiche/quic/masque/masque_server_bin.cc
index ac1c189..bae882f 100644
--- a/quiche/quic/masque/masque_server_bin.cc
+++ b/quiche/quic/masque/masque_server_bin.cc
@@ -31,9 +31,9 @@
"Specifies the authority over which the server will accept MASQUE "
"requests. Defaults to empty which allows all authorities.");
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
- "Allows setting MASQUE mode, valid values are "
- "open and legacy. Defaults to open.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, masque_mode, "",
+ "Allows setting MASQUE mode, currently only valid value is \"open\".");
int main(int argc, char* argv[]) {
quiche::QuicheSystemEventLoop event_loop("masque_server");
@@ -47,9 +47,7 @@
quic::MasqueMode masque_mode = quic::MasqueMode::kOpen;
std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
- if (mode_string == "legacy") {
- masque_mode = quic::MasqueMode::kLegacy;
- } else if (!mode_string.empty() && mode_string != "open") {
+ if (!mode_string.empty() && mode_string != "open") {
std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
return 1;
}
diff --git a/quiche/quic/masque/masque_server_session.cc b/quiche/quic/masque/masque_server_session.cc
index 268421f..3a81caa 100644
--- a/quiche/quic/masque/masque_server_session.cc
+++ b/quiche/quic/masque/masque_server_session.cc
@@ -78,7 +78,7 @@
MasqueServerSession::MasqueServerSession(
MasqueMode masque_mode, const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
+ QuicConnection* connection, QuicSession::Visitor* visitor,
QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
const QuicCryptoServerConfig* crypto_config,
QuicCompressedCertsCache* compressed_certs_cache,
@@ -87,9 +87,7 @@
helper, crypto_config, compressed_certs_cache,
masque_server_backend),
masque_server_backend_(masque_server_backend),
- owner_(owner),
epoll_server_(epoll_server),
- compression_engine_(this),
masque_mode_(masque_mode) {
// Artificially increase the max packet length to 1350 to ensure we can fit
// QUIC packets inside DATAGRAM frames.
@@ -100,44 +98,6 @@
QUICHE_DCHECK_NE(epoll_server_, nullptr);
}
-void MasqueServerSession::OnMessageReceived(absl::string_view message) {
- if (masque_mode_ == MasqueMode::kLegacy) {
- QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length();
- QuicConnectionId client_connection_id, server_connection_id;
- QuicSocketAddress target_server_address;
- std::vector<char> packet;
- bool version_present;
- if (!compression_engine_.DecompressDatagram(
- message, &client_connection_id, &server_connection_id,
- &target_server_address, &packet, &version_present)) {
- return;
- }
-
- QUIC_DVLOG(1) << "Received packet of length " << packet.size() << " for "
- << target_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(),
- target_server_address, nullptr);
- QUIC_DVLOG(1) << "Got " << write_result << " for " << packet.size()
- << " bytes to " << target_server_address;
- return;
- }
- QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
- QuicSpdySession::OnMessageReceived(message);
-}
-
void MasqueServerSession::OnMessageAcked(QuicMessageId message_id,
QuicTime /*receive_timestamp*/) {
QUIC_DVLOG(1) << "Received ack for DATAGRAM frame " << message_id;
@@ -166,206 +126,155 @@
}
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) {
- if (masque_mode_ != MasqueMode::kLegacy) {
- auto path_pair = request_headers.find(":path");
- auto scheme_pair = request_headers.find(":scheme");
- auto method_pair = request_headers.find(":method");
- auto protocol_pair = request_headers.find(":protocol");
- auto authority_pair = request_headers.find(":authority");
- if (path_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :path";
- return CreateBackendErrorResponse("400", "Missing :path");
- }
- if (scheme_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :scheme";
- return CreateBackendErrorResponse("400", "Missing :scheme");
- }
- if (method_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :method";
- return CreateBackendErrorResponse("400", "Missing :method");
- }
- if (protocol_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :protocol";
- return CreateBackendErrorResponse("400", "Missing :protocol");
- }
- if (authority_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :authority";
- return CreateBackendErrorResponse("400", "Missing :authority");
- }
- absl::string_view path = path_pair->second;
- absl::string_view scheme = scheme_pair->second;
- absl::string_view method = method_pair->second;
- absl::string_view protocol = protocol_pair->second;
- absl::string_view authority = authority_pair->second;
- if (path.empty()) {
- QUIC_DLOG(ERROR) << "MASQUE request with empty path";
- return CreateBackendErrorResponse("400", "Empty path");
- }
- if (scheme.empty()) {
- return CreateBackendErrorResponse("400", "Empty scheme");
- }
- if (method != "CONNECT") {
- QUIC_DLOG(ERROR) << "MASQUE request with bad method \"" << method << "\"";
- return CreateBackendErrorResponse("400", "Bad method");
- }
- if (protocol != "connect-udp") {
- QUIC_DLOG(ERROR) << "MASQUE request with bad protocol \"" << protocol
- << "\"";
- return CreateBackendErrorResponse("400", "Bad protocol");
- }
- absl::optional<QuicDatagramStreamId> flow_id;
- if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
- flow_id = SpdyUtils::ParseDatagramFlowIdHeader(request_headers);
- if (!flow_id.has_value()) {
- QUIC_DLOG(ERROR)
- << "MASQUE request with bad or missing DatagramFlowId header";
- return CreateBackendErrorResponse(
- "400", "Bad or missing DatagramFlowId header");
- }
- }
- // Extract target host and port from path using default template.
- std::vector<absl::string_view> path_split = absl::StrSplit(path, '/');
- if (path_split.size() != 4 || !path_split[0].empty() ||
- path_split[1].empty() || path_split[2].empty() ||
- !path_split[3].empty()) {
- QUIC_DLOG(ERROR) << "MASQUE request with bad path \"" << path << "\"";
- return CreateBackendErrorResponse("400", "Bad path");
- }
- absl::optional<std::string> host = quiche::AsciiUrlDecode(path_split[1]);
- if (!host.has_value()) {
- QUIC_DLOG(ERROR) << "Failed to decode host \"" << path_split[1] << "\"";
- return CreateBackendErrorResponse("500", "Failed to decode host");
- }
- absl::optional<std::string> port = quiche::AsciiUrlDecode(path_split[2]);
- if (!port.has_value()) {
- QUIC_DLOG(ERROR) << "Failed to decode port \"" << path_split[2] << "\"";
- return CreateBackendErrorResponse("500", "Failed to decode port");
- }
-
- // Perform DNS resolution.
- addrinfo hint = {};
- hint.ai_protocol = IPPROTO_UDP;
-
- addrinfo* info_list = nullptr;
- int result = getaddrinfo(host.value().c_str(), port.value().c_str(), &hint,
- &info_list);
- if (result != 0) {
- QUIC_DLOG(ERROR) << "Failed to resolve " << authority << ": "
- << gai_strerror(result);
- return CreateBackendErrorResponse("500", "DNS resolution failed");
- }
-
- QUICHE_CHECK_NE(info_list, nullptr);
- std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(
- info_list, freeaddrinfo);
- QuicSocketAddress target_server_address(info_list->ai_addr,
- info_list->ai_addrlen);
- QUIC_DLOG(INFO) << "Got CONNECT_UDP request on stream ID "
- << request_handler->stream_id() << " flow_id="
- << (flow_id.has_value() ? absl::StrCat(*flow_id) : "none")
- << " target_server_address=\"" << target_server_address
- << "\"";
-
- FdWrapper fd_wrapper(target_server_address.host().AddressFamilyToInt());
- if (fd_wrapper.fd() == kQuicInvalidSocketFd) {
- QUIC_DLOG(ERROR) << "Socket creation failed";
- return CreateBackendErrorResponse("500", "Socket creation failed");
- }
- QuicSocketAddress empty_address(QuicIpAddress::Any6(), 0);
- if (target_server_address.host().IsIPv4()) {
- empty_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
- }
- QuicUdpSocketApi socket_api;
- if (!socket_api.Bind(fd_wrapper.fd(), empty_address)) {
- QUIC_DLOG(ERROR) << "Socket bind failed";
- return CreateBackendErrorResponse("500", "Socket bind failed");
- }
- epoll_server_->RegisterFDForRead(fd_wrapper.fd(), this);
-
- QuicSpdyStream* stream = static_cast<QuicSpdyStream*>(
- GetActiveStream(request_handler->stream_id()));
- if (stream == nullptr) {
- QUIC_BUG(bad masque server stream type)
- << "Unexpected stream type for stream ID "
- << request_handler->stream_id();
- return CreateBackendErrorResponse("500", "Bad stream type");
- }
- if (flow_id.has_value()) {
- stream->RegisterHttp3DatagramFlowId(*flow_id);
- }
- connect_udp_server_states_.push_back(ConnectUdpServerState(
- stream, target_server_address, fd_wrapper.extract_fd(), this));
-
- if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
- // TODO(b/181256914) remove this when we drop support for
- // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
- stream->RegisterHttp3DatagramVisitor(&connect_udp_server_states_.back());
- }
-
- spdy::Http2HeaderBlock response_headers;
- response_headers[":status"] = "200";
- if (flow_id.has_value()) {
- SpdyUtils::AddDatagramFlowIdHeader(&response_headers, *flow_id);
- }
- auto response = std::make_unique<QuicBackendResponse>();
- response->set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
- response->set_headers(std::move(response_headers));
- response->set_body("");
-
- return response;
+ auto path_pair = request_headers.find(":path");
+ auto scheme_pair = request_headers.find(":scheme");
+ auto method_pair = request_headers.find(":method");
+ auto protocol_pair = request_headers.find(":protocol");
+ auto authority_pair = request_headers.find(":authority");
+ if (path_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :path";
+ return CreateBackendErrorResponse("400", "Missing :path");
}
-
- 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;
+ if (scheme_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :scheme";
+ return CreateBackendErrorResponse("400", "Missing :scheme");
+ }
+ if (method_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :method";
+ return CreateBackendErrorResponse("400", "Missing :method");
+ }
+ if (protocol_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :protocol";
+ return CreateBackendErrorResponse("400", "Missing :protocol");
+ }
+ if (authority_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :authority";
+ return CreateBackendErrorResponse("400", "Missing :authority");
+ }
+ absl::string_view path = path_pair->second;
+ absl::string_view scheme = scheme_pair->second;
+ absl::string_view method = method_pair->second;
+ absl::string_view protocol = protocol_pair->second;
+ absl::string_view authority = authority_pair->second;
+ if (path.empty()) {
+ QUIC_DLOG(ERROR) << "MASQUE request with empty path";
+ return CreateBackendErrorResponse("400", "Empty path");
+ }
+ if (scheme.empty()) {
+ return CreateBackendErrorResponse("400", "Empty scheme");
+ }
+ if (method != "CONNECT") {
+ QUIC_DLOG(ERROR) << "MASQUE request with bad method \"" << method << "\"";
+ return CreateBackendErrorResponse("400", "Bad method");
+ }
+ if (protocol != "connect-udp") {
+ QUIC_DLOG(ERROR) << "MASQUE request with bad protocol \"" << protocol
+ << "\"";
+ return CreateBackendErrorResponse("400", "Bad protocol");
+ }
+ absl::optional<QuicDatagramStreamId> flow_id;
+ if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
+ flow_id = SpdyUtils::ParseDatagramFlowIdHeader(request_headers);
+ if (!flow_id.has_value()) {
+ QUIC_DLOG(ERROR)
+ << "MASQUE request with bad or missing DatagramFlowId header";
+ return CreateBackendErrorResponse("400",
+ "Bad or missing DatagramFlowId header");
}
}
+ // Extract target host and port from path using default template.
+ std::vector<absl::string_view> path_split = absl::StrSplit(path, '/');
+ if (path_split.size() != 4 || !path_split[0].empty() ||
+ path_split[1].empty() || path_split[2].empty() ||
+ !path_split[3].empty()) {
+ QUIC_DLOG(ERROR) << "MASQUE request with bad path \"" << path << "\"";
+ return CreateBackendErrorResponse("400", "Bad path");
+ }
+ absl::optional<std::string> host = quiche::AsciiUrlDecode(path_split[1]);
+ if (!host.has_value()) {
+ QUIC_DLOG(ERROR) << "Failed to decode host \"" << path_split[1] << "\"";
+ return CreateBackendErrorResponse("500", "Failed to decode host");
+ }
+ absl::optional<std::string> port = quiche::AsciiUrlDecode(path_split[2]);
+ if (!port.has_value()) {
+ QUIC_DLOG(ERROR) << "Failed to decode port \"" << path_split[2] << "\"";
+ return CreateBackendErrorResponse("500", "Failed to decode port");
+ }
- // TODO(dschinazi) implement binary protocol sent in response body.
- const std::string response_body = "";
+ // Perform DNS resolution.
+ addrinfo hint = {};
+ hint.ai_protocol = IPPROTO_UDP;
+
+ addrinfo* info_list = nullptr;
+ int result = getaddrinfo(host.value().c_str(), port.value().c_str(), &hint,
+ &info_list);
+ if (result != 0 || info_list == nullptr) {
+ QUIC_DLOG(ERROR) << "Failed to resolve " << authority << ": "
+ << gai_strerror(result);
+ return CreateBackendErrorResponse("500", "DNS resolution failed");
+ }
+
+ std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(info_list,
+ freeaddrinfo);
+ QuicSocketAddress target_server_address(info_list->ai_addr,
+ info_list->ai_addrlen);
+ QUIC_DLOG(INFO) << "Got CONNECT_UDP request on stream ID "
+ << request_handler->stream_id() << " flow_id="
+ << (flow_id.has_value() ? absl::StrCat(*flow_id) : "none")
+ << " target_server_address=\"" << target_server_address
+ << "\"";
+
+ FdWrapper fd_wrapper(target_server_address.host().AddressFamilyToInt());
+ if (fd_wrapper.fd() == kQuicInvalidSocketFd) {
+ QUIC_DLOG(ERROR) << "Socket creation failed";
+ return CreateBackendErrorResponse("500", "Socket creation failed");
+ }
+ QuicSocketAddress empty_address(QuicIpAddress::Any6(), 0);
+ if (target_server_address.host().IsIPv4()) {
+ empty_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
+ }
+ QuicUdpSocketApi socket_api;
+ if (!socket_api.Bind(fd_wrapper.fd(), empty_address)) {
+ QUIC_DLOG(ERROR) << "Socket bind failed";
+ return CreateBackendErrorResponse("500", "Socket bind failed");
+ }
+ epoll_server_->RegisterFDForRead(fd_wrapper.fd(), this);
+
+ QuicSpdyStream* stream =
+ static_cast<QuicSpdyStream*>(GetActiveStream(request_handler->stream_id()));
+ if (stream == nullptr) {
+ QUIC_BUG(bad masque server stream type)
+ << "Unexpected stream type for stream ID "
+ << request_handler->stream_id();
+ return CreateBackendErrorResponse("500", "Bad stream type");
+ }
+ if (flow_id.has_value()) {
+ stream->RegisterHttp3DatagramFlowId(*flow_id);
+ }
+ connect_udp_server_states_.push_back(ConnectUdpServerState(
+ stream, target_server_address, fd_wrapper.extract_fd(), this));
+
+ if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
+ // TODO(b/181256914) remove this when we drop support for
+ // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+ stream->RegisterHttp3DatagramVisitor(&connect_udp_server_states_.back());
+ }
+
spdy::Http2HeaderBlock response_headers;
response_headers[":status"] = "200";
+ if (flow_id.has_value()) {
+ SpdyUtils::AddDatagramFlowIdHeader(&response_headers, *flow_id);
+ }
auto response = std::make_unique<QuicBackendResponse>();
- response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE);
+ response->set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
response->set_headers(std::move(response_headers));
- response->set_body(response_body);
+ response->set_body("");
return response;
}
-void MasqueServerSession::HandlePacketFromServer(
- const ReceivedPacketInfo& packet_info) {
- QUIC_DVLOG(1) << "MasqueServerSession received " << packet_info;
- if (masque_mode_ == MasqueMode::kLegacy) {
- compression_engine_.CompressAndSendPacket(
- packet_info.packet.AsStringPiece(),
- packet_info.destination_connection_id, packet_info.source_connection_id,
- packet_info.peer_address);
- return;
- }
- QUIC_LOG(ERROR) << "Ignoring packet from server in " << masque_mode_
- << " mode";
-}
-
void MasqueServerSession::OnRegistration(QuicEpollServer* /*eps*/,
QuicUdpSocketFd fd, int event_mask) {
QUIC_DVLOG(1) << "OnRegistration " << fd << " event_mask " << event_mask;
diff --git a/quiche/quic/masque/masque_server_session.h b/quiche/quic/masque/masque_server_session.h
index 09aedb9..a2ae75d 100644
--- a/quiche/quic/masque/masque_server_session.h
+++ b/quiche/quic/masque/masque_server_session.h
@@ -7,7 +7,6 @@
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_udp_socket.h"
-#include "quiche/quic/masque/masque_compression_engine.h"
#include "quiche/quic/masque/masque_server_backend.h"
#include "quiche/quic/masque/masque_utils.h"
#include "quiche/quic/platform/api/quic_epoll.h"
@@ -22,25 +21,10 @@
public MasqueServerBackend::BackendClient,
public QuicEpollCallbackInterface {
public:
- // Interface meant to be implemented by owner of this MasqueServerSession
- // instance.
- class QUIC_NO_EXPORT Visitor {
- public:
- virtual ~Visitor() {}
- // Register a client connection ID as being handled by this session.
- virtual void RegisterClientConnectionId(
- QuicConnectionId client_connection_id,
- MasqueServerSession* masque_server_session) = 0;
-
- // Unregister a client connection ID.
- virtual void UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) = 0;
- };
-
explicit MasqueServerSession(
MasqueMode masque_mode, const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
+ QuicConnection* connection, QuicSession::Visitor* visitor,
QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
const QuicCryptoServerConfig* crypto_config,
QuicCompressedCertsCache* compressed_certs_cache,
@@ -51,7 +35,6 @@
MasqueServerSession& operator=(const MasqueServerSession&) = delete;
// From QuicSession.
- void OnMessageReceived(absl::string_view message) override;
void OnMessageAcked(QuicMessageId message_id,
QuicTime receive_timestamp) override;
void OnMessageLost(QuicMessageId message_id) override;
@@ -61,9 +44,7 @@
// From MasqueServerBackend::BackendClient.
std::unique_ptr<QuicBackendResponse> HandleMasqueRequest(
- const std::string& masque_path,
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) override;
// From QuicEpollCallbackInterface.
@@ -75,9 +56,6 @@
void OnShutdown(QuicEpollServer* eps, QuicUdpSocketFd fd) override;
std::string Name() const override;
- // Handle packet for client, meant to be called by MasqueDispatcher.
- void HandlePacketFromServer(const ReceivedPacketInfo& packet_info);
-
QuicEpollServer* epoll_server() const { return epoll_server_; }
private:
@@ -124,9 +102,7 @@
}
MasqueServerBackend* masque_server_backend_; // Unowned.
- Visitor* owner_; // Unowned.
QuicEpollServer* epoll_server_; // Unowned.
- MasqueCompressionEngine compression_engine_;
MasqueMode masque_mode_;
std::list<ConnectUdpServerState> connect_udp_server_states_;
bool masque_initialized_ = false;
diff --git a/quiche/quic/masque/masque_utils.cc b/quiche/quic/masque/masque_utils.cc
index b440bd1..d09fc49 100644
--- a/quiche/quic/masque/masque_utils.cc
+++ b/quiche/quic/masque/masque_utils.cc
@@ -30,8 +30,6 @@
switch (masque_mode) {
case MasqueMode::kInvalid:
return "Invalid";
- case MasqueMode::kLegacy:
- return "Legacy";
case MasqueMode::kOpen:
return "Open";
}
diff --git a/quiche/quic/masque/masque_utils.h b/quiche/quic/masque/masque_utils.h
index 652bf35..12faae0 100644
--- a/quiche/quic/masque/masque_utils.h
+++ b/quiche/quic/masque/masque_utils.h
@@ -26,10 +26,6 @@
// Mode that MASQUE is operating in.
enum class MasqueMode : uint8_t {
kInvalid = 0, // Should never be used.
- kLegacy = 1, // Legacy mode uses the legacy MASQUE protocol as documented in
- // <https://tools.ietf.org/html/draft-schinazi-masque-protocol>. That version
- // of MASQUE uses a custom application-protocol over HTTP/3, and also allows
- // unauthenticated clients.
kOpen = 2, // Open mode uses the MASQUE HTTP CONNECT-UDP method as documented
// in <https://tools.ietf.org/html/draft-ietf-masque-connect-udp>. This mode
// allows unauthenticated clients (a more restricted mode will be added to