OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // TODO(ukai): code is similar with http_network_transaction.cc. We should | 5 // TODO(ukai): code is similar with http_network_transaction.cc. We should |
6 // think about ways to share code, if possible. | 6 // think about ways to share code, if possible. |
7 | 7 |
8 #include "net/socket_stream/socket_stream.h" | 8 #include "net/socket_stream/socket_stream.h" |
9 | 9 |
10 #include <set> | 10 #include <set> |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 Delegate* delegate = delegate_; | 297 Delegate* delegate = delegate_; |
298 delegate_ = NULL; | 298 delegate_ = NULL; |
299 if (delegate) { | 299 if (delegate) { |
300 delegate->OnError(this, result); | 300 delegate->OnError(this, result); |
301 if (result != ERR_PROTOCOL_SWITCHED) | 301 if (result != ERR_PROTOCOL_SWITCHED) |
302 delegate->OnClose(this); | 302 delegate->OnClose(this); |
303 } | 303 } |
304 Release(); | 304 Release(); |
305 } | 305 } |
306 | 306 |
307 int SocketStream::DidEstablishSSL(int result) { | |
308 if (IsCertificateError(result)) { | |
309 if (socket_->IsConnectedAndIdle()) { | |
310 result = HandleCertificateError(result); | |
311 } else { | |
312 // SSLClientSocket for Mac will report socket is not connected, | |
313 // if it returns cert verification error. It didn't perform | |
314 // SSLHandshake yet. | |
315 // So, we should restart establishing connection with the | |
316 // certificate in allowed bad certificates in |ssl_config_|. | |
317 // See also net/http/http_network_transaction.cc | |
318 // HandleCertificateError() and RestartIgnoringLastError(). | |
319 SSLClientSocket* ssl_socket = | |
320 reinterpret_cast<SSLClientSocket*>(socket_.get()); | |
321 SSLInfo ssl_info; | |
322 ssl_socket->GetSSLInfo(&ssl_info); | |
323 if (ssl_info.cert == NULL || | |
324 ssl_config_.IsAllowedBadCert(ssl_info.cert, NULL)) { | |
325 // If we already have the certificate in the set of allowed bad | |
326 // certificates, we did try it and failed again, so we should not | |
327 // retry again: the connection should fail at last. | |
328 next_state_ = STATE_CLOSE; | |
329 return result; | |
330 } | |
331 // Add the bad certificate to the set of allowed certificates in the | |
332 // SSL config object. | |
333 SSLConfig::CertAndStatus bad_cert; | |
334 if (!ssl_info.cert->GetDEREncoded(&bad_cert.der_cert)) { | |
335 next_state_ = STATE_CLOSE; | |
336 return result; | |
337 } | |
338 bad_cert.cert_status = ssl_info.cert_status; | |
339 ssl_config_.allowed_bad_certs.push_back(bad_cert); | |
340 // Restart connection ignoring the bad certificate. | |
341 socket_->Disconnect(); | |
342 socket_.reset(); | |
343 next_state_ = STATE_TCP_CONNECT; | |
344 return OK; | |
345 } | |
346 } | |
347 return result; | |
348 } | |
349 | |
350 int SocketStream::DidEstablishConnection() { | 307 int SocketStream::DidEstablishConnection() { |
351 if (!socket_.get() || !socket_->IsConnected()) { | 308 if (!socket_.get() || !socket_->IsConnected()) { |
352 next_state_ = STATE_CLOSE; | 309 next_state_ = STATE_CLOSE; |
353 return ERR_CONNECTION_FAILED; | 310 return ERR_CONNECTION_FAILED; |
354 } | 311 } |
355 next_state_ = STATE_READ_WRITE; | 312 next_state_ = STATE_READ_WRITE; |
356 metrics_->OnConnected(); | 313 metrics_->OnConnected(); |
357 | 314 |
358 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); | 315 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); |
359 if (delegate_) | 316 if (delegate_) |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 case STATE_READ_TUNNEL_HEADERS_COMPLETE: | 433 case STATE_READ_TUNNEL_HEADERS_COMPLETE: |
477 result = DoReadTunnelHeadersComplete(result); | 434 result = DoReadTunnelHeadersComplete(result); |
478 break; | 435 break; |
479 case STATE_SOCKS_CONNECT: | 436 case STATE_SOCKS_CONNECT: |
480 DCHECK_EQ(OK, result); | 437 DCHECK_EQ(OK, result); |
481 result = DoSOCKSConnect(); | 438 result = DoSOCKSConnect(); |
482 break; | 439 break; |
483 case STATE_SOCKS_CONNECT_COMPLETE: | 440 case STATE_SOCKS_CONNECT_COMPLETE: |
484 result = DoSOCKSConnectComplete(result); | 441 result = DoSOCKSConnectComplete(result); |
485 break; | 442 break; |
486 case STATE_SECURE_PROXY_CONNECT: | |
487 DCHECK_EQ(OK, result); | |
488 result = DoSecureProxyConnect(); | |
489 break; | |
490 case STATE_SECURE_PROXY_CONNECT_COMPLETE: | |
491 result = DoSecureProxyConnectComplete(result); | |
492 break; | |
493 case STATE_SSL_CONNECT: | 443 case STATE_SSL_CONNECT: |
494 DCHECK_EQ(OK, result); | 444 DCHECK_EQ(OK, result); |
495 result = DoSSLConnect(); | 445 result = DoSSLConnect(); |
496 break; | 446 break; |
497 case STATE_SSL_CONNECT_COMPLETE: | 447 case STATE_SSL_CONNECT_COMPLETE: |
498 result = DoSSLConnectComplete(result); | 448 result = DoSSLConnectComplete(result); |
499 break; | 449 break; |
500 case STATE_READ_WRITE: | 450 case STATE_READ_WRITE: |
501 result = DoReadWrite(result); | 451 result = DoReadWrite(result); |
502 break; | 452 break; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 return socket_->Connect(&io_callback_); | 609 return socket_->Connect(&io_callback_); |
660 } | 610 } |
661 | 611 |
662 int SocketStream::DoTcpConnectComplete(int result) { | 612 int SocketStream::DoTcpConnectComplete(int result) { |
663 // TODO(ukai): if error occured, reconsider proxy after error. | 613 // TODO(ukai): if error occured, reconsider proxy after error. |
664 if (result != OK) { | 614 if (result != OK) { |
665 next_state_ = STATE_CLOSE; | 615 next_state_ = STATE_CLOSE; |
666 return result; | 616 return result; |
667 } | 617 } |
668 | 618 |
669 if (proxy_mode_ == kTunnelProxy) { | 619 if (proxy_mode_ == kTunnelProxy) |
670 if (proxy_info_.is_https()) | 620 next_state_ = STATE_WRITE_TUNNEL_HEADERS; |
671 next_state_ = STATE_SECURE_PROXY_CONNECT; | 621 else if (proxy_mode_ == kSOCKSProxy) |
672 else | |
673 next_state_ = STATE_WRITE_TUNNEL_HEADERS; | |
674 } else if (proxy_mode_ == kSOCKSProxy) { | |
675 next_state_ = STATE_SOCKS_CONNECT; | 622 next_state_ = STATE_SOCKS_CONNECT; |
676 } else if (is_secure()) { | 623 else if (is_secure()) { |
677 next_state_ = STATE_SSL_CONNECT; | 624 next_state_ = STATE_SSL_CONNECT; |
678 } else { | 625 } else { |
679 result = DidEstablishConnection(); | 626 result = DidEstablishConnection(); |
680 } | 627 } |
681 return result; | 628 return result; |
682 } | 629 } |
683 | 630 |
684 int SocketStream::DoWriteTunnelHeaders() { | 631 int SocketStream::DoWriteTunnelHeaders() { |
685 DCHECK_EQ(kTunnelProxy, proxy_mode_); | 632 DCHECK_EQ(kTunnelProxy, proxy_mode_); |
686 | 633 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 if (is_secure()) | 843 if (is_secure()) |
897 next_state_ = STATE_SSL_CONNECT; | 844 next_state_ = STATE_SSL_CONNECT; |
898 else | 845 else |
899 result = DidEstablishConnection(); | 846 result = DidEstablishConnection(); |
900 } else { | 847 } else { |
901 next_state_ = STATE_CLOSE; | 848 next_state_ = STATE_CLOSE; |
902 } | 849 } |
903 return result; | 850 return result; |
904 } | 851 } |
905 | 852 |
906 int SocketStream::DoSecureProxyConnect() { | |
907 DCHECK(factory_); | |
908 SSLClientSocketContext ssl_context; | |
909 ssl_context.cert_verifier = cert_verifier_; | |
910 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; | |
911 // TODO(agl): look into plumbing SSLHostInfo here. | |
912 socket_.reset(factory_->CreateSSLClientSocket( | |
913 socket_.release(), | |
914 proxy_info_.proxy_server().host_port_pair(), | |
915 ssl_config_, | |
916 NULL /* ssl_host_info */, | |
917 ssl_context)); | |
918 next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE; | |
919 metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION); | |
920 return socket_->Connect(&io_callback_); | |
921 } | |
922 | |
923 int SocketStream::DoSecureProxyConnectComplete(int result) { | |
924 DCHECK_EQ(STATE_NONE, next_state_); | |
925 result = DidEstablishSSL(result); | |
926 if (next_state_ != STATE_NONE) | |
927 return result; | |
928 if (result == OK) | |
929 next_state_ = STATE_WRITE_TUNNEL_HEADERS; | |
930 else | |
931 next_state_ = STATE_CLOSE; | |
932 return result; | |
933 } | |
934 | |
935 int SocketStream::DoSSLConnect() { | 853 int SocketStream::DoSSLConnect() { |
936 DCHECK(factory_); | 854 DCHECK(factory_); |
937 SSLClientSocketContext ssl_context; | 855 SSLClientSocketContext ssl_context; |
938 ssl_context.cert_verifier = cert_verifier_; | 856 ssl_context.cert_verifier = cert_verifier_; |
939 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; | 857 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; |
940 // TODO(agl): look into plumbing SSLHostInfo here. | 858 // TODO(agl): look into plumbing SSLHostInfo here. |
941 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), | 859 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), |
942 HostPortPair::FromURL(url_), | 860 HostPortPair::FromURL(url_), |
943 ssl_config_, | 861 ssl_config_, |
944 NULL /* ssl_host_info */, | 862 NULL /* ssl_host_info */, |
945 ssl_context)); | 863 ssl_context)); |
946 next_state_ = STATE_SSL_CONNECT_COMPLETE; | 864 next_state_ = STATE_SSL_CONNECT_COMPLETE; |
947 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION); | 865 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION); |
948 return socket_->Connect(&io_callback_); | 866 return socket_->Connect(&io_callback_); |
949 } | 867 } |
950 | 868 |
951 int SocketStream::DoSSLConnectComplete(int result) { | 869 int SocketStream::DoSSLConnectComplete(int result) { |
952 DCHECK_EQ(STATE_NONE, next_state_); | 870 if (IsCertificateError(result)) { |
953 result = DidEstablishSSL(result); | 871 if (socket_->IsConnectedAndIdle()) { |
954 if (next_state_ != STATE_NONE) | 872 result = HandleCertificateError(result); |
955 return result; | 873 } else { |
| 874 // SSLClientSocket for Mac will report socket is not connected, |
| 875 // if it returns cert verification error. It didn't perform |
| 876 // SSLHandshake yet. |
| 877 // So, we should restart establishing connection with the |
| 878 // certificate in allowed bad certificates in |ssl_config_|. |
| 879 // See also net/http/http_network_transaction.cc |
| 880 // HandleCertificateError() and RestartIgnoringLastError(). |
| 881 SSLClientSocket* ssl_socket = |
| 882 reinterpret_cast<SSLClientSocket*>(socket_.get()); |
| 883 SSLInfo ssl_info; |
| 884 ssl_socket->GetSSLInfo(&ssl_info); |
| 885 if (ssl_info.cert == NULL || |
| 886 ssl_config_.IsAllowedBadCert(ssl_info.cert, NULL)) { |
| 887 // If we already have the certificate in the set of allowed bad |
| 888 // certificates, we did try it and failed again, so we should not |
| 889 // retry again: the connection should fail at last. |
| 890 next_state_ = STATE_CLOSE; |
| 891 return result; |
| 892 } |
| 893 // Add the bad certificate to the set of allowed certificates in the |
| 894 // SSL config object. |
| 895 SSLConfig::CertAndStatus bad_cert; |
| 896 if (!ssl_info.cert->GetDEREncoded(&bad_cert.der_cert)) { |
| 897 next_state_ = STATE_CLOSE; |
| 898 return result; |
| 899 } |
| 900 bad_cert.cert_status = ssl_info.cert_status; |
| 901 ssl_config_.allowed_bad_certs.push_back(bad_cert); |
| 902 // Restart connection ignoring the bad certificate. |
| 903 socket_->Disconnect(); |
| 904 socket_.reset(); |
| 905 next_state_ = STATE_TCP_CONNECT; |
| 906 return OK; |
| 907 } |
| 908 } |
| 909 |
956 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible. | 910 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible. |
957 // If we use HTTPS and this is the first connection to the SPDY server, | 911 // If we use HTTPS and this is the first connection to the SPDY server, |
958 // we should take care of TLS NPN extension here. | 912 // we should take care of TLS NPN extension here. |
959 | 913 |
960 if (result == OK) | 914 if (result == OK) |
961 result = DidEstablishConnection(); | 915 result = DidEstablishConnection(); |
962 else | 916 else |
963 next_state_ = STATE_CLOSE; | 917 next_state_ = STATE_CLOSE; |
964 return result; | 918 return result; |
965 } | 919 } |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 | 1087 |
1134 SSLConfigService* SocketStream::ssl_config_service() const { | 1088 SSLConfigService* SocketStream::ssl_config_service() const { |
1135 return context_->ssl_config_service(); | 1089 return context_->ssl_config_service(); |
1136 } | 1090 } |
1137 | 1091 |
1138 ProxyService* SocketStream::proxy_service() const { | 1092 ProxyService* SocketStream::proxy_service() const { |
1139 return context_->proxy_service(); | 1093 return context_->proxy_service(); |
1140 } | 1094 } |
1141 | 1095 |
1142 } // namespace net | 1096 } // namespace net |
OLD | NEW |