File: connection_factory_impl.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (214 lines) | stat: -rw-r--r-- 8,706 bytes parent folder | download | duplicates (9)
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_