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

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

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « net/socket/tcp_socket_win.cc ('k') | net/socket/transport_client_socket_pool.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_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/profiler/scoped_tracker.h"
14 #include "base/time/time.h"
15 #include "base/timer/timer.h"
16 #include "net/base/host_port_pair.h"
17 #include "net/dns/host_resolver.h"
18 #include "net/dns/single_request_host_resolver.h"
19 #include "net/socket/client_socket_pool.h"
20 #include "net/socket/client_socket_pool_base.h"
21 #include "net/socket/client_socket_pool_histograms.h"
22
23 namespace net {
24
25 class ClientSocketFactory;
26
27 typedef base::Callback<int(const AddressList&, const BoundNetLog& net_log)>
28 OnHostResolutionCallback;
29
30 class NET_EXPORT_PRIVATE TransportSocketParams
31 : public base::RefCounted<TransportSocketParams> {
32 public:
33 // CombineConnectAndWrite currently translates to using TCP FastOpen.
34 // TCP FastOpen should not be used if the first write to the socket may
35 // be non-idempotent, as the underlying socket could retransmit the data
36 // on failure of the first transmission.
37 // NOTE: Currently, COMBINE_CONNECT_AND_WRITE_DESIRED is used if the data in
38 // the write is known to be idempotent, and COMBINE_CONNECT_AND_WRITE_DEFAULT
39 // is used as a default for other cases (including non-idempotent writes).
40 enum CombineConnectAndWritePolicy {
41 COMBINE_CONNECT_AND_WRITE_DEFAULT, // Default policy, implemented in
42 // TransportSocketParams constructor.
43 COMBINE_CONNECT_AND_WRITE_DESIRED, // Combine if supported by socket.
44 COMBINE_CONNECT_AND_WRITE_PROHIBITED // Do not combine.
45 };
46
47 // |host_resolution_callback| will be invoked after the the hostname is
48 // resolved. If |host_resolution_callback| does not return OK, then the
49 // connection will be aborted with that value. |combine_connect_and_write|
50 // defines the policy for use of TCP FastOpen on this socket.
51 TransportSocketParams(
52 const HostPortPair& host_port_pair,
53 bool disable_resolver_cache,
54 bool ignore_limits,
55 const OnHostResolutionCallback& host_resolution_callback,
56 CombineConnectAndWritePolicy combine_connect_and_write);
57
58 const HostResolver::RequestInfo& destination() const { return destination_; }
59 bool ignore_limits() const { return ignore_limits_; }
60 const OnHostResolutionCallback& host_resolution_callback() const {
61 return host_resolution_callback_;
62 }
63
64 CombineConnectAndWritePolicy combine_connect_and_write() const {
65 return combine_connect_and_write_;
66 }
67
68 private:
69 friend class base::RefCounted<TransportSocketParams>;
70 ~TransportSocketParams();
71
72 HostResolver::RequestInfo destination_;
73 bool ignore_limits_;
74 const OnHostResolutionCallback host_resolution_callback_;
75 CombineConnectAndWritePolicy combine_connect_and_write_;
76
77 DISALLOW_COPY_AND_ASSIGN(TransportSocketParams);
78 };
79
80 // Common data and logic shared between TransportConnectJob and
81 // WebSocketTransportConnectJob.
82 class NET_EXPORT_PRIVATE TransportConnectJobHelper {
83 public:
84 enum State {
85 STATE_RESOLVE_HOST,
86 STATE_RESOLVE_HOST_COMPLETE,
87 STATE_TRANSPORT_CONNECT,
88 STATE_TRANSPORT_CONNECT_COMPLETE,
89 STATE_NONE,
90 };
91
92 // For recording the connection time in the appropriate bucket.
93 enum ConnectionLatencyHistogram {
94 CONNECTION_LATENCY_UNKNOWN,
95 CONNECTION_LATENCY_IPV4_WINS_RACE,
96 CONNECTION_LATENCY_IPV4_NO_RACE,
97 CONNECTION_LATENCY_IPV6_RACEABLE,
98 CONNECTION_LATENCY_IPV6_SOLO,
99 };
100
101 TransportConnectJobHelper(const scoped_refptr<TransportSocketParams>& params,
102 ClientSocketFactory* client_socket_factory,
103 HostResolver* host_resolver,
104 LoadTimingInfo::ConnectTiming* connect_timing);
105 ~TransportConnectJobHelper();
106
107 ClientSocketFactory* client_socket_factory() {
108 return client_socket_factory_;
109 }
110
111 const AddressList& addresses() const { return addresses_; }
112 State next_state() const { return next_state_; }
113 void set_next_state(State next_state) { next_state_ = next_state; }
114 CompletionCallback on_io_complete() const { return on_io_complete_; }
115 const TransportSocketParams* params() { return params_.get(); }
116
117 int DoResolveHost(RequestPriority priority, const BoundNetLog& net_log);
118 int DoResolveHostComplete(int result, const BoundNetLog& net_log);
119
120 template <class T>
121 int DoConnectInternal(T* job);
122
123 template <class T>
124 void SetOnIOComplete(T* job);
125
126 template <class T>
127 void OnIOComplete(T* job, int result);
128
129 // Record the histograms Net.DNS_Resolution_And_TCP_Connection_Latency2 and
130 // Net.TCP_Connection_Latency and return the connect duration.
131 base::TimeDelta HistogramDuration(ConnectionLatencyHistogram race_result);
132
133 static const int kIPv6FallbackTimerInMs;
134
135 private:
136 template <class T>
137 int DoLoop(T* job, int result);
138
139 scoped_refptr<TransportSocketParams> params_;
140 ClientSocketFactory* const client_socket_factory_;
141 SingleRequestHostResolver resolver_;
142 AddressList addresses_;
143 State next_state_;
144 CompletionCallback on_io_complete_;
145 LoadTimingInfo::ConnectTiming* connect_timing_;
146
147 DISALLOW_COPY_AND_ASSIGN(TransportConnectJobHelper);
148 };
149
150 // TransportConnectJob handles the host resolution necessary for socket creation
151 // and the transport (likely TCP) connect. TransportConnectJob also has fallback
152 // logic for IPv6 connect() timeouts (which may happen due to networks / routers
153 // with broken IPv6 support). Those timeouts take 20s, so rather than make the
154 // user wait 20s for the timeout to fire, we use a fallback timer
155 // (kIPv6FallbackTimerInMs) and start a connect() to a IPv4 address if the timer
156 // fires. Then we race the IPv4 connect() against the IPv6 connect() (which has
157 // a headstart) and return the one that completes first to the socket pool.
158 class NET_EXPORT_PRIVATE TransportConnectJob : public ConnectJob {
159 public:
160 TransportConnectJob(const std::string& group_name,
161 RequestPriority priority,
162 const scoped_refptr<TransportSocketParams>& params,
163 base::TimeDelta timeout_duration,
164 ClientSocketFactory* client_socket_factory,
165 HostResolver* host_resolver,
166 Delegate* delegate,
167 NetLog* net_log);
168 ~TransportConnectJob() override;
169
170 // ConnectJob methods.
171 LoadState GetLoadState() const override;
172
173 // Rolls |addrlist| forward until the first IPv4 address, if any.
174 // WARNING: this method should only be used to implement the prefer-IPv4 hack.
175 static void MakeAddressListStartWithIPv4(AddressList* addrlist);
176
177 private:
178 enum ConnectInterval {
179 CONNECT_INTERVAL_LE_10MS,
180 CONNECT_INTERVAL_LE_20MS,
181 CONNECT_INTERVAL_GT_20MS,
182 };
183
184 friend class TransportConnectJobHelper;
185
186 int DoResolveHost();
187 int DoResolveHostComplete(int result);
188 int DoTransportConnect();
189 int DoTransportConnectComplete(int result);
190
191 // Not part of the state machine.
192 void DoIPv6FallbackTransportConnect();
193 void DoIPv6FallbackTransportConnectComplete(int result);
194
195 // Begins the host resolution and the TCP connect. Returns OK on success
196 // and ERR_IO_PENDING if it cannot immediately service the request.
197 // Otherwise, it returns a net error code.
198 int ConnectInternal() override;
199
200 TransportConnectJobHelper helper_;
201
202 scoped_ptr<StreamSocket> transport_socket_;
203
204 scoped_ptr<StreamSocket> fallback_transport_socket_;
205 scoped_ptr<AddressList> fallback_addresses_;
206 base::TimeTicks fallback_connect_start_time_;
207 base::OneShotTimer<TransportConnectJob> fallback_timer_;
208
209 // Track the interval between this connect and previous connect.
210 ConnectInterval interval_between_connects_;
211
212 DISALLOW_COPY_AND_ASSIGN(TransportConnectJob);
213 };
214
215 class NET_EXPORT_PRIVATE TransportClientSocketPool : public ClientSocketPool {
216 public:
217 typedef TransportSocketParams SocketParams;
218
219 TransportClientSocketPool(
220 int max_sockets,
221 int max_sockets_per_group,
222 ClientSocketPoolHistograms* histograms,
223 HostResolver* host_resolver,
224 ClientSocketFactory* client_socket_factory,
225 NetLog* net_log);
226
227 ~TransportClientSocketPool() override;
228
229 // ClientSocketPool implementation.
230 int RequestSocket(const std::string& group_name,
231 const void* resolve_info,
232 RequestPriority priority,
233 ClientSocketHandle* handle,
234 const CompletionCallback& callback,
235 const BoundNetLog& net_log) override;
236 void RequestSockets(const std::string& group_name,
237 const void* params,
238 int num_sockets,
239 const BoundNetLog& net_log) override;
240 void CancelRequest(const std::string& group_name,
241 ClientSocketHandle* handle) override;
242 void ReleaseSocket(const std::string& group_name,
243 scoped_ptr<StreamSocket> socket,
244 int id) override;
245 void FlushWithError(int error) override;
246 void CloseIdleSockets() override;
247 int IdleSocketCount() const override;
248 int IdleSocketCountInGroup(const std::string& group_name) const override;
249 LoadState GetLoadState(const std::string& group_name,
250 const ClientSocketHandle* handle) const override;
251 base::DictionaryValue* GetInfoAsValue(
252 const std::string& name,
253 const std::string& type,
254 bool include_nested_pools) const override;
255 base::TimeDelta ConnectionTimeout() const override;
256 ClientSocketPoolHistograms* histograms() const override;
257
258 // HigherLayeredPool implementation.
259 bool IsStalled() const override;
260 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override;
261 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override;
262
263 protected:
264 // Methods shared with WebSocketTransportClientSocketPool
265 void NetLogTcpClientSocketPoolRequestedSocket(
266 const BoundNetLog& net_log,
267 const scoped_refptr<TransportSocketParams>* casted_params);
268
269 private:
270 typedef ClientSocketPoolBase<TransportSocketParams> PoolBase;
271
272 class TransportConnectJobFactory
273 : public PoolBase::ConnectJobFactory {
274 public:
275 TransportConnectJobFactory(ClientSocketFactory* client_socket_factory,
276 HostResolver* host_resolver,
277 NetLog* net_log)
278 : client_socket_factory_(client_socket_factory),
279 host_resolver_(host_resolver),
280 net_log_(net_log) {}
281
282 ~TransportConnectJobFactory() override {}
283
284 // ClientSocketPoolBase::ConnectJobFactory methods.
285
286 scoped_ptr<ConnectJob> NewConnectJob(
287 const std::string& group_name,
288 const PoolBase::Request& request,
289 ConnectJob::Delegate* delegate) const override;
290
291 base::TimeDelta ConnectionTimeout() const override;
292
293 private:
294 ClientSocketFactory* const client_socket_factory_;
295 HostResolver* const host_resolver_;
296 NetLog* net_log_;
297
298 DISALLOW_COPY_AND_ASSIGN(TransportConnectJobFactory);
299 };
300
301 PoolBase base_;
302
303 DISALLOW_COPY_AND_ASSIGN(TransportClientSocketPool);
304 };
305
306 template <class T>
307 int TransportConnectJobHelper::DoConnectInternal(T* job) {
308 next_state_ = STATE_RESOLVE_HOST;
309 return this->DoLoop(job, OK);
310 }
311
312 template <class T>
313 void TransportConnectJobHelper::SetOnIOComplete(T* job) {
314 // These usages of base::Unretained() are safe because IO callbacks are
315 // guaranteed not to be called after the object is destroyed.
316 on_io_complete_ = base::Bind(&TransportConnectJobHelper::OnIOComplete<T>,
317 base::Unretained(this),
318 base::Unretained(job));
319 }
320
321 template <class T>
322 void TransportConnectJobHelper::OnIOComplete(T* job, int result) {
323 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed.
324 tracked_objects::ScopedTracker tracking_profile(
325 FROM_HERE_WITH_EXPLICIT_FUNCTION(
326 "436634 TransportConnectJobHelper::OnIOComplete"));
327
328 result = this->DoLoop(job, result);
329
330 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed.
331 tracked_objects::ScopedTracker tracking_profile1(
332 FROM_HERE_WITH_EXPLICIT_FUNCTION(
333 "436634 TransportConnectJobHelper::OnIOComplete1"));
334
335 if (result != ERR_IO_PENDING)
336 job->NotifyDelegateOfCompletion(result); // Deletes |job| and |this|
337 }
338
339 template <class T>
340 int TransportConnectJobHelper::DoLoop(T* job, int result) {
341 DCHECK_NE(next_state_, STATE_NONE);
342
343 int rv = result;
344 do {
345 State state = next_state_;
346 next_state_ = STATE_NONE;
347 switch (state) {
348 case STATE_RESOLVE_HOST:
349 DCHECK_EQ(OK, rv);
350 rv = job->DoResolveHost();
351 break;
352 case STATE_RESOLVE_HOST_COMPLETE:
353 rv = job->DoResolveHostComplete(rv);
354 break;
355 case STATE_TRANSPORT_CONNECT:
356 DCHECK_EQ(OK, rv);
357 rv = job->DoTransportConnect();
358 break;
359 case STATE_TRANSPORT_CONNECT_COMPLETE:
360 rv = job->DoTransportConnectComplete(rv);
361 break;
362 default:
363 NOTREACHED();
364 rv = ERR_FAILED;
365 break;
366 }
367 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
368
369 return rv;
370 }
371
372 } // namespace net
373
374 #endif // NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_
OLDNEW
« no previous file with comments | « net/socket/tcp_socket_win.cc ('k') | net/socket/transport_client_socket_pool.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698