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:
MasquePacketWriter(MasqueEncapsulatedEpollClient * client)20 explicit MasquePacketWriter(MasqueEncapsulatedEpollClient* client)
21 : client_(client) {}
WritePacket(const char * buffer,size_t buf_len,const QuicIpAddress &,const QuicSocketAddress & peer_address,PerPacketOptions *)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 absl::string_view 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
IsWriteBlocked() const38 bool IsWriteBlocked() const override { return false; }
39
SetWritable()40 void SetWritable() override {}
41
GetMaxPacketSize(const QuicSocketAddress &) const42 QuicByteCount GetMaxPacketSize(
43 const QuicSocketAddress& /*peer_address*/) const override {
44 return kMasqueMaxEncapsulatedPacketSize;
45 }
46
SupportsReleaseTime() const47 bool SupportsReleaseTime() const override { return false; }
48
IsBatchMode() const49 bool IsBatchMode() const override { return false; }
GetNextWriteLocation(const QuicIpAddress &,const QuicSocketAddress &)50 QuicPacketBuffer GetNextWriteLocation(
51 const QuicIpAddress& /*self_address*/,
52 const QuicSocketAddress& /*peer_address*/) override {
53 return {nullptr, nullptr};
54 }
55
Flush()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:
MasqueClientEpollNetworkHelper(QuicEpollServer * epoll_server,MasqueEncapsulatedEpollClient * client)66 MasqueClientEpollNetworkHelper(QuicEpollServer* epoll_server,
67 MasqueEncapsulatedEpollClient* client)
68 : QuicClientEpollNetworkHelper(epoll_server, client), client_(client) {}
CreateQuicPacketWriter()69 QuicPacketWriter* CreateQuicPacketWriter() override {
70 return new MasquePacketWriter(client_);
71 }
72
73 private:
74 MasqueEncapsulatedEpollClient* client_; // Unowned.
75 };
76
77 } // namespace
78
MasqueEncapsulatedEpollClient(QuicSocketAddress server_address,const QuicServerId & server_id,QuicEpollServer * epoll_server,std::unique_ptr<ProofVerifier> proof_verifier,MasqueEpollClient * masque_client)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
~MasqueEncapsulatedEpollClient()95 MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
96 masque_client_->masque_client_session()->UnregisterConnectionId(
97 client_connection_id_);
98 }
99
100 std::unique_ptr<QuicSession>
CreateQuicClientSession(const ParsedQuicVersionVector & supported_versions,QuicConnection * connection)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*
masque_encapsulated_client_session()112 MasqueEncapsulatedEpollClient::masque_encapsulated_client_session() {
113 return static_cast<MasqueEncapsulatedClientSession*>(QuicClient::session());
114 }
115
GetClientConnectionId()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
126