diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2018-02-27 14:10:06 -0500 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2018-02-27 14:10:06 -0500 |
commit | de05b0b6b8c2f2e4b29f7eb2277c9503879e85da (patch) | |
tree | 3d97315d9f46edcc40cc833d89b781079703204a /src/mongo/util/net/ssl | |
parent | f2a8d9f2350f8cd5122cf3394b6783e85da5c390 (diff) | |
download | mongo-de05b0b6b8c2f2e4b29f7eb2277c9503879e85da.tar.gz |
SERVER-22411 Clang-Format
Diffstat (limited to 'src/mongo/util/net/ssl')
20 files changed, 1719 insertions, 1969 deletions
diff --git a/src/mongo/util/net/ssl/context.hpp b/src/mongo/util/net/ssl/context.hpp index e306f79c1de..278530f5916 100644 --- a/src/mongo/util/net/ssl/context.hpp +++ b/src/mongo/util/net/ssl/context.hpp @@ -37,4 +37,3 @@ #else #error "Unknown SSL Provider" #endif - diff --git a/src/mongo/util/net/ssl/context_base.hpp b/src/mongo/util/net/ssl/context_base.hpp index 1eca98fa729..01af07f20fa 100644 --- a/src/mongo/util/net/ssl/context_base.hpp +++ b/src/mongo/util/net/ssl/context_base.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_CONTEXT_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -28,138 +28,134 @@ namespace ssl { /// The context_base class is used as a base for the basic_context class /// template so that we have a common place to define various enums. -class context_base -{ +class context_base { public: - /// Different methods supported by a context. - enum method - { - /// Generic SSL version 2. - sslv2, + /// Different methods supported by a context. + enum method { + /// Generic SSL version 2. + sslv2, - /// SSL version 2 client. - sslv2_client, + /// SSL version 2 client. + sslv2_client, - /// SSL version 2 server. - sslv2_server, + /// SSL version 2 server. + sslv2_server, - /// Generic SSL version 3. - sslv3, + /// Generic SSL version 3. + sslv3, - /// SSL version 3 client. - sslv3_client, + /// SSL version 3 client. + sslv3_client, - /// SSL version 3 server. - sslv3_server, + /// SSL version 3 server. + sslv3_server, - /// Generic TLS version 1. - tlsv1, + /// Generic TLS version 1. + tlsv1, - /// TLS version 1 client. - tlsv1_client, + /// TLS version 1 client. + tlsv1_client, - /// TLS version 1 server. - tlsv1_server, + /// TLS version 1 server. + tlsv1_server, - /// Generic SSL/TLS. - sslv23, + /// Generic SSL/TLS. + sslv23, - /// SSL/TLS client. - sslv23_client, + /// SSL/TLS client. + sslv23_client, - /// SSL/TLS server. - sslv23_server, + /// SSL/TLS server. + sslv23_server, - /// Generic TLS version 1.1. - tlsv11, + /// Generic TLS version 1.1. + tlsv11, - /// TLS version 1.1 client. - tlsv11_client, + /// TLS version 1.1 client. + tlsv11_client, - /// TLS version 1.1 server. - tlsv11_server, + /// TLS version 1.1 server. + tlsv11_server, - /// Generic TLS version 1.2. - tlsv12, + /// Generic TLS version 1.2. + tlsv12, - /// TLS version 1.2 client. - tlsv12_client, + /// TLS version 1.2 client. + tlsv12_client, - /// TLS version 1.2 server. - tlsv12_server, + /// TLS version 1.2 server. + tlsv12_server, - /// Generic TLS. - tls, + /// Generic TLS. + tls, - /// TLS client. - tls_client, + /// TLS client. + tls_client, - /// TLS server. - tls_server - }; + /// TLS server. + tls_server + }; - /// Bitmask type for SSL options. - typedef long options; + /// Bitmask type for SSL options. + typedef long options; #if MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_OPENSSL #if defined(GENERATING_DOCUMENTATION) - /// Implement various bug workarounds. - static const long default_workarounds = implementation_defined; + /// Implement various bug workarounds. + static const long default_workarounds = implementation_defined; - /// Always create a new key when using tmp_dh parameters. - static const long single_dh_use = implementation_defined; + /// Always create a new key when using tmp_dh parameters. + static const long single_dh_use = implementation_defined; - /// Disable SSL v2. - static const long no_sslv2 = implementation_defined; + /// Disable SSL v2. + static const long no_sslv2 = implementation_defined; - /// Disable SSL v3. - static const long no_sslv3 = implementation_defined; + /// Disable SSL v3. + static const long no_sslv3 = implementation_defined; - /// Disable TLS v1. - static const long no_tlsv1 = implementation_defined; + /// Disable TLS v1. + static const long no_tlsv1 = implementation_defined; - /// Disable TLS v1.1. - static const long no_tlsv1_1 = implementation_defined; + /// Disable TLS v1.1. + static const long no_tlsv1_1 = implementation_defined; - /// Disable TLS v1.2. - static const long no_tlsv1_2 = implementation_defined; + /// Disable TLS v1.2. + static const long no_tlsv1_2 = implementation_defined; - /// Disable compression. Compression is disabled by default. - static const long no_compression = implementation_defined; + /// Disable compression. Compression is disabled by default. + static const long no_compression = implementation_defined; #else - ASIO_STATIC_CONSTANT(long, default_workarounds = SSL_OP_ALL); - ASIO_STATIC_CONSTANT(long, single_dh_use = SSL_OP_SINGLE_DH_USE); - ASIO_STATIC_CONSTANT(long, no_sslv2 = SSL_OP_NO_SSLv2); - ASIO_STATIC_CONSTANT(long, no_sslv3 = SSL_OP_NO_SSLv3); - ASIO_STATIC_CONSTANT(long, no_tlsv1 = SSL_OP_NO_TLSv1); -# if defined(SSL_OP_NO_TLSv1_1) - ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = SSL_OP_NO_TLSv1_1); -# else // defined(SSL_OP_NO_TLSv1_1) - ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = 0x10000000L); -# endif // defined(SSL_OP_NO_TLSv1_1) -# if defined(SSL_OP_NO_TLSv1_2) - ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = SSL_OP_NO_TLSv1_2); -# else // defined(SSL_OP_NO_TLSv1_2) - ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = 0x08000000L); -# endif // defined(SSL_OP_NO_TLSv1_2) -# if defined(SSL_OP_NO_COMPRESSION) - ASIO_STATIC_CONSTANT(long, no_compression = SSL_OP_NO_COMPRESSION); -# else // defined(SSL_OP_NO_COMPRESSION) - ASIO_STATIC_CONSTANT(long, no_compression = 0x20000L); -# endif // defined(SSL_OP_NO_COMPRESSION) + ASIO_STATIC_CONSTANT(long, default_workarounds = SSL_OP_ALL); + ASIO_STATIC_CONSTANT(long, single_dh_use = SSL_OP_SINGLE_DH_USE); + ASIO_STATIC_CONSTANT(long, no_sslv2 = SSL_OP_NO_SSLv2); + ASIO_STATIC_CONSTANT(long, no_sslv3 = SSL_OP_NO_SSLv3); + ASIO_STATIC_CONSTANT(long, no_tlsv1 = SSL_OP_NO_TLSv1); +#if defined(SSL_OP_NO_TLSv1_1) + ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = SSL_OP_NO_TLSv1_1); +#else // defined(SSL_OP_NO_TLSv1_1) + ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = 0x10000000L); +#endif // defined(SSL_OP_NO_TLSv1_1) +#if defined(SSL_OP_NO_TLSv1_2) + ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = SSL_OP_NO_TLSv1_2); +#else // defined(SSL_OP_NO_TLSv1_2) + ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = 0x08000000L); +#endif // defined(SSL_OP_NO_TLSv1_2) +#if defined(SSL_OP_NO_COMPRESSION) + ASIO_STATIC_CONSTANT(long, no_compression = SSL_OP_NO_COMPRESSION); +#else // defined(SSL_OP_NO_COMPRESSION) + ASIO_STATIC_CONSTANT(long, no_compression = 0x20000L); +#endif // defined(SSL_OP_NO_COMPRESSION) #endif #endif protected: - /// Protected destructor to prevent deletion through this type. - ~context_base() - { - } + /// Protected destructor to prevent deletion through this type. + ~context_base() {} }; -} // namespace ssl -} // namespace asio +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_CONTEXT_BASE_HPP +#endif // ASIO_SSL_CONTEXT_BASE_HPP diff --git a/src/mongo/util/net/ssl/context_openssl.hpp b/src/mongo/util/net/ssl/context_openssl.hpp index e457886ff02..b473d986c3a 100644 --- a/src/mongo/util/net/ssl/context_openssl.hpp +++ b/src/mongo/util/net/ssl/context_openssl.hpp @@ -12,84 +12,81 @@ #define ASIO_SSL_CONTEXT_OPENSSL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" -#include <string> #include "asio/buffer.hpp" #include "asio/io_context.hpp" #include "mongo/util/net/ssl/context_base.hpp" #include "mongo/util/net/ssl/detail/openssl_types.hpp" +#include <string> #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { -class context - : public context_base, - private noncopyable -{ +class context : public context_base, private noncopyable { public: - /// The native handle type of the SSL context. - typedef SSL_CTX* native_handle_type; + /// The native handle type of the SSL context. + typedef SSL_CTX* native_handle_type; - /// Constructor. - ASIO_DECL explicit context(method m); + /// Constructor. + ASIO_DECL explicit context(method m); #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a context from another. - /** - * This constructor moves an SSL context from one object to another. - * - * @param other The other context object from which the move will occur. - * - * @note Following the move, the following operations only are valid for the - * moved-from object: - * @li Destruction. - * @li As a target for move-assignment. - */ - ASIO_DECL context(context&& other); - - /// Move-assign a context from another. - /** - * This assignment operator moves an SSL context from one object to another. - * - * @param other The other context object from which the move will occur. - * - * @note Following the move, the following operations only are valid for the - * moved-from object: - * @li Destruction. - * @li As a target for move-assignment. - */ - ASIO_DECL context& operator=(context&& other); -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destructor. - ASIO_DECL ~context(); - - /// Get the underlying implementation in the native type. - /** - * This function may be used to obtain the underlying implementation of the - * context. This is intended to allow access to context functionality that is - * not otherwise provided. - */ - ASIO_DECL native_handle_type native_handle(); + /// Move-construct a context from another. + /** + * This constructor moves an SSL context from one object to another. + * + * @param other The other context object from which the move will occur. + * + * @note Following the move, the following operations only are valid for the + * moved-from object: + * @li Destruction. + * @li As a target for move-assignment. + */ + ASIO_DECL context(context&& other); + + /// Move-assign a context from another. + /** + * This assignment operator moves an SSL context from one object to another. + * + * @param other The other context object from which the move will occur. + * + * @note Following the move, the following operations only are valid for the + * moved-from object: + * @li Destruction. + * @li As a target for move-assignment. + */ + ASIO_DECL context& operator=(context&& other); +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destructor. + ASIO_DECL ~context(); + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to context functionality that is + * not otherwise provided. + */ + ASIO_DECL native_handle_type native_handle(); private: - // The underlying native implementation. - native_handle_type handle_; + // The underlying native implementation. + native_handle_type handle_; }; -} // namespace ssl -} // namespace asio +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) -# include "mongo/util/net/ssl/impl/context_openssl.ipp" -#endif // defined(ASIO_HEADER_ONLY) +#include "mongo/util/net/ssl/impl/context_openssl.ipp" +#endif // defined(ASIO_HEADER_ONLY) -#endif // ASIO_SSL_CONTEXT_OPENSSL_HPP +#endif // ASIO_SSL_CONTEXT_OPENSSL_HPP diff --git a/src/mongo/util/net/ssl/detail/buffered_handshake_op.hpp b/src/mongo/util/net/ssl/detail/buffered_handshake_op.hpp index 0390c1c9ce3..2dbfbb9f472 100644 --- a/src/mongo/util/net/ssl/detail/buffered_handshake_op.hpp +++ b/src/mongo/util/net/ssl/detail/buffered_handshake_op.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -26,89 +26,79 @@ namespace ssl { namespace detail { template <typename ConstBufferSequence> -class buffered_handshake_op -{ +class buffered_handshake_op { public: - buffered_handshake_op(stream_base::handshake_type type, - const ConstBufferSequence& buffers) - : type_(type), - buffers_(buffers), - total_buffer_size_(asio::buffer_size(buffers_)) - { - } - - engine::want operator()(engine& eng, - asio::error_code& ec, - std::size_t& bytes_transferred) const - { - return this->process(eng, ec, bytes_transferred, - asio::buffer_sequence_begin(buffers_), - asio::buffer_sequence_end(buffers_)); - } - - template <typename Handler> - void call_handler(Handler& handler, - const asio::error_code& ec, - const std::size_t& bytes_transferred) const - { - handler(ec, bytes_transferred); - } + buffered_handshake_op(stream_base::handshake_type type, const ConstBufferSequence& buffers) + : type_(type), buffers_(buffers), total_buffer_size_(asio::buffer_size(buffers_)) {} + + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const { + return this->process(eng, + ec, + bytes_transferred, + asio::buffer_sequence_begin(buffers_), + asio::buffer_sequence_end(buffers_)); + } + + template <typename Handler> + void call_handler(Handler& handler, + const asio::error_code& ec, + const std::size_t& bytes_transferred) const { + handler(ec, bytes_transferred); + } private: - template <typename Iterator> - engine::want process(engine& eng, - asio::error_code& ec, - std::size_t& bytes_transferred, - Iterator begin, Iterator end) const - { - Iterator iter = begin; - std::size_t accumulated_size = 0; - - for (;;) - { - engine::want want = eng.handshake(type_, ec); - if (want != engine::want_input_and_retry - || bytes_transferred == total_buffer_size_) - return want; - - // Find the next buffer piece to be fed to the engine. - while (iter != end) - { - const_buffer buffer(*iter); - - // Skip over any buffers which have already been consumed by the engine. - if (bytes_transferred >= accumulated_size + buffer.size()) - { - accumulated_size += buffer.size(); - ++iter; - continue; + template <typename Iterator> + engine::want process(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred, + Iterator begin, + Iterator end) const { + Iterator iter = begin; + std::size_t accumulated_size = 0; + + for (;;) { + engine::want want = eng.handshake(type_, ec); + if (want != engine::want_input_and_retry || bytes_transferred == total_buffer_size_) + return want; + + // Find the next buffer piece to be fed to the engine. + while (iter != end) { + const_buffer buffer(*iter); + + // Skip over any buffers which have already been consumed by the engine. + if (bytes_transferred >= accumulated_size + buffer.size()) { + accumulated_size += buffer.size(); + ++iter; + continue; + } + + // The current buffer may have been partially consumed by the engine on + // a previous iteration. If so, adjust the buffer to point to the + // unused portion. + if (bytes_transferred > accumulated_size) + buffer = buffer + (bytes_transferred - accumulated_size); + + // Pass the buffer to the engine, and update the bytes transferred to + // reflect the total number of bytes consumed so far. + bytes_transferred += buffer.size(); + buffer = eng.put_input(buffer); + bytes_transferred -= buffer.size(); + break; + } } - - // The current buffer may have been partially consumed by the engine on - // a previous iteration. If so, adjust the buffer to point to the - // unused portion. - if (bytes_transferred > accumulated_size) - buffer = buffer + (bytes_transferred - accumulated_size); - - // Pass the buffer to the engine, and update the bytes transferred to - // reflect the total number of bytes consumed so far. - bytes_transferred += buffer.size(); - buffer = eng.put_input(buffer); - bytes_transferred -= buffer.size(); - break; - } } - } - stream_base::handshake_type type_; - ConstBufferSequence buffers_; - std::size_t total_buffer_size_; + stream_base::handshake_type type_; + ConstBufferSequence buffers_; + std::size_t total_buffer_size_; }; -} // namespace detail -} // namespace ssl -} // namespace asio +} // namespace detail +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP +#endif // ASIO_SSL_DETAIL_BUFFERED_HANDSHAKE_OP_HPP diff --git a/src/mongo/util/net/ssl/detail/engine.hpp b/src/mongo/util/net/ssl/detail/engine.hpp index e190753a3f1..80fc21c5daf 100644 --- a/src/mongo/util/net/ssl/detail/engine.hpp +++ b/src/mongo/util/net/ssl/detail/engine.hpp @@ -37,4 +37,3 @@ #else #error "Unknown SSL Provider" #endif - diff --git a/src/mongo/util/net/ssl/detail/engine_openssl.hpp b/src/mongo/util/net/ssl/detail/engine_openssl.hpp index 75657d6307d..b1137e84eaf 100644 --- a/src/mongo/util/net/ssl/detail/engine_openssl.hpp +++ b/src/mongo/util/net/ssl/detail/engine_openssl.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_DETAIL_ENGINE_OPENSSL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -28,115 +28,113 @@ namespace asio { namespace ssl { namespace detail { -class engine -{ +class engine { public: - enum want - { - // Returned by functions to indicate that the engine wants input. The input - // buffer should be updated to point to the data. The engine then needs to - // be called again to retry the operation. - want_input_and_retry = -2, - - // Returned by functions to indicate that the engine wants to write output. - // The output buffer points to the data to be written. The engine then - // needs to be called again to retry the operation. - want_output_and_retry = -1, - - // Returned by functions to indicate that the engine doesn't need input or - // output. - want_nothing = 0, - - // Returned by functions to indicate that the engine wants to write output. - // The output buffer points to the data to be written. After that the - // operation is complete, and the engine does not need to be called again. - want_output = 1 - }; - - // Construct a new engine for the specified context. - ASIO_DECL explicit engine(SSL_CTX* context); - - // Destructor. - ASIO_DECL ~engine(); - - // Get the underlying implementation in the native type. - ASIO_DECL SSL* native_handle(); - - // Perform an SSL handshake using either SSL_connect (client-side) or - // SSL_accept (server-side). - ASIO_DECL want handshake( - stream_base::handshake_type type, asio::error_code& ec); - - // Perform a graceful shutdown of the SSL session. - ASIO_DECL want shutdown(asio::error_code& ec); - - // Write bytes to the SSL session. - ASIO_DECL want write(const asio::const_buffer& data, - asio::error_code& ec, std::size_t& bytes_transferred); - - // Read bytes from the SSL session. - ASIO_DECL want read(const asio::mutable_buffer& data, - asio::error_code& ec, std::size_t& bytes_transferred); - - // Get output data to be written to the transport. - ASIO_DECL asio::mutable_buffer get_output( - const asio::mutable_buffer& data); - - // Put input data that was read from the transport. - ASIO_DECL asio::const_buffer put_input( - const asio::const_buffer& data); - - // Map an error::eof code returned by the underlying transport according to - // the type and state of the SSL session. Returns a const reference to the - // error code object, suitable for passing to a completion handler. - ASIO_DECL const asio::error_code& map_error_code( - asio::error_code& ec) const; + enum want { + // Returned by functions to indicate that the engine wants input. The input + // buffer should be updated to point to the data. The engine then needs to + // be called again to retry the operation. + want_input_and_retry = -2, + + // Returned by functions to indicate that the engine wants to write output. + // The output buffer points to the data to be written. The engine then + // needs to be called again to retry the operation. + want_output_and_retry = -1, + + // Returned by functions to indicate that the engine doesn't need input or + // output. + want_nothing = 0, + + // Returned by functions to indicate that the engine wants to write output. + // The output buffer points to the data to be written. After that the + // operation is complete, and the engine does not need to be called again. + want_output = 1 + }; + + // Construct a new engine for the specified context. + ASIO_DECL explicit engine(SSL_CTX* context); + + // Destructor. + ASIO_DECL ~engine(); + + // Get the underlying implementation in the native type. + ASIO_DECL SSL* native_handle(); + + // Perform an SSL handshake using either SSL_connect (client-side) or + // SSL_accept (server-side). + ASIO_DECL want handshake(stream_base::handshake_type type, asio::error_code& ec); + + // Perform a graceful shutdown of the SSL session. + ASIO_DECL want shutdown(asio::error_code& ec); + + // Write bytes to the SSL session. + ASIO_DECL want write(const asio::const_buffer& data, + asio::error_code& ec, + std::size_t& bytes_transferred); + + // Read bytes from the SSL session. + ASIO_DECL want read(const asio::mutable_buffer& data, + asio::error_code& ec, + std::size_t& bytes_transferred); + + // Get output data to be written to the transport. + ASIO_DECL asio::mutable_buffer get_output(const asio::mutable_buffer& data); + + // Put input data that was read from the transport. + ASIO_DECL asio::const_buffer put_input(const asio::const_buffer& data); + + // Map an error::eof code returned by the underlying transport according to + // the type and state of the SSL session. Returns a const reference to the + // error code object, suitable for passing to a completion handler. + ASIO_DECL const asio::error_code& map_error_code(asio::error_code& ec) const; private: - // Disallow copying and assignment. - engine(const engine&); - engine& operator=(const engine&); + // Disallow copying and assignment. + engine(const engine&); + engine& operator=(const engine&); #if (OPENSSL_VERSION_NUMBER < 0x10000000L) - // The SSL_accept function may not be thread safe. This mutex is used to - // protect all calls to the SSL_accept function. - ASIO_DECL static asio::detail::static_mutex& accept_mutex(); -#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) + // The SSL_accept function may not be thread safe. This mutex is used to + // protect all calls to the SSL_accept function. + ASIO_DECL static asio::detail::static_mutex& accept_mutex(); +#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) - // Perform one operation. Returns >= 0 on success or error, want_read if the - // operation needs more input, or want_write if it needs to write some output - // before the operation can complete. - ASIO_DECL want perform(int (engine::* op)(void*, std::size_t), - void* data, std::size_t length, asio::error_code& ec, - std::size_t* bytes_transferred); + // Perform one operation. Returns >= 0 on success or error, want_read if the + // operation needs more input, or want_write if it needs to write some output + // before the operation can complete. + ASIO_DECL want perform(int (engine::*op)(void*, std::size_t), + void* data, + std::size_t length, + asio::error_code& ec, + std::size_t* bytes_transferred); - // Adapt the SSL_accept function to the signature needed for perform(). - ASIO_DECL int do_accept(void*, std::size_t); + // Adapt the SSL_accept function to the signature needed for perform(). + ASIO_DECL int do_accept(void*, std::size_t); - // Adapt the SSL_connect function to the signature needed for perform(). - ASIO_DECL int do_connect(void*, std::size_t); + // Adapt the SSL_connect function to the signature needed for perform(). + ASIO_DECL int do_connect(void*, std::size_t); - // Adapt the SSL_shutdown function to the signature needed for perform(). - ASIO_DECL int do_shutdown(void*, std::size_t); + // Adapt the SSL_shutdown function to the signature needed for perform(). + ASIO_DECL int do_shutdown(void*, std::size_t); - // Adapt the SSL_read function to the signature needed for perform(). - ASIO_DECL int do_read(void* data, std::size_t length); + // Adapt the SSL_read function to the signature needed for perform(). + ASIO_DECL int do_read(void* data, std::size_t length); - // Adapt the SSL_write function to the signature needed for perform(). - ASIO_DECL int do_write(void* data, std::size_t length); + // Adapt the SSL_write function to the signature needed for perform(). + ASIO_DECL int do_write(void* data, std::size_t length); - SSL* ssl_; - BIO* ext_bio_; + SSL* ssl_; + BIO* ext_bio_; }; -} // namespace detail -} // namespace ssl -} // namespace asio +} // namespace detail +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) -# include "mongo/util/net/ssl/detail/impl/engine_openssl.ipp" -#endif // defined(ASIO_HEADER_ONLY) +#include "mongo/util/net/ssl/detail/impl/engine_openssl.ipp" +#endif // defined(ASIO_HEADER_ONLY) -#endif // ASIO_SSL_DETAIL_ENGINE_OPENSSL_HPP +#endif // ASIO_SSL_DETAIL_ENGINE_OPENSSL_HPP diff --git a/src/mongo/util/net/ssl/detail/handshake_op.hpp b/src/mongo/util/net/ssl/detail/handshake_op.hpp index b15133db125..a6840f8bb01 100644 --- a/src/mongo/util/net/ssl/detail/handshake_op.hpp +++ b/src/mongo/util/net/ssl/detail/handshake_op.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -25,38 +25,30 @@ namespace asio { namespace ssl { namespace detail { -class handshake_op -{ +class handshake_op { public: - handshake_op(stream_base::handshake_type type) - : type_(type) - { - } - - engine::want operator()(engine& eng, - asio::error_code& ec, - std::size_t& bytes_transferred) const - { - bytes_transferred = 0; - return eng.handshake(type_, ec); - } - - template <typename Handler> - void call_handler(Handler& handler, - const asio::error_code& ec, - const std::size_t&) const - { - handler(ec); - } + handshake_op(stream_base::handshake_type type) : type_(type) {} + + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const { + bytes_transferred = 0; + return eng.handshake(type_, ec); + } + + template <typename Handler> + void call_handler(Handler& handler, const asio::error_code& ec, const std::size_t&) const { + handler(ec); + } private: - stream_base::handshake_type type_; + stream_base::handshake_type type_; }; -} // namespace detail -} // namespace ssl -} // namespace asio +} // namespace detail +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP +#endif // ASIO_SSL_DETAIL_HANDSHAKE_OP_HPP diff --git a/src/mongo/util/net/ssl/detail/impl/engine_openssl.ipp b/src/mongo/util/net/ssl/detail/impl/engine_openssl.ipp index c53a31e6a26..8ee2013d542 100644 --- a/src/mongo/util/net/ssl/detail/impl/engine_openssl.ipp +++ b/src/mongo/util/net/ssl/detail/impl/engine_openssl.ipp @@ -12,8 +12,8 @@ #define ASIO_SSL_DETAIL_IMPL_ENGINE_OPENSSL_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -28,237 +28,194 @@ namespace asio { namespace ssl { namespace detail { -engine::engine(SSL_CTX* context) - : ssl_(::SSL_new(context)) -{ - if (!ssl_) - { - asio::error_code ec( - static_cast<int>(::ERR_get_error()), - asio::error::get_ssl_category()); - asio::detail::throw_error(ec, "engine"); - } +engine::engine(SSL_CTX* context) : ssl_(::SSL_new(context)) { + if (!ssl_) { + asio::error_code ec(static_cast<int>(::ERR_get_error()), asio::error::get_ssl_category()); + asio::detail::throw_error(ec, "engine"); + } #if (OPENSSL_VERSION_NUMBER < 0x10000000L) - accept_mutex().init(); -#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) + accept_mutex().init(); +#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) - ::SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE); - ::SSL_set_mode(ssl_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + ::SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE); + ::SSL_set_mode(ssl_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); #if defined(SSL_MODE_RELEASE_BUFFERS) - ::SSL_set_mode(ssl_, SSL_MODE_RELEASE_BUFFERS); -#endif // defined(SSL_MODE_RELEASE_BUFFERS) + ::SSL_set_mode(ssl_, SSL_MODE_RELEASE_BUFFERS); +#endif // defined(SSL_MODE_RELEASE_BUFFERS) - ::BIO* int_bio = 0; - ::BIO_new_bio_pair(&int_bio, 0, &ext_bio_, 0); - ::SSL_set_bio(ssl_, int_bio, int_bio); + ::BIO* int_bio = 0; + ::BIO_new_bio_pair(&int_bio, 0, &ext_bio_, 0); + ::SSL_set_bio(ssl_, int_bio, int_bio); } -engine::~engine() -{ - if (SSL_get_app_data(ssl_)) - { - SSL_set_app_data(ssl_, 0); - } +engine::~engine() { + if (SSL_get_app_data(ssl_)) { + SSL_set_app_data(ssl_, 0); + } - ::BIO_free(ext_bio_); - ::SSL_free(ssl_); + ::BIO_free(ext_bio_); + ::SSL_free(ssl_); } -SSL* engine::native_handle() -{ - return ssl_; +SSL* engine::native_handle() { + return ssl_; } -engine::want engine::handshake( - stream_base::handshake_type type, asio::error_code& ec) -{ - return perform((type == asio::ssl::stream_base::client) - ? &engine::do_connect : &engine::do_accept, 0, 0, ec, 0); +engine::want engine::handshake(stream_base::handshake_type type, asio::error_code& ec) { + return perform((type == asio::ssl::stream_base::client) ? &engine::do_connect + : &engine::do_accept, + 0, + 0, + ec, + 0); } -engine::want engine::shutdown(asio::error_code& ec) -{ - return perform(&engine::do_shutdown, 0, 0, ec, 0); +engine::want engine::shutdown(asio::error_code& ec) { + return perform(&engine::do_shutdown, 0, 0, ec, 0); } engine::want engine::write(const asio::const_buffer& data, - asio::error_code& ec, std::size_t& bytes_transferred) -{ - if (data.size() == 0) - { - ec = asio::error_code(); - return engine::want_nothing; - } - - return perform(&engine::do_write, - const_cast<void*>(data.data()), - data.size(), ec, &bytes_transferred); + asio::error_code& ec, + std::size_t& bytes_transferred) { + if (data.size() == 0) { + ec = asio::error_code(); + return engine::want_nothing; + } + + return perform( + &engine::do_write, const_cast<void*>(data.data()), data.size(), ec, &bytes_transferred); } engine::want engine::read(const asio::mutable_buffer& data, - asio::error_code& ec, std::size_t& bytes_transferred) -{ - if (data.size() == 0) - { - ec = asio::error_code(); - return engine::want_nothing; - } - - return perform(&engine::do_read, data.data(), - data.size(), ec, &bytes_transferred); + asio::error_code& ec, + std::size_t& bytes_transferred) { + if (data.size() == 0) { + ec = asio::error_code(); + return engine::want_nothing; + } + + return perform(&engine::do_read, data.data(), data.size(), ec, &bytes_transferred); } -asio::mutable_buffer engine::get_output( - const asio::mutable_buffer& data) -{ - int length = ::BIO_read(ext_bio_, - data.data(), static_cast<int>(data.size())); +asio::mutable_buffer engine::get_output(const asio::mutable_buffer& data) { + int length = ::BIO_read(ext_bio_, data.data(), static_cast<int>(data.size())); - return asio::buffer(data, - length > 0 ? static_cast<std::size_t>(length) : 0); + return asio::buffer(data, length > 0 ? static_cast<std::size_t>(length) : 0); } -asio::const_buffer engine::put_input( - const asio::const_buffer& data) -{ - int length = ::BIO_write(ext_bio_, - data.data(), static_cast<int>(data.size())); +asio::const_buffer engine::put_input(const asio::const_buffer& data) { + int length = ::BIO_write(ext_bio_, data.data(), static_cast<int>(data.size())); - return asio::buffer(data + - (length > 0 ? static_cast<std::size_t>(length) : 0)); + return asio::buffer(data + (length > 0 ? static_cast<std::size_t>(length) : 0)); } -const asio::error_code& engine::map_error_code( - asio::error_code& ec) const -{ - // We only want to map the error::eof code. - if (ec != asio::error::eof) - return ec; +const asio::error_code& engine::map_error_code(asio::error_code& ec) const { + // We only want to map the error::eof code. + if (ec != asio::error::eof) + return ec; - // If there's data yet to be read, it's an error. - if (BIO_wpending(ext_bio_)) - { - ec = asio::ssl::error::stream_truncated; - return ec; - } + // If there's data yet to be read, it's an error. + if (BIO_wpending(ext_bio_)) { + ec = asio::ssl::error::stream_truncated; + return ec; + } - // SSL v2 doesn't provide a protocol-level shutdown, so an eof on the - // underlying transport is passed through. +// SSL v2 doesn't provide a protocol-level shutdown, so an eof on the +// underlying transport is passed through. #if (OPENSSL_VERSION_NUMBER < 0x10100000L) - if (SSL_version(ssl_) == SSL2_VERSION) - return ec; -#endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) + if (SSL_version(ssl_) == SSL2_VERSION) + return ec; +#endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) - // Otherwise, the peer should have negotiated a proper shutdown. - if ((::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN) == 0) - { - ec = asio::ssl::error::stream_truncated; - } + // Otherwise, the peer should have negotiated a proper shutdown. + if ((::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN) == 0) { + ec = asio::ssl::error::stream_truncated; + } - return ec; + return ec; } #if (OPENSSL_VERSION_NUMBER < 0x10000000L) -asio::detail::static_mutex& engine::accept_mutex() -{ - static asio::detail::static_mutex mutex = ASIO_STATIC_MUTEX_INIT; - return mutex; -} -#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) - -engine::want engine::perform(int (engine::* op)(void*, std::size_t), - void* data, std::size_t length, asio::error_code& ec, - std::size_t* bytes_transferred) -{ - std::size_t pending_output_before = ::BIO_ctrl_pending(ext_bio_); - ::ERR_clear_error(); - int result = (this->*op)(data, length); - int ssl_error = ::SSL_get_error(ssl_, result); - int sys_error = static_cast<int>(::ERR_get_error()); - std::size_t pending_output_after = ::BIO_ctrl_pending(ext_bio_); - - if (ssl_error == SSL_ERROR_SSL) - { - ec = asio::error_code(sys_error, - asio::error::get_ssl_category()); - return want_nothing; - } - - if (ssl_error == SSL_ERROR_SYSCALL) - { - ec = asio::error_code(sys_error, - asio::error::get_system_category()); - return want_nothing; - } - - if (result > 0 && bytes_transferred) - *bytes_transferred = static_cast<std::size_t>(result); - - if (ssl_error == SSL_ERROR_WANT_WRITE) - { - ec = asio::error_code(); - return want_output_and_retry; - } - else if (pending_output_after > pending_output_before) - { - ec = asio::error_code(); - return result > 0 ? want_output : want_output_and_retry; - } - else if (ssl_error == SSL_ERROR_WANT_READ) - { - ec = asio::error_code(); - return want_input_and_retry; - } - else if (::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN) - { - ec = asio::error::eof; - return want_nothing; - } - else - { - ec = asio::error_code(); - return want_nothing; - } -} - -int engine::do_accept(void*, std::size_t) -{ +asio::detail::static_mutex& engine::accept_mutex() { + static asio::detail::static_mutex mutex = ASIO_STATIC_MUTEX_INIT; + return mutex; +} +#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) + +engine::want engine::perform(int (engine::*op)(void*, std::size_t), + void* data, + std::size_t length, + asio::error_code& ec, + std::size_t* bytes_transferred) { + std::size_t pending_output_before = ::BIO_ctrl_pending(ext_bio_); + ::ERR_clear_error(); + int result = (this->*op)(data, length); + int ssl_error = ::SSL_get_error(ssl_, result); + int sys_error = static_cast<int>(::ERR_get_error()); + std::size_t pending_output_after = ::BIO_ctrl_pending(ext_bio_); + + if (ssl_error == SSL_ERROR_SSL) { + ec = asio::error_code(sys_error, asio::error::get_ssl_category()); + return want_nothing; + } + + if (ssl_error == SSL_ERROR_SYSCALL) { + ec = asio::error_code(sys_error, asio::error::get_system_category()); + return want_nothing; + } + + if (result > 0 && bytes_transferred) + *bytes_transferred = static_cast<std::size_t>(result); + + if (ssl_error == SSL_ERROR_WANT_WRITE) { + ec = asio::error_code(); + return want_output_and_retry; + } else if (pending_output_after > pending_output_before) { + ec = asio::error_code(); + return result > 0 ? want_output : want_output_and_retry; + } else if (ssl_error == SSL_ERROR_WANT_READ) { + ec = asio::error_code(); + return want_input_and_retry; + } else if (::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN) { + ec = asio::error::eof; + return want_nothing; + } else { + ec = asio::error_code(); + return want_nothing; + } +} + +int engine::do_accept(void*, std::size_t) { #if (OPENSSL_VERSION_NUMBER < 0x10000000L) - asio::detail::static_mutex::scoped_lock lock(accept_mutex()); -#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) - return ::SSL_accept(ssl_); + asio::detail::static_mutex::scoped_lock lock(accept_mutex()); +#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) + return ::SSL_accept(ssl_); } -int engine::do_connect(void*, std::size_t) -{ - return ::SSL_connect(ssl_); +int engine::do_connect(void*, std::size_t) { + return ::SSL_connect(ssl_); } -int engine::do_shutdown(void*, std::size_t) -{ - int result = ::SSL_shutdown(ssl_); - if (result == 0) - result = ::SSL_shutdown(ssl_); - return result; +int engine::do_shutdown(void*, std::size_t) { + int result = ::SSL_shutdown(ssl_); + if (result == 0) + result = ::SSL_shutdown(ssl_); + return result; } -int engine::do_read(void* data, std::size_t length) -{ - return ::SSL_read(ssl_, data, - length < INT_MAX ? static_cast<int>(length) : INT_MAX); +int engine::do_read(void* data, std::size_t length) { + return ::SSL_read(ssl_, data, length < INT_MAX ? static_cast<int>(length) : INT_MAX); } -int engine::do_write(void* data, std::size_t length) -{ - return ::SSL_write(ssl_, data, - length < INT_MAX ? static_cast<int>(length) : INT_MAX); +int engine::do_write(void* data, std::size_t length) { + return ::SSL_write(ssl_, data, length < INT_MAX ? static_cast<int>(length) : INT_MAX); } -} // namespace detail -} // namespace ssl -} // namespace asio +} // namespace detail +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_DETAIL_IMPL_ENGINE_OPENSSL_IPP +#endif // ASIO_SSL_DETAIL_IMPL_ENGINE_OPENSSL_IPP diff --git a/src/mongo/util/net/ssl/detail/io.hpp b/src/mongo/util/net/ssl/detail/io.hpp index c1176e5f3e3..a8f0cc42047 100644 --- a/src/mongo/util/net/ssl/detail/io.hpp +++ b/src/mongo/util/net/ssl/detail/io.hpp @@ -12,14 +12,14 @@ #define ASIO_SSL_DETAIL_IO_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" +#include "asio/write.hpp" #include "mongo/util/net/ssl/detail/engine.hpp" #include "mongo/util/net/ssl/detail/stream_core.hpp" -#include "asio/write.hpp" #include "asio/detail/push_options.hpp" @@ -28,345 +28,294 @@ namespace ssl { namespace detail { template <typename Stream, typename Operation> -std::size_t io(Stream& next_layer, stream_core& core, - const Operation& op, asio::error_code& ec) -{ - std::size_t bytes_transferred = 0; - do switch (op(core.engine_, ec, bytes_transferred)) - { - case engine::want_input_and_retry: +std::size_t io(Stream& next_layer, stream_core& core, const Operation& op, asio::error_code& ec) { + std::size_t bytes_transferred = 0; + do + switch (op(core.engine_, ec, bytes_transferred)) { + case engine::want_input_and_retry: - // If the input buffer is empty then we need to read some more data from - // the underlying transport. - if (core.input_.size() == 0) - core.input_ = asio::buffer(core.input_buffer_, - next_layer.read_some(core.input_buffer_, ec)); + // If the input buffer is empty then we need to read some more data from + // the underlying transport. + if (core.input_.size() == 0) + core.input_ = asio::buffer(core.input_buffer_, + next_layer.read_some(core.input_buffer_, ec)); - // Pass the new input data to the engine. - core.input_ = core.engine_.put_input(core.input_); + // Pass the new input data to the engine. + core.input_ = core.engine_.put_input(core.input_); - // Try the operation again. - continue; + // Try the operation again. + continue; - case engine::want_output_and_retry: + case engine::want_output_and_retry: - // Get output data from the engine and write it to the underlying - // transport. - asio::write(next_layer, - core.engine_.get_output(core.output_buffer_), ec); + // Get output data from the engine and write it to the underlying + // transport. + asio::write(next_layer, core.engine_.get_output(core.output_buffer_), ec); - // Try the operation again. - continue; + // Try the operation again. + continue; - case engine::want_output: + case engine::want_output: - // Get output data from the engine and write it to the underlying - // transport. - asio::write(next_layer, - core.engine_.get_output(core.output_buffer_), ec); - - // Operation is complete. Return result to caller. - core.engine_.map_error_code(ec); - return bytes_transferred; + // Get output data from the engine and write it to the underlying + // transport. + asio::write(next_layer, core.engine_.get_output(core.output_buffer_), ec); - default: + // Operation is complete. Return result to caller. + core.engine_.map_error_code(ec); + return bytes_transferred; - // Operation is complete. Return result to caller. - core.engine_.map_error_code(ec); - return bytes_transferred; + default: - } while (!ec); + // Operation is complete. Return result to caller. + core.engine_.map_error_code(ec); + return bytes_transferred; + } + while (!ec); - // Operation failed. Return result to caller. - core.engine_.map_error_code(ec); - return 0; + // Operation failed. Return result to caller. + core.engine_.map_error_code(ec); + return 0; } template <typename Stream, typename Operation, typename Handler> -class io_op -{ +class io_op { public: - io_op(Stream& next_layer, stream_core& core, - const Operation& op, Handler& handler) - : next_layer_(next_layer), - core_(core), - op_(op), - start_(0), - want_(engine::want_nothing), - bytes_transferred_(0), - handler_(ASIO_MOVE_CAST(Handler)(handler)) - { - } + io_op(Stream& next_layer, stream_core& core, const Operation& op, Handler& handler) + : next_layer_(next_layer), + core_(core), + op_(op), + start_(0), + want_(engine::want_nothing), + bytes_transferred_(0), + handler_(ASIO_MOVE_CAST(Handler)(handler)) {} #if defined(ASIO_HAS_MOVE) - io_op(const io_op& other) - : next_layer_(other.next_layer_), - core_(other.core_), - op_(other.op_), - start_(other.start_), - want_(other.want_), - ec_(other.ec_), - bytes_transferred_(other.bytes_transferred_), - handler_(other.handler_) - { - } - - io_op(io_op&& other) - : next_layer_(other.next_layer_), - core_(other.core_), - op_(other.op_), - start_(other.start_), - want_(other.want_), - ec_(other.ec_), - bytes_transferred_(other.bytes_transferred_), - handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) - { - } -#endif // defined(ASIO_HAS_MOVE) - - void operator()(asio::error_code ec, - std::size_t bytes_transferred = ~std::size_t(0), int start = 0) - { - switch (start_ = start) - { - case 1: // Called after at least one async operation. - do - { - switch (want_ = op_(core_.engine_, ec_, bytes_transferred_)) - { - case engine::want_input_and_retry: - - // If the input buffer already has data in it we can pass it to the - // engine and then retry the operation immediately. - if (core_.input_.size() != 0) - { - core_.input_ = core_.engine_.put_input(core_.input_); - continue; - } - - // The engine wants more data to be read from input. However, we - // cannot allow more than one read operation at a time on the - // underlying transport. The pending_read_ timer's expiry is set to - // pos_infin if a read is in progress, and neg_infin otherwise. - if (core_.expiry(core_.pending_read_) == core_.neg_infin()) - { - // Prevent other read operations from being started. - core_.pending_read_.expires_at(core_.pos_infin()); - - // Start reading some data from the underlying transport. - next_layer_.async_read_some( - asio::buffer(core_.input_buffer_), - ASIO_MOVE_CAST(io_op)(*this)); - } - else - { - // Wait until the current read operation completes. - core_.pending_read_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); - } - - // Yield control until asynchronous operation completes. Control - // resumes at the "default:" label below. - return; - - case engine::want_output_and_retry: - case engine::want_output: - - // The engine wants some data to be written to the output. However, we - // cannot allow more than one write operation at a time on the - // underlying transport. The pending_write_ timer's expiry is set to - // pos_infin if a write is in progress, and neg_infin otherwise. - if (core_.expiry(core_.pending_write_) == core_.neg_infin()) - { - // Prevent other write operations from being started. - core_.pending_write_.expires_at(core_.pos_infin()); - - // Start writing all the data to the underlying transport. - asio::async_write(next_layer_, - core_.engine_.get_output(core_.output_buffer_), - ASIO_MOVE_CAST(io_op)(*this)); - } - else - { - // Wait until the current write operation completes. - core_.pending_write_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); - } - - // Yield control until asynchronous operation completes. Control - // resumes at the "default:" label below. - return; - - default: - - // The SSL operation is done and we can invoke the handler, but we - // have to keep in mind that this function might be being called from - // the async operation's initiating function. In this case we're not - // allowed to call the handler directly. Instead, issue a zero-sized - // read so the handler runs "as-if" posted using io_context::post(). - if (start) - { - next_layer_.async_read_some( - asio::buffer(core_.input_buffer_, 0), - ASIO_MOVE_CAST(io_op)(*this)); - - // Yield control until asynchronous operation completes. Control - // resumes at the "default:" label below. - return; - } - else - { - // Continue on to run handler directly. - break; - } + io_op(const io_op& other) + : next_layer_(other.next_layer_), + core_(other.core_), + op_(other.op_), + start_(other.start_), + want_(other.want_), + ec_(other.ec_), + bytes_transferred_(other.bytes_transferred_), + handler_(other.handler_) {} + + io_op(io_op&& other) + : next_layer_(other.next_layer_), + core_(other.core_), + op_(other.op_), + start_(other.start_), + want_(other.want_), + ec_(other.ec_), + bytes_transferred_(other.bytes_transferred_), + handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) {} +#endif // defined(ASIO_HAS_MOVE) + + void operator()(asio::error_code ec, + std::size_t bytes_transferred = ~std::size_t(0), + int start = 0) { + switch (start_ = start) { + case 1: // Called after at least one async operation. + do { + switch (want_ = op_(core_.engine_, ec_, bytes_transferred_)) { + case engine::want_input_and_retry: + + // If the input buffer already has data in it we can pass it to the + // engine and then retry the operation immediately. + if (core_.input_.size() != 0) { + core_.input_ = core_.engine_.put_input(core_.input_); + continue; + } + + // The engine wants more data to be read from input. However, we + // cannot allow more than one read operation at a time on the + // underlying transport. The pending_read_ timer's expiry is set to + // pos_infin if a read is in progress, and neg_infin otherwise. + if (core_.expiry(core_.pending_read_) == core_.neg_infin()) { + // Prevent other read operations from being started. + core_.pending_read_.expires_at(core_.pos_infin()); + + // Start reading some data from the underlying transport. + next_layer_.async_read_some(asio::buffer(core_.input_buffer_), + ASIO_MOVE_CAST(io_op)(*this)); + } else { + // Wait until the current read operation completes. + core_.pending_read_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); + } + + // Yield control until asynchronous operation completes. Control + // resumes at the "default:" label below. + return; + + case engine::want_output_and_retry: + case engine::want_output: + + // The engine wants some data to be written to the output. However, we + // cannot allow more than one write operation at a time on the + // underlying transport. The pending_write_ timer's expiry is set to + // pos_infin if a write is in progress, and neg_infin otherwise. + if (core_.expiry(core_.pending_write_) == core_.neg_infin()) { + // Prevent other write operations from being started. + core_.pending_write_.expires_at(core_.pos_infin()); + + // Start writing all the data to the underlying transport. + asio::async_write(next_layer_, + core_.engine_.get_output(core_.output_buffer_), + ASIO_MOVE_CAST(io_op)(*this)); + } else { + // Wait until the current write operation completes. + core_.pending_write_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); + } + + // Yield control until asynchronous operation completes. Control + // resumes at the "default:" label below. + return; + + default: + + // The SSL operation is done and we can invoke the handler, but we + // have to keep in mind that this function might be being called from + // the async operation's initiating function. In this case we're not + // allowed to call the handler directly. Instead, issue a zero-sized + // read so the handler runs "as-if" posted using io_context::post(). + if (start) { + next_layer_.async_read_some(asio::buffer(core_.input_buffer_, 0), + ASIO_MOVE_CAST(io_op)(*this)); + + // Yield control until asynchronous operation completes. Control + // resumes at the "default:" label below. + return; + } else { + // Continue on to run handler directly. + break; + } + } + + default: + if (bytes_transferred == ~std::size_t(0)) + bytes_transferred = 0; // Timer cancellation, no data transferred. + else if (!ec_) + ec_ = ec; + + switch (want_) { + case engine::want_input_and_retry: + + // Add received data to the engine's input. + core_.input_ = asio::buffer(core_.input_buffer_, bytes_transferred); + core_.input_ = core_.engine_.put_input(core_.input_); + + // Release any waiting read operations. + core_.pending_read_.expires_at(core_.neg_infin()); + + // Try the operation again. + continue; + + case engine::want_output_and_retry: + + // Release any waiting write operations. + core_.pending_write_.expires_at(core_.neg_infin()); + + // Try the operation again. + continue; + + case engine::want_output: + + // Release any waiting write operations. + core_.pending_write_.expires_at(core_.neg_infin()); + + // Fall through to call handler. + + default: + + // Pass the result to the handler. + op_.call_handler(handler_, + core_.engine_.map_error_code(ec_), + ec_ ? 0 : bytes_transferred_); + + // Our work here is done. + return; + } + } while (!ec_); + + // Operation failed. Pass the result to the handler. + op_.call_handler(handler_, core_.engine_.map_error_code(ec_), 0); } - - default: - if (bytes_transferred == ~std::size_t(0)) - bytes_transferred = 0; // Timer cancellation, no data transferred. - else if (!ec_) - ec_ = ec; - - switch (want_) - { - case engine::want_input_and_retry: - - // Add received data to the engine's input. - core_.input_ = asio::buffer( - core_.input_buffer_, bytes_transferred); - core_.input_ = core_.engine_.put_input(core_.input_); - - // Release any waiting read operations. - core_.pending_read_.expires_at(core_.neg_infin()); - - // Try the operation again. - continue; - - case engine::want_output_and_retry: - - // Release any waiting write operations. - core_.pending_write_.expires_at(core_.neg_infin()); - - // Try the operation again. - continue; - - case engine::want_output: - - // Release any waiting write operations. - core_.pending_write_.expires_at(core_.neg_infin()); - - // Fall through to call handler. - - default: - - // Pass the result to the handler. - op_.call_handler(handler_, - core_.engine_.map_error_code(ec_), - ec_ ? 0 : bytes_transferred_); - - // Our work here is done. - return; - } - } while (!ec_); - - // Operation failed. Pass the result to the handler. - op_.call_handler(handler_, core_.engine_.map_error_code(ec_), 0); } - } - -//private: - Stream& next_layer_; - stream_core& core_; - Operation op_; - int start_; - engine::want want_; - asio::error_code ec_; - std::size_t bytes_transferred_; - Handler handler_; + + // private: + Stream& next_layer_; + stream_core& core_; + Operation op_; + int start_; + engine::want want_; + asio::error_code ec_; + std::size_t bytes_transferred_; + Handler handler_; }; template <typename Stream, typename Operation, typename Handler> inline void* asio_handler_allocate(std::size_t size, - io_op<Stream, Operation, Handler>* this_handler) -{ - return asio_handler_alloc_helpers::allocate( - size, this_handler->handler_); + io_op<Stream, Operation, Handler>* this_handler) { + return asio_handler_alloc_helpers::allocate(size, this_handler->handler_); } template <typename Stream, typename Operation, typename Handler> -inline void asio_handler_deallocate(void* pointer, std::size_t size, - io_op<Stream, Operation, Handler>* this_handler) -{ - asio_handler_alloc_helpers::deallocate( - pointer, size, this_handler->handler_); +inline void asio_handler_deallocate(void* pointer, + std::size_t size, + io_op<Stream, Operation, Handler>* this_handler) { + asio_handler_alloc_helpers::deallocate(pointer, size, this_handler->handler_); } template <typename Stream, typename Operation, typename Handler> -inline bool asio_handler_is_continuation( - io_op<Stream, Operation, Handler>* this_handler) -{ - return this_handler->start_ == 0 ? true - : asio_handler_cont_helpers::is_continuation(this_handler->handler_); +inline bool asio_handler_is_continuation(io_op<Stream, Operation, Handler>* this_handler) { + return this_handler->start_ == 0 + ? true + : asio_handler_cont_helpers::is_continuation(this_handler->handler_); } -template <typename Function, typename Stream, - typename Operation, typename Handler> +template <typename Function, typename Stream, typename Operation, typename Handler> inline void asio_handler_invoke(Function& function, - io_op<Stream, Operation, Handler>* this_handler) -{ - asio_handler_invoke_helpers::invoke( - function, this_handler->handler_); + io_op<Stream, Operation, Handler>* this_handler) { + asio_handler_invoke_helpers::invoke(function, this_handler->handler_); } -template <typename Function, typename Stream, - typename Operation, typename Handler> +template <typename Function, typename Stream, typename Operation, typename Handler> inline void asio_handler_invoke(const Function& function, - io_op<Stream, Operation, Handler>* this_handler) -{ - asio_handler_invoke_helpers::invoke( - function, this_handler->handler_); + io_op<Stream, Operation, Handler>* this_handler) { + asio_handler_invoke_helpers::invoke(function, this_handler->handler_); } template <typename Stream, typename Operation, typename Handler> -inline void async_io(Stream& next_layer, stream_core& core, - const Operation& op, Handler& handler) -{ - io_op<Stream, Operation, Handler>( - next_layer, core, op, handler)( - asio::error_code(), 0, 1); +inline void async_io(Stream& next_layer, stream_core& core, const Operation& op, Handler& handler) { + io_op<Stream, Operation, Handler>(next_layer, core, op, handler)(asio::error_code(), 0, 1); } -} // namespace detail -} // namespace ssl - -template <typename Stream, typename Operation, - typename Handler, typename Allocator> -struct associated_allocator< - ssl::detail::io_op<Stream, Operation, Handler>, Allocator> -{ - typedef typename associated_allocator<Handler, Allocator>::type type; - - static type get(const ssl::detail::io_op<Stream, Operation, Handler>& h, - const Allocator& a = Allocator()) ASIO_NOEXCEPT - { - return associated_allocator<Handler, Allocator>::get(h.handler_, a); - } +} // namespace detail +} // namespace ssl + +template <typename Stream, typename Operation, typename Handler, typename Allocator> +struct associated_allocator<ssl::detail::io_op<Stream, Operation, Handler>, Allocator> { + typedef typename associated_allocator<Handler, Allocator>::type type; + + static type get(const ssl::detail::io_op<Stream, Operation, Handler>& h, + const Allocator& a = Allocator()) ASIO_NOEXCEPT { + return associated_allocator<Handler, Allocator>::get(h.handler_, a); + } }; -template <typename Stream, typename Operation, - typename Handler, typename Executor> -struct associated_executor< - ssl::detail::io_op<Stream, Operation, Handler>, Executor> -{ - typedef typename associated_executor<Handler, Executor>::type type; - - static type get(const ssl::detail::io_op<Stream, Operation, Handler>& h, - const Executor& ex = Executor()) ASIO_NOEXCEPT - { - return associated_executor<Handler, Executor>::get(h.handler_, ex); - } +template <typename Stream, typename Operation, typename Handler, typename Executor> +struct associated_executor<ssl::detail::io_op<Stream, Operation, Handler>, Executor> { + typedef typename associated_executor<Handler, Executor>::type type; + + static type get(const ssl::detail::io_op<Stream, Operation, Handler>& h, + const Executor& ex = Executor()) ASIO_NOEXCEPT { + return associated_executor<Handler, Executor>::get(h.handler_, ex); + } }; -} // namespace asio +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_DETAIL_IO_HPP +#endif // ASIO_SSL_DETAIL_IO_HPP diff --git a/src/mongo/util/net/ssl/detail/openssl_types.hpp b/src/mongo/util/net/ssl/detail/openssl_types.hpp index a5ef5bb84d8..02dff7caac0 100644 --- a/src/mongo/util/net/ssl/detail/openssl_types.hpp +++ b/src/mongo/util/net/ssl/detail/openssl_types.hpp @@ -12,19 +12,19 @@ #define ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/detail/socket_types.hpp" #include <openssl/conf.h> #include <openssl/ssl.h> #if !defined(OPENSSL_NO_ENGINE) -# include <openssl/engine.h> -#endif // !defined(OPENSSL_NO_ENGINE) +#include <openssl/engine.h> +#endif // !defined(OPENSSL_NO_ENGINE) #include <openssl/dh.h> #include <openssl/err.h> #include <openssl/rsa.h> #include <openssl/x509v3.h> -#endif // ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP +#endif // ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP diff --git a/src/mongo/util/net/ssl/detail/read_op.hpp b/src/mongo/util/net/ssl/detail/read_op.hpp index 8eb4b1ad0ec..c2c0ee528e4 100644 --- a/src/mongo/util/net/ssl/detail/read_op.hpp +++ b/src/mongo/util/net/ssl/detail/read_op.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_DETAIL_READ_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -27,41 +27,35 @@ namespace ssl { namespace detail { template <typename MutableBufferSequence> -class read_op -{ +class read_op { public: - read_op(const MutableBufferSequence& buffers) - : buffers_(buffers) - { - } + read_op(const MutableBufferSequence& buffers) : buffers_(buffers) {} - engine::want operator()(engine& eng, - asio::error_code& ec, - std::size_t& bytes_transferred) const - { - asio::mutable_buffer buffer = - asio::detail::buffer_sequence_adapter<asio::mutable_buffer, - MutableBufferSequence>::first(buffers_); + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const { + asio::mutable_buffer buffer = + asio::detail::buffer_sequence_adapter<asio::mutable_buffer, + MutableBufferSequence>::first(buffers_); - return eng.read(buffer, ec, bytes_transferred); - } + return eng.read(buffer, ec, bytes_transferred); + } - template <typename Handler> - void call_handler(Handler& handler, - const asio::error_code& ec, - const std::size_t& bytes_transferred) const - { - handler(ec, bytes_transferred); - } + template <typename Handler> + void call_handler(Handler& handler, + const asio::error_code& ec, + const std::size_t& bytes_transferred) const { + handler(ec, bytes_transferred); + } private: - MutableBufferSequence buffers_; + MutableBufferSequence buffers_; }; -} // namespace detail -} // namespace ssl -} // namespace asio +} // namespace detail +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_DETAIL_READ_OP_HPP +#endif // ASIO_SSL_DETAIL_READ_OP_HPP diff --git a/src/mongo/util/net/ssl/detail/shutdown_op.hpp b/src/mongo/util/net/ssl/detail/shutdown_op.hpp index aaf3065ac72..7a289f74b34 100644 --- a/src/mongo/util/net/ssl/detail/shutdown_op.hpp +++ b/src/mongo/util/net/ssl/detail/shutdown_op.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -25,30 +25,25 @@ namespace asio { namespace ssl { namespace detail { -class shutdown_op -{ +class shutdown_op { public: - engine::want operator()(engine& eng, - asio::error_code& ec, - std::size_t& bytes_transferred) const - { - bytes_transferred = 0; - return eng.shutdown(ec); - } - - template <typename Handler> - void call_handler(Handler& handler, - const asio::error_code& ec, - const std::size_t&) const - { - handler(ec); - } + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const { + bytes_transferred = 0; + return eng.shutdown(ec); + } + + template <typename Handler> + void call_handler(Handler& handler, const asio::error_code& ec, const std::size_t&) const { + handler(ec); + } }; -} // namespace detail -} // namespace ssl -} // namespace asio +} // namespace detail +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP +#endif // ASIO_SSL_DETAIL_SHUTDOWN_OP_HPP diff --git a/src/mongo/util/net/ssl/detail/stream_core.hpp b/src/mongo/util/net/ssl/detail/stream_core.hpp index ae240d463af..21841fec2b9 100644 --- a/src/mongo/util/net/ssl/detail/stream_core.hpp +++ b/src/mongo/util/net/ssl/detail/stream_core.hpp @@ -12,18 +12,18 @@ #define ASIO_SSL_DETAIL_STREAM_CORE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #if defined(ASIO_HAS_BOOST_DATE_TIME) -# include "asio/deadline_timer.hpp" -#else // defined(ASIO_HAS_BOOST_DATE_TIME) -# include "asio/steady_timer.hpp" -#endif // defined(ASIO_HAS_BOOST_DATE_TIME) -#include "mongo/util/net/ssl/detail/engine.hpp" +#include "asio/deadline_timer.hpp" +#else // defined(ASIO_HAS_BOOST_DATE_TIME) +#include "asio/steady_timer.hpp" +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) #include "asio/buffer.hpp" +#include "mongo/util/net/ssl/detail/engine.hpp" #include "asio/detail/push_options.hpp" @@ -31,110 +31,98 @@ namespace asio { namespace ssl { namespace detail { -struct stream_core -{ - // According to the OpenSSL documentation, this is the buffer size that is - // sufficient to hold the largest possible TLS record. - enum { max_tls_record_size = 17 * 1024 }; +struct stream_core { + // According to the OpenSSL documentation, this is the buffer size that is + // sufficient to hold the largest possible TLS record. + enum { max_tls_record_size = 17 * 1024 }; #if MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_WINDOWS - stream_core(SCHANNEL_CRED* context, asio::io_context& io_context) + stream_core(SCHANNEL_CRED* context, asio::io_context& io_context) #elif MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_OPENSSL - stream_core(SSL_CTX* context, asio::io_context& io_context) + stream_core(SSL_CTX* context, asio::io_context& io_context) #else #error "Unknown SSL Provider" #endif - : engine_(context), - pending_read_(io_context), - pending_write_(io_context), - output_buffer_space_(max_tls_record_size), - output_buffer_(asio::buffer(output_buffer_space_)), - input_buffer_space_(max_tls_record_size), - input_buffer_(asio::buffer(input_buffer_space_)) - { - pending_read_.expires_at(neg_infin()); - pending_write_.expires_at(neg_infin()); - } - - ~stream_core() - { - } - - // The SSL engine. - engine engine_; + : engine_(context), + pending_read_(io_context), + pending_write_(io_context), + output_buffer_space_(max_tls_record_size), + output_buffer_(asio::buffer(output_buffer_space_)), + input_buffer_space_(max_tls_record_size), + input_buffer_(asio::buffer(input_buffer_space_)) { + pending_read_.expires_at(neg_infin()); + pending_write_.expires_at(neg_infin()); + } + + ~stream_core() {} + + // The SSL engine. + engine engine_; #if defined(ASIO_HAS_BOOST_DATE_TIME) - // Timer used for storing queued read operations. - asio::deadline_timer pending_read_; - - // Timer used for storing queued write operations. - asio::deadline_timer pending_write_; - - // Helper function for obtaining a time value that always fires. - static asio::deadline_timer::time_type neg_infin() - { - return boost::posix_time::neg_infin; - } - - // Helper function for obtaining a time value that never fires. - static asio::deadline_timer::time_type pos_infin() - { - return boost::posix_time::pos_infin; - } - - // Helper function to get a timer's expiry time. - static asio::deadline_timer::time_type expiry( - const asio::deadline_timer& timer) - { - return timer.expires_at(); - } -#else // defined(ASIO_HAS_BOOST_DATE_TIME) - // Timer used for storing queued read operations. - asio::steady_timer pending_read_; - - // Timer used for storing queued write operations. - asio::steady_timer pending_write_; - - // Helper function for obtaining a time value that always fires. - static asio::steady_timer::time_point neg_infin() - { - return (asio::steady_timer::time_point::min)(); - } - - // Helper function for obtaining a time value that never fires. - static asio::steady_timer::time_point pos_infin() - { - return (asio::steady_timer::time_point::max)(); - } - - // Helper function to get a timer's expiry time. - static asio::steady_timer::time_point expiry( - const asio::steady_timer& timer) - { - return timer.expiry(); - } -#endif // defined(ASIO_HAS_BOOST_DATE_TIME) - - // Buffer space used to prepare output intended for the transport. - std::vector<unsigned char> output_buffer_space_; - - // A buffer that may be used to prepare output intended for the transport. - const asio::mutable_buffer output_buffer_; - - // Buffer space used to read input intended for the engine. - std::vector<unsigned char> input_buffer_space_; - - // A buffer that may be used to read input intended for the engine. - const asio::mutable_buffer input_buffer_; - - // The buffer pointing to the engine's unconsumed input. - asio::const_buffer input_; + // Timer used for storing queued read operations. + asio::deadline_timer pending_read_; + + // Timer used for storing queued write operations. + asio::deadline_timer pending_write_; + + // Helper function for obtaining a time value that always fires. + static asio::deadline_timer::time_type neg_infin() { + return boost::posix_time::neg_infin; + } + + // Helper function for obtaining a time value that never fires. + static asio::deadline_timer::time_type pos_infin() { + return boost::posix_time::pos_infin; + } + + // Helper function to get a timer's expiry time. + static asio::deadline_timer::time_type expiry(const asio::deadline_timer& timer) { + return timer.expires_at(); + } +#else // defined(ASIO_HAS_BOOST_DATE_TIME) + // Timer used for storing queued read operations. + asio::steady_timer pending_read_; + + // Timer used for storing queued write operations. + asio::steady_timer pending_write_; + + // Helper function for obtaining a time value that always fires. + static asio::steady_timer::time_point neg_infin() { + return (asio::steady_timer::time_point::min)(); + } + + // Helper function for obtaining a time value that never fires. + static asio::steady_timer::time_point pos_infin() { + return (asio::steady_timer::time_point::max)(); + } + + // Helper function to get a timer's expiry time. + static asio::steady_timer::time_point expiry(const asio::steady_timer& timer) { + return timer.expiry(); + } +#endif // defined(ASIO_HAS_BOOST_DATE_TIME) + + // Buffer space used to prepare output intended for the transport. + std::vector<unsigned char> output_buffer_space_; + + // A buffer that may be used to prepare output intended for the transport. + const asio::mutable_buffer output_buffer_; + + // Buffer space used to read input intended for the engine. + std::vector<unsigned char> input_buffer_space_; + + // A buffer that may be used to read input intended for the engine. + const asio::mutable_buffer input_buffer_; + + // The buffer pointing to the engine's unconsumed input. + asio::const_buffer input_; }; -} // namespace detail -} // namespace ssl -} // namespace asio +} // namespace detail +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_DETAIL_STREAM_CORE_HPP +#endif // ASIO_SSL_DETAIL_STREAM_CORE_HPP diff --git a/src/mongo/util/net/ssl/detail/write_op.hpp b/src/mongo/util/net/ssl/detail/write_op.hpp index 4e69b31956f..21014137cc9 100644 --- a/src/mongo/util/net/ssl/detail/write_op.hpp +++ b/src/mongo/util/net/ssl/detail/write_op.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_DETAIL_WRITE_OP_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -27,41 +27,35 @@ namespace ssl { namespace detail { template <typename ConstBufferSequence> -class write_op -{ +class write_op { public: - write_op(const ConstBufferSequence& buffers) - : buffers_(buffers) - { - } + write_op(const ConstBufferSequence& buffers) : buffers_(buffers) {} - engine::want operator()(engine& eng, - asio::error_code& ec, - std::size_t& bytes_transferred) const - { - asio::const_buffer buffer = - asio::detail::buffer_sequence_adapter<asio::const_buffer, - ConstBufferSequence>::first(buffers_); + engine::want operator()(engine& eng, + asio::error_code& ec, + std::size_t& bytes_transferred) const { + asio::const_buffer buffer = + asio::detail::buffer_sequence_adapter<asio::const_buffer, ConstBufferSequence>::first( + buffers_); - return eng.write(buffer, ec, bytes_transferred); - } + return eng.write(buffer, ec, bytes_transferred); + } - template <typename Handler> - void call_handler(Handler& handler, - const asio::error_code& ec, - const std::size_t& bytes_transferred) const - { - handler(ec, bytes_transferred); - } + template <typename Handler> + void call_handler(Handler& handler, + const asio::error_code& ec, + const std::size_t& bytes_transferred) const { + handler(ec, bytes_transferred); + } private: - ConstBufferSequence buffers_; + ConstBufferSequence buffers_; }; -} // namespace detail -} // namespace ssl -} // namespace asio +} // namespace detail +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_DETAIL_WRITE_OP_HPP +#endif // ASIO_SSL_DETAIL_WRITE_OP_HPP diff --git a/src/mongo/util/net/ssl/error.hpp b/src/mongo/util/net/ssl/error.hpp index 6c96c3efe93..d8ad0f7a9b9 100644 --- a/src/mongo/util/net/ssl/error.hpp +++ b/src/mongo/util/net/ssl/error.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_ERROR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/error_code.hpp" @@ -27,88 +27,79 @@ namespace asio { namespace error { -enum ssl_errors -{ - // Error numbers are those produced by openssl. +enum ssl_errors { + // Error numbers are those produced by openssl. }; -extern ASIO_DECL -const asio::error_category& get_ssl_category(); +extern ASIO_DECL const asio::error_category& get_ssl_category(); -static const asio::error_category& - ssl_category ASIO_UNUSED_VARIABLE - = asio::error::get_ssl_category(); +static const asio::error_category& ssl_category ASIO_UNUSED_VARIABLE = + asio::error::get_ssl_category(); -} // namespace error +} // namespace error namespace ssl { namespace error { -enum stream_errors -{ +enum stream_errors { #if defined(GENERATING_DOCUMENTATION) - /// The underlying stream closed before the ssl stream gracefully shut down. - stream_truncated -#elif (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL) && MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_OPENSSL - stream_truncated = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ) + /// The underlying stream closed before the ssl stream gracefully shut down. + stream_truncated +#elif (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL) && \ + MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_OPENSSL + stream_truncated = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ) #else - stream_truncated = 1 + stream_truncated = 1 #endif }; -extern ASIO_DECL -const asio::error_category& get_stream_category(); +extern ASIO_DECL const asio::error_category& get_stream_category(); -static const asio::error_category& - stream_category ASIO_UNUSED_VARIABLE - = asio::ssl::error::get_stream_category(); +static const asio::error_category& stream_category ASIO_UNUSED_VARIABLE = + asio::ssl::error::get_stream_category(); -} // namespace error -} // namespace ssl -} // namespace asio +} // namespace error +} // namespace ssl +} // namespace asio #if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { -template<> struct is_error_code_enum<asio::error::ssl_errors> -{ - static const bool value = true; +template <> +struct is_error_code_enum<asio::error::ssl_errors> { + static const bool value = true; }; -template<> struct is_error_code_enum<asio::ssl::error::stream_errors> -{ - static const bool value = true; +template <> +struct is_error_code_enum<asio::ssl::error::stream_errors> { + static const bool value = true; }; -} // namespace std -#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) +} // namespace std +#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace asio { namespace error { -inline asio::error_code make_error_code(ssl_errors e) -{ - return asio::error_code( - static_cast<int>(e), get_ssl_category()); +inline asio::error_code make_error_code(ssl_errors e) { + return asio::error_code(static_cast<int>(e), get_ssl_category()); } -} // namespace error +} // namespace error namespace ssl { namespace error { -inline asio::error_code make_error_code(stream_errors e) -{ - return asio::error_code( - static_cast<int>(e), get_stream_category()); +inline asio::error_code make_error_code(stream_errors e) { + return asio::error_code(static_cast<int>(e), get_stream_category()); } -} // namespace error -} // namespace ssl -} // namespace asio +} // namespace error +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" #if defined(ASIO_HEADER_ONLY) -# include "mongo/util/net/ssl/impl/error.ipp" -#endif // defined(ASIO_HEADER_ONLY) +#include "mongo/util/net/ssl/impl/error.ipp" +#endif // defined(ASIO_HEADER_ONLY) -#endif // ASIO_SSL_ERROR_HPP +#endif // ASIO_SSL_ERROR_HPP diff --git a/src/mongo/util/net/ssl/impl/context_openssl.ipp b/src/mongo/util/net/ssl/impl/context_openssl.ipp index e2eeb2b83d4..b0b48910b4a 100644 --- a/src/mongo/util/net/ssl/impl/context_openssl.ipp +++ b/src/mongo/util/net/ssl/impl/context_openssl.ipp @@ -13,319 +13,291 @@ #define ASIO_SSL_IMPL_CONTEXT_OPENSSL_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" -#include <cstring> #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" #include "mongo/util/net/ssl/context.hpp" #include "mongo/util/net/ssl/error.hpp" +#include <cstring> #include "asio/detail/push_options.hpp" namespace asio { namespace ssl { -context::context(context::method m) - : handle_(0) -{ - ::ERR_clear_error(); +context::context(context::method m) : handle_(0) { + ::ERR_clear_error(); - switch (m) - { - // SSL v2. + switch (m) { +// SSL v2. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2) - case context::sslv2: - case context::sslv2_client: - case context::sslv2_server: - asio::detail::throw_error( - asio::error::invalid_argument, "context"); - break; -#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2) - case context::sslv2: - handle_ = ::SSL_CTX_new(::SSLv2_method()); - break; - case context::sslv2_client: - handle_ = ::SSL_CTX_new(::SSLv2_client_method()); - break; - case context::sslv2_server: - handle_ = ::SSL_CTX_new(::SSLv2_server_method()); - break; -#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2) + case context::sslv2: + case context::sslv2_client: + case context::sslv2_server: + asio::detail::throw_error(asio::error::invalid_argument, "context"); + break; +#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2) + case context::sslv2: + handle_ = ::SSL_CTX_new(::SSLv2_method()); + break; + case context::sslv2_client: + handle_ = ::SSL_CTX_new(::SSLv2_client_method()); + break; + case context::sslv2_server: + handle_ = ::SSL_CTX_new(::SSLv2_server_method()); + break; +#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2) - // SSL v3. +// SSL v3. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) - case context::sslv3: - handle_ = ::SSL_CTX_new(::TLS_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); - SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); - } - break; - case context::sslv3_client: - handle_ = ::SSL_CTX_new(::TLS_client_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); - SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); - } - break; - case context::sslv3_server: - handle_ = ::SSL_CTX_new(::TLS_server_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); - SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); - } - break; + case context::sslv3: + handle_ = ::SSL_CTX_new(::TLS_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); + SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); + } + break; + case context::sslv3_client: + handle_ = ::SSL_CTX_new(::TLS_client_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); + SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); + } + break; + case context::sslv3_server: + handle_ = ::SSL_CTX_new(::TLS_server_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION); + SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION); + } + break; #elif defined(OPENSSL_NO_SSL3) - case context::sslv3: - case context::sslv3_client: - case context::sslv3_server: - asio::detail::throw_error( - asio::error::invalid_argument, "context"); - break; -#else // defined(OPENSSL_NO_SSL3) - case context::sslv3: - handle_ = ::SSL_CTX_new(::SSLv3_method()); - break; - case context::sslv3_client: - handle_ = ::SSL_CTX_new(::SSLv3_client_method()); - break; - case context::sslv3_server: - handle_ = ::SSL_CTX_new(::SSLv3_server_method()); - break; -#endif // defined(OPENSSL_NO_SSL3) + case context::sslv3: + case context::sslv3_client: + case context::sslv3_server: + asio::detail::throw_error(asio::error::invalid_argument, "context"); + break; +#else // defined(OPENSSL_NO_SSL3) + case context::sslv3: + handle_ = ::SSL_CTX_new(::SSLv3_method()); + break; + case context::sslv3_client: + handle_ = ::SSL_CTX_new(::SSLv3_client_method()); + break; + case context::sslv3_server: + handle_ = ::SSL_CTX_new(::SSLv3_server_method()); + break; +#endif // defined(OPENSSL_NO_SSL3) - // TLS v1.0. +// TLS v1.0. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) - case context::tlsv1: - handle_ = ::SSL_CTX_new(::TLS_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); - } - break; - case context::tlsv1_client: - handle_ = ::SSL_CTX_new(::TLS_client_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); - } - break; - case context::tlsv1_server: - handle_ = ::SSL_CTX_new(::TLS_server_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); - } - break; -#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) - case context::tlsv1: - handle_ = ::SSL_CTX_new(::TLSv1_method()); - break; - case context::tlsv1_client: - handle_ = ::SSL_CTX_new(::TLSv1_client_method()); - break; - case context::tlsv1_server: - handle_ = ::SSL_CTX_new(::TLSv1_server_method()); - break; -#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) + case context::tlsv1: + handle_ = ::SSL_CTX_new(::TLS_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); + } + break; + case context::tlsv1_client: + handle_ = ::SSL_CTX_new(::TLS_client_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); + } + break; + case context::tlsv1_server: + handle_ = ::SSL_CTX_new(::TLS_server_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION); + } + break; +#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) + case context::tlsv1: + handle_ = ::SSL_CTX_new(::TLSv1_method()); + break; + case context::tlsv1_client: + handle_ = ::SSL_CTX_new(::TLSv1_client_method()); + break; + case context::tlsv1_server: + handle_ = ::SSL_CTX_new(::TLSv1_server_method()); + break; +#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) - // TLS v1.1. +// TLS v1.1. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) - case context::tlsv11: - handle_ = ::SSL_CTX_new(::TLS_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); - } - break; - case context::tlsv11_client: - handle_ = ::SSL_CTX_new(::TLS_client_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); - } - break; - case context::tlsv11_server: - handle_ = ::SSL_CTX_new(::TLS_server_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); - } - break; + case context::tlsv11: + handle_ = ::SSL_CTX_new(::TLS_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); + } + break; + case context::tlsv11_client: + handle_ = ::SSL_CTX_new(::TLS_client_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); + } + break; + case context::tlsv11_server: + handle_ = ::SSL_CTX_new(::TLS_server_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION); + } + break; #elif defined(SSL_TXT_TLSV1_1) - case context::tlsv11: - handle_ = ::SSL_CTX_new(::TLSv1_1_method()); - break; - case context::tlsv11_client: - handle_ = ::SSL_CTX_new(::TLSv1_1_client_method()); - break; - case context::tlsv11_server: - handle_ = ::SSL_CTX_new(::TLSv1_1_server_method()); - break; -#else // defined(SSL_TXT_TLSV1_1) - case context::tlsv11: - case context::tlsv11_client: - case context::tlsv11_server: - asio::detail::throw_error( - asio::error::invalid_argument, "context"); - break; -#endif // defined(SSL_TXT_TLSV1_1) + case context::tlsv11: + handle_ = ::SSL_CTX_new(::TLSv1_1_method()); + break; + case context::tlsv11_client: + handle_ = ::SSL_CTX_new(::TLSv1_1_client_method()); + break; + case context::tlsv11_server: + handle_ = ::SSL_CTX_new(::TLSv1_1_server_method()); + break; +#else // defined(SSL_TXT_TLSV1_1) + case context::tlsv11: + case context::tlsv11_client: + case context::tlsv11_server: + asio::detail::throw_error(asio::error::invalid_argument, "context"); + break; +#endif // defined(SSL_TXT_TLSV1_1) - // TLS v1.2. +// TLS v1.2. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) - case context::tlsv12: - handle_ = ::SSL_CTX_new(::TLS_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); - } - break; - case context::tlsv12_client: - handle_ = ::SSL_CTX_new(::TLS_client_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); - } - break; - case context::tlsv12_server: - handle_ = ::SSL_CTX_new(::TLS_server_method()); - if (handle_) - { - SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); - SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); - } - break; + case context::tlsv12: + handle_ = ::SSL_CTX_new(::TLS_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); + } + break; + case context::tlsv12_client: + handle_ = ::SSL_CTX_new(::TLS_client_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); + } + break; + case context::tlsv12_server: + handle_ = ::SSL_CTX_new(::TLS_server_method()); + if (handle_) { + SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION); + SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION); + } + break; #elif defined(SSL_TXT_TLSV1_1) - case context::tlsv12: - handle_ = ::SSL_CTX_new(::TLSv1_2_method()); - break; - case context::tlsv12_client: - handle_ = ::SSL_CTX_new(::TLSv1_2_client_method()); - break; - case context::tlsv12_server: - handle_ = ::SSL_CTX_new(::TLSv1_2_server_method()); - break; -#else // defined(SSL_TXT_TLSV1_1) - case context::tlsv12: - case context::tlsv12_client: - case context::tlsv12_server: - asio::detail::throw_error( - asio::error::invalid_argument, "context"); - break; -#endif // defined(SSL_TXT_TLSV1_1) + case context::tlsv12: + handle_ = ::SSL_CTX_new(::TLSv1_2_method()); + break; + case context::tlsv12_client: + handle_ = ::SSL_CTX_new(::TLSv1_2_client_method()); + break; + case context::tlsv12_server: + handle_ = ::SSL_CTX_new(::TLSv1_2_server_method()); + break; +#else // defined(SSL_TXT_TLSV1_1) + case context::tlsv12: + case context::tlsv12_client: + case context::tlsv12_server: + asio::detail::throw_error(asio::error::invalid_argument, "context"); + break; +#endif // defined(SSL_TXT_TLSV1_1) - // Any supported SSL/TLS version. - case context::sslv23: - handle_ = ::SSL_CTX_new(::SSLv23_method()); - break; - case context::sslv23_client: - handle_ = ::SSL_CTX_new(::SSLv23_client_method()); - break; - case context::sslv23_server: - handle_ = ::SSL_CTX_new(::SSLv23_server_method()); - break; + // Any supported SSL/TLS version. + case context::sslv23: + handle_ = ::SSL_CTX_new(::SSLv23_method()); + break; + case context::sslv23_client: + handle_ = ::SSL_CTX_new(::SSLv23_client_method()); + break; + case context::sslv23_server: + handle_ = ::SSL_CTX_new(::SSLv23_server_method()); + break; - // Any supported TLS version. +// Any supported TLS version. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) - case context::tls: - handle_ = ::SSL_CTX_new(::TLS_method()); - if (handle_) - SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); - break; - case context::tls_client: - handle_ = ::SSL_CTX_new(::TLS_client_method()); - if (handle_) - SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); - break; - case context::tls_server: - handle_ = ::SSL_CTX_new(::TLS_server_method()); - if (handle_) - SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); - break; -#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) - case context::tls: - handle_ = ::SSL_CTX_new(::SSLv23_method()); - if (handle_) - SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - break; - case context::tls_client: - handle_ = ::SSL_CTX_new(::SSLv23_client_method()); - if (handle_) - SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - break; - case context::tls_server: - handle_ = ::SSL_CTX_new(::SSLv23_server_method()); - if (handle_) - SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - break; -#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) + case context::tls: + handle_ = ::SSL_CTX_new(::TLS_method()); + if (handle_) + SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); + break; + case context::tls_client: + handle_ = ::SSL_CTX_new(::TLS_client_method()); + if (handle_) + SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); + break; + case context::tls_server: + handle_ = ::SSL_CTX_new(::TLS_server_method()); + if (handle_) + SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION); + break; +#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) + case context::tls: + handle_ = ::SSL_CTX_new(::SSLv23_method()); + if (handle_) + SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + break; + case context::tls_client: + handle_ = ::SSL_CTX_new(::SSLv23_client_method()); + if (handle_) + SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + break; + case context::tls_server: + handle_ = ::SSL_CTX_new(::SSLv23_server_method()); + if (handle_) + SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + break; +#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) - default: - handle_ = ::SSL_CTX_new(0); - break; - } + default: + handle_ = ::SSL_CTX_new(0); + break; + } - if (handle_ == 0) - { - asio::error_code ec( - static_cast<int>(::ERR_get_error()), - asio::error::get_ssl_category()); - asio::detail::throw_error(ec, "context"); - } + if (handle_ == 0) { + asio::error_code ec(static_cast<int>(::ERR_get_error()), asio::error::get_ssl_category()); + asio::detail::throw_error(ec, "context"); + } } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) -context::context(context&& other) -{ - handle_ = other.handle_; - other.handle_ = 0; +context::context(context&& other) { + handle_ = other.handle_; + other.handle_ = 0; } -context& context::operator=(context&& other) -{ - context tmp(ASIO_MOVE_CAST(context)(*this)); - handle_ = other.handle_; - other.handle_ = 0; - return *this; +context& context::operator=(context&& other) { + context tmp(ASIO_MOVE_CAST(context)(*this)); + handle_ = other.handle_; + other.handle_ = 0; + return *this; } -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) -context::~context() -{ - if (handle_) - { - if (SSL_CTX_get_app_data(handle_)) - { - SSL_CTX_set_app_data(handle_, 0); - } +context::~context() { + if (handle_) { + if (SSL_CTX_get_app_data(handle_)) { + SSL_CTX_set_app_data(handle_, 0); + } - ::SSL_CTX_free(handle_); - } + ::SSL_CTX_free(handle_); + } } -context::native_handle_type context::native_handle() -{ - return handle_; +context::native_handle_type context::native_handle() { + return handle_; } -} // namespace ssl -} // namespace asio +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_IMPL_CONTEXT_OPENSSL_IPP +#endif // ASIO_SSL_IMPL_CONTEXT_OPENSSL_IPP diff --git a/src/mongo/util/net/ssl/impl/error.ipp b/src/mongo/util/net/ssl/impl/error.ipp index 64d3a28bae7..60b8f0da177 100644 --- a/src/mongo/util/net/ssl/impl/error.ipp +++ b/src/mongo/util/net/ssl/impl/error.ipp @@ -12,12 +12,12 @@ #define ASIO_SSL_IMPL_ERROR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" -#include "mongo/util/net/ssl/error.hpp" #include "mongo/util/errno_util.h" +#include "mongo/util/net/ssl/error.hpp" #include "asio/detail/push_options.hpp" @@ -25,85 +25,76 @@ namespace asio { namespace error { namespace detail { -class ssl_category : public asio::error_category -{ +class ssl_category : public asio::error_category { public: - const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT - { - return "asio.ssl"; - } + const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { + return "asio.ssl"; + } #if MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_WINDOWS - std::string message(int value) const - { - return mongo::errnoWithDescription(value); - } + std::string message(int value) const { + return mongo::errnoWithDescription(value); + } #elif MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_OPENSSL - std::string message(int value) const - { - const char* s = ::ERR_reason_error_string(value); - return s ? s : "asio.ssl error"; - } + std::string message(int value) const { + const char* s = ::ERR_reason_error_string(value); + return s ? s : "asio.ssl error"; + } #else #error "Unknown SSL Provider" #endif }; -} // namespace detail +} // namespace detail -const asio::error_category& get_ssl_category() -{ - static detail::ssl_category instance; - return instance; +const asio::error_category& get_ssl_category() { + static detail::ssl_category instance; + return instance; } -} // namespace error +} // namespace error namespace ssl { namespace error { #if (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL) -const asio::error_category& get_stream_category() -{ - return asio::error::get_ssl_category(); +const asio::error_category& get_stream_category() { + return asio::error::get_ssl_category(); } #else namespace detail { -class stream_category : public asio::error_category -{ +class stream_category : public asio::error_category { public: - const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT - { - return "asio.ssl.stream"; - } - - std::string message(int value) const - { - switch (value) - { - case stream_truncated: return "stream truncated"; - default: return "asio.ssl.stream error"; + const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { + return "asio.ssl.stream"; + } + + std::string message(int value) const { + switch (value) { + case stream_truncated: + return "stream truncated"; + default: + return "asio.ssl.stream error"; + } } - } }; -} // namespace detail +} // namespace detail -const asio::error_category& get_stream_category() -{ - static detail::stream_category instance; - return instance; +const asio::error_category& get_stream_category() { + static detail::stream_category instance; + return instance; } #endif -} // namespace error -} // namespace ssl -} // namespace asio +} // namespace error +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_IMPL_ERROR_IPP +#endif // ASIO_SSL_IMPL_ERROR_IPP diff --git a/src/mongo/util/net/ssl/impl/src.hpp b/src/mongo/util/net/ssl/impl/src.hpp index fd940e414af..f5bb866efee 100644 --- a/src/mongo/util/net/ssl/impl/src.hpp +++ b/src/mongo/util/net/ssl/impl/src.hpp @@ -16,27 +16,26 @@ #include "asio/detail/config.hpp" #if defined(ASIO_HEADER_ONLY) -# error Do not compile Asio library source with ASIO_HEADER_ONLY defined +#error Do not compile Asio library source with ASIO_HEADER_ONLY defined #endif #if MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_WINDOWS -#include "mongo/util/net/ssl/impl/context_schannel.ipp" -#include "mongo/util/net/ssl/impl/error.ipp" #include "mongo/util/net/ssl/detail/impl/engine_schannel.ipp" #include "mongo/util/net/ssl/detail/impl/schannel.ipp" +#include "mongo/util/net/ssl/impl/context_schannel.ipp" +#include "mongo/util/net/ssl/impl/error.ipp" #elif MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_OPENSSL +#include "mongo/util/net/ssl/detail/impl/engine_openssl.ipp" #include "mongo/util/net/ssl/impl/context_openssl.ipp" #include "mongo/util/net/ssl/impl/error.ipp" -#include "mongo/util/net/ssl/detail/impl/engine_openssl.ipp" #else #error "Unknown SSL Provider" #endif - -#endif // ASIO_SSL_IMPL_SRC_HPP +#endif // ASIO_SSL_IMPL_SRC_HPP diff --git a/src/mongo/util/net/ssl/stream.hpp b/src/mongo/util/net/ssl/stream.hpp index bcf92cf9eaa..d44bdc4bd08 100644 --- a/src/mongo/util/net/ssl/stream.hpp +++ b/src/mongo/util/net/ssl/stream.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_STREAM_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -60,573 +60,526 @@ namespace ssl { * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. */ template <typename Stream> -class stream : - public stream_base, - private noncopyable -{ +class stream : public stream_base, private noncopyable { public: - /// The native handle type of the SSL stream. +/// The native handle type of the SSL stream. #if MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_WINDOWS - typedef PCtxtHandle native_handle_type; + typedef PCtxtHandle native_handle_type; #elif MONGO_CONFIG_SSL_PROVIDER == SSL_PROVIDER_OPENSSL - typedef SSL* native_handle_type; + typedef SSL* native_handle_type; #else #error "Unknown SSL Provider" #endif - /// The type of the next layer. - typedef typename remove_reference<Stream>::type next_layer_type; + /// The type of the next layer. + typedef typename remove_reference<Stream>::type next_layer_type; - /// The type of the lowest layer. - typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; - /// The type of the executor associated with the object. - typedef typename lowest_layer_type::executor_type executor_type; + /// The type of the executor associated with the object. + typedef typename lowest_layer_type::executor_type executor_type; #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Construct a stream. - /** - * This constructor creates a stream and initialises the underlying stream - * object. - * - * @param arg The argument to be passed to initialise the underlying stream. - * - * @param ctx The SSL context to be used for the stream. - */ - template <typename Arg> - stream(Arg&& arg, context& ctx) - : next_layer_(ASIO_MOVE_CAST(Arg)(arg)), - core_(ctx.native_handle(), - next_layer_.lowest_layer().get_executor().context()) - { - } -#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - template <typename Arg> - stream(Arg& arg, context& ctx) - : next_layer_(arg), - core_(ctx.native_handle(), - next_layer_.lowest_layer().get_executor().context()) - { - } -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destructor. - /** - * @note A @c stream object must not be destroyed while there are pending - * asynchronous operations associated with it. - */ - ~stream() - { - } - - /// Get the executor associated with the object. - /** - * This function may be used to obtain the executor object that the stream - * uses to dispatch handlers for asynchronous operations. - * - * @return A copy of the executor that stream will use to dispatch handlers. - */ - executor_type get_executor() ASIO_NOEXCEPT - { - return next_layer_.lowest_layer().get_executor(); - } + /// Construct a stream. + /** + * This constructor creates a stream and initialises the underlying stream + * object. + * + * @param arg The argument to be passed to initialise the underlying stream. + * + * @param ctx The SSL context to be used for the stream. + */ + template <typename Arg> + stream(Arg&& arg, context& ctx) + : next_layer_(ASIO_MOVE_CAST(Arg)(arg)), + core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor().context()) {} +#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + template <typename Arg> + stream(Arg& arg, context& ctx) + : next_layer_(arg), + core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor().context()) {} +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destructor. + /** + * @note A @c stream object must not be destroyed while there are pending + * asynchronous operations associated with it. + */ + ~stream() {} + + /// Get the executor associated with the object. + /** + * This function may be used to obtain the executor object that the stream + * uses to dispatch handlers for asynchronous operations. + * + * @return A copy of the executor that stream will use to dispatch handlers. + */ + executor_type get_executor() ASIO_NOEXCEPT { + return next_layer_.lowest_layer().get_executor(); + } #if !defined(ASIO_NO_DEPRECATED) - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - asio::io_context& get_io_context() - { - return next_layer_.lowest_layer().get_io_context(); - } - - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - asio::io_context& get_io_service() - { - return next_layer_.lowest_layer().get_io_service(); - } -#endif // !defined(ASIO_NO_DEPRECATED) - - /// Get the underlying implementation in the native type. - /** - * This function may be used to obtain the underlying implementation of the - * context. This is intended to allow access to context functionality that is - * not otherwise provided. - * - * @par Example - * The native_handle() function returns a pointer of type @c SSL* that is - * suitable for passing to functions such as @c SSL_get_verify_result and - * @c SSL_get_peer_certificate: - * @code - * asio::ssl::stream<asio:ip::tcp::socket> sock(io_context, ctx); - * - * // ... establish connection and perform handshake ... - * - * if (X509* cert = SSL_get_peer_certificate(sock.native_handle())) - * { - * if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK) - * { - * // ... - * } - * } - * @endcode - */ - native_handle_type native_handle() - { - return core_.engine_.native_handle(); - } - - /// Get a reference to the next layer. - /** - * This function returns a reference to the next layer in a stack of stream - * layers. - * - * @return A reference to the next layer in the stack of stream layers. - * Ownership is not transferred to the caller. - */ - const next_layer_type& next_layer() const - { - return next_layer_; - } - - /// Get a reference to the next layer. - /** - * This function returns a reference to the next layer in a stack of stream - * layers. - * - * @return A reference to the next layer in the stack of stream layers. - * Ownership is not transferred to the caller. - */ - next_layer_type& next_layer() - { - return next_layer_; - } - - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * stream layers. - * - * @return A reference to the lowest layer in the stack of stream layers. - * Ownership is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return next_layer_.lowest_layer(); - } - - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * stream layers. - * - * @return A reference to the lowest layer in the stack of stream layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return next_layer_.lowest_layer(); - } - - /// Perform SSL handshaking. - /** - * This function is used to perform SSL handshaking on the stream. The - * function call will block until handshaking is complete or an error occurs. - * - * @param type The type of handshaking to be performed, i.e. as a client or as - * a server. - * - * @throws asio::system_error Thrown on failure. - */ - void handshake(handshake_type type) - { - asio::error_code ec; - handshake(type, ec); - asio::detail::throw_error(ec, "handshake"); - } - - /// Perform SSL handshaking. - /** - * This function is used to perform SSL handshaking on the stream. The - * function call will block until handshaking is complete or an error occurs. - * - * @param type The type of handshaking to be performed, i.e. as a client or as - * a server. - * - * @param ec Set to indicate what error occurred, if any. - */ - ASIO_SYNC_OP_VOID handshake(handshake_type type, - asio::error_code& ec) - { - detail::io(next_layer_, core_, detail::handshake_op(type), ec); - ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform SSL handshaking. - /** - * This function is used to perform SSL handshaking on the stream. The - * function call will block until handshaking is complete or an error occurs. - * - * @param type The type of handshaking to be performed, i.e. as a client or as - * a server. - * - * @param buffers The buffered data to be reused for the handshake. - * - * @throws asio::system_error Thrown on failure. - */ - template <typename ConstBufferSequence> - void handshake(handshake_type type, const ConstBufferSequence& buffers) - { - asio::error_code ec; - handshake(type, buffers, ec); - asio::detail::throw_error(ec, "handshake"); - } - - /// Perform SSL handshaking. - /** - * This function is used to perform SSL handshaking on the stream. The - * function call will block until handshaking is complete or an error occurs. - * - * @param type The type of handshaking to be performed, i.e. as a client or as - * a server. - * - * @param buffers The buffered data to be reused for the handshake. - * - * @param ec Set to indicate what error occurred, if any. - */ - template <typename ConstBufferSequence> - ASIO_SYNC_OP_VOID handshake(handshake_type type, - const ConstBufferSequence& buffers, asio::error_code& ec) - { - detail::io(next_layer_, core_, - detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), ec); - ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous SSL handshake. - /** - * This function is used to asynchronously perform an SSL handshake on the - * stream. This function call always returns immediately. - * - * @param type The type of handshaking to be performed, i.e. as a client or as - * a server. - * - * @param handler The handler to be called when the handshake operation - * completes. Copies will be made of the handler as required. The equivalent - * function signature of the handler must be: - * @code void handler( - * const asio::error_code& error // Result of operation. - * ); @endcode - */ - template <typename HandshakeHandler> - ASIO_INITFN_RESULT_TYPE(HandshakeHandler, - void (asio::error_code)) - async_handshake(handshake_type type, - ASIO_MOVE_ARG(HandshakeHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a HandshakeHandler. - ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check; - - asio::async_completion<HandshakeHandler, - void (asio::error_code)> init(handler); - - detail::async_io(next_layer_, core_, - detail::handshake_op(type), init.completion_handler); - - return init.result.get(); - } - - /// Start an asynchronous SSL handshake. - /** - * This function is used to asynchronously perform an SSL handshake on the - * stream. This function call always returns immediately. - * - * @param type The type of handshaking to be performed, i.e. as a client or as - * a server. - * - * @param buffers The buffered data to be reused for the handshake. Although - * the buffers object may be copied as necessary, ownership of the underlying - * buffers is retained by the caller, which must guarantee that they remain - * valid until the handler is called. - * - * @param handler The handler to be called when the handshake operation - * completes. Copies will be made of the handler as required. The equivalent - * function signature of the handler must be: - * @code void handler( - * const asio::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Amount of buffers used in handshake. - * ); @endcode - */ - template <typename ConstBufferSequence, typename BufferedHandshakeHandler> - ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, - void (asio::error_code, std::size_t)) - async_handshake(handshake_type type, const ConstBufferSequence& buffers, - ASIO_MOVE_ARG(BufferedHandshakeHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a BufferedHandshakeHandler. - ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( - BufferedHandshakeHandler, handler) type_check; - - asio::async_completion<BufferedHandshakeHandler, - void (asio::error_code, std::size_t)> init(handler); - - detail::async_io(next_layer_, core_, - detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), - init.completion_handler); - - return init.result.get(); - } - - /// Shut down SSL on the stream. - /** - * This function is used to shut down SSL on the stream. The function call - * will block until SSL has been shut down or an error occurs. - * - * @throws asio::system_error Thrown on failure. - */ - void shutdown() - { - asio::error_code ec; - shutdown(ec); - asio::detail::throw_error(ec, "shutdown"); - } - - /// Shut down SSL on the stream. - /** - * This function is used to shut down SSL on the stream. The function call - * will block until SSL has been shut down or an error occurs. - * - * @param ec Set to indicate what error occurred, if any. - */ - ASIO_SYNC_OP_VOID shutdown(asio::error_code& ec) - { - detail::io(next_layer_, core_, detail::shutdown_op(), ec); - ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously shut down SSL on the stream. - /** - * This function is used to asynchronously shut down SSL on the stream. This - * function call always returns immediately. - * - * @param handler The handler to be called when the handshake operation - * completes. Copies will be made of the handler as required. The equivalent - * function signature of the handler must be: - * @code void handler( - * const asio::error_code& error // Result of operation. - * ); @endcode - */ - template <typename ShutdownHandler> - ASIO_INITFN_RESULT_TYPE(ShutdownHandler, - void (asio::error_code)) - async_shutdown(ASIO_MOVE_ARG(ShutdownHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ShutdownHandler. - ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check; - - asio::async_completion<ShutdownHandler, - void (asio::error_code)> init(handler); - - detail::async_io(next_layer_, core_, detail::shutdown_op(), - init.completion_handler); - - return init.result.get(); - } - - /// Write some data to the stream. - /** - * This function is used to write data on the stream. The function call will - * block until one or more bytes of data has been written successfully, or - * until an error occurs. - * - * @param buffers The data to be written. - * - * @returns The number of bytes written. - * - * @throws asio::system_error Thrown on failure. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that all - * data is written before the blocking operation completes. - */ - template <typename ConstBufferSequence> - std::size_t write_some(const ConstBufferSequence& buffers) - { - asio::error_code ec; - std::size_t n = write_some(buffers, ec); - asio::detail::throw_error(ec, "write_some"); - return n; - } - - /// Write some data to the stream. - /** - * This function is used to write data on the stream. The function call will - * block until one or more bytes of data has been written successfully, or - * until an error occurs. - * - * @param buffers The data to be written to the stream. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that all - * data is written before the blocking operation completes. - */ - template <typename ConstBufferSequence> - std::size_t write_some(const ConstBufferSequence& buffers, - asio::error_code& ec) - { - return detail::io(next_layer_, core_, - detail::write_op<ConstBufferSequence>(buffers), ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write one or more bytes of data to - * the stream. The function call always returns immediately. - * - * @param buffers The data to be written to the stream. Although the buffers - * object may be copied as necessary, ownership of the underlying buffers is - * retained by the caller, which must guarantee that they remain valid until - * the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The equivalent function - * signature of the handler must be: - * @code void handler( - * const asio::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * - * @note The async_write_some operation may not transmit all of the data to - * the peer. Consider using the @ref async_write function if you need to - * ensure that all data is written before the blocking operation completes. - */ - template <typename ConstBufferSequence, typename WriteHandler> - ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (asio::error_code, std::size_t)) - async_write_some(const ConstBufferSequence& buffers, - ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - asio::async_completion<WriteHandler, - void (asio::error_code, std::size_t)> init(handler); - - detail::async_io(next_layer_, core_, - detail::write_op<ConstBufferSequence>(buffers), - init.completion_handler); - - return init.result.get(); - } - - /// Read some data from the stream. - /** - * This function is used to read data from the stream. The function call will - * block until one or more bytes of data has been read successfully, or until - * an error occurs. - * - * @param buffers The buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws asio::system_error Thrown on failure. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template <typename MutableBufferSequence> - std::size_t read_some(const MutableBufferSequence& buffers) - { - asio::error_code ec; - std::size_t n = read_some(buffers, ec); - asio::detail::throw_error(ec, "read_some"); - return n; - } - - /// Read some data from the stream. - /** - * This function is used to read data from the stream. The function call will - * block until one or more bytes of data has been read successfully, or until - * an error occurs. - * - * @param buffers The buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template <typename MutableBufferSequence> - std::size_t read_some(const MutableBufferSequence& buffers, - asio::error_code& ec) - { - return detail::io(next_layer_, core_, - detail::read_op<MutableBufferSequence>(buffers), ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read one or more bytes of data from - * the stream. The function call always returns immediately. - * - * @param buffers The buffers into which the data will be read. Although the - * buffers object may be copied as necessary, ownership of the underlying - * buffers is retained by the caller, which must guarantee that they remain - * valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The equivalent function - * signature of the handler must be: - * @code void handler( - * const asio::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * - * @note The async_read_some operation may not read all of the requested - * number of bytes. Consider using the @ref async_read function if you need to - * ensure that the requested amount of data is read before the asynchronous - * operation completes. - */ - template <typename MutableBufferSequence, typename ReadHandler> - ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (asio::error_code, std::size_t)) - async_read_some(const MutableBufferSequence& buffers, - ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - asio::async_completion<ReadHandler, - void (asio::error_code, std::size_t)> init(handler); - - detail::async_io(next_layer_, core_, - detail::read_op<MutableBufferSequence>(buffers), - init.completion_handler); - - return init.result.get(); - } + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_context() { + return next_layer_.lowest_layer().get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + asio::io_context& get_io_service() { + return next_layer_.lowest_layer().get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to context functionality that is + * not otherwise provided. + * + * @par Example + * The native_handle() function returns a pointer of type @c SSL* that is + * suitable for passing to functions such as @c SSL_get_verify_result and + * @c SSL_get_peer_certificate: + * @code + * asio::ssl::stream<asio:ip::tcp::socket> sock(io_context, ctx); + * + * // ... establish connection and perform handshake ... + * + * if (X509* cert = SSL_get_peer_certificate(sock.native_handle())) + * { + * if (SSL_get_verify_result(sock.native_handle()) == X509_V_OK) + * { + * // ... + * } + * } + * @endcode + */ + native_handle_type native_handle() { + return core_.engine_.native_handle(); + } + + /// Get a reference to the next layer. + /** + * This function returns a reference to the next layer in a stack of stream + * layers. + * + * @return A reference to the next layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + const next_layer_type& next_layer() const { + return next_layer_; + } + + /// Get a reference to the next layer. + /** + * This function returns a reference to the next layer in a stack of stream + * layers. + * + * @return A reference to the next layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + next_layer_type& next_layer() { + return next_layer_; + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * stream layers. + * + * @return A reference to the lowest layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() { + return next_layer_.lowest_layer(); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * stream layers. + * + * @return A reference to the lowest layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const { + return next_layer_.lowest_layer(); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @throws asio::system_error Thrown on failure. + */ + void handshake(handshake_type type) { + asio::error_code ec; + handshake(type, ec); + asio::detail::throw_error(ec, "handshake"); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID handshake(handshake_type type, asio::error_code& ec) { + detail::io(next_layer_, core_, detail::handshake_op(type), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param buffers The buffered data to be reused for the handshake. + * + * @throws asio::system_error Thrown on failure. + */ + template <typename ConstBufferSequence> + void handshake(handshake_type type, const ConstBufferSequence& buffers) { + asio::error_code ec; + handshake(type, buffers, ec); + asio::detail::throw_error(ec, "handshake"); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param buffers The buffered data to be reused for the handshake. + * + * @param ec Set to indicate what error occurred, if any. + */ + template <typename ConstBufferSequence> + ASIO_SYNC_OP_VOID handshake(handshake_type type, + const ConstBufferSequence& buffers, + asio::error_code& ec) { + detail::io(next_layer_, + core_, + detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), + ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Start an asynchronous SSL handshake. + /** + * This function is used to asynchronously perform an SSL handshake on the + * stream. This function call always returns immediately. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + */ + template <typename HandshakeHandler> + ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void(asio::error_code)) + async_handshake(handshake_type type, ASIO_MOVE_ARG(HandshakeHandler) handler) { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a HandshakeHandler. + ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check; + + asio::async_completion<HandshakeHandler, void(asio::error_code)> init(handler); + + detail::async_io(next_layer_, core_, detail::handshake_op(type), init.completion_handler); + + return init.result.get(); + } + + /// Start an asynchronous SSL handshake. + /** + * This function is used to asynchronously perform an SSL handshake on the + * stream. This function call always returns immediately. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param buffers The buffered data to be reused for the handshake. Although + * the buffers object may be copied as necessary, ownership of the underlying + * buffers is retained by the caller, which must guarantee that they remain + * valid until the handler is called. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Amount of buffers used in handshake. + * ); @endcode + */ + template <typename ConstBufferSequence, typename BufferedHandshakeHandler> + ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void(asio::error_code, std::size_t)) + async_handshake(handshake_type type, + const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(BufferedHandshakeHandler) handler) { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a BufferedHandshakeHandler. + ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(BufferedHandshakeHandler, handler) type_check; + + asio::async_completion<BufferedHandshakeHandler, void(asio::error_code, std::size_t)> init( + handler); + + detail::async_io(next_layer_, + core_, + detail::buffered_handshake_op<ConstBufferSequence>(type, buffers), + init.completion_handler); + + return init.result.get(); + } + + /// Shut down SSL on the stream. + /** + * This function is used to shut down SSL on the stream. The function call + * will block until SSL has been shut down or an error occurs. + * + * @throws asio::system_error Thrown on failure. + */ + void shutdown() { + asio::error_code ec; + shutdown(ec); + asio::detail::throw_error(ec, "shutdown"); + } + + /// Shut down SSL on the stream. + /** + * This function is used to shut down SSL on the stream. The function call + * will block until SSL has been shut down or an error occurs. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID shutdown(asio::error_code& ec) { + detail::io(next_layer_, core_, detail::shutdown_op(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Asynchronously shut down SSL on the stream. + /** + * This function is used to asynchronously shut down SSL on the stream. This + * function call always returns immediately. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + */ + template <typename ShutdownHandler> + ASIO_INITFN_RESULT_TYPE(ShutdownHandler, void(asio::error_code)) + async_shutdown(ASIO_MOVE_ARG(ShutdownHandler) handler) { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ShutdownHandler. + ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check; + + asio::async_completion<ShutdownHandler, void(asio::error_code)> init(handler); + + detail::async_io(next_layer_, core_, detail::shutdown_op(), init.completion_handler); + + return init.result.get(); + } + + /// Write some data to the stream. + /** + * This function is used to write data on the stream. The function call will + * block until one or more bytes of data has been written successfully, or + * until an error occurs. + * + * @param buffers The data to be written. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that all + * data is written before the blocking operation completes. + */ + template <typename ConstBufferSequence> + std::size_t write_some(const ConstBufferSequence& buffers) { + asio::error_code ec; + std::size_t n = write_some(buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return n; + } + + /// Write some data to the stream. + /** + * This function is used to write data on the stream. The function call will + * block until one or more bytes of data has been written successfully, or + * until an error occurs. + * + * @param buffers The data to be written to the stream. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that all + * data is written before the blocking operation completes. + */ + template <typename ConstBufferSequence> + std::size_t write_some(const ConstBufferSequence& buffers, asio::error_code& ec) { + return detail::io(next_layer_, core_, detail::write_op<ConstBufferSequence>(buffers), ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write one or more bytes of data to + * the stream. The function call always returns immediately. + * + * @param buffers The data to be written to the stream. Although the buffers + * object may be copied as necessary, ownership of the underlying buffers is + * retained by the caller, which must guarantee that they remain valid until + * the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The equivalent function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * + * @note The async_write_some operation may not transmit all of the data to + * the peer. Consider using the @ref async_write function if you need to + * ensure that all data is written before the blocking operation completes. + */ + template <typename ConstBufferSequence, typename WriteHandler> + ASIO_INITFN_RESULT_TYPE(WriteHandler, void(asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, ASIO_MOVE_ARG(WriteHandler) handler) { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + asio::async_completion<WriteHandler, void(asio::error_code, std::size_t)> init(handler); + + detail::async_io(next_layer_, + core_, + detail::write_op<ConstBufferSequence>(buffers), + init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the stream. + /** + * This function is used to read data from the stream. The function call will + * block until one or more bytes of data has been read successfully, or until + * an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template <typename MutableBufferSequence> + std::size_t read_some(const MutableBufferSequence& buffers) { + asio::error_code ec; + std::size_t n = read_some(buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return n; + } + + /// Read some data from the stream. + /** + * This function is used to read data from the stream. The function call will + * block until one or more bytes of data has been read successfully, or until + * an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template <typename MutableBufferSequence> + std::size_t read_some(const MutableBufferSequence& buffers, asio::error_code& ec) { + return detail::io(next_layer_, core_, detail::read_op<MutableBufferSequence>(buffers), ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read one or more bytes of data from + * the stream. The function call always returns immediately. + * + * @param buffers The buffers into which the data will be read. Although the + * buffers object may be copied as necessary, ownership of the underlying + * buffers is retained by the caller, which must guarantee that they remain + * valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The equivalent function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * + * @note The async_read_some operation may not read all of the requested + * number of bytes. Consider using the @ref async_read function if you need to + * ensure that the requested amount of data is read before the asynchronous + * operation completes. + */ + template <typename MutableBufferSequence, typename ReadHandler> + ASIO_INITFN_RESULT_TYPE(ReadHandler, void(asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, ASIO_MOVE_ARG(ReadHandler) handler) { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + asio::async_completion<ReadHandler, void(asio::error_code, std::size_t)> init(handler); + + detail::async_io(next_layer_, + core_, + detail::read_op<MutableBufferSequence>(buffers), + init.completion_handler); + + return init.result.get(); + } private: - Stream next_layer_; - detail::stream_core core_; + Stream next_layer_; + detail::stream_core core_; }; -} // namespace ssl -} // namespace asio +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_STREAM_HPP +#endif // ASIO_SSL_STREAM_HPP diff --git a/src/mongo/util/net/ssl/stream_base.hpp b/src/mongo/util/net/ssl/stream_base.hpp index ca95c761d47..cd4b390adee 100644 --- a/src/mongo/util/net/ssl/stream_base.hpp +++ b/src/mongo/util/net/ssl/stream_base.hpp @@ -12,8 +12,8 @@ #define ASIO_SSL_STREAM_BASE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" @@ -24,29 +24,25 @@ namespace ssl { /// The stream_base class is used as a base for the asio::ssl::stream /// class template so that we have a common place to define various enums. -class stream_base -{ +class stream_base { public: - /// Different handshake types. - enum handshake_type - { - /// Perform handshaking as a client. - client, + /// Different handshake types. + enum handshake_type { + /// Perform handshaking as a client. + client, - /// Perform handshaking as a server. - server - }; + /// Perform handshaking as a server. + server + }; protected: - /// Protected destructor to prevent deletion through this type. - ~stream_base() - { - } + /// Protected destructor to prevent deletion through this type. + ~stream_base() {} }; -} // namespace ssl -} // namespace asio +} // namespace ssl +} // namespace asio #include "asio/detail/pop_options.hpp" -#endif // ASIO_SSL_STREAM_BASE_HPP +#endif // ASIO_SSL_STREAM_BASE_HPP |