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