blob: 1f3986284acd1529eeea3866a758638ef81de1e0 [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_encapsulated_epoll_client.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/masque/masque_client_session.h"
#include "net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h"
#include "net/third_party/quiche/src/quic/masque/masque_epoll_client.h"
#include "net/third_party/quiche/src/quic/masque/masque_utils.h"
namespace quic {
namespace {
// Custom packet writer that allows getting all of a connection's outgoing
// packets.
class MasquePacketWriter : public QuicPacketWriter {
public:
explicit MasquePacketWriter(MasqueEncapsulatedEpollClient* client)
: client_(client) {}
WriteResult WritePacket(const char* buffer,
size_t buf_len,
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& peer_address,
PerPacketOptions* /*options*/) override {
DCHECK(peer_address.IsInitialized());
QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len
<< " bytes to " << peer_address;
quiche::QuicheStringPiece 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);
return WriteResult(WRITE_STATUS_OK, buf_len);
}
bool IsWriteBlocked() const override { return false; }
void SetWritable() override {}
QuicByteCount GetMaxPacketSize(
const QuicSocketAddress& /*peer_address*/) const override {
return kMasqueMaxEncapsulatedPacketSize;
}
bool SupportsReleaseTime() const override { return false; }
bool IsBatchMode() const override { return false; }
QuicPacketBuffer GetNextWriteLocation(
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/) override {
return {nullptr, nullptr};
}
WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
private:
MasqueEncapsulatedEpollClient* client_; // Unowned.
};
// Custom network helper that allows injecting a custom packet writer in order
// to get all of a connection's outgoing packets.
class MasqueClientEpollNetworkHelper : public QuicClientEpollNetworkHelper {
public:
MasqueClientEpollNetworkHelper(QuicEpollServer* epoll_server,
MasqueEncapsulatedEpollClient* client)
: QuicClientEpollNetworkHelper(epoll_server, client), client_(client) {}
QuicPacketWriter* CreateQuicPacketWriter() override {
return new MasquePacketWriter(client_);
}
private:
MasqueEncapsulatedEpollClient* client_; // Unowned.
};
} // namespace
MasqueEncapsulatedEpollClient::MasqueEncapsulatedEpollClient(
QuicSocketAddress server_address,
const QuicServerId& server_id,
QuicEpollServer* epoll_server,
std::unique_ptr<ProofVerifier> proof_verifier,
MasqueEpollClient* masque_client)
: QuicClient(
server_address,
server_id,
MasqueSupportedVersions(),
MasqueEncapsulatedConfig(),
epoll_server,
std::make_unique<MasqueClientEpollNetworkHelper>(epoll_server, this),
std::move(proof_verifier)),
masque_client_(masque_client) {}
MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
masque_client_->masque_client_session()->UnregisterConnectionId(
client_connection_id_);
}
std::unique_ptr<QuicSession>
MasqueEncapsulatedEpollClient::CreateQuicClientSession(
const ParsedQuicVersionVector& supported_versions,
QuicConnection* connection) {
QUIC_DLOG(INFO) << "Creating MASQUE encapsulated session for "
<< connection->connection_id();
return std::make_unique<MasqueEncapsulatedClientSession>(
*config(), supported_versions, connection, server_id(), crypto_config(),
push_promise_index(), masque_client_->masque_client_session());
}
MasqueEncapsulatedClientSession*
MasqueEncapsulatedEpollClient::masque_encapsulated_client_session() {
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