improved error handling, specifically socket timeouts

This commit is contained in:
Guenter Obiltschnig
2013-12-13 12:36:24 +01:00
parent 8b456cd293
commit 3838d665a0

View File

@@ -1,7 +1,7 @@
// //
// SecureSocketImpl.cpp // SecureSocketImpl.cpp
// //
// $Id: //poco/1.4/NetSSL_OpenSSL/src/SecureSocketImpl.cpp#5 $ // $Id: //poco/1.4/NetSSL_OpenSSL/src/SecureSocketImpl.cpp#11 $
// //
// Library: NetSSL_OpenSSL // Library: NetSSL_OpenSSL
// Package: SSLSockets // Package: SSLSockets
@@ -146,7 +146,7 @@ void SecureSocketImpl::connect(const SocketAddress& address, const Poco::Timespa
_pSocket->setSendTimeout(timeout); _pSocket->setSendTimeout(timeout);
connectSSL(performHandshake); connectSSL(performHandshake);
_pSocket->setReceiveTimeout(receiveTimeout); _pSocket->setReceiveTimeout(receiveTimeout);
_pSocket->setSendTimeout(sendTimeout); _pSocket->setSendTimeout(sendTimeout);
} }
@@ -155,6 +155,7 @@ void SecureSocketImpl::connectNB(const SocketAddress& address)
if (_pSSL) reset(); if (_pSSL) reset();
poco_assert (!_pSSL); poco_assert (!_pSSL);
_pSocket->connectNB(address); _pSocket->connectNB(address);
connectSSL(false); connectSSL(false);
} }
@@ -231,12 +232,12 @@ void SecureSocketImpl::listen(int backlog)
void SecureSocketImpl::shutdown() void SecureSocketImpl::shutdown()
{ {
if (_pSSL) if (_pSSL)
{ {
// Don't shut down the socket more than once. // Don't shut down the socket more than once.
int shutdownState = SSL_get_shutdown(_pSSL); int shutdownState = SSL_get_shutdown(_pSSL);
bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN; bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
if (!shutdownSent) if (!shutdownSent)
{ {
// A proper clean shutdown would require us to // A proper clean shutdown would require us to
// retry the shutdown if we get a zero return // retry the shutdown if we get a zero return
// value, until SSL_shutdown() returns 1. // value, until SSL_shutdown() returns 1.
@@ -246,7 +247,10 @@ void SecureSocketImpl::shutdown()
// done with it. // done with it.
int rc = SSL_shutdown(_pSSL); int rc = SSL_shutdown(_pSSL);
if (rc < 0) handleError(rc); if (rc < 0) handleError(rc);
if (_pSocket->getBlocking()) _pSocket->shutdown(); if (_pSocket->getBlocking())
{
_pSocket->shutdown();
}
} }
} }
} }
@@ -254,7 +258,13 @@ void SecureSocketImpl::shutdown()
void SecureSocketImpl::close() void SecureSocketImpl::close()
{ {
try { shutdown(); } catch (...) { } try
{
shutdown();
}
catch (...)
{
}
_pSocket->close(); _pSocket->close();
} }
@@ -403,12 +413,21 @@ int SecureSocketImpl::handleError(int rc)
{ {
if (rc > 0) return rc; if (rc > 0) return rc;
int sslError = SSL_get_error(_pSSL, rc); int sslError = SSL_get_error(_pSSL, rc);
int error = SocketImpl::lastError();
switch (sslError) switch (sslError)
{ {
case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_ZERO_RETURN:
return 0; return 0;
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
if (_pSocket->getBlocking() && error != 0)
{
if (error == POCO_EAGAIN)
throw TimeoutException(error);
else
SocketImpl::error(error);
}
return SecureStreamSocket::ERR_SSL_WANT_READ; return SecureStreamSocket::ERR_SSL_WANT_READ;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
return SecureStreamSocket::ERR_SSL_WANT_WRITE; return SecureStreamSocket::ERR_SSL_WANT_WRITE;
@@ -418,12 +437,22 @@ int SecureSocketImpl::handleError(int rc)
// these should not occur // these should not occur
poco_bugcheck(); poco_bugcheck();
return rc; return rc;
case SSL_ERROR_SYSCALL:
if (error != 0)
{
if (_pSocket->getBlocking() && error == POCO_EAGAIN)
throw TimeoutException(error);
else
SocketImpl::error(error);
return rc;
}
// fallthrough
default: default:
{ {
long lastError = ERR_get_error(); long lastError = ERR_get_error();
if (lastError == 0) if (lastError == 0)
{ {
if (rc == 0) if (rc == 0 || rc == -1)
{ {
throw SSLConnectionUnexpectedlyClosedException(); throw SSLConnectionUnexpectedlyClosedException();
} }