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)