Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: net/socket/websocket_transport_client_socket_pool.h

Issue 240873003: Create WebSocketTransportClientSocketPool (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Minor fixes and comment tidying. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_
6 #define NET_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_
7
8 #include <map>
9 #include <set>
10 #include <string>
11
12 #include "base/basictypes.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/time/time.h"
17 #include "base/timer/timer.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/dns/host_resolver.h"
20 #include "net/dns/single_request_host_resolver.h"
21 #include "net/socket/client_socket_pool.h"
22 #include "net/socket/client_socket_pool_base.h"
23 #include "net/socket/client_socket_pool_histograms.h"
24 #include "net/socket/transport_client_socket_pool.h"
25
26 namespace net {
27
28 class ClientSocketFactory;
29
30 typedef base::Callback<int(const AddressList&, const BoundNetLog& net_log)>
31 OnHostResolutionCallback;
32
33 class WebSocketEndpointLockManager;
34
35 // WebSocketTransportConnectJob handles the host resolution necessary for socket
36 // creation and the TCP connect. WebSocketTransportConnectJob
37 // also has fallback logic for IPv6 connect() timeouts (which may happen due to
38 // networks / routers with broken IPv6 support). Those timeouts take 20s, so
39 // rather than make the user wait 20s for the timeout to fire, we use a fallback
40 // timer (kIPv6FallbackTimerInMs) and start a connect() to a IPv4 address if the
41 // timer fires. Then we race the IPv4 connect(s) against the IPv6 connect(s)
42 // and use the socket that completes successfully first or fails last.
43 class NET_EXPORT_PRIVATE WebSocketTransportConnectJob : public ConnectJob {
44 public:
45 WebSocketTransportConnectJob(
46 const std::string& group_name,
47 RequestPriority priority,
48 const scoped_refptr<TransportSocketParams>& params,
49 base::TimeDelta timeout_duration,
50 const CompletionCallback& callback,
51 ClientSocketFactory* client_socket_factory,
52 HostResolver* host_resolver,
53 ClientSocketHandle* handle,
54 Delegate* delegate,
55 NetLog* pool_net_log,
56 const BoundNetLog& request_net_log);
57 virtual ~WebSocketTransportConnectJob();
58
59 // Unlike normal socket pools, the WebSocketTransportClientPool uses
60 // early-binding of sockets.
61 ClientSocketHandle* handle() const { return handle_; }
62
63 // Stash the callback from RequestSocket() here for convenience.
64 const CompletionCallback& callback() const { return callback_; }
65
66 const BoundNetLog& request_net_log() const { return request_net_log_; }
67
68 // ConnectJob methods.
69 virtual LoadState GetLoadState() const OVERRIDE;
70
71 static const int kIPv6FallbackTimerInMs;
72
73 private:
74 class SubJob;
75 friend class SubJob;
76 friend class WebSocketEndpointLockManager;
77
78 enum State {
79 STATE_NONE,
80 STATE_RESOLVE_HOST,
81 STATE_RESOLVE_HOST_COMPLETE,
82 STATE_TRANSPORT_CONNECT,
83 STATE_TRANSPORT_CONNECT_COMPLETE,
84 };
85
86 // Although it is not strictly necessary, it makes the code simpler if each
87 // subjob knows what type it is.
88 enum SubJobType { SUB_JOB_IPV4, SUB_JOB_IPV6 };
89
90 // For recording the connection time in the appropriate bucket.
91 enum ConnectionLatencyHistogram {
92 CONNECTION_LATENCY_UNKNOWN,
93 CONNECTION_LATENCY_IPV4_WINS_RACE,
94 CONNECTION_LATENCY_IPV4_NO_RACE,
95 CONNECTION_LATENCY_IPV6_RACEABLE,
96 CONNECTION_LATENCY_IPV6_SOLO,
97 };
98
99 void OnIOComplete(int result);
100
101 int DoLoop(int result);
102
103 int DoResolveHost();
104 int DoResolveHostComplete(int result);
105 int DoTransportConnect();
106 int DoTransportConnectComplete(int result);
107
108 // Called back from a SubJob when it completes.
109 void OnSubJobComplete(int result, SubJob* job);
110
111 // Called from fallback_timer_
112 void StartIPv4JobAsync();
113
114 // Begins the host resolution and the TCP connect. Returns OK on success
115 // and ERR_IO_PENDING if it cannot immediately service the request.
116 // Otherwise, it returns a net error code.
117 virtual int ConnectInternal() OVERRIDE;
118
119 const scoped_refptr<TransportSocketParams> params_;
120 ClientSocketFactory* const client_socket_factory_;
121 SingleRequestHostResolver resolver_;
122 AddressList addresses_;
123
124 // The addresses are divided into IPv4 and IPv6, which are performed partially
125 // in parallel. If the list of IPv6 addresses is not-empty, then the IPv6 jobs
126 // go first, followed after |kIPv6FallbackTimerInMs| by the IPV4
127 // addresses. First sub-job to establish a connection wins.
128 scoped_ptr<SubJob> ipv4_job_;
129 scoped_ptr<SubJob> ipv6_job_;
130
131 base::OneShotTimer<WebSocketTransportConnectJob> fallback_timer_;
132 ConnectionLatencyHistogram histogram_;
133 ClientSocketHandle* const handle_;
134 CompletionCallback callback_;
135 BoundNetLog request_net_log_;
136 State next_state_;
137
138 bool had_ipv4_;
139 bool had_ipv6_;
140
141 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportConnectJob);
142 };
143
144 class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
145 : public TransportClientSocketPool {
146 public:
147 typedef TransportSocketParams SocketParams;
148
149 WebSocketTransportClientSocketPool(int max_sockets,
150 int max_sockets_per_group,
151 ClientSocketPoolHistograms* histograms,
152 HostResolver* host_resolver,
153 ClientSocketFactory* client_socket_factory,
154 NetLog* net_log);
155
156 virtual ~WebSocketTransportClientSocketPool();
157
158 // Allow another connection to be started to the IPEndPoint that this |handle|
159 // is connected to. Used when the WebSocket handshake completes successfully.
160 static void UnlockEndpoint(ClientSocketHandle* handle);
161
162 // ClientSocketPool implementation.
163 virtual int RequestSocket(const std::string& group_name,
164 const void* resolve_info,
165 RequestPriority priority,
166 ClientSocketHandle* handle,
167 const CompletionCallback& callback,
168 const BoundNetLog& net_log) OVERRIDE;
169 virtual void RequestSockets(const std::string& group_name,
170 const void* params,
171 int num_sockets,
172 const BoundNetLog& net_log) OVERRIDE;
173 virtual void CancelRequest(const std::string& group_name,
174 ClientSocketHandle* handle) OVERRIDE;
175 virtual void ReleaseSocket(const std::string& group_name,
176 scoped_ptr<StreamSocket> socket,
177 int id) OVERRIDE;
178 virtual void FlushWithError(int error) OVERRIDE;
179 virtual void CloseIdleSockets() OVERRIDE;
180 virtual int IdleSocketCount() const OVERRIDE;
181 virtual int IdleSocketCountInGroup(const std::string& group_name) const
182 OVERRIDE;
183 virtual LoadState GetLoadState(const std::string& group_name,
184 const ClientSocketHandle* handle) const
185 OVERRIDE;
186 virtual base::DictionaryValue* GetInfoAsValue(const std::string& name,
187 const std::string& type,
188 bool include_nested_pools) const
189 OVERRIDE;
190 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE;
191 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE;
192
193 // HigherLayeredPool implementation.
194 virtual bool IsStalled() const OVERRIDE;
195 virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE;
196 virtual void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE;
197
198 private:
199 class ConnectJobDelegate : public ConnectJob::Delegate {
200 public:
201 ConnectJobDelegate(WebSocketTransportClientSocketPool* owner);
202 virtual ~ConnectJobDelegate();
203
204 virtual void OnConnectJobComplete(int result, ConnectJob* job) OVERRIDE;
205
206 private:
207 WebSocketTransportClientSocketPool* owner_;
208
209 DISALLOW_COPY_AND_ASSIGN(ConnectJobDelegate);
210 };
211 friend class ConnectJobDelegate;
212 typedef std::map<const ClientSocketHandle*, WebSocketTransportConnectJob*>
213 PendingConnectsMap;
214
215 void OnConnectJobComplete(int result, WebSocketTransportConnectJob* job);
216 void InvokeUserCallbackLater(ClientSocketHandle* handle,
217 const CompletionCallback& callback,
218 int rv);
219 void InvokeUserCallback(ClientSocketHandle* handle,
220 const CompletionCallback& callback,
221 int rv);
222 bool ReachedMaxSocketsLimit() const;
223 void HandOutSocket(scoped_ptr<StreamSocket> socket,
224 const LoadTimingInfo::ConnectTiming& connect_timing,
225 ClientSocketHandle* handle,
226 const BoundNetLog& net_log);
227 void AddJob(ClientSocketHandle* handle,
228 scoped_ptr<WebSocketTransportConnectJob> connect_job);
229 bool DeleteJob(ClientSocketHandle* handle);
230 void CancelJob(ClientSocketHandle* handle);
231 void CancelAllConnectJobs();
232 const WebSocketTransportConnectJob* LookupConnectJob(
233 const ClientSocketHandle* handle) const;
234
235 ConnectJobDelegate connect_job_delegate_;
236 std::set<HigherLayeredPool*> higher_pools_;
237 std::set<const ClientSocketHandle*> pending_callbacks_;
238 PendingConnectsMap pending_connects_;
239 ClientSocketPoolHistograms* const histograms_;
240 NetLog* const pool_net_log_;
241 ClientSocketFactory* const client_socket_factory_;
242 HostResolver* const host_resolver_;
243 const int max_sockets_;
244 int handed_out_socket_count_;
245 bool is_stalled_;
246
247 base::WeakPtrFactory<WebSocketTransportClientSocketPool> weak_factory_;
248
249 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPool);
250 };
251
252 } // namespace net
253
254 #endif // NET_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698