mirror of
https://github.com/Icinga/icinga2.git
synced 2025-04-08 17:05:25 +02:00
Performance fixes for TLS sockets.
This commit is contained in:
parent
e2253b8624
commit
7f299fb2a7
@ -72,6 +72,7 @@ void Socket::SetFD(SOCKET fd)
|
|||||||
{
|
{
|
||||||
unsigned long lTrue = 1;
|
unsigned long lTrue = 1;
|
||||||
|
|
||||||
|
/* mark the socket as non-blocking */
|
||||||
if (fd != INVALID_SOCKET) {
|
if (fd != INVALID_SOCKET) {
|
||||||
#ifdef F_GETFL
|
#ifdef F_GETFL
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -124,6 +124,20 @@ FIFO::Ptr TcpClient::GetSendQueue(void)
|
|||||||
return m_SendQueue;
|
return m_SendQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t TcpClient::FlushSendQueue(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = send(GetFD(), (const char *)m_SendQueue->GetReadBuffer(), m_SendQueue->GetSize(), 0);
|
||||||
|
|
||||||
|
if (rc <= 0) {
|
||||||
|
HandleSocketError(SocketException("send() failed", GetError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_SendQueue->Read(NULL, rc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the recv queue for the socket.
|
* Retrieves the recv queue for the socket.
|
||||||
*
|
*
|
||||||
@ -134,10 +148,7 @@ FIFO::Ptr TcpClient::GetRecvQueue(void)
|
|||||||
return m_RecvQueue;
|
return m_RecvQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
size_t TcpClient::FillRecvQueue(void)
|
||||||
* Processes data that is available for this socket.
|
|
||||||
*/
|
|
||||||
void TcpClient::ReadableEventHandler(void)
|
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -150,16 +161,34 @@ void TcpClient::ReadableEventHandler(void)
|
|||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
if (rc < 0 && errno == EAGAIN)
|
if (rc < 0 && errno == EAGAIN)
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
HandleSocketError(SocketException("recv() failed", GetError()));
|
HandleSocketError(SocketException("recv() failed", GetError()));
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_RecvQueue->Write(NULL, rc);
|
m_RecvQueue->Write(NULL, rc);
|
||||||
|
|
||||||
OnDataAvailable(GetSelf());
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcpClient::Flush(void)
|
||||||
|
{
|
||||||
|
/* try to speculatively flush the buffer if there's a reasonable amount
|
||||||
|
* of data, this may fail, e.g. when the socket cannot immediately
|
||||||
|
* send this much data - the event loop will take care of this later on */
|
||||||
|
if (GetSendQueue()->GetSize() > 128 * 1024)
|
||||||
|
FlushSendQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes data that is available for this socket.
|
||||||
|
*/
|
||||||
|
void TcpClient::ReadableEventHandler(void)
|
||||||
|
{
|
||||||
|
if (FillRecvQueue() > 0)
|
||||||
|
OnDataAvailable(GetSelf());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,16 +196,7 @@ void TcpClient::ReadableEventHandler(void)
|
|||||||
*/
|
*/
|
||||||
void TcpClient::WritableEventHandler(void)
|
void TcpClient::WritableEventHandler(void)
|
||||||
{
|
{
|
||||||
int rc;
|
FlushSendQueue();
|
||||||
|
|
||||||
rc = send(GetFD(), (const char *)m_SendQueue->GetReadBuffer(), m_SendQueue->GetSize(), 0);
|
|
||||||
|
|
||||||
if (rc <= 0) {
|
|
||||||
HandleSocketError(SocketException("send() failed", GetError()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_SendQueue->Read(NULL, rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,6 +58,8 @@ public:
|
|||||||
FIFO::Ptr GetSendQueue(void);
|
FIFO::Ptr GetSendQueue(void);
|
||||||
FIFO::Ptr GetRecvQueue(void);
|
FIFO::Ptr GetRecvQueue(void);
|
||||||
|
|
||||||
|
void Flush(void);
|
||||||
|
|
||||||
virtual bool WantsToRead(void) const;
|
virtual bool WantsToRead(void) const;
|
||||||
virtual bool WantsToWrite(void) const;
|
virtual bool WantsToWrite(void) const;
|
||||||
|
|
||||||
@ -69,8 +71,11 @@ private:
|
|||||||
FIFO::Ptr m_SendQueue;
|
FIFO::Ptr m_SendQueue;
|
||||||
FIFO::Ptr m_RecvQueue;
|
FIFO::Ptr m_RecvQueue;
|
||||||
|
|
||||||
virtual void ReadableEventHandler(void);
|
virtual size_t FillRecvQueue(void);
|
||||||
virtual void WritableEventHandler(void);
|
virtual size_t FlushSendQueue(void);
|
||||||
|
|
||||||
|
void ReadableEventHandler(void);
|
||||||
|
void WritableEventHandler(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,52 +106,62 @@ void TlsClient::Start(void)
|
|||||||
/**
|
/**
|
||||||
* Processes data that is available for this socket.
|
* Processes data that is available for this socket.
|
||||||
*/
|
*/
|
||||||
void TlsClient::ReadableEventHandler(void)
|
size_t TlsClient::FillRecvQueue(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int result;
|
||||||
|
|
||||||
m_BlockRead = false;
|
m_BlockRead = false;
|
||||||
m_BlockWrite = false;
|
m_BlockWrite = false;
|
||||||
|
|
||||||
size_t bufferSize = FIFO::BlockSize / 2;
|
result = 0;
|
||||||
char *buffer = (char *)GetRecvQueue()->GetWriteBuffer(&bufferSize);
|
|
||||||
rc = SSL_read(m_SSL.get(), buffer, bufferSize);
|
|
||||||
|
|
||||||
if (rc <= 0) {
|
for (;;) {
|
||||||
switch (SSL_get_error(m_SSL.get(), rc)) {
|
int rc;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
size_t bufferSize = FIFO::BlockSize / 2;
|
||||||
m_BlockRead = true;
|
char *buffer = (char *)GetRecvQueue()->GetWriteBuffer(&bufferSize);
|
||||||
/* fall through */
|
rc = SSL_read(m_SSL.get(), buffer, bufferSize);
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
return;
|
if (rc <= 0) {
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
switch (SSL_get_error(m_SSL.get(), rc)) {
|
||||||
Close();
|
case SSL_ERROR_WANT_WRITE:
|
||||||
return;
|
m_BlockRead = true;
|
||||||
default:
|
/* fall through */
|
||||||
HandleSocketError(OpenSSLException(
|
case SSL_ERROR_WANT_READ:
|
||||||
"SSL_read failed", ERR_get_error()));
|
return result;
|
||||||
return;
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
|
Close();
|
||||||
|
return result;
|
||||||
|
default:
|
||||||
|
HandleSocketError(OpenSSLException(
|
||||||
|
"SSL_read failed", ERR_get_error()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetRecvQueue()->Write(NULL, rc);
|
||||||
|
|
||||||
|
result += rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetRecvQueue()->Write(NULL, rc);
|
return result;
|
||||||
|
|
||||||
OnDataAvailable(GetSelf());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes data that can be written for this socket.
|
* Processes data that can be written for this socket.
|
||||||
*/
|
*/
|
||||||
void TlsClient::WritableEventHandler(void)
|
size_t TlsClient::FlushSendQueue(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!WantsToWrite())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::cerr << "tls sendq: " << GetSendQueue()->GetSize() << " bytes" << std::endl;
|
||||||
|
|
||||||
m_BlockRead = false;
|
m_BlockRead = false;
|
||||||
m_BlockWrite = false;
|
m_BlockWrite = false;
|
||||||
|
|
||||||
size_t write_size = std::min(GetSendQueue()->GetSize(), (size_t)(16 * 1024));
|
rc = SSL_write(m_SSL.get(), (const char *)GetSendQueue()->GetReadBuffer(), GetSendQueue()->GetSize());
|
||||||
|
|
||||||
rc = SSL_write(m_SSL.get(), (const char *)GetSendQueue()->GetReadBuffer(), write_size);
|
|
||||||
|
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
switch (SSL_get_error(m_SSL.get(), rc)) {
|
switch (SSL_get_error(m_SSL.get(), rc)) {
|
||||||
@ -159,18 +169,20 @@ void TlsClient::WritableEventHandler(void)
|
|||||||
m_BlockWrite = true;
|
m_BlockWrite = true;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
return;
|
return 0;
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
Close();
|
Close();
|
||||||
return;
|
return 0;
|
||||||
default:
|
default:
|
||||||
HandleSocketError(OpenSSLException(
|
HandleSocketError(OpenSSLException(
|
||||||
"SSL_write failed", ERR_get_error()));
|
"SSL_write failed", ERR_get_error()));
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetSendQueue()->Read(NULL, rc);
|
GetSendQueue()->Read(NULL, rc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,8 +56,8 @@ private:
|
|||||||
static int m_SSLIndex;
|
static int m_SSLIndex;
|
||||||
static bool m_SSLIndexInitialized;
|
static bool m_SSLIndexInitialized;
|
||||||
|
|
||||||
virtual void ReadableEventHandler(void);
|
virtual size_t FillRecvQueue(void);
|
||||||
virtual void WritableEventHandler(void);
|
virtual size_t FlushSendQueue(void);
|
||||||
|
|
||||||
virtual void CloseInternal(bool from_dtor);
|
virtual void CloseInternal(bool from_dtor);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user