| // 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 "quic/masque/masque_encapsulated_epoll_client.h" |
| #include "quic/core/quic_utils.h" |
| #include "quic/masque/masque_client_session.h" |
| #include "quic/masque/masque_encapsulated_client_session.h" |
| #include "quic/masque/masque_epoll_client.h" |
| #include "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( |
| 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 |