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:
parent
bd378bbfa2
commit
696e3ff902
@ -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)
|
void TLSSocket_GnuTLS::sendRaw(const byte_t* buffer, const size_t count)
|
||||||
{
|
{
|
||||||
ssize_t ret = gnutls_record_send
|
m_status &= ~STATUS_WOULDBLOCK;
|
||||||
(*m_session->m_gnutlsSession,
|
|
||||||
buffer, static_cast <size_t>(count));
|
|
||||||
|
|
||||||
if (m_ex)
|
for (size_t size = count ; size > 0 ; )
|
||||||
internalThrow();
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
if (ret == GNUTLS_E_AGAIN)
|
ssize_t ret = gnutls_record_send
|
||||||
{
|
(*m_session->m_gnutlsSession,
|
||||||
m_status |= STATUS_WOULDBLOCK;
|
buffer, static_cast <size_t>(size));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ void TLSSocket_OpenSSL::createSSLHandle()
|
|||||||
|
|
||||||
SSL_set_bio(m_ssl, sockBio, sockBio);
|
SSL_set_bio(m_ssl, sockBio, sockBio);
|
||||||
SSL_set_connect_state(m_ssl);
|
SSL_set_connect_state(m_ssl);
|
||||||
|
SSL_set_mode(m_ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||||
}
|
}
|
||||||
else
|
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)
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user