QUIC - enable persisting of QUICServerInfo (server config) to disk
[chromium-blink-merge.git] / net / socket / websocket_transport_client_socket_pool.h
blobd0d2d9df22637ae28a5925690548bc7e4ae8407a
1 // Copyright 2014 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.
5 #ifndef NET_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_
6 #define NET_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_
8 #include <list>
9 #include <map>
10 #include <set>
11 #include <string>
13 #include "base/basictypes.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/time/time.h"
18 #include "base/timer/timer.h"
19 #include "net/base/net_export.h"
20 #include "net/base/net_log.h"
21 #include "net/socket/client_socket_pool.h"
22 #include "net/socket/client_socket_pool_base.h"
23 #include "net/socket/transport_client_socket_pool.h"
25 namespace net {
27 class ClientSocketFactory;
28 class ClientSocketPoolHistograms;
29 class HostResolver;
30 class NetLog;
31 class WebSocketEndpointLockManager;
32 class WebSocketTransportConnectSubJob;
34 // WebSocketTransportConnectJob handles the host resolution necessary for socket
35 // creation and the TCP connect. WebSocketTransportConnectJob also has fallback
36 // logic for IPv6 connect() timeouts (which may happen due to networks / routers
37 // with broken IPv6 support). Those timeouts take 20s, so rather than make the
38 // user wait 20s for the timeout to fire, we use a fallback timer
39 // (kIPv6FallbackTimerInMs) and start a connect() to an IPv4 address if the
40 // timer fires. Then we race the IPv4 connect(s) against the IPv6 connect(s) and
41 // use the socket that completes successfully first or fails last.
42 class NET_EXPORT_PRIVATE WebSocketTransportConnectJob : public ConnectJob {
43 public:
44 WebSocketTransportConnectJob(
45 const std::string& group_name,
46 RequestPriority priority,
47 const scoped_refptr<TransportSocketParams>& params,
48 base::TimeDelta timeout_duration,
49 const CompletionCallback& callback,
50 ClientSocketFactory* client_socket_factory,
51 HostResolver* host_resolver,
52 ClientSocketHandle* handle,
53 Delegate* delegate,
54 NetLog* pool_net_log,
55 const BoundNetLog& request_net_log);
56 virtual ~WebSocketTransportConnectJob();
58 // Unlike normal socket pools, the WebSocketTransportClientPool uses
59 // early-binding of sockets.
60 ClientSocketHandle* handle() const { return handle_; }
62 // Stash the callback from RequestSocket() here for convenience.
63 const CompletionCallback& callback() const { return callback_; }
65 const BoundNetLog& request_net_log() const { return request_net_log_; }
67 // ConnectJob methods.
68 virtual LoadState GetLoadState() const OVERRIDE;
70 private:
71 friend class WebSocketTransportConnectSubJob;
72 friend class TransportConnectJobHelper;
73 friend class WebSocketEndpointLockManager;
75 // Although it is not strictly necessary, it makes the code simpler if each
76 // subjob knows what type it is.
77 enum SubJobType { SUB_JOB_IPV4, SUB_JOB_IPV6 };
79 int DoResolveHost();
80 int DoResolveHostComplete(int result);
81 int DoTransportConnect();
82 int DoTransportConnectComplete(int result);
84 // Called back from a SubJob when it completes.
85 void OnSubJobComplete(int result, WebSocketTransportConnectSubJob* job);
87 // Called from |fallback_timer_|.
88 void StartIPv4JobAsync();
90 // Begins the host resolution and the TCP connect. Returns OK on success
91 // and ERR_IO_PENDING if it cannot immediately service the request.
92 // Otherwise, it returns a net error code.
93 virtual int ConnectInternal() OVERRIDE;
95 TransportConnectJobHelper helper_;
97 // The addresses are divided into IPv4 and IPv6, which are performed partially
98 // in parallel. If the list of IPv6 addresses is non-empty, then the IPv6 jobs
99 // go first, followed after |kIPv6FallbackTimerInMs| by the IPv4
100 // addresses. First sub-job to establish a connection wins.
101 scoped_ptr<WebSocketTransportConnectSubJob> ipv4_job_;
102 scoped_ptr<WebSocketTransportConnectSubJob> ipv6_job_;
104 base::OneShotTimer<WebSocketTransportConnectJob> fallback_timer_;
105 TransportConnectJobHelper::ConnectionLatencyHistogram race_result_;
106 ClientSocketHandle* const handle_;
107 CompletionCallback callback_;
108 BoundNetLog request_net_log_;
110 bool had_ipv4_;
111 bool had_ipv6_;
113 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportConnectJob);
116 class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
117 : public TransportClientSocketPool {
118 public:
119 WebSocketTransportClientSocketPool(int max_sockets,
120 int max_sockets_per_group,
121 ClientSocketPoolHistograms* histograms,
122 HostResolver* host_resolver,
123 ClientSocketFactory* client_socket_factory,
124 NetLog* net_log);
126 virtual ~WebSocketTransportClientSocketPool();
128 // Allow another connection to be started to the IPEndPoint that this |handle|
129 // is connected to. Used when the WebSocket handshake completes successfully.
130 static void UnlockEndpoint(ClientSocketHandle* handle);
132 // ClientSocketPool implementation.
133 virtual int RequestSocket(const std::string& group_name,
134 const void* resolve_info,
135 RequestPriority priority,
136 ClientSocketHandle* handle,
137 const CompletionCallback& callback,
138 const BoundNetLog& net_log) OVERRIDE;
139 virtual void RequestSockets(const std::string& group_name,
140 const void* params,
141 int num_sockets,
142 const BoundNetLog& net_log) OVERRIDE;
143 virtual void CancelRequest(const std::string& group_name,
144 ClientSocketHandle* handle) OVERRIDE;
145 virtual void ReleaseSocket(const std::string& group_name,
146 scoped_ptr<StreamSocket> socket,
147 int id) OVERRIDE;
148 virtual void FlushWithError(int error) OVERRIDE;
149 virtual void CloseIdleSockets() OVERRIDE;
150 virtual int IdleSocketCount() const OVERRIDE;
151 virtual int IdleSocketCountInGroup(
152 const std::string& group_name) const OVERRIDE;
153 virtual LoadState GetLoadState(
154 const std::string& group_name,
155 const ClientSocketHandle* handle) const OVERRIDE;
156 virtual base::DictionaryValue* GetInfoAsValue(
157 const std::string& name,
158 const std::string& type,
159 bool include_nested_pools) const OVERRIDE;
160 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE;
161 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE;
163 // HigherLayeredPool implementation.
164 virtual bool IsStalled() const OVERRIDE;
166 private:
167 class ConnectJobDelegate : public ConnectJob::Delegate {
168 public:
169 explicit ConnectJobDelegate(WebSocketTransportClientSocketPool* owner);
170 virtual ~ConnectJobDelegate();
172 virtual void OnConnectJobComplete(int result, ConnectJob* job) OVERRIDE;
174 private:
175 WebSocketTransportClientSocketPool* owner_;
177 DISALLOW_COPY_AND_ASSIGN(ConnectJobDelegate);
180 // Store the arguments from a call to RequestSocket() that has stalled so we
181 // can replay it when there are available socket slots.
182 struct StalledRequest {
183 StalledRequest(const scoped_refptr<TransportSocketParams>& params,
184 RequestPriority priority,
185 ClientSocketHandle* handle,
186 const CompletionCallback& callback,
187 const BoundNetLog& net_log);
188 ~StalledRequest();
189 const scoped_refptr<TransportSocketParams> params;
190 const RequestPriority priority;
191 ClientSocketHandle* const handle;
192 const CompletionCallback callback;
193 const BoundNetLog net_log;
195 friend class ConnectJobDelegate;
196 typedef std::map<const ClientSocketHandle*, WebSocketTransportConnectJob*>
197 PendingConnectsMap;
198 // This is a list so that we can remove requests from the middle, and also
199 // so that iterators are not invalidated unless the corresponding request is
200 // removed.
201 typedef std::list<StalledRequest> StalledRequestQueue;
202 typedef std::map<const ClientSocketHandle*, StalledRequestQueue::iterator>
203 StalledRequestMap;
205 void OnConnectJobComplete(int result, WebSocketTransportConnectJob* job);
206 void InvokeUserCallbackLater(ClientSocketHandle* handle,
207 const CompletionCallback& callback,
208 int rv);
209 void InvokeUserCallback(ClientSocketHandle* handle,
210 const CompletionCallback& callback,
211 int rv);
212 bool ReachedMaxSocketsLimit() const;
213 void HandOutSocket(scoped_ptr<StreamSocket> socket,
214 const LoadTimingInfo::ConnectTiming& connect_timing,
215 ClientSocketHandle* handle,
216 const BoundNetLog& net_log);
217 void AddJob(ClientSocketHandle* handle,
218 scoped_ptr<WebSocketTransportConnectJob> connect_job);
219 bool DeleteJob(ClientSocketHandle* handle);
220 const WebSocketTransportConnectJob* LookupConnectJob(
221 const ClientSocketHandle* handle) const;
222 void ActivateStalledRequest();
223 bool DeleteStalledRequest(ClientSocketHandle* handle);
225 ConnectJobDelegate connect_job_delegate_;
226 std::set<const ClientSocketHandle*> pending_callbacks_;
227 PendingConnectsMap pending_connects_;
228 StalledRequestQueue stalled_request_queue_;
229 StalledRequestMap stalled_request_map_;
230 ClientSocketPoolHistograms* const histograms_;
231 NetLog* const pool_net_log_;
232 ClientSocketFactory* const client_socket_factory_;
233 HostResolver* const host_resolver_;
234 const int max_sockets_;
235 int handed_out_socket_count_;
236 bool flushing_;
238 base::WeakPtrFactory<WebSocketTransportClientSocketPool> weak_factory_;
240 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPool);
243 } // namespace net
245 #endif // NET_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_