diff --git a/src/mongo/executor/SConscript b/src/mongo/executor/SConscript index ee69252bfe9ce..22e895e1f5d6b 100644 --- a/src/mongo/executor/SConscript +++ b/src/mongo/executor/SConscript @@ -84,6 +84,7 @@ env.Library( 'network_interface_asio_operation.cpp', ], LIBDEPS=[ + '$BUILD_DIR/mongo/base/system_error', '$BUILD_DIR/mongo/client/authentication', '$BUILD_DIR/mongo/db/auth/authcommon', '$BUILD_DIR/mongo/rpc/rpc', diff --git a/src/mongo/executor/async_secure_stream.cpp b/src/mongo/executor/async_secure_stream.cpp index 96160d24f147b..956ef53793511 100644 --- a/src/mongo/executor/async_secure_stream.cpp +++ b/src/mongo/executor/async_secure_stream.cpp @@ -32,9 +32,10 @@ #include "mongo/executor/async_secure_stream.h" +#include "mongo/base/system_error.h" #include "mongo/config.h" -#include "mongo/util/net/ssl_manager.h" #include "mongo/util/log.h" +#include "mongo/util/net/ssl_manager.h" #ifdef MONGO_CONFIG_SSL @@ -52,7 +53,7 @@ void AsyncSecureStream::connect(const asio::ip::tcp::resolver::iterator endpoint asio::async_connect(_stream.lowest_layer(), std::move(endpoints), [this](std::error_code ec, asio::ip::tcp::resolver::iterator iter) { - if (ec) { + if (ec != ErrorCodes::OK) { return _userHandler(ec); } return _handleConnect(ec, std::move(iter)); @@ -70,7 +71,7 @@ void AsyncSecureStream::read(asio::mutable_buffer buffer, StreamHandler&& stream void AsyncSecureStream::_handleConnect(std::error_code ec, asio::ip::tcp::resolver::iterator iter) { _stream.async_handshake(decltype(_stream)::client, [this, iter](std::error_code ec) { - if (ec) { + if (ec != ErrorCodes::OK) { return _userHandler(ec); } return _handleHandshake(ec, iter->host_name()); @@ -82,11 +83,8 @@ void AsyncSecureStream::_handleHandshake(std::error_code ec, const std::string& getSSLManager()->parseAndValidatePeerCertificate(_stream.native_handle(), hostName); if (!certStatus.isOK()) { warning() << certStatus.getStatus(); - return _userHandler( - // TODO: fix handling of std::error_code w.r.t. codes used by Status - std::error_code(certStatus.getStatus().code(), std::generic_category())); } - _userHandler(std::error_code()); + _userHandler(make_error_code(certStatus.getStatus().code())); } } // namespace executor diff --git a/src/mongo/executor/network_interface_asio.h b/src/mongo/executor/network_interface_asio.h index 3f4cd0204e912..9b972aaacd07d 100644 --- a/src/mongo/executor/network_interface_asio.h +++ b/src/mongo/executor/network_interface_asio.h @@ -37,6 +37,7 @@ #include #include "mongo/base/status.h" +#include "mongo/base/system_error.h" #include "mongo/executor/network_interface.h" #include "mongo/executor/remote_command_request.h" #include "mongo/executor/remote_command_response.h" @@ -225,7 +226,7 @@ class NetworkInterfaceASIO final : public NetworkInterface { if (op->canceled()) return _completeOperation(op, Status(ErrorCodes::CallbackCanceled, "Callback canceled")); - if (ec) + if (ec != ErrorCodes::OK) return _networkErrorCallback(op, ec); handler(); diff --git a/src/mongo/executor/network_interface_asio_command.cpp b/src/mongo/executor/network_interface_asio_command.cpp index 1abef492f5cb5..e1d43e673d210 100644 --- a/src/mongo/executor/network_interface_asio_command.cpp +++ b/src/mongo/executor/network_interface_asio_command.cpp @@ -35,9 +35,9 @@ #include #include -#include "mongo/executor/async_stream_interface.h" #include "mongo/db/dbmessage.h" #include "mongo/db/jsobj.h" +#include "mongo/executor/async_stream_interface.h" #include "mongo/rpc/factory.h" #include "mongo/rpc/protocol.h" #include "mongo/rpc/reply_interface.h" @@ -95,19 +95,16 @@ void asyncRecvMessageBody(AsyncStreamInterface& stream, static_assert( IsNetworkHandler::value, "Handler passed to asyncRecvMessageBody does not conform to NetworkHandler concept"); - // TODO: This error code should be more meaningful. - std::error_code ec; - // validate message length int len = header->constView().getMessageLength(); if (len == 542393671) { LOG(3) << "attempt to access MongoDB over HTTP on the native driver port."; - return handler(ec, 0); + return handler(make_error_code(ErrorCodes::ProtocolError), 0); } else if (static_cast(len) < sizeof(MSGHEADER::Value) || static_cast(len) > MaxMessageSizeBytes) { warning() << "recv(): message len " << len << " is invalid. " << "Min " << sizeof(MSGHEADER::Value) << " Max: " << MaxMessageSizeBytes; - return handler(ec, 0); + return handler(make_error_code(ErrorCodes::InvalidLength), 0); } int z = (len + 1023) & 0xfffffc00; @@ -220,7 +217,13 @@ void NetworkInterfaceASIO::_completedOpCallback(AsyncOp* op) { void NetworkInterfaceASIO::_networkErrorCallback(AsyncOp* op, const std::error_code& ec) { LOG(3) << "networking error occurred"; - _completeOperation(op, Status(ErrorCodes::HostUnreachable, ec.message())); + if (ec.category() == mongoErrorCategory()) { + // If we get a Mongo error code, we can preserve it. + _completeOperation(op, Status(ErrorCodes::fromInt(ec.value()), ec.message())); + } else { + // If we get an asio or system error, we just convert it to a network error. + _completeOperation(op, Status(ErrorCodes::HostUnreachable, ec.message())); + } } // NOTE: This method may only be called by ASIO threads @@ -252,7 +255,7 @@ void NetworkInterfaceASIO::_asyncRunCommand(AsyncCommand* cmd, NetworkOpHandler // Step 3 auto recvHeaderCallback = [this, cmd, handler, recvMessageCallback](std::error_code ec, size_t bytes) { - if (ec) + if (ec != ErrorCodes::OK) return handler(ec, bytes); // validate response id @@ -272,7 +275,7 @@ void NetworkInterfaceASIO::_asyncRunCommand(AsyncCommand* cmd, NetworkOpHandler // Step 2 auto sendMessageCallback = [this, cmd, handler, recvHeaderCallback](std::error_code ec, size_t bytes) { - if (ec) + if (ec != ErrorCodes::OK) return handler(ec, bytes); asyncRecvMessageHeader(cmd->conn().stream(), &cmd->header(), std::move(recvHeaderCallback));