summaryrefslogtreecommitdiff
path: root/src/mongo/transport
diff options
context:
space:
mode:
authorTyler Seip <Tyler.Seip@mongodb.com>2021-11-29 16:50:34 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-11-29 17:48:31 +0000
commitd2bca5f1c72212d05dd99a22b5ee1b283ecb65ed (patch)
tree29164d9586d3bd28f21320c1670a6c6b70a39376 /src/mongo/transport
parentdcdf971889b00ef0b98815d8abff54add18cdcbe (diff)
downloadmongo-d2bca5f1c72212d05dd99a22b5ee1b283ecb65ed.tar.gz
SERVER-60603: Allow connection reset errors without assertion in ASIOSession::ensureSync()
Diffstat (limited to 'src/mongo/transport')
-rw-r--r--src/mongo/transport/session_asio.cpp8
-rw-r--r--src/mongo/transport/transport_layer_asio_test.cpp33
2 files changed, 35 insertions, 6 deletions
diff --git a/src/mongo/transport/session_asio.cpp b/src/mongo/transport/session_asio.cpp
index 3acecb954cf..3c957556f15 100644
--- a/src/mongo/transport/session_asio.cpp
+++ b/src/mongo/transport/session_asio.cpp
@@ -343,18 +343,14 @@ void TransportLayerASIO::ASIOSession::ensureSync() {
"session send timeout",
logv2::LogSeverity::Info(),
ec);
- if (auto status = errorCodeToStatus(ec); !status.isOK()) {
- tasserted(5342000, status.reason());
- }
+ uassertStatusOK(errorCodeToStatus(ec));
setSocketOption(getSocket(),
ASIOSocketTimeoutOption<SO_RCVTIMEO>(timeout),
"session receive timeout",
logv2::LogSeverity::Info(),
ec);
- if (auto status = errorCodeToStatus(ec); !status.isOK()) {
- tasserted(5342001, status.reason());
- }
+ uassertStatusOK(errorCodeToStatus(ec));
_socketTimeout = _configuredTimeout;
}
diff --git a/src/mongo/transport/transport_layer_asio_test.cpp b/src/mongo/transport/transport_layer_asio_test.cpp
index 344393602b8..af9fbd30e9a 100644
--- a/src/mongo/transport/transport_layer_asio_test.cpp
+++ b/src/mongo/transport/transport_layer_asio_test.cpp
@@ -351,6 +351,39 @@ TEST(TransportLayerASIO, TCPResetAfterConnectionIsSilentlySwallowed) {
ASSERT_EQ(sessionsCreated.load(), 0);
}
+TEST(TransportLayerASIO, ThrowOnNetworkErrorInEnsureSync) {
+ TestFixture tf;
+ Notification<SessionThread*> mockSessionCreated;
+ tf.sep().setOnStartSession([&](SessionThread& st) { mockSessionCreated.set(&st); });
+
+ ConnectionThread connectThread(tf.tla().listenerPort(), [&](ConnectionThread& conn) {
+ // Linger timeout = 0 causes a RST packet on close.
+ struct linger sl = {1, 0};
+ if (setsockopt(conn.socket().rawFD(),
+ SOL_SOCKET,
+ SO_LINGER,
+ reinterpret_cast<SetsockoptPtr>(&sl),
+ sizeof(sl)) != 0) {
+ auto err = make_error_code(std::errc{errno});
+ LOGV2_ERROR(6060300, "setsockopt", "error"_attr = err.message());
+ }
+ });
+
+ auto& st = *mockSessionCreated.get();
+ connectThread.close();
+
+ // We set the timeout to ensure that the setsockopt calls are actually made in ensureSync()
+ st.session().setTimeout(Milliseconds{500});
+
+ // On Mac, setsockopt will immediately throw a SocketException since the socket is closed.
+ // On Linux, we will throw HostUnreachable once we try to actually read the socket.
+ // We allow for either exception here.
+ using namespace unittest::match;
+ ASSERT_THAT(
+ st.session().sourceMessage().getStatus(),
+ StatusIs(AnyOf(Eq(ErrorCodes::HostUnreachable), Eq(ErrorCodes::SocketException)), Any()));
+}
+
/* check that timeouts actually time out */
TEST(TransportLayerASIO, SourceSyncTimeoutTimesOut) {
TestFixture tf;