blob: 7c9749aa374435789eb581e2df52b647e1f36caa [file] [log] [blame]
dschinazi1c99fcf2019-12-13 11:54:22 -08001// 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
12namespace quic {
13
14namespace {
15
16// Custom packet writer that allows getting all of a connection's outgoing
17// packets.
18class 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.
64class 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
79MasqueEncapsulatedEpollClient::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
95MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
96 masque_client_->masque_client_session()->UnregisterConnectionId(
97 client_connection_id_);
98}
99
100std::unique_ptr<QuicSession>
101MasqueEncapsulatedEpollClient::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
111MasqueEncapsulatedClientSession*
112MasqueEncapsulatedEpollClient::masque_encapsulated_client_session() {
113 return static_cast<MasqueEncapsulatedClientSession*>(QuicClient::session());
114}
115
116QuicConnectionId 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