diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-16 19:36:31 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-16 19:36:31 +0000 |
commit | c0e4dd1e6b56543fb186289e5a45463d0b81d1e8 (patch) | |
tree | 250241fdca7730e2e18af407e3edcdb9882f4375 /net/socket/ssl_client_socket_nss.cc | |
parent | c1e3cefb7603bb0bac40cd8e73956e662504ee72 (diff) | |
download | chromium_src-c0e4dd1e6b56543fb186289e5a45463d0b81d1e8.zip chromium_src-c0e4dd1e6b56543fb186289e5a45463d0b81d1e8.tar.gz chromium_src-c0e4dd1e6b56543fb186289e5a45463d0b81d1e8.tar.bz2 |
Prevent the infinite loop inside SSLClientSocketNSS::OnSendComplete.
Two fixes are added. 1) We stay in the loop only if we will call
DoPayloadRead or DoPayloadWrite in the next iteration. 2) Don't call
BufferRecv again if BufferRecv has reported EOF before.
Each fix alone prevents the infinite loop. The second fix is less risky.
If necessary, we can go with just the second fix.
R=rsleevi@chromium.org
BUG=127822
TEST=SSLServerSocketTest.WriteAfterPeerClose in net_unittests
Review URL: https://chromiumcodereview.appspot.com/10382186
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137485 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket/ssl_client_socket_nss.cc')
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index b84805e..aba4f7a 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -430,6 +430,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, const SSLClientSocketContext& context) : transport_send_busy_(false), transport_recv_busy_(false), + transport_recv_eof_(false), transport_(transport_socket), host_and_port_(host_and_port), ssl_config_(ssl_config), @@ -633,6 +634,7 @@ void SSLClientSocketNSS::Disconnect() { user_write_callback_.Reset(); transport_send_busy_ = false; transport_recv_busy_ = false; + transport_recv_eof_ = false; user_read_buf_ = NULL; user_read_buf_len_ = 0; user_write_buf_ = NULL; @@ -1219,6 +1221,7 @@ void SSLClientSocketNSS::OnSendComplete(int result) { network_moved = DoTransportIO(); } while (rv_read == ERR_IO_PENDING && rv_write == ERR_IO_PENDING && + (user_read_buf_ || user_write_buf_) && network_moved); if (user_read_buf_ && rv_read != ERR_IO_PENDING) @@ -1922,7 +1925,7 @@ bool SSLClientSocketNSS::DoTransportIO() { if (rv > 0) network_moved = true; } while (rv > 0); - if (BufferRecv() >= 0) + if (!transport_recv_eof_ && BufferRecv() >= 0) network_moved = true; } LeaveFunction(network_moved); @@ -1932,7 +1935,7 @@ bool SSLClientSocketNSS::DoTransportIO() { // Return 0 for EOF, // > 0 for bytes transferred immediately, // < 0 for error (or the non-error ERR_IO_PENDING). -int SSLClientSocketNSS::BufferSend(void) { +int SSLClientSocketNSS::BufferSend() { if (transport_send_busy_) return ERR_IO_PENDING; @@ -1971,7 +1974,7 @@ void SSLClientSocketNSS::BufferSendComplete(int result) { LeaveFunction(""); } -int SSLClientSocketNSS::BufferRecv(void) { +int SSLClientSocketNSS::BufferRecv() { if (transport_recv_busy_) return ERR_IO_PENDING; char* buf; @@ -1990,8 +1993,11 @@ int SSLClientSocketNSS::BufferRecv(void) { if (rv == ERR_IO_PENDING) { transport_recv_busy_ = true; } else { - if (rv > 0) + if (rv > 0) { memcpy(buf, recv_buffer_->data(), rv); + } else if (rv == 0) { + transport_recv_eof_ = true; + } memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); recv_buffer_ = NULL; } @@ -2006,6 +2012,8 @@ void SSLClientSocketNSS::BufferRecvComplete(int result) { char* buf; memio_GetReadParams(nss_bufs_, &buf); memcpy(buf, recv_buffer_->data(), result); + } else if (result == 0) { + transport_recv_eof_ = true; } recv_buffer_ = NULL; memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); |