| 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 |
| 307 int SocketStream::DidEstablishConnection() { | 350 int SocketStream::DidEstablishConnection() { |
| 308 if (!socket_.get() || !socket_->IsConnected()) { | 351 if (!socket_.get() || !socket_->IsConnected()) { |
| 309 next_state_ = STATE_CLOSE; | 352 next_state_ = STATE_CLOSE; |
| 310 return ERR_CONNECTION_FAILED; | 353 return ERR_CONNECTION_FAILED; |
| 311 } | 354 } |
| 312 next_state_ = STATE_READ_WRITE; | 355 next_state_ = STATE_READ_WRITE; |
| 313 metrics_->OnConnected(); | 356 metrics_->OnConnected(); |
| 314 | 357 |
| 315 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); | 358 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); |
| 316 if (delegate_) | 359 if (delegate_) |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 case STATE_READ_TUNNEL_HEADERS_COMPLETE: | 476 case STATE_READ_TUNNEL_HEADERS_COMPLETE: |
| 434 result = DoReadTunnelHeadersComplete(result); | 477 result = DoReadTunnelHeadersComplete(result); |
| 435 break; | 478 break; |
| 436 case STATE_SOCKS_CONNECT: | 479 case STATE_SOCKS_CONNECT: |
| 437 DCHECK_EQ(OK, result); | 480 DCHECK_EQ(OK, result); |
| 438 result = DoSOCKSConnect(); | 481 result = DoSOCKSConnect(); |
| 439 break; | 482 break; |
| 440 case STATE_SOCKS_CONNECT_COMPLETE: | 483 case STATE_SOCKS_CONNECT_COMPLETE: |
| 441 result = DoSOCKSConnectComplete(result); | 484 result = DoSOCKSConnectComplete(result); |
| 442 break; | 485 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; |
| 443 case STATE_SSL_CONNECT: | 493 case STATE_SSL_CONNECT: |
| 444 DCHECK_EQ(OK, result); | 494 DCHECK_EQ(OK, result); |
| 445 result = DoSSLConnect(); | 495 result = DoSSLConnect(); |
| 446 break; | 496 break; |
| 447 case STATE_SSL_CONNECT_COMPLETE: | 497 case STATE_SSL_CONNECT_COMPLETE: |
| 448 result = DoSSLConnectComplete(result); | 498 result = DoSSLConnectComplete(result); |
| 449 break; | 499 break; |
| 450 case STATE_READ_WRITE: | 500 case STATE_READ_WRITE: |
| 451 result = DoReadWrite(result); | 501 result = DoReadWrite(result); |
| 452 break; | 502 break; |
| 453 case STATE_AUTH_REQUIRED: | 503 case STATE_AUTH_REQUIRED: |
| 454 // It might be called when DoClose is called while waiting in | 504 // It might be called when DoClose is called while waiting in |
| 455 // STATE_AUTH_REQUIRED. | 505 // STATE_AUTH_REQUIRED. |
| 456 Finish(result); | 506 Finish(result); |
| 457 return; | 507 return; |
| 458 case STATE_CLOSE: | 508 case STATE_CLOSE: |
| 459 DCHECK_LE(result, OK); | 509 DCHECK_LE(result, OK); |
| 460 Finish(result); | 510 Finish(result); |
| 461 return; | 511 return; |
| 462 default: | 512 default: |
| 463 NOTREACHED() << "bad state " << state; | 513 NOTREACHED() << "bad state " << state; |
| 464 Finish(result); | 514 Finish(result); |
| 465 return; | 515 return; |
| 466 } | 516 } |
| 467 if (state == STATE_RESOLVE_PROTOCOL && result == ERR_PROTOCOL_SWITCHED) | 517 if (state == STATE_RESOLVE_PROTOCOL && result == ERR_PROTOCOL_SWITCHED) |
| 468 continue; | 518 continue; |
| 469 // If the connection is not established yet and had actual errors, | 519 // If the connection is not established yet and had actual errors, |
| 470 // close the connection. | 520 // record the error. In next iteration, it will close the connection. |
| 471 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) { | 521 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) { |
| 472 DCHECK_EQ(next_state_, STATE_CLOSE); | |
| 473 net_log_.EndEventWithNetErrorCode( | 522 net_log_.EndEventWithNetErrorCode( |
| 474 NetLog::TYPE_SOCKET_STREAM_CONNECT, result); | 523 NetLog::TYPE_SOCKET_STREAM_CONNECT, result); |
| 475 } | 524 } |
| 476 } while (result != ERR_IO_PENDING); | 525 } while (result != ERR_IO_PENDING); |
| 477 } | 526 } |
| 478 | 527 |
| 479 int SocketStream::DoResolveProxy() { | 528 int SocketStream::DoResolveProxy() { |
| 480 DCHECK(!pac_request_); | 529 DCHECK(!pac_request_); |
| 481 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | 530 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
| 482 | 531 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 return socket_->Connect(&io_callback_); | 658 return socket_->Connect(&io_callback_); |
| 610 } | 659 } |
| 611 | 660 |
| 612 int SocketStream::DoTcpConnectComplete(int result) { | 661 int SocketStream::DoTcpConnectComplete(int result) { |
| 613 // TODO(ukai): if error occured, reconsider proxy after error. | 662 // TODO(ukai): if error occured, reconsider proxy after error. |
| 614 if (result != OK) { | 663 if (result != OK) { |
| 615 next_state_ = STATE_CLOSE; | 664 next_state_ = STATE_CLOSE; |
| 616 return result; | 665 return result; |
| 617 } | 666 } |
| 618 | 667 |
| 619 if (proxy_mode_ == kTunnelProxy) | 668 if (proxy_mode_ == kTunnelProxy) { |
| 620 next_state_ = STATE_WRITE_TUNNEL_HEADERS; | 669 if (proxy_info_.is_https()) |
| 621 else if (proxy_mode_ == kSOCKSProxy) | 670 next_state_ = STATE_SECURE_PROXY_CONNECT; |
| 671 else |
| 672 next_state_ = STATE_WRITE_TUNNEL_HEADERS; |
| 673 } else if (proxy_mode_ == kSOCKSProxy) { |
| 622 next_state_ = STATE_SOCKS_CONNECT; | 674 next_state_ = STATE_SOCKS_CONNECT; |
| 623 else if (is_secure()) { | 675 } else if (is_secure()) { |
| 624 next_state_ = STATE_SSL_CONNECT; | 676 next_state_ = STATE_SSL_CONNECT; |
| 625 } else { | 677 } else { |
| 626 result = DidEstablishConnection(); | 678 result = DidEstablishConnection(); |
| 627 } | 679 } |
| 628 return result; | 680 return result; |
| 629 } | 681 } |
| 630 | 682 |
| 631 int SocketStream::DoWriteTunnelHeaders() { | 683 int SocketStream::DoWriteTunnelHeaders() { |
| 632 DCHECK_EQ(kTunnelProxy, proxy_mode_); | 684 DCHECK_EQ(kTunnelProxy, proxy_mode_); |
| 633 | 685 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 if (is_secure()) | 895 if (is_secure()) |
| 844 next_state_ = STATE_SSL_CONNECT; | 896 next_state_ = STATE_SSL_CONNECT; |
| 845 else | 897 else |
| 846 result = DidEstablishConnection(); | 898 result = DidEstablishConnection(); |
| 847 } else { | 899 } else { |
| 848 next_state_ = STATE_CLOSE; | 900 next_state_ = STATE_CLOSE; |
| 849 } | 901 } |
| 850 return result; | 902 return result; |
| 851 } | 903 } |
| 852 | 904 |
| 905 int SocketStream::DoSecureProxyConnect() { |
| 906 DCHECK(factory_); |
| 907 SSLClientSocketContext ssl_context; |
| 908 ssl_context.cert_verifier = cert_verifier_; |
| 909 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; |
| 910 // TODO(agl): look into plumbing SSLHostInfo here. |
| 911 socket_.reset(factory_->CreateSSLClientSocket( |
| 912 socket_.release(), |
| 913 proxy_info_.proxy_server().host_port_pair(), |
| 914 ssl_config_, |
| 915 NULL /* ssl_host_info */, |
| 916 ssl_context)); |
| 917 next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE; |
| 918 metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION); |
| 919 return socket_->Connect(&io_callback_); |
| 920 } |
| 921 |
| 922 int SocketStream::DoSecureProxyConnectComplete(int result) { |
| 923 DCHECK_EQ(STATE_NONE, next_state_); |
| 924 result = DidEstablishSSL(result); |
| 925 if (next_state_ != STATE_NONE) |
| 926 return result; |
| 927 if (result == OK) |
| 928 next_state_ = STATE_WRITE_TUNNEL_HEADERS; |
| 929 else |
| 930 next_state_ = STATE_CLOSE; |
| 931 return result; |
| 932 } |
| 933 |
| 853 int SocketStream::DoSSLConnect() { | 934 int SocketStream::DoSSLConnect() { |
| 854 DCHECK(factory_); | 935 DCHECK(factory_); |
| 855 SSLClientSocketContext ssl_context; | 936 SSLClientSocketContext ssl_context; |
| 856 ssl_context.cert_verifier = cert_verifier_; | 937 ssl_context.cert_verifier = cert_verifier_; |
| 857 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; | 938 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; |
| 858 // TODO(agl): look into plumbing SSLHostInfo here. | 939 // TODO(agl): look into plumbing SSLHostInfo here. |
| 859 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), | 940 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), |
| 860 HostPortPair::FromURL(url_), | 941 HostPortPair::FromURL(url_), |
| 861 ssl_config_, | 942 ssl_config_, |
| 862 NULL /* ssl_host_info */, | 943 NULL /* ssl_host_info */, |
| 863 ssl_context)); | 944 ssl_context)); |
| 864 next_state_ = STATE_SSL_CONNECT_COMPLETE; | 945 next_state_ = STATE_SSL_CONNECT_COMPLETE; |
| 865 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION); | 946 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION); |
| 866 return socket_->Connect(&io_callback_); | 947 return socket_->Connect(&io_callback_); |
| 867 } | 948 } |
| 868 | 949 |
| 869 int SocketStream::DoSSLConnectComplete(int result) { | 950 int SocketStream::DoSSLConnectComplete(int result) { |
| 870 if (IsCertificateError(result)) { | 951 DCHECK_EQ(STATE_NONE, next_state_); |
| 871 if (socket_->IsConnectedAndIdle()) { | 952 result = DidEstablishSSL(result); |
| 872 result = HandleCertificateError(result); | 953 if (next_state_ != STATE_NONE) |
| 873 } else { | 954 return result; |
| 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 | |
| 910 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible. | 955 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible. |
| 911 // If we use HTTPS and this is the first connection to the SPDY server, | 956 // If we use HTTPS and this is the first connection to the SPDY server, |
| 912 // we should take care of TLS NPN extension here. | 957 // we should take care of TLS NPN extension here. |
| 913 | 958 |
| 914 if (result == OK) | 959 if (result == OK) |
| 915 result = DidEstablishConnection(); | 960 result = DidEstablishConnection(); |
| 916 else | 961 else |
| 917 next_state_ = STATE_CLOSE; | 962 next_state_ = STATE_CLOSE; |
| 918 return result; | 963 return result; |
| 919 } | 964 } |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1087 | 1132 |
| 1088 SSLConfigService* SocketStream::ssl_config_service() const { | 1133 SSLConfigService* SocketStream::ssl_config_service() const { |
| 1089 return context_->ssl_config_service(); | 1134 return context_->ssl_config_service(); |
| 1090 } | 1135 } |
| 1091 | 1136 |
| 1092 ProxyService* SocketStream::proxy_service() const { | 1137 ProxyService* SocketStream::proxy_service() const { |
| 1093 return context_->proxy_service(); | 1138 return context_->proxy_service(); |
| 1094 } | 1139 } |
| 1095 | 1140 |
| 1096 } // namespace net | 1141 } // namespace net |
| OLD | NEW |