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 // OpenSSL binding for SSLClientSocket. The class layout and general principle | 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle |
6 // of operation is derived from SSLClientSocketNSS. | 6 // of operation is derived from SSLClientSocketNSS. |
7 | 7 |
8 #include "net/socket/ssl_client_socket_openssl.h" | 8 #include "net/socket/ssl_client_socket_openssl.h" |
9 | 9 |
10 #include <openssl/ssl.h> | 10 #include <openssl/ssl.h> |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
409 context->session_cache()->Flush(); | 409 context->session_cache()->Flush(); |
410 } | 410 } |
411 | 411 |
412 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( | 412 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( |
413 ClientSocketHandle* transport_socket, | 413 ClientSocketHandle* transport_socket, |
414 const HostPortPair& host_and_port, | 414 const HostPortPair& host_and_port, |
415 const SSLConfig& ssl_config, | 415 const SSLConfig& ssl_config, |
416 const SSLClientSocketContext& context) | 416 const SSLClientSocketContext& context) |
417 : transport_send_busy_(false), | 417 : transport_send_busy_(false), |
418 transport_recv_busy_(false), | 418 transport_recv_busy_(false), |
419 transport_recv_eof_(false), | |
419 completed_handshake_(false), | 420 completed_handshake_(false), |
420 client_auth_cert_needed_(false), | 421 client_auth_cert_needed_(false), |
421 cert_verifier_(context.cert_verifier), | 422 cert_verifier_(context.cert_verifier), |
422 ssl_(NULL), | 423 ssl_(NULL), |
423 transport_bio_(NULL), | 424 transport_bio_(NULL), |
424 transport_(transport_socket), | 425 transport_(transport_socket), |
425 host_and_port_(host_and_port), | 426 host_and_port_(host_and_port), |
426 ssl_config_(ssl_config), | 427 ssl_config_(ssl_config), |
427 ssl_session_cache_shard_(context.ssl_session_cache_shard), | 428 ssl_session_cache_shard_(context.ssl_session_cache_shard), |
428 trying_cached_session_(false), | 429 trying_cached_session_(false), |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
711 } | 712 } |
712 | 713 |
713 // Shut down anything that may call us back. | 714 // Shut down anything that may call us back. |
714 verifier_.reset(); | 715 verifier_.reset(); |
715 transport_->socket()->Disconnect(); | 716 transport_->socket()->Disconnect(); |
716 | 717 |
717 // Null all callbacks, delete all buffers. | 718 // Null all callbacks, delete all buffers. |
718 transport_send_busy_ = false; | 719 transport_send_busy_ = false; |
719 send_buffer_ = NULL; | 720 send_buffer_ = NULL; |
720 transport_recv_busy_ = false; | 721 transport_recv_busy_ = false; |
722 transport_recv_eof_ = false; | |
721 recv_buffer_ = NULL; | 723 recv_buffer_ = NULL; |
722 | 724 |
723 user_connect_callback_.Reset(); | 725 user_connect_callback_.Reset(); |
724 user_read_callback_.Reset(); | 726 user_read_callback_.Reset(); |
725 user_write_callback_.Reset(); | 727 user_write_callback_.Reset(); |
726 user_read_buf_ = NULL; | 728 user_read_buf_ = NULL; |
727 user_read_buf_len_ = 0; | 729 user_read_buf_len_ = 0; |
728 user_write_buf_ = NULL; | 730 user_write_buf_ = NULL; |
729 user_write_buf_len_ = 0; | 731 user_write_buf_len_ = 0; |
730 | 732 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
948 intermediates.push_back(sk_X509_value(chain, i)); | 950 intermediates.push_back(sk_X509_value(chain, i)); |
949 } | 951 } |
950 server_cert_ = X509Certificate::CreateFromHandle(cert.get(), intermediates); | 952 server_cert_ = X509Certificate::CreateFromHandle(cert.get(), intermediates); |
951 DCHECK(server_cert_); | 953 DCHECK(server_cert_); |
952 | 954 |
953 return server_cert_; | 955 return server_cert_; |
954 } | 956 } |
955 | 957 |
956 bool SSLClientSocketOpenSSL::DoTransportIO() { | 958 bool SSLClientSocketOpenSSL::DoTransportIO() { |
957 bool network_moved = false; | 959 bool network_moved = false; |
958 int nsent = BufferSend(); | 960 int rv; |
959 int nreceived = BufferRecv(); | 961 // Read and write as much data as we can. The loop is neccessary |
960 network_moved = (nsent > 0 || nreceived >= 0); | 962 // because Write() may return synchronously. |
963 do { | |
964 rv = BufferSend(); | |
965 if (rv > 0) | |
966 network_moved = true; | |
967 } while (rv > 0); | |
Johnny(Jianning) Ding
2012/05/18 15:45:58
I don't think it's necessary to use the loop to ke
joth
2012/05/18 16:02:08
wtc will have a better understanding, but I believ
wtc
2012/05/18 18:38:00
jnd: you are right! I did a naive port of the SSL
| |
968 if (!transport_recv_eof_ && BufferRecv() >= 0) | |
969 network_moved = true; | |
961 return network_moved; | 970 return network_moved; |
962 } | 971 } |
963 | 972 |
964 int SSLClientSocketOpenSSL::BufferSend(void) { | 973 int SSLClientSocketOpenSSL::BufferSend(void) { |
965 if (transport_send_busy_) | 974 if (transport_send_busy_) |
966 return ERR_IO_PENDING; | 975 return ERR_IO_PENDING; |
967 | 976 |
968 if (!send_buffer_) { | 977 if (!send_buffer_) { |
969 // Get a fresh send buffer out of the send BIO. | 978 // Get a fresh send buffer out of the send BIO. |
970 size_t max_read = BIO_ctrl_pending(transport_bio_); | 979 size_t max_read = BIO_ctrl_pending(transport_bio_); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1043 OnRecvComplete(result); | 1052 OnRecvComplete(result); |
1044 } | 1053 } |
1045 | 1054 |
1046 void SSLClientSocketOpenSSL::TransportReadComplete(int result) { | 1055 void SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
1047 DCHECK(ERR_IO_PENDING != result); | 1056 DCHECK(ERR_IO_PENDING != result); |
1048 if (result <= 0) { | 1057 if (result <= 0) { |
1049 DVLOG(1) << "TransportReadComplete result " << result; | 1058 DVLOG(1) << "TransportReadComplete result " << result; |
1050 // Received 0 (end of file) or an error. Either way, bubble it up to the | 1059 // Received 0 (end of file) or an error. Either way, bubble it up to the |
1051 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to | 1060 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to |
1052 // relay up to the SSL socket client (i.e. via DoReadCallback). | 1061 // relay up to the SSL socket client (i.e. via DoReadCallback). |
1062 if (result == 0) | |
1063 transport_recv_eof_ = true; | |
1053 BIO_set_mem_eof_return(transport_bio_, 0); | 1064 BIO_set_mem_eof_return(transport_bio_, 0); |
1054 (void)BIO_shutdown_wr(transport_bio_); | 1065 (void)BIO_shutdown_wr(transport_bio_); |
1055 } else { | 1066 } else { |
1056 DCHECK(recv_buffer_); | 1067 DCHECK(recv_buffer_); |
1057 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); | 1068 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); |
1058 // A write into a memory BIO should always succeed. | 1069 // A write into a memory BIO should always succeed. |
1059 CHECK_EQ(result, ret); | 1070 CHECK_EQ(result, ret); |
1060 } | 1071 } |
1061 recv_buffer_ = NULL; | 1072 recv_buffer_ = NULL; |
1062 transport_recv_busy_ = false; | 1073 transport_recv_busy_ = false; |
(...skipping 28 matching lines...) Expand all Loading... | |
1091 int rv_write = ERR_IO_PENDING; | 1102 int rv_write = ERR_IO_PENDING; |
1092 bool network_moved; | 1103 bool network_moved; |
1093 do { | 1104 do { |
1094 if (user_read_buf_) | 1105 if (user_read_buf_) |
1095 rv_read = DoPayloadRead(); | 1106 rv_read = DoPayloadRead(); |
1096 if (user_write_buf_) | 1107 if (user_write_buf_) |
1097 rv_write = DoPayloadWrite(); | 1108 rv_write = DoPayloadWrite(); |
1098 network_moved = DoTransportIO(); | 1109 network_moved = DoTransportIO(); |
1099 } while (rv_read == ERR_IO_PENDING && | 1110 } while (rv_read == ERR_IO_PENDING && |
1100 rv_write == ERR_IO_PENDING && | 1111 rv_write == ERR_IO_PENDING && |
1112 (user_read_buf_ || user_write_buf_) && | |
1101 network_moved); | 1113 network_moved); |
1102 | 1114 |
1103 if (user_read_buf_ && rv_read != ERR_IO_PENDING) | 1115 if (user_read_buf_ && rv_read != ERR_IO_PENDING) |
1104 DoReadCallback(rv_read); | 1116 DoReadCallback(rv_read); |
1105 if (user_write_buf_ && rv_write != ERR_IO_PENDING) | 1117 if (user_write_buf_ && rv_write != ERR_IO_PENDING) |
1106 DoWriteCallback(rv_write); | 1118 DoWriteCallback(rv_write); |
1107 } | 1119 } |
1108 | 1120 |
1109 void SSLClientSocketOpenSSL::OnRecvComplete(int result) { | 1121 void SSLClientSocketOpenSSL::OnRecvComplete(int result) { |
1110 if (next_handshake_state_ == STATE_HANDSHAKE) { | 1122 if (next_handshake_state_ == STATE_HANDSHAKE) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1293 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv, | 1305 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv, |
1294 user_write_buf_->data()); | 1306 user_write_buf_->data()); |
1295 return rv; | 1307 return rv; |
1296 } | 1308 } |
1297 | 1309 |
1298 int err = SSL_get_error(ssl_, rv); | 1310 int err = SSL_get_error(ssl_, rv); |
1299 return MapOpenSSLError(err, err_tracer); | 1311 return MapOpenSSLError(err, err_tracer); |
1300 } | 1312 } |
1301 | 1313 |
1302 } // namespace net | 1314 } // namespace net |
OLD | NEW |