1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GOOGLE_APIS_GCM_ENGINE_CONNECTION_FACTORY_IMPL_H_
#define GOOGLE_APIS_GCM_ENGINE_CONNECTION_FACTORY_IMPL_H_
#include "base/memory/raw_ptr.h"
#include "google_apis/gcm/engine/connection_factory.h"
#include <stddef.h>
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "google_apis/gcm/engine/connection_event_tracker.h"
#include "google_apis/gcm/engine/connection_handler.h"
#include "google_apis/gcm/protocol/mcs.pb.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/backoff_entry.h"
#include "net/log/net_log_with_source.h"
#include "services/network/public/cpp/network_connection_tracker.h"
#include "services/network/public/mojom/proxy_resolving_socket.mojom.h"
#include "url/gurl.h"
namespace gcm {
class GCMStatsRecorder;
class GCM_EXPORT ConnectionFactoryImpl
: public ConnectionFactory,
public network::NetworkConnectionTracker::NetworkConnectionObserver {
public:
ConnectionFactoryImpl(
const std::vector<GURL>& mcs_endpoints,
const net::BackoffEntry::Policy& backoff_policy,
GetProxyResolvingFactoryCallback get_socket_factory_callback,
scoped_refptr<base::SequencedTaskRunner> io_task_runner,
GCMStatsRecorder* recorder,
network::NetworkConnectionTracker* network_connection_tracker);
ConnectionFactoryImpl(const ConnectionFactoryImpl&) = delete;
ConnectionFactoryImpl& operator=(const ConnectionFactoryImpl&) = delete;
~ConnectionFactoryImpl() override;
// ConnectionFactory implementation.
void Initialize(
const BuildLoginRequestCallback& request_builder,
const ConnectionHandler::ProtoReceivedCallback& read_callback,
const ConnectionHandler::ProtoSentCallback& write_callback) override;
ConnectionHandler* GetConnectionHandler() const override;
void Connect() override;
bool IsEndpointReachable() const override;
std::string GetConnectionStateString() const override;
base::TimeTicks NextRetryAttempt() const override;
void SignalConnectionReset(ConnectionResetReason reason) override;
void SetConnectionListener(ConnectionListener* listener) override;
// NetworkConnectionTracker implementation.
void OnConnectionChanged(network::mojom::ConnectionType type) override;
// Returns the server to which the factory is currently connected, or if
// a connection is currently pending, the server to which the next connection
// attempt will be made.
GURL GetCurrentEndpoint() const;
protected:
// Initiate the connection to the GCM server. When `ignore_connection_failure`
// is true, backoff delay won't be changed in case of failure.
// Virtual for testing.
virtual void StartConnection(bool ignore_connection_failure);
// Helper method for initalizing the connection hander.
// Virtual for testing.
virtual void InitHandler(mojo::ScopedDataPipeConsumerHandle receive_stream,
mojo::ScopedDataPipeProducerHandle send_stream);
// Helper method for creating a backoff entry.
// Virtual for testing.
virtual std::unique_ptr<net::BackoffEntry> CreateBackoffEntry(
const net::BackoffEntry::Policy* const policy);
// Helper method for creating the connection handler.
// Virtual for testing.
virtual std::unique_ptr<ConnectionHandler> CreateConnectionHandler(
base::TimeDelta read_timeout,
const ConnectionHandler::ProtoReceivedCallback& read_callback,
const ConnectionHandler::ProtoSentCallback& write_callback,
const ConnectionHandler::ConnectionChangedCallback& connection_callback);
// Returns the current time in Ticks.
// Virtual for testing.
virtual base::TimeTicks NowTicks();
// Callback for Socket connection completion. When `ignore_connection_failure`
// is true, backoff delay won't be changed in case of failure.
// This is public for testing.
void OnConnectDone(bool ignore_connection_failure,
int result,
const std::optional<net::IPEndPoint>& local_addr,
const std::optional<net::IPEndPoint>& peer_addr,
mojo::ScopedDataPipeConsumerHandle receive_stream,
mojo::ScopedDataPipeProducerHandle send_stream);
// ConnectionHandler callback for connection issues.
void ConnectionHandlerCallback(int result);
private:
friend class ConnectionFactoryImplTest;
ConnectionEventTracker* GetEventTrackerForTesting();
// Helper method for checking backoff and triggering a connection as
// necessary.
void ConnectWithBackoff();
// Implementation of Connect(..). If not in backoff attempts a connection and
// handshake. On connection/handshake failure, goes into backoff. When
// `ignore_connection_failure` is true, backoff delay won't be changed in case
// of failure.
void ConnectImpl(bool ignore_connection_failure);
// Closes the local socket if one is present, and resets connection handler.
void CloseSocket();
// Updates the GCM Network Session's with current data from HTTP Network
// Session's, if available.
// Specifically, HttpAuthCache and IsQuicEnabled are updated.
void UpdateFromHttpNetworkSession();
// The tracker will maintain a list of all connection attempts with GCM,
// whether they succeeded, and their duration.
ConnectionEventTracker event_tracker_;
// The MCS endpoints to make connections to, sorted in order of priority.
const std::vector<GURL> mcs_endpoints_;
// Index to the endpoint for which a connection should be attempted next.
size_t next_endpoint_;
// Index to the endpoint that was last successfully connected.
size_t last_successful_endpoint_;
// The backoff policy to use.
const net::BackoffEntry::Policy backoff_policy_;
// ---- network:: components for establishing connections. ----
// Socket factory for creating new GCM connections.
GetProxyResolvingFactoryCallback get_socket_factory_callback_;
mojo::Remote<network::mojom::ProxyResolvingSocketFactory> socket_factory_;
// The handle to the socket for the current connection, if one exists.
mojo::Remote<network::mojom::ProxyResolvingSocket> socket_;
// Peer address of |socket_|.
net::IPEndPoint peer_addr_;
// Current backoff entry.
std::unique_ptr<net::BackoffEntry> backoff_entry_;
// Backoff entry from previous connection attempt. Updated on each login
// completion.
std::unique_ptr<net::BackoffEntry> previous_backoff_;
// Whether a connection attempt is currently actively in progress.
bool connecting_;
// Whether the client is waiting for backoff to finish before attempting to
// connect. Canary jobs are able to preempt connections pending backoff
// expiration.
bool waiting_for_backoff_;
// Whether the NetworkConnectionTracker has informed the client that there is
// no current connection. No connection attempts will be made until the
// client is informed of a valid connection type.
bool waiting_for_network_online_;
// Whether handshake is in progress after the connection was established. If
// a connection reset happens while attempting to complete the handshake, the
// current backoff entry is reused (after incrementing with a new failure).
bool handshake_in_progress_;
// The time of the last login completion. Used for calculating whether to
// restore a previous backoff entry and for measuring uptime.
base::TimeTicks last_login_time_;
// Cached callbacks. Set at |Initialize| time, consumed at first |Connect|
// time.
ConnectionHandler::ProtoReceivedCallback read_callback_;
ConnectionHandler::ProtoSentCallback write_callback_;
// The current connection handler, if one exists.
std::unique_ptr<ConnectionHandler> connection_handler_;
// Builder for generating new login requests.
BuildLoginRequestCallback request_builder_;
// Task runner.
const scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
// Recorder that records GCM activities for debugging purpose. Not owned.
raw_ptr<GCMStatsRecorder> recorder_;
// Notifies this class of network connection changes.
// Must outlive the ConnectionFactoryImpl.
raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_;
// The currently registered listener to notify of connection changes.
raw_ptr<ConnectionListener> listener_;
base::WeakPtrFactory<ConnectionFactoryImpl> weak_ptr_factory_{this};
};
} // namespace gcm
#endif // GOOGLE_APIS_GCM_ENGINE_CONNECTION_FACTORY_IMPL_H_
|