blob: 242d26594d083e303426e3cfadcaca8abea8e62d [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 "quiche/quic/masque/masque_encapsulated_epoll_client.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/masque/masque_client_session.h"
#include "quiche/quic/masque/masque_encapsulated_client_session.h"
#include "quiche/quic/masque/masque_epoll_client.h"
#include "quiche/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 {
QUICHE_DCHECK(peer_address.IsInitialized());
QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len
<< " bytes to " << peer_address;
absl::string_view packet(buffer, buf_len);
client_->masque_client()->masque_client_session()->SendPacket(
packet, peer_address, client_->masque_encapsulated_client_session());
return WriteResult(WRITE_STATUS_OK, buf_len);
}
bool IsWriteBlocked() const override { return false; }
void SetWritable() override {}
absl::optional<int> MessageTooBigErrorCode() const override {
return EMSGSIZE;
}
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()->CloseConnectUdpStream(
masque_encapsulated_client_session());
}
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());
}
} // namespace quic