| Index: net/socket/ssl_client_socket_openssl.cc
|
| ===================================================================
|
| --- net/socket/ssl_client_socket_openssl.cc (revision 250122)
|
| +++ net/socket/ssl_client_socket_openssl.cc (working copy)
|
| @@ -343,6 +343,7 @@
|
| transport_recv_eof_(false),
|
| weak_factory_(this),
|
| pending_read_error_(kNoPendingReadResult),
|
| + transport_write_error_(OK),
|
| completed_handshake_(false),
|
| client_auth_cert_needed_(false),
|
| cert_verifier_(context.cert_verifier),
|
| @@ -466,6 +467,9 @@
|
| user_write_buf_ = NULL;
|
| user_write_buf_len_ = 0;
|
|
|
| + pending_read_error_ = kNoPendingReadResult;
|
| + transport_write_error_ = OK;
|
| +
|
| server_cert_verify_result_.Reset();
|
| completed_handshake_ = false;
|
|
|
| @@ -1204,7 +1208,7 @@
|
| if (rv == ERR_IO_PENDING) {
|
| transport_recv_busy_ = true;
|
| } else {
|
| - TransportReadComplete(rv);
|
| + rv = TransportReadComplete(rv);
|
| }
|
| return rv;
|
| }
|
| @@ -1216,7 +1220,7 @@
|
| }
|
|
|
| void SSLClientSocketOpenSSL::BufferRecvComplete(int result) {
|
| - TransportReadComplete(result);
|
| + result = TransportReadComplete(result);
|
| OnRecvComplete(result);
|
| }
|
|
|
| @@ -1224,9 +1228,19 @@
|
| DCHECK(ERR_IO_PENDING != result);
|
| if (result < 0) {
|
| // Got a socket write error; close the BIO to indicate this upward.
|
| + //
|
| + // TODO(davidben): The value of |result| gets lost. Feed the error back into
|
| + // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with
|
| + // BIO_set_callback.
|
| DVLOG(1) << "TransportWriteComplete error " << result;
|
| + (void)BIO_shutdown_wr(SSL_get_wbio(ssl_));
|
| +
|
| + // Match the fix for http://crbug.com/249848 in NSS by erroring future reads
|
| + // from the socket after a write error.
|
| + //
|
| + // TODO(davidben): Avoid having read and write ends interact this way.
|
| + transport_write_error_ = result;
|
| (void)BIO_shutdown_wr(transport_bio_);
|
| - BIO_set_mem_eof_return(transport_bio_, 0);
|
| send_buffer_ = NULL;
|
| } else {
|
| DCHECK(send_buffer_.get());
|
| @@ -1237,7 +1251,7 @@
|
| }
|
| }
|
|
|
| -void SSLClientSocketOpenSSL::TransportReadComplete(int result) {
|
| +int SSLClientSocketOpenSSL::TransportReadComplete(int result) {
|
| DCHECK(ERR_IO_PENDING != result);
|
| if (result <= 0) {
|
| DVLOG(1) << "TransportReadComplete result " << result;
|
| @@ -1246,8 +1260,12 @@
|
| // relay up to the SSL socket client (i.e. via DoReadCallback).
|
| if (result == 0)
|
| transport_recv_eof_ = true;
|
| - BIO_set_mem_eof_return(transport_bio_, 0);
|
| (void)BIO_shutdown_wr(transport_bio_);
|
| + } else if (transport_write_error_ < 0) {
|
| + // Mirror transport write errors as read failures; transport_bio_ has been
|
| + // shut down by TransportWriteComplete, so the BIO_write will fail, failing
|
| + // the CHECK. http://crbug.com/335557.
|
| + result = transport_write_error_;
|
| } else {
|
| DCHECK(recv_buffer_.get());
|
| int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
|
| @@ -1259,6 +1277,7 @@
|
| }
|
| recv_buffer_ = NULL;
|
| transport_recv_busy_ = false;
|
| + return result;
|
| }
|
|
|
| int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl,
|
|
|