| OLD | NEW | 
|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "net/socket/ssl_client_socket_pool.h" | 5 #include "net/socket/ssl_client_socket_pool.h" | 
| 6 | 6 | 
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" | 
| 8 #include "base/values.h" | 8 #include "base/values.h" | 
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" | 
|  | 10 #include "net/base/host_port_pair.h" | 
| 10 #include "net/base/ssl_cert_request_info.h" | 11 #include "net/base/ssl_cert_request_info.h" | 
| 11 #include "net/http/http_proxy_client_socket.h" | 12 #include "net/http/http_proxy_client_socket.h" | 
| 12 #include "net/http/http_proxy_client_socket_pool.h" | 13 #include "net/http/http_proxy_client_socket_pool.h" | 
| 13 #include "net/socket/client_socket_factory.h" | 14 #include "net/socket/client_socket_factory.h" | 
| 14 #include "net/socket/client_socket_handle.h" | 15 #include "net/socket/client_socket_handle.h" | 
| 15 #include "net/socket/socks_client_socket_pool.h" | 16 #include "net/socket/socks_client_socket_pool.h" | 
| 16 #include "net/socket/ssl_client_socket.h" | 17 #include "net/socket/ssl_client_socket.h" | 
| 17 #include "net/socket/ssl_host_info.h" | 18 #include "net/socket/ssl_host_info.h" | 
| 18 #include "net/socket/tcp_client_socket_pool.h" | 19 #include "net/socket/tcp_client_socket_pool.h" | 
| 19 | 20 | 
| 20 namespace net { | 21 namespace net { | 
| 21 | 22 | 
| 22 SSLSocketParams::SSLSocketParams( | 23 SSLSocketParams::SSLSocketParams( | 
| 23     const scoped_refptr<TCPSocketParams>& tcp_params, | 24     const scoped_refptr<TCPSocketParams>& tcp_params, | 
| 24     const scoped_refptr<SOCKSSocketParams>& socks_params, | 25     const scoped_refptr<SOCKSSocketParams>& socks_params, | 
| 25     const scoped_refptr<HttpProxySocketParams>& http_proxy_params, | 26     const scoped_refptr<HttpProxySocketParams>& http_proxy_params, | 
| 26     ProxyServer::Scheme proxy, | 27     ProxyServer::Scheme proxy, | 
| 27     const std::string& hostname, | 28     const HostPortPair& host_and_port, | 
| 28     const SSLConfig& ssl_config, | 29     const SSLConfig& ssl_config, | 
| 29     int load_flags, | 30     int load_flags, | 
| 30     bool force_spdy_over_ssl, | 31     bool force_spdy_over_ssl, | 
| 31     bool want_spdy_over_npn) | 32     bool want_spdy_over_npn) | 
| 32     : tcp_params_(tcp_params), | 33     : tcp_params_(tcp_params), | 
| 33       http_proxy_params_(http_proxy_params), | 34       http_proxy_params_(http_proxy_params), | 
| 34       socks_params_(socks_params), | 35       socks_params_(socks_params), | 
| 35       proxy_(proxy), | 36       proxy_(proxy), | 
| 36       hostname_(hostname), | 37       host_and_port_(host_and_port), | 
| 37       ssl_config_(ssl_config), | 38       ssl_config_(ssl_config), | 
| 38       load_flags_(load_flags), | 39       load_flags_(load_flags), | 
| 39       force_spdy_over_ssl_(force_spdy_over_ssl), | 40       force_spdy_over_ssl_(force_spdy_over_ssl), | 
| 40       want_spdy_over_npn_(want_spdy_over_npn) { | 41       want_spdy_over_npn_(want_spdy_over_npn) { | 
| 41   switch (proxy_) { | 42   switch (proxy_) { | 
| 42     case ProxyServer::SCHEME_DIRECT: | 43     case ProxyServer::SCHEME_DIRECT: | 
| 43       DCHECK(tcp_params_.get() != NULL); | 44       DCHECK(tcp_params_.get() != NULL); | 
| 44       DCHECK(http_proxy_params_.get() == NULL); | 45       DCHECK(http_proxy_params_.get() == NULL); | 
| 45       DCHECK(socks_params_.get() == NULL); | 46       DCHECK(socks_params_.get() == NULL); | 
| 46       break; | 47       break; | 
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 186   } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 187   } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 
| 187 | 188 | 
| 188   return rv; | 189   return rv; | 
| 189 } | 190 } | 
| 190 | 191 | 
| 191 int SSLConnectJob::DoTCPConnect() { | 192 int SSLConnectJob::DoTCPConnect() { | 
| 192   DCHECK(tcp_pool_); | 193   DCHECK(tcp_pool_); | 
| 193 | 194 | 
| 194   if (ssl_host_info_factory_ && SSLConfigService::snap_start_enabled()) { | 195   if (ssl_host_info_factory_ && SSLConfigService::snap_start_enabled()) { | 
| 195       ssl_host_info_.reset( | 196       ssl_host_info_.reset( | 
| 196           ssl_host_info_factory_->GetForHost(params_->hostname(), | 197           ssl_host_info_factory_->GetForHost(params_->host_and_port().host(), | 
| 197                                              params_->ssl_config())); | 198                                              params_->ssl_config())); | 
| 198   } | 199   } | 
| 199   if (ssl_host_info_.get()) { | 200   if (ssl_host_info_.get()) { | 
| 200     // This starts fetching the SSL host info from the disk cache for Snap | 201     // This starts fetching the SSL host info from the disk cache for Snap | 
| 201     // Start. | 202     // Start. | 
| 202     ssl_host_info_->Start(); | 203     ssl_host_info_->Start(); | 
| 203   } | 204   } | 
| 204 | 205 | 
| 205   next_state_ = STATE_TCP_CONNECT_COMPLETE; | 206   next_state_ = STATE_TCP_CONNECT_COMPLETE; | 
| 206   transport_socket_handle_.reset(new ClientSocketHandle()); | 207   transport_socket_handle_.reset(new ClientSocketHandle()); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 241   transport_socket_handle_.reset(new ClientSocketHandle()); | 242   transport_socket_handle_.reset(new ClientSocketHandle()); | 
| 242   scoped_refptr<HttpProxySocketParams> http_proxy_params = | 243   scoped_refptr<HttpProxySocketParams> http_proxy_params = | 
| 243       params_->http_proxy_params(); | 244       params_->http_proxy_params(); | 
| 244   return transport_socket_handle_->Init( | 245   return transport_socket_handle_->Init( | 
| 245       group_name(), http_proxy_params, | 246       group_name(), http_proxy_params, | 
| 246       http_proxy_params->destination().priority(), &callback_, | 247       http_proxy_params->destination().priority(), &callback_, | 
| 247       http_proxy_pool_, net_log()); | 248       http_proxy_pool_, net_log()); | 
| 248 } | 249 } | 
| 249 | 250 | 
| 250 int SSLConnectJob::DoTunnelConnectComplete(int result) { | 251 int SSLConnectJob::DoTunnelConnectComplete(int result) { | 
| 251   ClientSocket* socket = transport_socket_handle_->socket(); | 252   // Extract the information needed to prompt for appropriate proxy | 
| 252   HttpProxyClientSocket* tunnel_socket = | 253   // authentication so that when ClientSocketPoolBaseHelper calls | 
| 253       static_cast<HttpProxyClientSocket*>(socket); | 254   // |GetAdditionalErrorState|, we can easily set the state. | 
| 254 | 255   if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 
| 255   // Extract the information needed to prompt for the proxy authentication. | 256     error_response_info_ = transport_socket_handle_->ssl_error_response_info(); | 
| 256   // so that when ClientSocketPoolBaseHelper calls |GetAdditionalErrorState|, | 257   } else if (result == ERR_PROXY_AUTH_REQUESTED) { | 
| 257   // we can easily set the state. | 258     ClientSocket* socket = transport_socket_handle_->socket(); | 
| 258   if (result == ERR_PROXY_AUTH_REQUESTED) | 259     HttpProxyClientSocket* tunnel_socket = | 
|  | 260         static_cast<HttpProxyClientSocket*>(socket); | 
| 259     error_response_info_ = *tunnel_socket->GetResponseInfo(); | 261     error_response_info_ = *tunnel_socket->GetResponseInfo(); | 
| 260 | 262   } | 
| 261   if (result < 0) | 263   if (result < 0) | 
| 262     return result; | 264     return result; | 
| 263 | 265 | 
| 264   next_state_ = STATE_SSL_CONNECT; | 266   next_state_ = STATE_SSL_CONNECT; | 
| 265   return result; | 267   return result; | 
| 266 } | 268 } | 
| 267 | 269 | 
| 268 void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) { | 270 void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) { | 
| 269   // Headers in |error_response_info_| indicate a proxy tunnel setup | 271   // Headers in |error_response_info_| indicate a proxy tunnel setup | 
| 270   // problem. See DoTunnelConnectComplete. | 272   // problem. See DoTunnelConnectComplete. | 
| 271   if (error_response_info_.headers) { | 273   if (error_response_info_.headers) { | 
| 272     handle->set_pending_http_proxy_connection( | 274     handle->set_pending_http_proxy_connection( | 
| 273         transport_socket_handle_.release()); | 275         transport_socket_handle_.release()); | 
| 274   } | 276   } | 
| 275   handle->set_ssl_error_response_info(error_response_info_); | 277   handle->set_ssl_error_response_info(error_response_info_); | 
| 276   if (!ssl_connect_start_time_.is_null()) | 278   if (!ssl_connect_start_time_.is_null()) | 
| 277     handle->set_is_ssl_error(true); | 279     handle->set_is_ssl_error(true); | 
| 278 } | 280 } | 
| 279 | 281 | 
| 280 int SSLConnectJob::DoSSLConnect() { | 282 int SSLConnectJob::DoSSLConnect() { | 
| 281   next_state_ = STATE_SSL_CONNECT_COMPLETE; | 283   next_state_ = STATE_SSL_CONNECT_COMPLETE; | 
| 282   // Reset the timeout to just the time allowed for the SSL handshake. | 284   // Reset the timeout to just the time allowed for the SSL handshake. | 
| 283   ResetTimer(base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds)); | 285   ResetTimer(base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds)); | 
| 284   ssl_connect_start_time_ = base::TimeTicks::Now(); | 286   ssl_connect_start_time_ = base::TimeTicks::Now(); | 
| 285 | 287 | 
| 286   ssl_socket_.reset(client_socket_factory_->CreateSSLClientSocket( | 288   ssl_socket_.reset(client_socket_factory_->CreateSSLClientSocket( | 
| 287         transport_socket_handle_.release(), params_->hostname(), | 289       transport_socket_handle_.release(), params_->host_and_port(), | 
| 288         params_->ssl_config(), ssl_host_info_.release(), | 290       params_->ssl_config(), ssl_host_info_.release(), dnsrr_resolver_)); | 
| 289         dnsrr_resolver_)); |  | 
| 290   return ssl_socket_->Connect(&callback_); | 291   return ssl_socket_->Connect(&callback_); | 
| 291 } | 292 } | 
| 292 | 293 | 
| 293 int SSLConnectJob::DoSSLConnectComplete(int result) { | 294 int SSLConnectJob::DoSSLConnectComplete(int result) { | 
| 294   SSLClientSocket::NextProtoStatus status = | 295   SSLClientSocket::NextProtoStatus status = | 
| 295       SSLClientSocket::kNextProtoUnsupported; | 296       SSLClientSocket::kNextProtoUnsupported; | 
| 296   std::string proto; | 297   std::string proto; | 
| 297   // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket | 298   // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket | 
| 298   // that hasn't had SSL_ImportFD called on it. If we get a certificate error | 299   // that hasn't had SSL_ImportFD called on it. If we get a certificate error | 
| 299   // here, then we know that we called SSL_ImportFD. | 300   // here, then we know that we called SSL_ImportFD. | 
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 507       list->Append(http_proxy_pool_->GetInfoAsValue("http_proxy_pool", | 508       list->Append(http_proxy_pool_->GetInfoAsValue("http_proxy_pool", | 
| 508                                                     "http_proxy_pool", | 509                                                     "http_proxy_pool", | 
| 509                                                     true)); | 510                                                     true)); | 
| 510     } | 511     } | 
| 511     dict->Set("nested_pools", list); | 512     dict->Set("nested_pools", list); | 
| 512   } | 513   } | 
| 513   return dict; | 514   return dict; | 
| 514 } | 515 } | 
| 515 | 516 | 
| 516 }  // namespace net | 517 }  // namespace net | 
| OLD | NEW | 
|---|