From 4d49b442832de479523ea878f7ae2e35ea9a6682 Mon Sep 17 00:00:00 2001 From: Raoul Wols Date: Tue, 13 Jul 2021 11:37:31 +0200 Subject: [PATCH] separate cpp file --- src/linux_tcp/sslconnected.h | 28 +++++----- src/linux_tcp/sslerrorprinter.cpp | 93 +++++++++++++++++++++++++++++++ src/linux_tcp/sslerrorprinter.h | 59 ++------------------ 3 files changed, 111 insertions(+), 69 deletions(-) create mode 100644 src/linux_tcp/sslerrorprinter.cpp diff --git a/src/linux_tcp/sslconnected.h b/src/linux_tcp/sslconnected.h index d25185f..707443e 100644 --- a/src/linux_tcp/sslconnected.h +++ b/src/linux_tcp/sslconnected.h @@ -134,17 +134,17 @@ private: case SSL_ERROR_WANT_READ: // remember state _state = state; - + // the operation must be repeated when readable _parent->onIdle(this, _socket, readable); - + // allow chaining return true; - + case SSL_ERROR_WANT_WRITE: // remember state _state = state; - + // wait until socket becomes writable again _parent->onIdle(this, _socket, readable | writable); @@ -156,31 +156,31 @@ private: case SSL_ERROR_NONE: // we're ready for the next instruction from userspace _state = state_idle; - + // if we still have an outgoing buffer we want to send out data, otherwise we just read _parent->onIdle(this, _socket, _out ? readable | writable : readable); // nothing is wrong, we are done return true; - + default: - { // we are now in an error state _state = state_error; - // get a human-readable error string - const SslErrorPrinter printer{error}; + { + // get a human-readable error string + const SslErrorPrinter printer{error}; - // ensure it is null-terminated - const std::string message{printer.data(), printer.size()}; + // ensure it is null-terminated + const std::string message{printer.data(), printer.size()}; - // report an error to user-space - _parent->onError(this, message.data()); + // report an error to user-space + _parent->onError(this, message.data()); + } // ssl level error, we have to tear down the tcp connection return false; } - } } /** diff --git a/src/linux_tcp/sslerrorprinter.cpp b/src/linux_tcp/sslerrorprinter.cpp new file mode 100644 index 0000000..21e1493 --- /dev/null +++ b/src/linux_tcp/sslerrorprinter.cpp @@ -0,0 +1,93 @@ +/** + * SslErrorPrinter.cpp + * + * Implementation of SslErrorPrinter + * + * @copyright 2021 copernica BV + */ + +/** + * Dependencies + */ +#include "sslerrorprinter.h" +#include + +/** + * Begin namespace + */ +namespace AMQP { + +/** + * Constructor + * @param retval return value of SSL_get_error (must be a proper error) + * @throw std::bad_alloc if the BIO couldn't be allocated + */ +SslErrorPrinter::SslErrorPrinter(int retval) : _bio(nullptr, &::BIO_free) +{ + // check the return value of the SSL_get_error function, which has a very unfortunate name. + switch (retval) + { + // It can be a syscall error. + case SSL_ERROR_SYSCALL: + { + // The SSL_ERROR_SYSCALL with errno value of 0 indicates unexpected + // EOF from the peer. This will be properly reported as SSL_ERROR_SSL + // with reason code SSL_R_UNEXPECTED_EOF_WHILE_READING in the + // OpenSSL 3.0 release because it is truly a TLS protocol error to + // terminate the connection without a SSL_shutdown(). + if (errno == 0) _strerror = "SSL_R_UNEXPECTED_EOF_WHILE_READING"; + + // Otherwise we ask the OS for a description of the error. + else _strerror = ::strerror(errno); + + // done + break; + } + // It can be an error in OpenSSL. In that case the error stack contains + // more information. The documentation notes: if this error occurs then + // no further I/O operations should be performed on the connection and + // SSL_shutdown() must not be called. + case SSL_ERROR_SSL: + { + // create a new bio + _bio = decltype(_bio)(::BIO_new(::BIO_s_mem()), &::BIO_free); + + // check if it was allocated + if (!_bio) throw std::bad_alloc(); + + // invoke the convenience function to extract the whole error stack + ::ERR_print_errors(_bio.get()); + + // get it from the bio + ::BIO_get_mem_ptr(_bio.get(), &_bufmem); + + // done + break; + } + default: + { + // we don't know what kind of error this is + _strerror = "unknown ssl error"; + + // done + break; + } + } +} + +/** + * data ptr + * @return const char * + */ +const char *SslErrorPrinter::data() const noexcept { return _strerror ? _strerror : _bufmem->data; } + +/** + * length of the string + * @return size_t + */ +std::size_t SslErrorPrinter::size() const noexcept { return _strerror ? std::strlen(_strerror) : _bufmem->length; } + +/** + * End of namespace AMQP + */ +} diff --git a/src/linux_tcp/sslerrorprinter.h b/src/linux_tcp/sslerrorprinter.h index a6cc1a4..d361827 100644 --- a/src/linux_tcp/sslerrorprinter.h +++ b/src/linux_tcp/sslerrorprinter.h @@ -18,7 +18,6 @@ * Dependencies */ #include "openssl.h" -#include #include /** @@ -52,72 +51,22 @@ class SslErrorPrinter final public: /** * Constructor + * @param retval return value of SSL_get_error (must be a proper error) * @throw std::bad_alloc if the BIO couldn't be allocated */ - SslErrorPrinter(int retval) : _bio(nullptr, &::BIO_free) - { - // check the return value of the SSL_get_error function, which has a very unfortunate name. - switch (retval) - { - // It can be a syscall error. - case SSL_ERROR_SYSCALL: - { - // The SSL_ERROR_SYSCALL with errno value of 0 indicates unexpected - // EOF from the peer. This will be properly reported as SSL_ERROR_SSL - // with reason code SSL_R_UNEXPECTED_EOF_WHILE_READING in the - // OpenSSL 3.0 release because it is truly a TLS protocol error to - // terminate the connection without a SSL_shutdown(). - if (errno == 0) _strerror = "SSL_R_UNEXPECTED_EOF_WHILE_READING"; - - // Otherwise we ask the OS for a description of the error. - else _strerror = ::strerror(errno); - - // done - break; - } - // It can be an error in OpenSSL. In that case the error stack contains - // more information. The documentation notes: if this error occurs then - // no further I/O operations should be performed on the connection and - // SSL_shutdown() must not be called. - case SSL_ERROR_SSL: - { - // create a new bio - _bio = decltype(_bio)(::BIO_new(::BIO_s_mem()), &::BIO_free); - - // check if it was allocated - if (!_bio) throw std::bad_alloc(); - - // invoke the convenience function to extract the whole error stack - ::ERR_print_errors(_bio.get()); - - // get it from the bio - ::BIO_get_mem_ptr(_bio.get(), &_bufmem); - - // done - break; - } - default: - { - // we don't know what kind of error this is - _strerror = "unknown ssl error"; - - // done - break; - } - } - } + SslErrorPrinter(int retval); /** * data ptr * @return const char * */ - const char *data() const noexcept { return _strerror ? _strerror : _bufmem->data; } + const char *data() const noexcept; /** * length of the string * @return size_t */ - std::size_t size() const noexcept { return _strerror ? std::strlen(_strerror) : _bufmem->length; } + std::size_t size() const noexcept; }; /**