dschinazi | 1c99fcf | 2019-12-13 11:54:22 -0800 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.h" |
| 6 | #include "net/third_party/quiche/src/quic/core/quic_utils.h" |
| 7 | #include "net/third_party/quiche/src/quic/masque/masque_client_session.h" |
| 8 | #include "net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h" |
| 9 | #include "net/third_party/quiche/src/quic/masque/masque_epoll_client.h" |
| 10 | #include "net/third_party/quiche/src/quic/masque/masque_utils.h" |
| 11 | |
| 12 | namespace quic { |
| 13 | |
| 14 | namespace { |
| 15 | |
| 16 | // Custom packet writer that allows getting all of a connection's outgoing |
| 17 | // packets. |
| 18 | class MasquePacketWriter : public QuicPacketWriter { |
| 19 | public: |
| 20 | explicit MasquePacketWriter(MasqueEncapsulatedEpollClient* client) |
| 21 | : client_(client) {} |
| 22 | WriteResult WritePacket(const char* buffer, |
| 23 | size_t buf_len, |
| 24 | const QuicIpAddress& /*self_address*/, |
| 25 | const QuicSocketAddress& peer_address, |
| 26 | PerPacketOptions* /*options*/) override { |
| 27 | DCHECK(peer_address.IsInitialized()); |
| 28 | QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len |
| 29 | << " bytes to " << peer_address; |
| 30 | quiche::QuicheStringPiece packet(buffer, buf_len); |
| 31 | client_->masque_client()->masque_client_session()->SendPacket( |
| 32 | client_->session()->connection()->client_connection_id(), |
| 33 | client_->session()->connection()->connection_id(), packet, |
| 34 | peer_address); |
| 35 | return WriteResult(WRITE_STATUS_OK, buf_len); |
| 36 | } |
| 37 | |
| 38 | bool IsWriteBlocked() const override { return false; } |
| 39 | |
| 40 | void SetWritable() override {} |
| 41 | |
| 42 | QuicByteCount GetMaxPacketSize( |
| 43 | const QuicSocketAddress& /*peer_address*/) const override { |
| 44 | return kMasqueMaxEncapsulatedPacketSize; |
| 45 | } |
| 46 | |
| 47 | bool SupportsReleaseTime() const override { return false; } |
| 48 | |
| 49 | bool IsBatchMode() const override { return false; } |
| 50 | char* GetNextWriteLocation( |
| 51 | const QuicIpAddress& /*self_address*/, |
| 52 | const QuicSocketAddress& /*peer_address*/) override { |
| 53 | return nullptr; |
| 54 | } |
| 55 | |
| 56 | WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); } |
| 57 | |
| 58 | private: |
| 59 | MasqueEncapsulatedEpollClient* client_; // Unowned. |
| 60 | }; |
| 61 | |
| 62 | // Custom network helper that allows injecting a custom packet writer in order |
| 63 | // to get all of a connection's outgoing packets. |
| 64 | class MasqueClientEpollNetworkHelper : public QuicClientEpollNetworkHelper { |
| 65 | public: |
| 66 | MasqueClientEpollNetworkHelper(QuicEpollServer* epoll_server, |
| 67 | MasqueEncapsulatedEpollClient* client) |
| 68 | : QuicClientEpollNetworkHelper(epoll_server, client), client_(client) {} |
| 69 | QuicPacketWriter* CreateQuicPacketWriter() override { |
| 70 | return new MasquePacketWriter(client_); |
| 71 | } |
| 72 | |
| 73 | private: |
| 74 | MasqueEncapsulatedEpollClient* client_; // Unowned. |
| 75 | }; |
| 76 | |
| 77 | } // namespace |
| 78 | |
| 79 | MasqueEncapsulatedEpollClient::MasqueEncapsulatedEpollClient( |
| 80 | QuicSocketAddress server_address, |
| 81 | const QuicServerId& server_id, |
| 82 | QuicEpollServer* epoll_server, |
| 83 | std::unique_ptr<ProofVerifier> proof_verifier, |
| 84 | MasqueEpollClient* masque_client) |
| 85 | : QuicClient( |
| 86 | server_address, |
| 87 | server_id, |
| 88 | MasqueSupportedVersions(), |
| 89 | MasqueEncapsulatedConfig(), |
| 90 | epoll_server, |
| 91 | std::make_unique<MasqueClientEpollNetworkHelper>(epoll_server, this), |
| 92 | std::move(proof_verifier)), |
| 93 | masque_client_(masque_client) {} |
| 94 | |
| 95 | MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() { |
| 96 | masque_client_->masque_client_session()->UnregisterConnectionId( |
| 97 | client_connection_id_); |
| 98 | } |
| 99 | |
| 100 | std::unique_ptr<QuicSession> |
| 101 | MasqueEncapsulatedEpollClient::CreateQuicClientSession( |
| 102 | const ParsedQuicVersionVector& supported_versions, |
| 103 | QuicConnection* connection) { |
| 104 | QUIC_DLOG(INFO) << "Creating MASQUE encapsulated session for " |
| 105 | << connection->connection_id(); |
| 106 | return std::make_unique<MasqueEncapsulatedClientSession>( |
| 107 | *config(), supported_versions, connection, server_id(), crypto_config(), |
| 108 | push_promise_index(), masque_client_->masque_client_session()); |
| 109 | } |
| 110 | |
| 111 | MasqueEncapsulatedClientSession* |
| 112 | MasqueEncapsulatedEpollClient::masque_encapsulated_client_session() { |
| 113 | return static_cast<MasqueEncapsulatedClientSession*>(QuicClient::session()); |
| 114 | } |
| 115 | |
| 116 | QuicConnectionId MasqueEncapsulatedEpollClient::GetClientConnectionId() { |
| 117 | if (client_connection_id_.IsEmpty()) { |
| 118 | client_connection_id_ = QuicUtils::CreateRandomConnectionId(); |
| 119 | masque_client_->masque_client_session()->RegisterConnectionId( |
| 120 | client_connection_id_, masque_encapsulated_client_session()); |
| 121 | } |
| 122 | return client_connection_id_; |
| 123 | } |
| 124 | |
| 125 | } // namespace quic |