OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ | 5 #ifndef NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ |
6 #define NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ | 6 #define NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 friend class base::RefCounted<TransportSocketParams>; | 48 friend class base::RefCounted<TransportSocketParams>; |
49 ~TransportSocketParams(); | 49 ~TransportSocketParams(); |
50 | 50 |
51 HostResolver::RequestInfo destination_; | 51 HostResolver::RequestInfo destination_; |
52 bool ignore_limits_; | 52 bool ignore_limits_; |
53 const OnHostResolutionCallback host_resolution_callback_; | 53 const OnHostResolutionCallback host_resolution_callback_; |
54 | 54 |
55 DISALLOW_COPY_AND_ASSIGN(TransportSocketParams); | 55 DISALLOW_COPY_AND_ASSIGN(TransportSocketParams); |
56 }; | 56 }; |
57 | 57 |
58 // Common data and logic shared between TransportConnectJob and | |
59 // WebSocketTransportConnectJob. | |
60 class NET_EXPORT_PRIVATE TransportConnectJobHelper { | |
61 public: | |
62 enum State { | |
63 STATE_RESOLVE_HOST, | |
64 STATE_RESOLVE_HOST_COMPLETE, | |
65 STATE_TRANSPORT_CONNECT, | |
66 STATE_TRANSPORT_CONNECT_COMPLETE, | |
67 STATE_NONE, | |
68 }; | |
69 | |
70 // For recording the connection time in the appropriate bucket. | |
71 enum ConnectionLatencyHistogram { | |
72 CONNECTION_LATENCY_UNKNOWN, | |
73 CONNECTION_LATENCY_IPV4_WINS_RACE, | |
74 CONNECTION_LATENCY_IPV4_NO_RACE, | |
75 CONNECTION_LATENCY_IPV6_RACEABLE, | |
76 CONNECTION_LATENCY_IPV6_SOLO, | |
77 }; | |
78 | |
79 TransportConnectJobHelper(const scoped_refptr<TransportSocketParams>& params, | |
80 ClientSocketFactory* client_socket_factory, | |
81 HostResolver* host_resolver, | |
82 LoadTimingInfo::ConnectTiming* connect_timing); | |
83 ~TransportConnectJobHelper(); | |
84 | |
85 ClientSocketFactory* client_socket_factory() { | |
86 return client_socket_factory_; | |
87 } | |
88 | |
Ryan Sleevi
2014/07/08 18:50:02
This is a huge set of methods to leave public, for
tyoshino (SeeGerritForStatus)
2014/07/09 00:17:40
Sorry about this. I saw use of ClientSocketPoolBas
Ryan Sleevi
2014/07/09 00:20:46
Right, CSPBH is to be a base class for a set of te
| |
89 const AddressList& addresses() const { return addresses_; } | |
90 State next_state() const { return next_state_; } | |
91 void set_next_state(State next_state) { next_state_ = next_state; } | |
92 CompletionCallback on_io_complete() const { return on_io_complete_; } | |
93 | |
94 int DoResolveHost(RequestPriority priority, const BoundNetLog& net_log); | |
95 int DoResolveHostComplete(int result, const BoundNetLog& net_log); | |
96 | |
97 template <class T> | |
98 int DoConnectInternal(T* job); | |
Ryan Sleevi
2014/07/08 18:50:02
These methods are public.
Anyone with a helper ca
Adam Rice
2014/07/09 08:33:02
Sorry, yes, when I wrote this I was just focussed
| |
99 | |
100 template <class T> | |
101 void SetOnIOComplete(T* job); | |
102 | |
103 template <class T> | |
104 void OnIOComplete(T* job, int result); | |
Ryan Sleevi
2014/07/08 18:50:02
Template methods like this are almost always a bad
| |
105 | |
106 // Record the histograms Net.DNS_Resolution_And_TCP_Connection_Latency2 and | |
107 // Net.TCP_Connection_Latency and return the connect duration. | |
108 base::TimeDelta HistogramDuration(ConnectionLatencyHistogram race_result); | |
109 | |
110 static const int kIPv6FallbackTimerInMs; | |
111 | |
112 private: | |
113 template <class T> | |
114 int DoLoop(T* job, int result); | |
115 | |
116 scoped_refptr<TransportSocketParams> params_; | |
117 ClientSocketFactory* const client_socket_factory_; | |
118 SingleRequestHostResolver resolver_; | |
119 AddressList addresses_; | |
120 State next_state_; | |
121 CompletionCallback on_io_complete_; | |
122 LoadTimingInfo::ConnectTiming* connect_timing_; | |
123 | |
124 DISALLOW_COPY_AND_ASSIGN(TransportConnectJobHelper); | |
125 }; | |
126 | |
58 // TransportConnectJob handles the host resolution necessary for socket creation | 127 // TransportConnectJob handles the host resolution necessary for socket creation |
59 // and the transport (likely TCP) connect. TransportConnectJob also has fallback | 128 // and the transport (likely TCP) connect. TransportConnectJob also has fallback |
60 // logic for IPv6 connect() timeouts (which may happen due to networks / routers | 129 // 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 | 130 // 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 | 131 // 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 | 132 // (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 | 133 // 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. | 134 // a headstart) and return the one that completes first to the socket pool. |
66 class NET_EXPORT_PRIVATE TransportConnectJob : public ConnectJob { | 135 class NET_EXPORT_PRIVATE TransportConnectJob : public ConnectJob { |
67 public: | 136 public: |
68 TransportConnectJob(const std::string& group_name, | 137 TransportConnectJob(const std::string& group_name, |
69 RequestPriority priority, | 138 RequestPriority priority, |
70 const scoped_refptr<TransportSocketParams>& params, | 139 const scoped_refptr<TransportSocketParams>& params, |
71 base::TimeDelta timeout_duration, | 140 base::TimeDelta timeout_duration, |
72 ClientSocketFactory* client_socket_factory, | 141 ClientSocketFactory* client_socket_factory, |
73 HostResolver* host_resolver, | 142 HostResolver* host_resolver, |
74 Delegate* delegate, | 143 Delegate* delegate, |
75 NetLog* net_log); | 144 NetLog* net_log); |
76 virtual ~TransportConnectJob(); | 145 virtual ~TransportConnectJob(); |
77 | 146 |
78 // ConnectJob methods. | 147 // ConnectJob methods. |
79 virtual LoadState GetLoadState() const OVERRIDE; | 148 virtual LoadState GetLoadState() const OVERRIDE; |
80 | 149 |
81 // Rolls |addrlist| forward until the first IPv4 address, if any. | 150 // Rolls |addrlist| forward until the first IPv4 address, if any. |
82 // WARNING: this method should only be used to implement the prefer-IPv4 hack. | 151 // WARNING: this method should only be used to implement the prefer-IPv4 hack. |
83 static void MakeAddressListStartWithIPv4(AddressList* addrlist); | 152 static void MakeAddressListStartWithIPv4(AddressList* addrlist); |
84 | 153 |
85 static const int kIPv6FallbackTimerInMs; | |
86 | |
87 private: | 154 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 enum ConnectInterval { | 155 enum ConnectInterval { |
97 CONNECT_INTERVAL_LE_10MS, | 156 CONNECT_INTERVAL_LE_10MS, |
98 CONNECT_INTERVAL_LE_20MS, | 157 CONNECT_INTERVAL_LE_20MS, |
99 CONNECT_INTERVAL_GT_20MS, | 158 CONNECT_INTERVAL_GT_20MS, |
100 }; | 159 }; |
101 | 160 |
102 void OnIOComplete(int result); | 161 friend class TransportConnectJobHelper; |
Ryan Sleevi
2014/07/08 18:50:02
Every time we have a friend class, we have failed
| |
103 | |
104 // Runs the state transition loop. | |
105 int DoLoop(int result); | |
106 | 162 |
107 int DoResolveHost(); | 163 int DoResolveHost(); |
108 int DoResolveHostComplete(int result); | 164 int DoResolveHostComplete(int result); |
109 int DoTransportConnect(); | 165 int DoTransportConnect(); |
110 int DoTransportConnectComplete(int result); | 166 int DoTransportConnectComplete(int result); |
111 | 167 |
112 // Not part of the state machine. | 168 // Not part of the state machine. |
113 void DoIPv6FallbackTransportConnect(); | 169 void DoIPv6FallbackTransportConnect(); |
114 void DoIPv6FallbackTransportConnectComplete(int result); | 170 void DoIPv6FallbackTransportConnectComplete(int result); |
115 | 171 |
116 // Begins the host resolution and the TCP connect. Returns OK on success | 172 // Begins the host resolution and the TCP connect. Returns OK on success |
117 // and ERR_IO_PENDING if it cannot immediately service the request. | 173 // and ERR_IO_PENDING if it cannot immediately service the request. |
118 // Otherwise, it returns a net error code. | 174 // Otherwise, it returns a net error code. |
119 virtual int ConnectInternal() OVERRIDE; | 175 virtual int ConnectInternal() OVERRIDE; |
120 | 176 |
121 scoped_refptr<TransportSocketParams> params_; | 177 TransportConnectJobHelper helper_; |
122 ClientSocketFactory* const client_socket_factory_; | |
123 SingleRequestHostResolver resolver_; | |
124 AddressList addresses_; | |
125 State next_state_; | |
126 | 178 |
127 scoped_ptr<StreamSocket> transport_socket_; | 179 scoped_ptr<StreamSocket> transport_socket_; |
128 | 180 |
129 scoped_ptr<StreamSocket> fallback_transport_socket_; | 181 scoped_ptr<StreamSocket> fallback_transport_socket_; |
130 scoped_ptr<AddressList> fallback_addresses_; | 182 scoped_ptr<AddressList> fallback_addresses_; |
131 base::TimeTicks fallback_connect_start_time_; | 183 base::TimeTicks fallback_connect_start_time_; |
132 base::OneShotTimer<TransportConnectJob> fallback_timer_; | 184 base::OneShotTimer<TransportConnectJob> fallback_timer_; |
133 | 185 |
134 // Track the interval between this connect and previous connect. | 186 // Track the interval between this connect and previous connect. |
135 ConnectInterval interval_between_connects_; | 187 ConnectInterval interval_between_connects_; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 const std::string& type, | 232 const std::string& type, |
181 bool include_nested_pools) const OVERRIDE; | 233 bool include_nested_pools) const OVERRIDE; |
182 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE; | 234 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE; |
183 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE; | 235 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE; |
184 | 236 |
185 // HigherLayeredPool implementation. | 237 // HigherLayeredPool implementation. |
186 virtual bool IsStalled() const OVERRIDE; | 238 virtual bool IsStalled() const OVERRIDE; |
187 virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE; | 239 virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE; |
188 virtual void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE; | 240 virtual void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE; |
189 | 241 |
242 protected: | |
Ryan Sleevi
2014/07/08 18:50:02
The Chromium style guide strongly discourages prot
| |
243 // Methods shared with WebSocketTransportClientSocketPool | |
244 void NetLogTcpClientSocketPoolRequestedSocket( | |
245 const BoundNetLog& net_log, | |
246 const scoped_refptr<TransportSocketParams>* casted_params); | |
Ryan Sleevi
2014/07/08 18:50:02
This doesn't look right at all. A pointer to a con
Adam Rice
2014/07/09 08:33:02
Whereas the void* argument to RequestSocket() is t
| |
247 | |
190 private: | 248 private: |
191 typedef ClientSocketPoolBase<TransportSocketParams> PoolBase; | 249 typedef ClientSocketPoolBase<TransportSocketParams> PoolBase; |
192 | 250 |
193 class TransportConnectJobFactory | 251 class TransportConnectJobFactory |
194 : public PoolBase::ConnectJobFactory { | 252 : public PoolBase::ConnectJobFactory { |
195 public: | 253 public: |
196 TransportConnectJobFactory(ClientSocketFactory* client_socket_factory, | 254 TransportConnectJobFactory(ClientSocketFactory* client_socket_factory, |
197 HostResolver* host_resolver, | 255 HostResolver* host_resolver, |
198 NetLog* net_log) | 256 NetLog* net_log) |
199 : client_socket_factory_(client_socket_factory), | 257 : client_socket_factory_(client_socket_factory), |
(...skipping 17 matching lines...) Expand all Loading... | |
217 NetLog* net_log_; | 275 NetLog* net_log_; |
218 | 276 |
219 DISALLOW_COPY_AND_ASSIGN(TransportConnectJobFactory); | 277 DISALLOW_COPY_AND_ASSIGN(TransportConnectJobFactory); |
220 }; | 278 }; |
221 | 279 |
222 PoolBase base_; | 280 PoolBase base_; |
223 | 281 |
224 DISALLOW_COPY_AND_ASSIGN(TransportClientSocketPool); | 282 DISALLOW_COPY_AND_ASSIGN(TransportClientSocketPool); |
225 }; | 283 }; |
226 | 284 |
285 template <class T> | |
286 int TransportConnectJobHelper::DoConnectInternal(T* job) { | |
287 next_state_ = STATE_RESOLVE_HOST; | |
288 return this->DoLoop(job, OK); | |
289 } | |
290 | |
291 template <class T> | |
292 void TransportConnectJobHelper::SetOnIOComplete(T* job) { | |
293 // These usages of base::Unretained() are safe because IO callbacks are | |
294 // guaranteed not to be called after the object is destroyed. | |
295 on_io_complete_ = base::Bind(&TransportConnectJobHelper::OnIOComplete<T>, | |
296 base::Unretained(this), | |
297 base::Unretained(job)); | |
298 } | |
299 | |
300 template <class T> | |
301 void TransportConnectJobHelper::OnIOComplete(T* job, int result) { | |
302 result = this->DoLoop(job, result); | |
303 if (result != ERR_IO_PENDING) | |
304 job->NotifyDelegateOfCompletion(result); // Deletes |job| and |this| | |
305 } | |
306 | |
307 template <class T> | |
308 int TransportConnectJobHelper::DoLoop(T* job, int result) { | |
309 DCHECK_NE(next_state_, STATE_NONE); | |
310 | |
311 int rv = result; | |
312 do { | |
313 State state = next_state_; | |
314 next_state_ = STATE_NONE; | |
315 switch (state) { | |
316 case STATE_RESOLVE_HOST: | |
317 DCHECK_EQ(OK, rv); | |
318 rv = job->DoResolveHost(); | |
319 break; | |
320 case STATE_RESOLVE_HOST_COMPLETE: | |
321 rv = job->DoResolveHostComplete(rv); | |
322 break; | |
323 case STATE_TRANSPORT_CONNECT: | |
324 DCHECK_EQ(OK, rv); | |
325 rv = job->DoTransportConnect(); | |
326 break; | |
327 case STATE_TRANSPORT_CONNECT_COMPLETE: | |
328 rv = job->DoTransportConnectComplete(rv); | |
329 break; | |
330 default: | |
331 NOTREACHED(); | |
332 rv = ERR_FAILED; | |
333 break; | |
334 } | |
335 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | |
336 | |
337 return rv; | |
338 } | |
339 | |
227 } // namespace net | 340 } // namespace net |
228 | 341 |
229 #endif // NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ | 342 #endif // NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ |
OLD | NEW |