OLD | NEW |
---|---|
(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/socket/client_socket_pool.h" | |
19 #include "net/socket/client_socket_pool_base.h" | |
20 #include "net/socket/transport_client_socket_pool.h" | |
21 | |
22 namespace net { | |
23 | |
24 class ClientSocketFactory; | |
25 class ClientSocketPoolHistograms; | |
26 class HostResolver; | |
27 class NetLog; | |
28 | |
29 typedef base::Callback<int(const AddressList&, const BoundNetLog& net_log)> | |
30 OnHostResolutionCallback; | |
31 | |
32 class WebSocketEndpointLockManager; | |
33 | |
34 // WebSocketTransportConnectJob handles the host resolution necessary for socket | |
35 // creation and the TCP connect. WebSocketTransportConnectJob | |
36 // also has fallback logic for IPv6 connect() timeouts (which may happen due to | |
37 // networks / routers with broken IPv6 support). Those timeouts take 20s, so | |
38 // rather than make the user wait 20s for the timeout to fire, we use a fallback | |
39 // timer (kIPv6FallbackTimerInMs) and start a connect() to a IPv4 address if the | |
40 // timer fires. Then we race the IPv4 connect(s) against the IPv6 connect(s) | |
41 // and 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(); | |
57 | |
58 // Unlike normal socket pools, the WebSocketTransportClientPool uses | |
59 // early-binding of sockets. | |
60 ClientSocketHandle* handle() const { return handle_; } | |
61 | |
62 // Stash the callback from RequestSocket() here for convenience. | |
63 const CompletionCallback& callback() const { return callback_; } | |
64 | |
65 const BoundNetLog& request_net_log() const { return request_net_log_; } | |
66 | |
67 // ConnectJob methods. | |
68 virtual LoadState GetLoadState() const OVERRIDE; | |
69 | |
70 private: | |
71 class SubJob; | |
72 friend class SubJob; | |
73 friend class TransportConnectJobCommon; | |
74 friend class WebSocketEndpointLockManager; | |
75 | |
76 // Although it is not strictly necessary, it makes the code simpler if each | |
77 // subjob knows what type it is. | |
78 enum SubJobType { SUB_JOB_IPV4, SUB_JOB_IPV6 }; | |
79 | |
80 int DoResolveHost(); | |
81 int DoResolveHostComplete(int result); | |
82 int DoTransportConnect(); | |
83 int DoTransportConnectComplete(int result); | |
84 | |
85 // Called back from a SubJob when it completes. | |
86 void OnSubJobComplete(int result, SubJob* job); | |
87 | |
88 // Called from fallback_timer_ | |
89 void StartIPv4JobAsync(); | |
90 | |
91 // Begins the host resolution and the TCP connect. Returns OK on success | |
92 // and ERR_IO_PENDING if it cannot immediately service the request. | |
93 // Otherwise, it returns a net error code. | |
94 virtual int ConnectInternal() OVERRIDE; | |
95 | |
96 TransportConnectJobCommon data_; | |
97 | |
98 // The addresses are divided into IPv4 and IPv6, which are performed partially | |
99 // in parallel. If the list of IPv6 addresses is non-empty, then the IPv6 jobs | |
100 // go first, followed after |kIPv6FallbackTimerInMs| by the IPV4 | |
101 // addresses. First sub-job to establish a connection wins. | |
102 scoped_ptr<SubJob> ipv4_job_; | |
103 scoped_ptr<SubJob> ipv6_job_; | |
104 | |
105 base::OneShotTimer<WebSocketTransportConnectJob> fallback_timer_; | |
106 TransportConnectJobCommon::ConnectionLatencyHistogram race_result_; | |
107 ClientSocketHandle* const handle_; | |
108 CompletionCallback callback_; | |
109 BoundNetLog request_net_log_; | |
110 | |
111 bool had_ipv4_; | |
112 bool had_ipv6_; | |
113 | |
114 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportConnectJob); | |
115 }; | |
116 | |
117 class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool | |
118 : public TransportClientSocketPool { | |
119 public: | |
120 typedef TransportSocketParams SocketParams; | |
tyoshino (SeeGerritForStatus)
2014/06/11 06:46:45
remove?
Adam Rice
2014/06/11 08:17:09
Done.
| |
121 | |
122 WebSocketTransportClientSocketPool(int max_sockets, | |
123 int max_sockets_per_group, | |
124 ClientSocketPoolHistograms* histograms, | |
125 HostResolver* host_resolver, | |
126 ClientSocketFactory* client_socket_factory, | |
127 NetLog* net_log); | |
128 | |
129 virtual ~WebSocketTransportClientSocketPool(); | |
130 | |
131 // Allow another connection to be started to the IPEndPoint that this |handle| | |
132 // is connected to. Used when the WebSocket handshake completes successfully. | |
133 static void UnlockEndpoint(ClientSocketHandle* handle); | |
134 | |
135 // ClientSocketPool implementation. | |
136 virtual int RequestSocket(const std::string& group_name, | |
137 const void* resolve_info, | |
138 RequestPriority priority, | |
139 ClientSocketHandle* handle, | |
140 const CompletionCallback& callback, | |
141 const BoundNetLog& net_log) OVERRIDE; | |
142 virtual void RequestSockets(const std::string& group_name, | |
143 const void* params, | |
144 int num_sockets, | |
145 const BoundNetLog& net_log) OVERRIDE; | |
146 virtual void CancelRequest(const std::string& group_name, | |
147 ClientSocketHandle* handle) OVERRIDE; | |
148 virtual void ReleaseSocket(const std::string& group_name, | |
149 scoped_ptr<StreamSocket> socket, | |
150 int id) OVERRIDE; | |
151 virtual void FlushWithError(int error) OVERRIDE; | |
152 virtual void CloseIdleSockets() OVERRIDE; | |
153 virtual int IdleSocketCount() const OVERRIDE; | |
154 virtual int IdleSocketCountInGroup(const std::string& group_name) const | |
155 OVERRIDE; | |
156 virtual LoadState GetLoadState(const std::string& group_name, | |
157 const ClientSocketHandle* handle) const | |
158 OVERRIDE; | |
159 virtual base::DictionaryValue* GetInfoAsValue(const std::string& name, | |
160 const std::string& type, | |
161 bool include_nested_pools) const | |
162 OVERRIDE; | |
163 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE; | |
164 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE; | |
165 | |
166 // HigherLayeredPool implementation. | |
167 virtual bool IsStalled() const OVERRIDE; | |
168 virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE; | |
169 virtual void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE; | |
170 | |
171 private: | |
172 class ConnectJobDelegate : public ConnectJob::Delegate { | |
173 public: | |
174 explicit ConnectJobDelegate(WebSocketTransportClientSocketPool* owner); | |
175 virtual ~ConnectJobDelegate(); | |
176 | |
177 virtual void OnConnectJobComplete(int result, ConnectJob* job) OVERRIDE; | |
178 | |
179 private: | |
180 WebSocketTransportClientSocketPool* owner_; | |
181 | |
182 DISALLOW_COPY_AND_ASSIGN(ConnectJobDelegate); | |
183 }; | |
184 friend class ConnectJobDelegate; | |
185 typedef std::map<const ClientSocketHandle*, WebSocketTransportConnectJob*> | |
186 PendingConnectsMap; | |
187 | |
188 void OnConnectJobComplete(int result, WebSocketTransportConnectJob* job); | |
189 void InvokeUserCallbackLater(ClientSocketHandle* handle, | |
190 const CompletionCallback& callback, | |
191 int rv); | |
192 void InvokeUserCallback(ClientSocketHandle* handle, | |
193 const CompletionCallback& callback, | |
194 int rv); | |
195 bool ReachedMaxSocketsLimit() const; | |
196 void HandOutSocket(scoped_ptr<StreamSocket> socket, | |
197 const LoadTimingInfo::ConnectTiming& connect_timing, | |
198 ClientSocketHandle* handle, | |
199 const BoundNetLog& net_log); | |
200 void AddJob(ClientSocketHandle* handle, | |
201 scoped_ptr<WebSocketTransportConnectJob> connect_job); | |
202 bool DeleteJob(ClientSocketHandle* handle); | |
203 void CancelJob(ClientSocketHandle* handle); | |
204 void CancelAllConnectJobs(); | |
205 const WebSocketTransportConnectJob* LookupConnectJob( | |
206 const ClientSocketHandle* handle) const; | |
207 | |
208 ConnectJobDelegate connect_job_delegate_; | |
209 std::set<HigherLayeredPool*> higher_pools_; | |
210 std::set<const ClientSocketHandle*> pending_callbacks_; | |
211 PendingConnectsMap pending_connects_; | |
212 ClientSocketPoolHistograms* const histograms_; | |
213 NetLog* const pool_net_log_; | |
214 ClientSocketFactory* const client_socket_factory_; | |
215 HostResolver* const host_resolver_; | |
216 const int max_sockets_; | |
217 int handed_out_socket_count_; | |
218 bool is_stalled_; | |
219 | |
220 base::WeakPtrFactory<WebSocketTransportClientSocketPool> weak_factory_; | |
221 | |
222 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPool); | |
223 }; | |
224 | |
225 } // namespace net | |
226 | |
227 #endif // NET_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ | |
OLD | NEW |