diff options
author | Mathias Stearn <mathias@10gen.com> | 2017-04-12 14:24:00 -0400 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2017-04-27 14:31:25 -0400 |
commit | 86aa275a4b9b43d0c647dc0034c6626a95884e18 (patch) | |
tree | c5eaa30f81df846855f60399c32e2524a92685a2 /src/mongo/rpc/protocol.cpp | |
parent | 0bd0382b2bcd0517ce717e7e1d1e57da792c6855 (diff) | |
download | mongo-86aa275a4b9b43d0c647dc0034c6626a95884e18.tar.gz |
SERVER-28508 OP_MSG in egress and mongod
Diffstat (limited to 'src/mongo/rpc/protocol.cpp')
-rw-r--r-- | src/mongo/rpc/protocol.cpp | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/src/mongo/rpc/protocol.cpp b/src/mongo/rpc/protocol.cpp index ad4ec071cbd..5799b0bcc7d 100644 --- a/src/mongo/rpc/protocol.cpp +++ b/src/mongo/rpc/protocol.cpp @@ -47,12 +47,25 @@ namespace { /** * Protocols supported by order of preference. */ -const Protocol kPreferredProtos[] = {Protocol::kOpCommandV1, Protocol::kOpQuery}; - -const char kNone[] = "none"; -const char kOpQueryOnly[] = "opQueryOnly"; -const char kOpCommandOnly[] = "opCommandOnly"; -const char kAll[] = "all"; +const Protocol kPreferredProtos[] = {Protocol::kOpMsg, Protocol::kOpCommandV1, Protocol::kOpQuery}; + +struct ProtocolSetAndName { + StringData name; + ProtocolSet protocols; +}; + +constexpr ProtocolSetAndName protocolSetNames[] = { + // Most common ones go first. + {"all"_sd, supports::kAll}, // new mongod. + {"opQueryAndOpMsg"_sd, supports::kOpQueryOnly | supports::kOpMsgOnly}, // new mongos. + {"opQueryAndOpCommand"_sd, supports::kOpQueryOnly | supports::kOpCommandOnly}, // old mongod. + {"opQueryOnly"_sd, supports::kOpQueryOnly}, // old mongos or very old client or mongod. + + // Then the rest (these should never happen in production). + {"none"_sd, supports::kNone}, + {"opCommandOnly"_sd, supports::kOpCommandOnly}, + {"opMsgOnly"_sd, supports::kOpMsgOnly}, +}; } // namespace @@ -73,39 +86,22 @@ StatusWith<Protocol> negotiate(ProtocolSet fst, ProtocolSet snd) { } StatusWith<StringData> toString(ProtocolSet protocols) { - switch (protocols) { - case supports::kNone: - return StringData(kNone); - case supports::kOpQueryOnly: - return StringData(kOpQueryOnly); - case supports::kOpCommandOnly: - return StringData(kOpCommandOnly); - case supports::kAll: - return StringData(kAll); - default: - return Status(ErrorCodes::BadValue, - str::stream() << "Can not convert ProtocolSet " << protocols - << " to a string, only the predefined ProtocolSet " - << "constants 'none' (0x0), 'opQueryOnly' (0x1), " - << "'opCommandOnly' (0x2), and 'all' (0x3) are supported."); + for (auto& elem : protocolSetNames) { + if (elem.protocols == protocols) + return elem.name; } + return Status(ErrorCodes::BadValue, + str::stream() << "ProtocolSet " << protocols + << " does not match any well-known value."); } -StatusWith<ProtocolSet> parseProtocolSet(StringData repr) { - if (repr == kNone) { - return supports::kNone; - } else if (repr == kOpQueryOnly) { - return supports::kOpQueryOnly; - } else if (repr == kOpCommandOnly) { - return supports::kOpCommandOnly; - } else if (repr == kAll) { - return supports::kAll; +StatusWith<ProtocolSet> parseProtocolSet(StringData name) { + for (auto& elem : protocolSetNames) { + if (elem.name == name) + return elem.protocols; } return Status(ErrorCodes::BadValue, - str::stream() << "Can not parse a ProtocolSet from " << repr - << " only the predefined ProtocolSet constants " - << "'none' (0x0), 'opQueryOnly' (0x1), 'opCommandOnly' (0x2), " - << "and 'all' (0x3) are supported."); + str::stream() << name << " is not a valid name for a ProtocolSet."); } StatusWith<ProtocolSetAndWireVersionInfo> parseProtocolSetFromIsMasterReply( @@ -154,10 +150,14 @@ StatusWith<ProtocolSetAndWireVersionInfo> parseProtocolSetFromIsMasterReply( WireVersionInfo version{static_cast<int>(minWireVersion), static_cast<int>(maxWireVersion)}; - return {{(!isMongos && supportsWireVersionForOpCommandInMongod(version)) - ? supports::kAll - : supports::kOpQueryOnly, - version}}; + auto protos = computeProtocolSet(version); + if (isMongos) { + // Remove support for protocols that mongos doesn't support. + protos &= ~supports::kOpCommandOnly; + protos &= ~supports::kOpMsgOnly; // TODO remove this line once mongos supports OP_MSG. + } + + return {{protos, version}}; } bool supportsWireVersionForOpCommandInMongod(const WireVersionInfo version) { @@ -169,7 +169,12 @@ bool supportsWireVersionForOpCommandInMongod(const WireVersionInfo version) { ProtocolSet computeProtocolSet(const WireVersionInfo version) { ProtocolSet result = supports::kNone; if (version.minWireVersion <= version.maxWireVersion) { - if (version.maxWireVersion >= WireVersion::FIND_COMMAND) { + if (version.maxWireVersion >= WireVersion::SUPPORTS_OP_MSG) { + result |= supports::kOpMsgOnly; + } + if (version.maxWireVersion >= WireVersion::FIND_COMMAND && + version.maxWireVersion <= WireVersion::SUPPORTS_OP_MSG) { + // Future versions may remove support for OP_COMMAND. result |= supports::kOpCommandOnly; } if (version.minWireVersion <= WireVersion::RELEASE_2_4_AND_BEFORE) { |