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;
|
||||
|
||||
/* mark the socket as non-blocking */
|
||||
if (fd != INVALID_SOCKET) {
|
||||
#ifdef F_GETFL
|
||||
int flags;
|
||||
|
@ -124,6 +124,20 @@ FIFO::Ptr TcpClient::GetSendQueue(void)
|
||||
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.
|
||||
*
|
||||
@ -134,10 +148,7 @@ FIFO::Ptr TcpClient::GetRecvQueue(void)
|
||||
return m_RecvQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes data that is available for this socket.
|
||||
*/
|
||||
void TcpClient::ReadableEventHandler(void)
|
||||
size_t TcpClient::FillRecvQueue(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@ -150,16 +161,34 @@ void TcpClient::ReadableEventHandler(void)
|
||||
#else /* _WIN32 */
|
||||
if (rc < 0 && errno == EAGAIN)
|
||||
#endif /* _WIN32 */
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (rc <= 0) {
|
||||
HandleSocketError(SocketException("recv() failed", GetError()));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
|
||||
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);
|
||||
FlushSendQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,6 +58,8 @@ public:
|
||||
FIFO::Ptr GetSendQueue(void);
|
||||
FIFO::Ptr GetRecvQueue(void);
|
||||
|
||||
void Flush(void);
|
||||
|
||||
virtual bool WantsToRead(void) const;
|
||||
virtual bool WantsToWrite(void) const;
|
||||
|
||||
@ -69,8 +71,11 @@ private:
|
||||
FIFO::Ptr m_SendQueue;
|
||||
FIFO::Ptr m_RecvQueue;
|
||||
|
||||
virtual void ReadableEventHandler(void);
|
||||
virtual void WritableEventHandler(void);
|
||||
virtual size_t FillRecvQueue(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.
|
||||
*/
|
||||
void TlsClient::ReadableEventHandler(void)
|
||||
size_t TlsClient::FillRecvQueue(void)
|
||||
{
|
||||
int rc;
|
||||
int result;
|
||||
|
||||
m_BlockRead = false;
|
||||
m_BlockWrite = false;
|
||||
|
||||
size_t bufferSize = FIFO::BlockSize / 2;
|
||||
char *buffer = (char *)GetRecvQueue()->GetWriteBuffer(&bufferSize);
|
||||
rc = SSL_read(m_SSL.get(), buffer, bufferSize);
|
||||
result = 0;
|
||||
|
||||
if (rc <= 0) {
|
||||
switch (SSL_get_error(m_SSL.get(), rc)) {
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
m_BlockRead = true;
|
||||
/* fall through */
|
||||
case SSL_ERROR_WANT_READ:
|
||||
return;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
Close();
|
||||
return;
|
||||
default:
|
||||
HandleSocketError(OpenSSLException(
|
||||
"SSL_read failed", ERR_get_error()));
|
||||
return;
|
||||
for (;;) {
|
||||
int rc;
|
||||
size_t bufferSize = FIFO::BlockSize / 2;
|
||||
char *buffer = (char *)GetRecvQueue()->GetWriteBuffer(&bufferSize);
|
||||
rc = SSL_read(m_SSL.get(), buffer, bufferSize);
|
||||
|
||||
if (rc <= 0) {
|
||||
switch (SSL_get_error(m_SSL.get(), rc)) {
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
m_BlockRead = true;
|
||||
/* fall through */
|
||||
case SSL_ERROR_WANT_READ:
|
||||
return result;
|
||||
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);
|
||||
|
||||
OnDataAvailable(GetSelf());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes data that can be written for this socket.
|
||||
*/
|
||||
void TlsClient::WritableEventHandler(void)
|
||||
size_t TlsClient::FlushSendQueue(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!WantsToWrite())
|
||||
return 0;
|
||||
|
||||
std::cerr << "tls sendq: " << GetSendQueue()->GetSize() << " bytes" << std::endl;
|
||||
|
||||
m_BlockRead = 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(), write_size);
|
||||
rc = SSL_write(m_SSL.get(), (const char *)GetSendQueue()->GetReadBuffer(), GetSendQueue()->GetSize());
|
||||
|
||||
if (rc <= 0) {
|
||||
switch (SSL_get_error(m_SSL.get(), rc)) {
|
||||
@ -159,18 +169,20 @@ void TlsClient::WritableEventHandler(void)
|
||||
m_BlockWrite = true;
|
||||
/* fall through */
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return;
|
||||
return 0;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
Close();
|
||||
return;
|
||||
return 0;
|
||||
default:
|
||||
HandleSocketError(OpenSSLException(
|
||||
"SSL_write failed", ERR_get_error()));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
GetSendQueue()->Read(NULL, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,8 +56,8 @@ private:
|
||||
static int m_SSLIndex;
|
||||
static bool m_SSLIndexInitialized;
|
||||
|
||||
virtual void ReadableEventHandler(void);
|
||||
virtual void WritableEventHandler(void);
|
||||
virtual size_t FillRecvQueue(void);
|
||||
virtual size_t FlushSendQueue(void);
|
||||
|
||||
virtual void CloseInternal(bool from_dtor);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user