1 // Copyright (c) 2013 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 #ifndef GOOGLE_APIS_GCM_ENGINE_CONNECTION_FACTORY_IMPL_H_ 6 #define GOOGLE_APIS_GCM_ENGINE_CONNECTION_FACTORY_IMPL_H_ 7 8 #include "google_apis/gcm/engine/connection_factory.h" 9 10 #include "base/memory/weak_ptr.h" 11 #include "base/time/time.h" 12 #include "google_apis/gcm/protocol/mcs.pb.h" 13 #include "net/base/backoff_entry.h" 14 #include "net/base/network_change_notifier.h" 15 #include "net/proxy/proxy_info.h" 16 #include "net/proxy/proxy_service.h" 17 #include "net/socket/client_socket_handle.h" 18 #include "url/gurl.h" 19 20 namespace net { 21 class HttpNetworkSession; 22 class NetLog; 23 } 24 25 namespace gcm { 26 27 class ConnectionHandlerImpl; 28 class GCMStatsRecorder; 29 30 class GCM_EXPORT ConnectionFactoryImpl : 31 public ConnectionFactory, 32 public net::NetworkChangeNotifier::NetworkChangeObserver { 33 public: 34 // |http_network_session| is an optional network session to use as a source 35 // for proxy auth credentials (via its HttpAuthCache). |gcm_network_session| 36 // is the network session through which GCM connections should be made, and 37 // must not be the same as |http_network_session|. 38 ConnectionFactoryImpl( 39 const std::vector<GURL>& mcs_endpoints, 40 const net::BackoffEntry::Policy& backoff_policy, 41 const scoped_refptr<net::HttpNetworkSession>& gcm_network_session, 42 const scoped_refptr<net::HttpNetworkSession>& http_network_session, 43 net::NetLog* net_log, 44 GCMStatsRecorder* recorder); 45 virtual ~ConnectionFactoryImpl(); 46 47 // ConnectionFactory implementation. 48 virtual void Initialize( 49 const BuildLoginRequestCallback& request_builder, 50 const ConnectionHandler::ProtoReceivedCallback& read_callback, 51 const ConnectionHandler::ProtoSentCallback& write_callback) OVERRIDE; 52 virtual ConnectionHandler* GetConnectionHandler() const OVERRIDE; 53 virtual void Connect() OVERRIDE; 54 virtual bool IsEndpointReachable() const OVERRIDE; 55 virtual std::string GetConnectionStateString() const OVERRIDE; 56 virtual base::TimeTicks NextRetryAttempt() const OVERRIDE; 57 virtual void SignalConnectionReset(ConnectionResetReason reason) OVERRIDE; 58 virtual void SetConnectionListener(ConnectionListener* listener) OVERRIDE; 59 60 // NetworkChangeObserver implementation. 61 virtual void OnNetworkChanged( 62 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE; 63 64 // Returns the server to which the factory is currently connected, or if 65 // a connection is currently pending, the server to which the next connection 66 // attempt will be made. 67 GURL GetCurrentEndpoint() const; 68 69 // Returns the IPEndpoint to which the factory is currently connected. If no 70 // connection is active, returns an empty IPEndpoint. 71 net::IPEndPoint GetPeerIP(); 72 73 protected: 74 // Implementation of Connect(..). If not in backoff, uses |login_request_| 75 // in attempting a connection/handshake. On connection/handshake failure, goes 76 // into backoff. 77 // Virtual for testing. 78 virtual void ConnectImpl(); 79 80 // Helper method for initalizing the connection hander. 81 // Virtual for testing. 82 virtual void InitHandler(); 83 84 // Helper method for creating a backoff entry. 85 // Virtual for testing. 86 virtual scoped_ptr<net::BackoffEntry> CreateBackoffEntry( 87 const net::BackoffEntry::Policy* const policy); 88 89 // Helper method for creating the connection handler. 90 // Virtual for testing. 91 virtual scoped_ptr<ConnectionHandler> CreateConnectionHandler( 92 base::TimeDelta read_timeout, 93 const ConnectionHandler::ProtoReceivedCallback& read_callback, 94 const ConnectionHandler::ProtoSentCallback& write_callback, 95 const ConnectionHandler::ConnectionChangedCallback& connection_callback); 96 97 // Returns the current time in Ticks. 98 // Virtual for testing. 99 virtual base::TimeTicks NowTicks(); 100 101 // Callback for Socket connection completion. 102 void OnConnectDone(int result); 103 104 // ConnectionHandler callback for connection issues. 105 void ConnectionHandlerCallback(int result); 106 107 private: 108 // Helper method for checking backoff and triggering a connection as 109 // necessary. 110 void ConnectWithBackoff(); 111 112 // Proxy resolution and connection functions. 113 void OnProxyResolveDone(int status); 114 void OnProxyConnectDone(int status); 115 int ReconsiderProxyAfterError(int error); 116 void ReportSuccessfulProxyConnection(); 117 118 // Closes the local socket if one is present, and resets connection handler. 119 void CloseSocket(); 120 121 // Updates the GCM Network Session's HttpAuthCache with the HTTP Network 122 // Session's cache, if available. 123 void RebuildNetworkSessionAuthCache(); 124 125 // The MCS endpoints to make connections to, sorted in order of priority. 126 const std::vector<GURL> mcs_endpoints_; 127 // Index to the endpoint for which a connection should be attempted next. 128 size_t next_endpoint_; 129 // Index to the endpoint that was last successfully connected. 130 size_t last_successful_endpoint_; 131 132 // The backoff policy to use. 133 const net::BackoffEntry::Policy backoff_policy_; 134 135 // ---- net:: components for establishing connections. ---- 136 // Network session for creating new GCM connections. 137 const scoped_refptr<net::HttpNetworkSession> gcm_network_session_; 138 // HTTP Network session. If set, is used for extracting proxy auth 139 // credentials. If not set, is ignored. 140 const scoped_refptr<net::HttpNetworkSession> http_network_session_; 141 // Net log to use in connection attempts. 142 net::BoundNetLog bound_net_log_; 143 // The current PAC request, if one exists. Owned by the proxy service. 144 net::ProxyService::PacRequest* pac_request_; 145 // The current proxy info. 146 net::ProxyInfo proxy_info_; 147 // The handle to the socket for the current connection, if one exists. 148 net::ClientSocketHandle socket_handle_; 149 // Current backoff entry. 150 scoped_ptr<net::BackoffEntry> backoff_entry_; 151 // Backoff entry from previous connection attempt. Updated on each login 152 // completion. 153 scoped_ptr<net::BackoffEntry> previous_backoff_; 154 155 // Whether a connection attempt is currently actively in progress. 156 bool connecting_; 157 158 // Whether the client is waiting for backoff to finish before attempting to 159 // connect. Canary jobs are able to preempt connections pending backoff 160 // expiration. 161 bool waiting_for_backoff_; 162 163 // Whether the NetworkChangeNotifier has informed the client that there is 164 // no current connection. No connection attempts will be made until the 165 // client is informed of a valid connection type. 166 bool waiting_for_network_online_; 167 168 // Whether login successfully completed after the connection was established. 169 // If a connection reset happens while attempting to log in, the current 170 // backoff entry is reused (after incrementing with a new failure). 171 bool logging_in_; 172 173 // The time of the last login completion. Used for calculating whether to 174 // restore a previous backoff entry and for measuring uptime. 175 base::TimeTicks last_login_time_; 176 177 // The current connection handler, if one exists. 178 scoped_ptr<ConnectionHandler> connection_handler_; 179 180 // Builder for generating new login requests. 181 BuildLoginRequestCallback request_builder_; 182 183 // Recorder that records GCM activities for debugging purpose. Not owned. 184 GCMStatsRecorder* recorder_; 185 186 // Listener for connection change events. 187 ConnectionListener* listener_; 188 189 base::WeakPtrFactory<ConnectionFactoryImpl> weak_ptr_factory_; 190 191 DISALLOW_COPY_AND_ASSIGN(ConnectionFactoryImpl); 192 }; 193 194 } // namespace gcm 195 196 #endif // GOOGLE_APIS_GCM_ENGINE_CONNECTION_FACTORY_IMPL_H_ 197