mirror of https://github.com/Icinga/icinga2.git
Add timeout for TLS handshakes
This commit is contained in:
parent
aa1ccd7ada
commit
70c81734c5
|
@ -60,7 +60,7 @@ void Stream::SignalDataAvailable(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool Stream::WaitForData(int timeout)
|
||||
bool Stream::WaitForData()
|
||||
{
|
||||
if (!SupportsWaiting())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Stream does not support waiting."));
|
||||
|
@ -68,10 +68,25 @@ bool Stream::WaitForData(int timeout)
|
|||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
while (!IsDataAvailable() && !IsEof())
|
||||
if (timeout < 0)
|
||||
m_CV.wait(lock);
|
||||
else
|
||||
m_CV.timed_wait(lock, boost::posix_time::milliseconds(timeout * 1000));
|
||||
m_CV.wait(lock);
|
||||
|
||||
return IsDataAvailable() || IsEof();
|
||||
}
|
||||
|
||||
bool Stream::WaitForData(int timeout)
|
||||
{
|
||||
if (!SupportsWaiting())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Stream does not support waiting."));
|
||||
|
||||
if (timeout < 0)
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Timeout can't be negative"));
|
||||
|
||||
boost::system_time const point_of_timeout = boost::get_system_time() + boost::posix_time::seconds(timeout);
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
while (!IsDataAvailable() && !IsEof() && point_of_timeout > boost::get_system_time())
|
||||
m_CV.timed_wait(lock, point_of_timeout);
|
||||
|
||||
return IsDataAvailable() || IsEof();
|
||||
}
|
||||
|
|
|
@ -124,8 +124,10 @@ public:
|
|||
|
||||
/**
|
||||
* Waits until data can be read from the stream.
|
||||
* Optionally with a timeout.
|
||||
*/
|
||||
bool WaitForData(int timeout = -1);
|
||||
bool WaitForData();
|
||||
bool WaitForData(int timeout);
|
||||
|
||||
virtual bool SupportsWaiting(void) const;
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
# include <poll.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define TLS_TIMEOUT_SECONDS 10
|
||||
#define TLS_TIMEOUT_STEP_SECONDS 1
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
int I2_EXPORT TlsStream::m_SSLIndex;
|
||||
|
@ -286,8 +289,14 @@ void TlsStream::Handshake(void)
|
|||
m_CurrentAction = TlsActionHandshake;
|
||||
ChangeEvents(POLLOUT);
|
||||
|
||||
while (!m_HandshakeOK && !m_ErrorOccurred && !m_Eof)
|
||||
m_CV.wait(lock);
|
||||
boost::system_time const timeout = boost::get_system_time() + boost::posix_time::seconds(TLS_TIMEOUT_SECONDS);
|
||||
|
||||
while (!m_HandshakeOK && !m_ErrorOccurred && !m_Eof && timeout > boost::get_system_time())
|
||||
m_CV.timed_wait(lock, timeout);
|
||||
|
||||
// We should _NOT_ (underline, bold, itallic and wordart) throw an exception for a timeout.
|
||||
if (timeout < boost::get_system_time())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Timeout during handshake."));
|
||||
|
||||
if (m_Eof)
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Socket was closed during TLS handshake."));
|
||||
|
|
|
@ -511,11 +511,17 @@ void ApiListener::NewClientHandlerInternal(const Socket::Ptr& client, const Stri
|
|||
JsonRpc::SendMessage(tlsStream, message);
|
||||
ctype = ClientJsonRpc;
|
||||
} else {
|
||||
tlsStream->WaitForData(5);
|
||||
tlsStream->WaitForData(10);
|
||||
|
||||
if (!tlsStream->IsDataAvailable()) {
|
||||
Log(LogWarning, "ApiListener")
|
||||
<< "No data received on new API connection for identity '" << identity << "'. Ensure that the remote endpoints are properly configured in a cluster setup.";
|
||||
if (identity.IsEmpty())
|
||||
Log(LogInformation, "ApiListener")
|
||||
<< "No data received on new API connection. "
|
||||
<< "Ensure that the remote endpoints are properly configured in a cluster setup.";
|
||||
else
|
||||
Log(LogWarning, "ApiListener")
|
||||
<< "No data received on new API connection for identity '" << identity << "'. "
|
||||
<< "Ensure that the remote endpoints are properly configured in a cluster setup.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ void HttpServerConnection::StaticInitialize(void)
|
|||
{
|
||||
l_HttpServerConnectionTimeoutTimer = new Timer();
|
||||
l_HttpServerConnectionTimeoutTimer->OnTimerExpired.connect(boost::bind(&HttpServerConnection::TimeoutTimerHandler));
|
||||
l_HttpServerConnectionTimeoutTimer->SetInterval(15);
|
||||
l_HttpServerConnectionTimeoutTimer->SetInterval(5);
|
||||
l_HttpServerConnectionTimeoutTimer->Start();
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,12 @@ TlsStream::Ptr HttpServerConnection::GetStream(void) const
|
|||
|
||||
void HttpServerConnection::Disconnect(void)
|
||||
{
|
||||
boost::mutex::scoped_try_lock lock(m_DataHandlerMutex);
|
||||
if (!lock.owns_lock()) {
|
||||
Log(LogInformation, "HttpServerConnection", "Unable to disconnect Http client, I/O thread busy");
|
||||
return;
|
||||
}
|
||||
|
||||
Log(LogDebug, "HttpServerConnection", "Http client disconnected");
|
||||
|
||||
ApiListener::Ptr listener = ApiListener::GetInstance();
|
||||
|
|
|
@ -121,8 +121,10 @@ boost::shared_ptr<X509> PkiUtility::FetchCert(const String& host, const String&
|
|||
|
||||
try {
|
||||
stream->Handshake();
|
||||
} catch (...) {
|
||||
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogCritical, "pki")
|
||||
<< "Client TLS handshake failed. (" << ex.what() << ")";
|
||||
return std::shared_ptr<X509>();
|
||||
}
|
||||
|
||||
return stream->GetPeerCertificate();
|
||||
|
|
Loading…
Reference in New Issue