xref: /aosp_15_r20/external/openscreen/osp/impl/quic/quic_client.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2018 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #ifndef OSP_IMPL_QUIC_QUIC_CLIENT_H_
6*3f982cf4SFabien Sanglard #define OSP_IMPL_QUIC_QUIC_CLIENT_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <cstdint>
9*3f982cf4SFabien Sanglard #include <map>
10*3f982cf4SFabien Sanglard #include <memory>
11*3f982cf4SFabien Sanglard #include <vector>
12*3f982cf4SFabien Sanglard 
13*3f982cf4SFabien Sanglard #include "osp/impl/quic/quic_connection_factory.h"
14*3f982cf4SFabien Sanglard #include "osp/impl/quic/quic_service_common.h"
15*3f982cf4SFabien Sanglard #include "osp/public/protocol_connection_client.h"
16*3f982cf4SFabien Sanglard #include "platform/api/task_runner.h"
17*3f982cf4SFabien Sanglard #include "platform/api/time.h"
18*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h"
19*3f982cf4SFabien Sanglard #include "util/alarm.h"
20*3f982cf4SFabien Sanglard 
21*3f982cf4SFabien Sanglard namespace openscreen {
22*3f982cf4SFabien Sanglard namespace osp {
23*3f982cf4SFabien Sanglard 
24*3f982cf4SFabien Sanglard // This class is the default implementation of ProtocolConnectionClient for the
25*3f982cf4SFabien Sanglard // library.  It manages connections to other endpoints as well as the lifetime
26*3f982cf4SFabien Sanglard // of each incoming and outgoing stream.  It works in conjunction with a
27*3f982cf4SFabien Sanglard // QuicConnectionFactory implementation and MessageDemuxer.
28*3f982cf4SFabien Sanglard // QuicConnectionFactory provides the actual ability to make a new QUIC
29*3f982cf4SFabien Sanglard // connection with another endpoint.  Incoming data is given to the QuicClient
30*3f982cf4SFabien Sanglard // by the underlying QUIC implementation (through QuicConnectionFactory) and
31*3f982cf4SFabien Sanglard // this is in turn handed to MessageDemuxer for routing CBOR messages.
32*3f982cf4SFabien Sanglard //
33*3f982cf4SFabien Sanglard // The two most significant methods of this class are Connect and
34*3f982cf4SFabien Sanglard // CreateProtocolConnection.  Both will return a new QUIC stream to a given
35*3f982cf4SFabien Sanglard // endpoint to which the caller can write but the former is allowed to be
36*3f982cf4SFabien Sanglard // asynchronous.  If there isn't currently a connection to the specified
37*3f982cf4SFabien Sanglard // endpoint, Connect will start a connection attempt and store the callback for
38*3f982cf4SFabien Sanglard // when the connection completes.  CreateProtocolConnection simply returns
39*3f982cf4SFabien Sanglard // nullptr if there's no existing connection.
40*3f982cf4SFabien Sanglard class QuicClient final : public ProtocolConnectionClient,
41*3f982cf4SFabien Sanglard                          public ServiceConnectionDelegate::ServiceDelegate {
42*3f982cf4SFabien Sanglard  public:
43*3f982cf4SFabien Sanglard   QuicClient(MessageDemuxer* demuxer,
44*3f982cf4SFabien Sanglard              std::unique_ptr<QuicConnectionFactory> connection_factory,
45*3f982cf4SFabien Sanglard              ProtocolConnectionServiceObserver* observer,
46*3f982cf4SFabien Sanglard              ClockNowFunctionPtr now_function,
47*3f982cf4SFabien Sanglard              TaskRunner* task_runner);
48*3f982cf4SFabien Sanglard   ~QuicClient() override;
49*3f982cf4SFabien Sanglard 
50*3f982cf4SFabien Sanglard   // ProtocolConnectionClient overrides.
51*3f982cf4SFabien Sanglard   bool Start() override;
52*3f982cf4SFabien Sanglard   bool Stop() override;
53*3f982cf4SFabien Sanglard   ConnectRequest Connect(const IPEndpoint& endpoint,
54*3f982cf4SFabien Sanglard                          ConnectionRequestCallback* request) override;
55*3f982cf4SFabien Sanglard   std::unique_ptr<ProtocolConnection> CreateProtocolConnection(
56*3f982cf4SFabien Sanglard       uint64_t endpoint_id) override;
57*3f982cf4SFabien Sanglard 
58*3f982cf4SFabien Sanglard   // QuicProtocolConnection::Owner overrides.
59*3f982cf4SFabien Sanglard   void OnConnectionDestroyed(QuicProtocolConnection* connection) override;
60*3f982cf4SFabien Sanglard 
61*3f982cf4SFabien Sanglard   // ServiceConnectionDelegate::ServiceDelegate overrides.
62*3f982cf4SFabien Sanglard   uint64_t OnCryptoHandshakeComplete(ServiceConnectionDelegate* delegate,
63*3f982cf4SFabien Sanglard                                      uint64_t connection_id) override;
64*3f982cf4SFabien Sanglard   void OnIncomingStream(
65*3f982cf4SFabien Sanglard       std::unique_ptr<QuicProtocolConnection> connection) override;
66*3f982cf4SFabien Sanglard   void OnConnectionClosed(uint64_t endpoint_id,
67*3f982cf4SFabien Sanglard                           uint64_t connection_id) override;
68*3f982cf4SFabien Sanglard   void OnDataReceived(uint64_t endpoint_id,
69*3f982cf4SFabien Sanglard                       uint64_t connection_id,
70*3f982cf4SFabien Sanglard                       const uint8_t* data,
71*3f982cf4SFabien Sanglard                       size_t data_size) override;
72*3f982cf4SFabien Sanglard 
73*3f982cf4SFabien Sanglard  private:
74*3f982cf4SFabien Sanglard   struct PendingConnectionData {
75*3f982cf4SFabien Sanglard     explicit PendingConnectionData(ServiceConnectionData&& data);
76*3f982cf4SFabien Sanglard     PendingConnectionData(PendingConnectionData&&) noexcept;
77*3f982cf4SFabien Sanglard     ~PendingConnectionData();
78*3f982cf4SFabien Sanglard     PendingConnectionData& operator=(PendingConnectionData&&) noexcept;
79*3f982cf4SFabien Sanglard 
80*3f982cf4SFabien Sanglard     ServiceConnectionData data;
81*3f982cf4SFabien Sanglard 
82*3f982cf4SFabien Sanglard     // Pairs of request IDs and the associated connection callback.
83*3f982cf4SFabien Sanglard     std::vector<std::pair<uint64_t, ConnectionRequestCallback*>> callbacks;
84*3f982cf4SFabien Sanglard   };
85*3f982cf4SFabien Sanglard 
86*3f982cf4SFabien Sanglard   ConnectRequest CreatePendingConnection(const IPEndpoint& endpoint,
87*3f982cf4SFabien Sanglard                                          ConnectionRequestCallback* request);
88*3f982cf4SFabien Sanglard   uint64_t StartConnectionRequest(const IPEndpoint& endpoint,
89*3f982cf4SFabien Sanglard                                   ConnectionRequestCallback* request);
90*3f982cf4SFabien Sanglard   void CloseAllConnections();
91*3f982cf4SFabien Sanglard   std::unique_ptr<QuicProtocolConnection> MakeProtocolConnection(
92*3f982cf4SFabien Sanglard       QuicConnection* connection,
93*3f982cf4SFabien Sanglard       ServiceConnectionDelegate* delegate,
94*3f982cf4SFabien Sanglard       uint64_t endpoint_id);
95*3f982cf4SFabien Sanglard 
96*3f982cf4SFabien Sanglard   void CancelConnectRequest(uint64_t request_id) override;
97*3f982cf4SFabien Sanglard 
98*3f982cf4SFabien Sanglard   // Deletes dead QUIC connections then returns the time interval before this
99*3f982cf4SFabien Sanglard   // method should be run again.
100*3f982cf4SFabien Sanglard   void Cleanup();
101*3f982cf4SFabien Sanglard 
102*3f982cf4SFabien Sanglard   std::unique_ptr<QuicConnectionFactory> connection_factory_;
103*3f982cf4SFabien Sanglard 
104*3f982cf4SFabien Sanglard   // Maps an IPEndpoint to a generated endpoint ID.  This is used to insulate
105*3f982cf4SFabien Sanglard   // callers from post-handshake changes to a connections actual peer endpoint.
106*3f982cf4SFabien Sanglard   std::map<IPEndpoint, uint64_t> endpoint_map_;
107*3f982cf4SFabien Sanglard 
108*3f982cf4SFabien Sanglard   // Value that will be used for the next new endpoint in a Connect call.
109*3f982cf4SFabien Sanglard   uint64_t next_endpoint_id_ = 0;
110*3f982cf4SFabien Sanglard 
111*3f982cf4SFabien Sanglard   // Maps request IDs to their callbacks.  The callback is paired with the
112*3f982cf4SFabien Sanglard   // IPEndpoint it originally requested to connect to so cancelling the request
113*3f982cf4SFabien Sanglard   // can also remove a pending connection.
114*3f982cf4SFabien Sanglard   std::map<uint64_t, std::pair<IPEndpoint, ConnectionRequestCallback*>>
115*3f982cf4SFabien Sanglard       request_map_;
116*3f982cf4SFabien Sanglard 
117*3f982cf4SFabien Sanglard   // Value that will be used for the next new connection request.
118*3f982cf4SFabien Sanglard   uint64_t next_request_id_ = 1;
119*3f982cf4SFabien Sanglard 
120*3f982cf4SFabien Sanglard   // Maps endpoint addresses to data about connections that haven't successfully
121*3f982cf4SFabien Sanglard   // completed the QUIC handshake.
122*3f982cf4SFabien Sanglard   std::map<IPEndpoint, PendingConnectionData> pending_connections_;
123*3f982cf4SFabien Sanglard 
124*3f982cf4SFabien Sanglard   // Maps endpoint IDs to data about connections that have successfully
125*3f982cf4SFabien Sanglard   // completed the QUIC handshake.
126*3f982cf4SFabien Sanglard   std::map<uint64_t, ServiceConnectionData> connections_;
127*3f982cf4SFabien Sanglard 
128*3f982cf4SFabien Sanglard   // Connections (endpoint IDs) that need to be destroyed, but have to wait for
129*3f982cf4SFabien Sanglard   // the next event loop due to the underlying QUIC implementation's way of
130*3f982cf4SFabien Sanglard   // referencing them.
131*3f982cf4SFabien Sanglard   std::vector<uint64_t> delete_connections_;
132*3f982cf4SFabien Sanglard 
133*3f982cf4SFabien Sanglard   Alarm cleanup_alarm_;
134*3f982cf4SFabien Sanglard };
135*3f982cf4SFabien Sanglard 
136*3f982cf4SFabien Sanglard }  // namespace osp
137*3f982cf4SFabien Sanglard }  // namespace openscreen
138*3f982cf4SFabien Sanglard 
139*3f982cf4SFabien Sanglard #endif  // OSP_IMPL_QUIC_QUIC_CLIENT_H_
140