Chromium Code Reviews| Index: net/socket/ssl_client_socket_openssl.cc |
| diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc |
| index 3925ca1a36ec6b401d4625bb7d0055c308ab0943..8735dc725a68ffcc9cdac240dac97aeca8f5f26c 100644 |
| --- a/net/socket/ssl_client_socket_openssl.cc |
| +++ b/net/socket/ssl_client_socket_openssl.cc |
| @@ -343,6 +343,7 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( |
| 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), |
| @@ -1204,7 +1205,7 @@ int SSLClientSocketOpenSSL::BufferRecv(void) { |
| if (rv == ERR_IO_PENDING) { |
| transport_recv_busy_ = true; |
| } else { |
| - TransportReadComplete(rv); |
| + rv = TransportReadComplete(rv); |
| } |
| return rv; |
| } |
| @@ -1216,7 +1217,7 @@ void SSLClientSocketOpenSSL::BufferSendComplete(int result) { |
| } |
| void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { |
| - TransportReadComplete(result); |
| + result = TransportReadComplete(result); |
| OnRecvComplete(result); |
| } |
| @@ -1224,9 +1225,19 @@ void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { |
| 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_)); |
|
davidben
2014/02/04 19:27:57
Could get away with even avoiding this line for mi
davidben
2014/02/04 19:27:57
It looks like sometimes OpenSSL wraps the wbio in
Ryan Sleevi
2014/02/04 20:45:02
Future work: Should we be using BIO_set_close() in
davidben
2014/02/04 23:00:11
Hrm. That seems to set the shutdown flag on the BI
|
| + |
| + // 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); |
|
davidben
2014/02/04 19:27:57
Looks like these calls don't do anything in BIO pa
|
| send_buffer_ = NULL; |
|
davidben
2014/02/04 19:27:57
This line is sort of funny. The next time we get a
Ryan Sleevi
2014/02/04 20:45:02
I'm not sure I follow why it's funny. We just had
davidben
2014/02/04 23:00:11
Keeping send_buffer_ around avoids the succeeds wi
|
| } else { |
| DCHECK(send_buffer_.get()); |
| @@ -1237,7 +1248,7 @@ void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { |
| } |
| } |
| -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 +1257,11 @@ void SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
| // 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. |
| + result = transport_write_error_; |
|
Ryan Sleevi
2014/02/04 20:45:02
Let's add bug numbers. This is perhaps the most co
davidben
2014/02/04 23:00:11
Agreed. I kept it this way just to minimize behavi
|
| } else { |
| DCHECK(recv_buffer_.get()); |
| int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); |
| @@ -1259,6 +1273,7 @@ void SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
| } |
| recv_buffer_ = NULL; |
| transport_recv_busy_ = false; |
| + return result; |
| } |
| int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, |