- add sources.
[platform/framework/web/crosswalk.git] / src / net / socket / transport_client_socket_pool.h
1 // Copyright (c) 2012 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 NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_
6 #define NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_
7
8 #include <string>
9
10 #include "base/basictypes.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/time/time.h"
14 #include "base/timer/timer.h"
15 #include "net/base/host_port_pair.h"
16 #include "net/dns/host_resolver.h"
17 #include "net/dns/single_request_host_resolver.h"
18 #include "net/socket/client_socket_pool.h"
19 #include "net/socket/client_socket_pool_base.h"
20 #include "net/socket/client_socket_pool_histograms.h"
21
22 namespace net {
23
24 class ClientSocketFactory;
25
26 typedef base::Callback<int(const AddressList&, const BoundNetLog& net_log)>
27 OnHostResolutionCallback;
28
29 class NET_EXPORT_PRIVATE TransportSocketParams
30     : public base::RefCounted<TransportSocketParams> {
31  public:
32   // |host_resolution_callback| will be invoked after the the hostname is
33   // resolved.  If |host_resolution_callback| does not return OK, then the
34   // connection will be aborted with that value.
35   TransportSocketParams(
36       const HostPortPair& host_port_pair,
37       bool disable_resolver_cache,
38       bool ignore_limits,
39       const OnHostResolutionCallback& host_resolution_callback);
40
41   const HostResolver::RequestInfo& destination() const { return destination_; }
42   bool ignore_limits() const { return ignore_limits_; }
43   const OnHostResolutionCallback& host_resolution_callback() const {
44     return host_resolution_callback_;
45   }
46
47  private:
48   friend class base::RefCounted<TransportSocketParams>;
49   ~TransportSocketParams();
50
51   HostResolver::RequestInfo destination_;
52   bool ignore_limits_;
53   const OnHostResolutionCallback host_resolution_callback_;
54
55   DISALLOW_COPY_AND_ASSIGN(TransportSocketParams);
56 };
57
58 // TransportConnectJob handles the host resolution necessary for socket creation
59 // and the transport (likely TCP) connect. TransportConnectJob also has fallback
60 // logic for IPv6 connect() timeouts (which may happen due to networks / routers
61 // with broken IPv6 support). Those timeouts take 20s, so rather than make the
62 // user wait 20s for the timeout to fire, we use a fallback timer
63 // (kIPv6FallbackTimerInMs) and start a connect() to a IPv4 address if the timer
64 // fires. Then we race the IPv4 connect() against the IPv6 connect() (which has
65 // a headstart) and return the one that completes first to the socket pool.
66 class NET_EXPORT_PRIVATE TransportConnectJob : public ConnectJob {
67  public:
68   TransportConnectJob(const std::string& group_name,
69                       RequestPriority priority,
70                       const scoped_refptr<TransportSocketParams>& params,
71                       base::TimeDelta timeout_duration,
72                       ClientSocketFactory* client_socket_factory,
73                       HostResolver* host_resolver,
74                       Delegate* delegate,
75                       NetLog* net_log);
76   virtual ~TransportConnectJob();
77
78   // ConnectJob methods.
79   virtual LoadState GetLoadState() const OVERRIDE;
80
81   // Rolls |addrlist| forward until the first IPv4 address, if any.
82   // WARNING: this method should only be used to implement the prefer-IPv4 hack.
83   static void MakeAddressListStartWithIPv4(AddressList* addrlist);
84
85   static const int kIPv6FallbackTimerInMs;
86
87  private:
88   enum State {
89     STATE_RESOLVE_HOST,
90     STATE_RESOLVE_HOST_COMPLETE,
91     STATE_TRANSPORT_CONNECT,
92     STATE_TRANSPORT_CONNECT_COMPLETE,
93     STATE_NONE,
94   };
95
96   void OnIOComplete(int result);
97
98   // Runs the state transition loop.
99   int DoLoop(int result);
100
101   int DoResolveHost();
102   int DoResolveHostComplete(int result);
103   int DoTransportConnect();
104   int DoTransportConnectComplete(int result);
105
106   // Not part of the state machine.
107   void DoIPv6FallbackTransportConnect();
108   void DoIPv6FallbackTransportConnectComplete(int result);
109
110   // Begins the host resolution and the TCP connect.  Returns OK on success
111   // and ERR_IO_PENDING if it cannot immediately service the request.
112   // Otherwise, it returns a net error code.
113   virtual int ConnectInternal() OVERRIDE;
114
115   scoped_refptr<TransportSocketParams> params_;
116   ClientSocketFactory* const client_socket_factory_;
117   SingleRequestHostResolver resolver_;
118   AddressList addresses_;
119   State next_state_;
120
121   scoped_ptr<StreamSocket> transport_socket_;
122
123   scoped_ptr<StreamSocket> fallback_transport_socket_;
124   scoped_ptr<AddressList> fallback_addresses_;
125   base::TimeTicks fallback_connect_start_time_;
126   base::OneShotTimer<TransportConnectJob> fallback_timer_;
127
128   // If the interval between this connect and previous connect is less than
129   // 20ms, then |less_than_20ms_since_connect_| is set to true.
130   bool less_than_20ms_since_connect_;
131
132   DISALLOW_COPY_AND_ASSIGN(TransportConnectJob);
133 };
134
135 class NET_EXPORT_PRIVATE TransportClientSocketPool : public ClientSocketPool {
136  public:
137   typedef TransportSocketParams SocketParams;
138
139   TransportClientSocketPool(
140       int max_sockets,
141       int max_sockets_per_group,
142       ClientSocketPoolHistograms* histograms,
143       HostResolver* host_resolver,
144       ClientSocketFactory* client_socket_factory,
145       NetLog* net_log);
146
147   virtual ~TransportClientSocketPool();
148
149   // ClientSocketPool implementation.
150   virtual int RequestSocket(const std::string& group_name,
151                             const void* resolve_info,
152                             RequestPriority priority,
153                             ClientSocketHandle* handle,
154                             const CompletionCallback& callback,
155                             const BoundNetLog& net_log) OVERRIDE;
156   virtual void RequestSockets(const std::string& group_name,
157                               const void* params,
158                               int num_sockets,
159                               const BoundNetLog& net_log) OVERRIDE;
160   virtual void CancelRequest(const std::string& group_name,
161                              ClientSocketHandle* handle) OVERRIDE;
162   virtual void ReleaseSocket(const std::string& group_name,
163                              scoped_ptr<StreamSocket> socket,
164                              int id) OVERRIDE;
165   virtual void FlushWithError(int error) OVERRIDE;
166   virtual void CloseIdleSockets() OVERRIDE;
167   virtual int IdleSocketCount() const OVERRIDE;
168   virtual int IdleSocketCountInGroup(
169       const std::string& group_name) const OVERRIDE;
170   virtual LoadState GetLoadState(
171       const std::string& group_name,
172       const ClientSocketHandle* handle) const OVERRIDE;
173   virtual base::DictionaryValue* GetInfoAsValue(
174       const std::string& name,
175       const std::string& type,
176       bool include_nested_pools) const OVERRIDE;
177   virtual base::TimeDelta ConnectionTimeout() const OVERRIDE;
178   virtual ClientSocketPoolHistograms* histograms() const OVERRIDE;
179
180   // HigherLayeredPool implementation.
181   virtual bool IsStalled() const OVERRIDE;
182   virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE;
183   virtual void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE;
184
185  private:
186   typedef ClientSocketPoolBase<TransportSocketParams> PoolBase;
187
188   class TransportConnectJobFactory
189       : public PoolBase::ConnectJobFactory {
190    public:
191     TransportConnectJobFactory(ClientSocketFactory* client_socket_factory,
192                          HostResolver* host_resolver,
193                          NetLog* net_log)
194         : client_socket_factory_(client_socket_factory),
195           host_resolver_(host_resolver),
196           net_log_(net_log) {}
197
198     virtual ~TransportConnectJobFactory() {}
199
200     // ClientSocketPoolBase::ConnectJobFactory methods.
201
202     virtual scoped_ptr<ConnectJob> NewConnectJob(
203         const std::string& group_name,
204         const PoolBase::Request& request,
205         ConnectJob::Delegate* delegate) const OVERRIDE;
206
207     virtual base::TimeDelta ConnectionTimeout() const OVERRIDE;
208
209    private:
210     ClientSocketFactory* const client_socket_factory_;
211     HostResolver* const host_resolver_;
212     NetLog* net_log_;
213
214     DISALLOW_COPY_AND_ASSIGN(TransportConnectJobFactory);
215   };
216
217   PoolBase base_;
218
219   DISALLOW_COPY_AND_ASSIGN(TransportClientSocketPool);
220 };
221
222 }  // namespace net
223
224 #endif  // NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_