diff options
author | Matt Cotter <matt.cotter@mongodb.com> | 2016-06-15 14:22:48 -0400 |
---|---|---|
committer | Andrew Morrow <acm@mongodb.com> | 2017-04-09 16:23:50 -0400 |
commit | 3aa8cf14fd7c6c821c81aac03cb4948663743d22 (patch) | |
tree | 0515250e5ca2d919c8b551f73893440a4c911305 /src | |
parent | 15d286b971df65e58184643a031bbe579ac040a5 (diff) | |
download | mongo-3aa8cf14fd7c6c821c81aac03cb4948663743d22.tar.gz |
SERVER-24595 enforce ismaster response has ok:1
(cherry picked from commit e9cd7667471eff437463e7de842af95747847be4)
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/client/dbclient.cpp | 6 | ||||
-rw-r--r-- | src/mongo/executor/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/executor/network_interface_asio_auth.cpp | 7 | ||||
-rw-r--r-- | src/mongo/executor/network_interface_asio_test.cpp | 40 |
4 files changed, 54 insertions, 0 deletions
diff --git a/src/mongo/client/dbclient.cpp b/src/mongo/client/dbclient.cpp index 73a5e5d52a1..ab4ba058d00 100644 --- a/src/mongo/client/dbclient.cpp +++ b/src/mongo/client/dbclient.cpp @@ -924,6 +924,12 @@ Status DBClientConnection::connect(const HostAndPort& serverAddress) { return swIsMasterReply.getStatus(); } + // Ensure that the isMaster response is "ok:1". + auto isMasterStatus = getStatusFromCommandResult(swIsMasterReply.getValue().data); + if (!isMasterStatus.isOK()) { + return isMasterStatus; + } + auto swProtocolSet = rpc::parseProtocolSetFromIsMasterReply(swIsMasterReply.getValue().data); if (!swProtocolSet.isOK()) { return swProtocolSet.getStatus(); diff --git a/src/mongo/executor/SConscript b/src/mongo/executor/SConscript index c8ff0e69fd0..ec25fc15952 100644 --- a/src/mongo/executor/SConscript +++ b/src/mongo/executor/SConscript @@ -149,6 +149,7 @@ env.Library( '$BUILD_DIR/mongo/base/system_error', '$BUILD_DIR/mongo/db/auth/authcommon', '$BUILD_DIR/mongo/db/commands/test_commands_enabled', + '$BUILD_DIR/mongo/rpc/command_status', '$BUILD_DIR/mongo/rpc/rpc', '$BUILD_DIR/third_party/shim_asio', 'async_stream', diff --git a/src/mongo/executor/network_interface_asio_auth.cpp b/src/mongo/executor/network_interface_asio_auth.cpp index b9a341d13d6..22a35ce8f8f 100644 --- a/src/mongo/executor/network_interface_asio_auth.cpp +++ b/src/mongo/executor/network_interface_asio_auth.cpp @@ -40,6 +40,7 @@ #include "mongo/db/commands.h" #include "mongo/db/server_options.h" #include "mongo/rpc/factory.h" +#include "mongo/rpc/get_status_from_command_result.h" #include "mongo/rpc/legacy_request_builder.h" #include "mongo/rpc/reply_interface.h" #include "mongo/stdx/memory.h" @@ -90,6 +91,12 @@ void NetworkInterfaceASIO::_runIsMaster(AsyncOp* op) { auto commandReply = std::move(swCommandReply.getValue()); + // Ensure that the isMaster response is "ok:1". + auto commandStatus = getStatusFromCommandResult(commandReply.data); + if (!commandStatus.isOK()) { + return _completeOperation(op, commandStatus); + } + auto protocolSet = rpc::parseProtocolSetFromIsMasterReply(commandReply.data); if (!protocolSet.isOK()) return _completeOperation(op, protocolSet.getStatus()); diff --git a/src/mongo/executor/network_interface_asio_test.cpp b/src/mongo/executor/network_interface_asio_test.cpp index bbe75be5f49..144a0ad91d4 100644 --- a/src/mongo/executor/network_interface_asio_test.cpp +++ b/src/mongo/executor/network_interface_asio_test.cpp @@ -533,6 +533,46 @@ public: } }; +TEST_F(NetworkInterfaceASIOConnectionHookTest, InvalidIsMaster) { + auto validationFailedStatus = + Status(ErrorCodes::InterruptedDueToReplStateChange, "operation was interrupted"); + + start(makeTestHook( + [&](const HostAndPort& remoteHost, const RemoteCommandResponse& isMasterReply) { + return Status(ErrorCodes::UnknownError, "unused"); + }, + [&](const HostAndPort& remoteHost) + -> StatusWith<boost::optional<RemoteCommandRequest>> { return {boost::none}; }, + [&](const HostAndPort& remoteHost, RemoteCommandResponse&& response) { + return Status::OK(); + })); + + auto deferred = startCommand(makeCallbackHandle(), + {testHost, + "blah", + BSON("foo" + << "bar")}); + + auto stream = streamFactory().blockUntilStreamExists(testHost); + + ConnectEvent{stream}.skip(); + + // simulate isMaster reply. + stream->simulateServer(rpc::Protocol::kOpQuery, + [](RemoteCommandRequest request) -> RemoteCommandResponse { + RemoteCommandResponse response; + response.data = BSON("ok" << 0.0 << "errmsg" + << "operation was interrupted" + << "code" << 11602); + return response; + }); + + // we should stop here. + auto& res = deferred.get(); + + ASSERT(res == validationFailedStatus); +} + TEST_F(NetworkInterfaceASIOConnectionHookTest, ValidateHostInvalid) { bool validateCalled = false; bool hostCorrect = false; |