Loop on SSL_write/gnutls_record_send in blocking send.

OpenSSL reports SSL3_WRITE_PENDING on slow network connections, this
patch fixes it (and is the correct way to do).
This commit is contained in:
Vincent Richard 2014-01-03 21:54:32 +01:00
parent bd378bbfa2
commit 696e3ff902
2 changed files with 48 additions and 14 deletions

View File

@ -179,22 +179,32 @@ size_t TLSSocket_GnuTLS::receiveRaw(byte_t* buffer, const size_t count)
void TLSSocket_GnuTLS::sendRaw(const byte_t* buffer, const size_t count)
{
ssize_t ret = gnutls_record_send
(*m_session->m_gnutlsSession,
buffer, static_cast <size_t>(count));
m_status &= ~STATUS_WOULDBLOCK;
if (m_ex)
internalThrow();
if (ret < 0)
for (size_t size = count ; size > 0 ; )
{
if (ret == GNUTLS_E_AGAIN)
{
m_status |= STATUS_WOULDBLOCK;
return;
}
ssize_t ret = gnutls_record_send
(*m_session->m_gnutlsSession,
buffer, static_cast <size_t>(size));
TLSSession_GnuTLS::throwTLSException("gnutls_record_send", static_cast <int>(ret));
if (m_ex)
internalThrow();
if (ret < 0)
{
if (ret == GNUTLS_E_AGAIN)
{
platform::getHandler()->wait();
continue;
}
TLSSession_GnuTLS::throwTLSException("gnutls_record_send", static_cast <int>(ret));
}
else
{
buffer += ret;
size -= ret;
}
}
}

View File

@ -119,6 +119,7 @@ void TLSSocket_OpenSSL::createSSLHandle()
SSL_set_bio(m_ssl, sockBio, sockBio);
SSL_set_connect_state(m_ssl);
SSL_set_mode(m_ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
}
else
{
@ -234,7 +235,30 @@ size_t TLSSocket_OpenSSL::receiveRaw(byte_t* buffer, const size_t count)
void TLSSocket_OpenSSL::sendRaw(const byte_t* buffer, const size_t count)
{
sendRawNonBlocking(buffer, count);
m_status &= ~STATUS_WOULDBLOCK;
for (size_t size = count ; size > 0 ; )
{
int rc = SSL_write(m_ssl, buffer, static_cast <int>(size));
if (rc <= 0)
{
int error = SSL_get_error(m_ssl, rc);
if (error == SSL_ERROR_WANT_WRITE || error == SSL_ERROR_WANT_READ)
{
platform::getHandler()->wait();
continue;
}
handleError(rc);
}
else
{
buffer += rc;
size -= rc;
}
}
}