Home | History | Annotate | Download | only in engine
      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