diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp index 5a90565b..18ea352d 100644 --- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp @@ -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 (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)); - TLSSession_GnuTLS::throwTLSException("gnutls_record_send", static_cast (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 (ret)); + } + else + { + buffer += ret; + size -= ret; + } } } diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp index ef6647d6..9857b8fb 100644 --- a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp @@ -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 (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; + } + } }