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