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