summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer Jackson <spencer.jackson@mongodb.com>2020-01-08 16:20:47 +0000
committerevergreen <evergreen@mongodb.com>2020-01-08 16:20:47 +0000
commited9e4d252512f42a5f6843f835ead80b0eb0a987 (patch)
treed57b069b78795d4c501660e55d99c93e7379d8e0
parent1709f2c1ef957978ca3632ad88c87b7f23124d5e (diff)
downloadmongo-ed9e4d252512f42a5f6843f835ead80b0eb0a987.tar.gz
SERVER-38945: Cache OpenSSL error states to elide error clearing
(cherry picked from commit 0842ea78e70147501c92f188706b0c161b3ac76e)
-rw-r--r--src/third_party/asio-master/asio/include/asio/ssl/detail/engine.hpp2
-rw-r--r--src/third_party/asio-master/asio/include/asio/ssl/detail/impl/engine.ipp27
-rw-r--r--src/third_party/asio-master/patches/0003-SERVER-38945-Cache-OpenSSL-error-states-to-elide-err.patch62
-rw-r--r--src/third_party/asio-master/patches/0004-SERVER-40393-Disable-SSL_MODE_RELEASE_BUFFERS-in-ASI.patch34
4 files changed, 120 insertions, 5 deletions
diff --git a/src/third_party/asio-master/asio/include/asio/ssl/detail/engine.hpp b/src/third_party/asio-master/asio/include/asio/ssl/detail/engine.hpp
index 061a50dd2ac..b256b063baf 100644
--- a/src/third_party/asio-master/asio/include/asio/ssl/detail/engine.hpp
+++ b/src/third_party/asio-master/asio/include/asio/ssl/detail/engine.hpp
@@ -121,6 +121,8 @@ private:
ASIO_DECL static asio::detail::static_mutex& accept_mutex();
#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
+ ASIO_DECL void purge_error_state();
+
// 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.
diff --git a/src/third_party/asio-master/asio/include/asio/ssl/detail/impl/engine.ipp b/src/third_party/asio-master/asio/include/asio/ssl/detail/impl/engine.ipp
index d55bc87f59d..077a1a1948c 100644
--- a/src/third_party/asio-master/asio/include/asio/ssl/detail/impl/engine.ipp
+++ b/src/third_party/asio-master/asio/include/asio/ssl/detail/impl/engine.ipp
@@ -46,10 +46,10 @@ engine::engine(SSL_CTX* context)
::SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE);
::SSL_set_mode(ssl_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-// SERVER-40393 - Disable SSL_MODE_RELEASE_BUFFERS in ASIO
-//#if defined(SSL_MODE_RELEASE_BUFFERS)
- //::SSL_set_mode(ssl_, SSL_MODE_RELEASE_BUFFERS);
-//#endif // defined(SSL_MODE_RELEASE_BUFFERS)
+ // SERVER-40393 - Disable SSL_MODE_RELEASE_BUFFERS in ASIO
+ //#if 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);
@@ -226,12 +226,29 @@ asio::detail::static_mutex& engine::accept_mutex()
}
#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
+void engine::purge_error_state() {
+#if (OPENSSL_VERSION_NUMBER < 0x1010000fL && !defined(__APPLE__))
+ // OpenSSL 1.1.0 introduced a thread local state storage mechanism.
+ // Versions prior sometimes had contention issues on global mutexes
+ // which protected thread local state.
+ // If we are compiled against a version without native thread local
+ // support, cache a pointer to this thread's error state, which we can
+ // access without contention. If that state requires no cleanup,
+ // we can avoid invoking OpenSSL's more expensive machinery.
+ const static thread_local ERR_STATE* es = ERR_get_state();
+ if (es->bottom == es->top) {
+ return;
+ }
+#endif // (OPENSSL_VERSION_NUMBER < 0x1010000fL && !defined(__APPLE__))
+ ::ERR_clear_error();
+}
+
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();
+ purge_error_state();
int result = (this->*op)(data, length);
int ssl_error = ::SSL_get_error(ssl_, result);
int sys_error = static_cast<int>(::ERR_get_error());
diff --git a/src/third_party/asio-master/patches/0003-SERVER-38945-Cache-OpenSSL-error-states-to-elide-err.patch b/src/third_party/asio-master/patches/0003-SERVER-38945-Cache-OpenSSL-error-states-to-elide-err.patch
new file mode 100644
index 00000000000..1a1939acf47
--- /dev/null
+++ b/src/third_party/asio-master/patches/0003-SERVER-38945-Cache-OpenSSL-error-states-to-elide-err.patch
@@ -0,0 +1,62 @@
+From 5f1ffc409805a3279b09e2d2a005f3f744895348 Mon Sep 17 00:00:00 2001
+From: Spencer Jackson <spencer.jackson@mongodb.com>
+Date: Fri, 17 May 2019 12:58:57 -0400
+Subject: [PATCH 3/4] SERVER-38945: Cache OpenSSL error states to elide error
+ clearing
+
+---
+ asio/include/asio/ssl/detail/engine.hpp | 2 ++
+ asio/include/asio/ssl/detail/impl/engine.ipp | 19 ++++++++++++++++++-
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/asio/include/asio/ssl/detail/engine.hpp b/asio/include/asio/ssl/detail/engine.hpp
+index 061a50dd..b256b063 100644
+--- a/asio/include/asio/ssl/detail/engine.hpp
++++ b/asio/include/asio/ssl/detail/engine.hpp
+@@ -121,6 +121,8 @@ private:
+ ASIO_DECL static asio::detail::static_mutex& accept_mutex();
+ #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
+
++ ASIO_DECL void purge_error_state();
++
+ // 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.
+diff --git a/asio/include/asio/ssl/detail/impl/engine.ipp b/asio/include/asio/ssl/detail/impl/engine.ipp
+index 345461b1..310c838d 100644
+--- a/asio/include/asio/ssl/detail/impl/engine.ipp
++++ b/asio/include/asio/ssl/detail/impl/engine.ipp
+@@ -225,12 +225,29 @@ asio::detail::static_mutex& engine::accept_mutex()
+ }
+ #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
+
++void engine::purge_error_state() {
++#if (OPENSSL_VERSION_NUMBER < 0x1010000fL && !defined(__APPLE__))
++ // OpenSSL 1.1.0 introduced a thread local state storage mechanism.
++ // Versions prior sometimes had contention issues on global mutexes
++ // which protected thread local state.
++ // If we are compiled against a version without native thread local
++ // support, cache a pointer to this thread's error state, which we can
++ // access without contention. If that state requires no cleanup,
++ // we can avoid invoking OpenSSL's more expensive machinery.
++ const static thread_local ERR_STATE* es = ERR_get_state();
++ if (es->bottom == es->top) {
++ return;
++ }
++#endif // (OPENSSL_VERSION_NUMBER < 0x1010000fL && !defined(__APPLE__))
++ ::ERR_clear_error();
++}
++
+ 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();
++ purge_error_state();
+ int result = (this->*op)(data, length);
+ int ssl_error = ::SSL_get_error(ssl_, result);
+ int sys_error = static_cast<int>(::ERR_get_error());
+--
+2.24.1
+
diff --git a/src/third_party/asio-master/patches/0004-SERVER-40393-Disable-SSL_MODE_RELEASE_BUFFERS-in-ASI.patch b/src/third_party/asio-master/patches/0004-SERVER-40393-Disable-SSL_MODE_RELEASE_BUFFERS-in-ASI.patch
new file mode 100644
index 00000000000..a5b2cbee4fe
--- /dev/null
+++ b/src/third_party/asio-master/patches/0004-SERVER-40393-Disable-SSL_MODE_RELEASE_BUFFERS-in-ASI.patch
@@ -0,0 +1,34 @@
+From 346f05a77bbc3a4d882d1e15b8f70cf5920a656b Mon Sep 17 00:00:00 2001
+From: Spencer Jackson <spencer.jackson@mongodb.com>
+Date: Fri, 17 May 2019 13:08:29 -0400
+Subject: [PATCH] SERVER-40393 Disable SSL_MODE_RELEASE_BUFFERS in ASIO
+
+---
+ asio/include/asio/ssl/detail/impl/engine.ipp | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/asio/include/asio/ssl/detail/impl/engine.ipp b/asio/include/asio/ssl/detail/impl/engine.ipp
+index d001723b..96aeeb76 100644
+--- a/asio/include/asio/ssl/detail/impl/engine.ipp
++++ b/asio/include/asio/ssl/detail/impl/engine.ipp
+@@ -44,13 +44,14 @@ engine::engine(SSL_CTX* context)
+ 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);
+-#if defined(SSL_MODE_RELEASE_BUFFERS)
+- ::SSL_set_mode(ssl_, SSL_MODE_RELEASE_BUFFERS);
+-#endif // defined(SSL_MODE_RELEASE_BUFFERS)
++ // SERVER-40393 - Disable SSL_MODE_RELEASE_BUFFERS in ASIO
++ //#if 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);
+ }
+--
+2.21.0
+