diff --git a/iowrapper.cpp b/iowrapper.cpp
index 51f4171..4fdb2af 100644
--- a/iowrapper.cpp
+++ b/iowrapper.cpp
@@ -22,8 +22,8 @@ License along with FlashMQ. If not, see .
#include "logger.h"
#include "client.h"
-IncompleteSslWrite::IncompleteSslWrite(const void *buf, size_t nbytes) :
- buf(buf),
+IncompleteSslWrite::IncompleteSslWrite(size_t nbytes) :
+ valid(true),
nbytes(nbytes)
{
@@ -31,13 +31,13 @@ IncompleteSslWrite::IncompleteSslWrite(const void *buf, size_t nbytes) :
void IncompleteSslWrite::reset()
{
- buf = nullptr;
+ valid = false;
nbytes = 0;
}
bool IncompleteSslWrite::hasPendingWrite() const
{
- return buf != nullptr;
+ return valid;
}
void IncompleteWebsocketRead::reset()
@@ -264,7 +264,6 @@ ssize_t IoWrapper::writeOrSslWrite(int fd, const void *buf, size_t nbytes, IoWra
}
else
{
- const void *buf_ = buf;
size_t nbytes_ = nbytes;
/*
@@ -273,7 +272,6 @@ ssize_t IoWrapper::writeOrSslWrite(int fd, const void *buf, size_t nbytes, IoWra
*/
if (this->incompleteSslWrite.hasPendingWrite())
{
- buf_ = this->incompleteSslWrite.buf;
nbytes_ = this->incompleteSslWrite.nbytes;
}
@@ -285,7 +283,7 @@ ssize_t IoWrapper::writeOrSslWrite(int fd, const void *buf, size_t nbytes, IoWra
ERR_clear_error();
char sslErrorBuf[OPENSSL_ERROR_STRING_SIZE];
- n = SSL_write(ssl, buf_, nbytes_);
+ n = SSL_write(ssl, buf, nbytes_);
if (n <= 0)
{
@@ -295,7 +293,7 @@ ssize_t IoWrapper::writeOrSslWrite(int fd, const void *buf, size_t nbytes, IoWra
{
logger->logf(LOG_DEBUG, "SSL Write is incomplete: %d. Will be retried later.", err);
*error = IoWrapResult::Wouldblock;
- IncompleteSslWrite sslAction(buf_, nbytes_);
+ IncompleteSslWrite sslAction(nbytes_);
this->incompleteSslWrite = sslAction;
if (err == SSL_ERROR_WANT_READ)
this->sslWriteWantsRead = true;
diff --git a/iowrapper.h b/iowrapper.h
index 2ffd804..e8441f9 100644
--- a/iowrapper.h
+++ b/iowrapper.h
@@ -56,17 +56,21 @@ enum class WebsocketOpcode
Unknown = 0xF
};
-/*
+/**
+ * @brief The IncompleteSslWrite struct facilities the SSL retry
+ *
* OpenSSL doc: "When a write function call has to be repeated because SSL_get_error(3) returned
* SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be repeated with the same arguments"
+ *
+ * Note that we use SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER.
*/
struct IncompleteSslWrite
{
- const void *buf = nullptr;
+ bool valid = false;
size_t nbytes = 0;
IncompleteSslWrite() = default;
- IncompleteSslWrite(const void *buf, size_t nbytes);
+ IncompleteSslWrite(size_t nbytes);
bool hasPendingWrite() const;
void reset();
diff --git a/listener.cpp b/listener.cpp
index adc30f9..9d4a18b 100644
--- a/listener.cpp
+++ b/listener.cpp
@@ -86,6 +86,8 @@ void Listener::loadCertAndKeyFromConfig()
sslctx = std::make_unique();
SSL_CTX_set_options(sslctx->get(), SSL_OP_NO_SSLv3); // TODO: config option
SSL_CTX_set_options(sslctx->get(), SSL_OP_NO_TLSv1); // TODO: config option
+
+ SSL_CTX_set_mode(sslctx->get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
}
if (SSL_CTX_use_certificate_file(sslctx->get(), sslFullchain.c_str(), SSL_FILETYPE_PEM) != 1)