Chromium Code Reviews| 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 |