diff --git a/lib/base/tlsstream.cpp b/lib/base/tlsstream.cpp index c04e9a264..8f27bb6a0 100644 --- a/lib/base/tlsstream.cpp +++ b/lib/base/tlsstream.cpp @@ -126,7 +126,7 @@ boost::shared_ptr TlsStream::GetPeerCertificate(void) const void TlsStream::OnEvent(int revents) { - int rc, err; + int rc; size_t count; boost::mutex::scoped_lock lock(m_Mutex); @@ -147,6 +147,8 @@ void TlsStream::OnEvent(int revents) } } + bool success = false; + switch (m_CurrentAction) { case TlsActionRead: do { @@ -154,9 +156,12 @@ void TlsStream::OnEvent(int revents) if (rc > 0) { m_RecvQ->Write(buffer, rc); - m_CV.notify_all(); + success = true; } - } while (SSL_pending(m_SSL.get())); + } while (rc > 0); + + if (success) + m_CV.notify_all(); break; case TlsActionWrite: @@ -164,14 +169,17 @@ void TlsStream::OnEvent(int revents) rc = SSL_write(m_SSL.get(), buffer, count); - if (rc > 0) + if (rc > 0) { m_SendQ->Read(NULL, rc, true); + success = true; + } break; case TlsActionHandshake: rc = SSL_do_handshake(m_SSL.get()); if (rc > 0) { + success = true; m_HandshakeOK = true; m_CV.notify_all(); } @@ -181,7 +189,46 @@ void TlsStream::OnEvent(int revents) VERIFY(!"Invalid TlsAction"); } - if (rc > 0) { + if (rc < 0) { + int err = SSL_get_error(m_SSL.get(), rc); + + switch (err) { + case SSL_ERROR_WANT_READ: + m_Retry = true; + ChangeEvents(POLLIN); + + break; + case SSL_ERROR_WANT_WRITE: + m_Retry = true; + ChangeEvents(POLLOUT); + + break; + case SSL_ERROR_ZERO_RETURN: + lock.unlock(); + + Close(); + + break; + default: + m_ErrorCode = ERR_peek_error(); + m_ErrorOccurred = true; + + if (m_ErrorCode != 0) { + Log(LogWarning, "TlsStream") + << "OpenSSL error: " << ERR_error_string(m_ErrorCode, NULL); + } else { + Log(LogWarning, "TlsStream", "TLS stream was disconnected."); + } + + lock.unlock(); + + Close(); + + break; + } + } + + if (success) { m_CurrentAction = TlsActionNone; if (!m_Eof) { @@ -198,51 +245,6 @@ void TlsStream::OnEvent(int revents) if (m_Shutdown && !m_SendQ->IsDataAvailable()) Close(); - - return; - } - - err = SSL_get_error(m_SSL.get(), rc); - - switch (err) { - case SSL_ERROR_WANT_READ: - m_Retry = true; - ChangeEvents(POLLIN); - - break; - case SSL_ERROR_WANT_WRITE: - m_Retry = true; - ChangeEvents(POLLOUT); - - break; - case SSL_ERROR_ZERO_RETURN: - lock.unlock(); - - if (IsHandlingEvents()) - SignalDataAvailable(); - - Close(); - - break; - default: - m_ErrorCode = ERR_peek_error(); - m_ErrorOccurred = true; - - if (m_ErrorCode != 0) { - Log(LogWarning, "TlsStream") - << "OpenSSL error: " << ERR_error_string(m_ErrorCode, NULL); - } else { - Log(LogWarning, "TlsStream", "TLS stream was disconnected."); - } - - lock.unlock(); - - if (IsHandlingEvents()) - SignalDataAvailable(); - - Close(); - - break; } }