diff options
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/commands/feature_compatibility_version.cpp | 36 | ||||
-rw-r--r-- | src/mongo/db/commands/feature_compatibility_version.h | 6 | ||||
-rw-r--r-- | src/mongo/db/db.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/dbdirectclient.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/check_quorum_for_config_change.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_heartbeat_args.cpp | 29 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_heartbeat_args.h | 14 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp | 26 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_heartbeat_args_v1.h | 18 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_info.cpp | 21 | ||||
-rw-r--r-- | src/mongo/db/repl/topology_coordinator_impl.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/wire_version.h | 34 |
12 files changed, 193 insertions, 22 deletions
diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp index 8a2ed8a54ad..9e31469fe51 100644 --- a/src/mongo/db/commands/feature_compatibility_version.cpp +++ b/src/mongo/db/commands/feature_compatibility_version.cpp @@ -40,6 +40,7 @@ #include "mongo/db/server_parameters.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/storage_engine.h" +#include "mongo/db/wire_version.h" #include "mongo/db/write_concern_options.h" #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/transport/service_entry_point.h" @@ -340,8 +341,11 @@ void FeatureCompatibilityVersion::onInsertOrUpdate(OperationContext* opCtx, cons // version that is below the minimum. opCtx->recoveryUnit()->onCommit([opCtx, newVersion]() { serverGlobalParams.featureCompatibility.setVersion(newVersion); + updateMinWireVersion(); - // Close all connections from internal clients with binary versions lower than 3.6. + // Close all incoming connections from internal clients with binary versions lower than + // ours. It would be desirable to close all outgoing connections to servers with lower + // binary version, but it is not currently possible. if (newVersion != ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) { opCtx->getServiceContext()->getServiceEntryPoint()->endAllSessions( transport::Session::kLatestVersionInternalClientKeepOpen | @@ -367,6 +371,7 @@ void FeatureCompatibilityVersion::onDelete(OperationContext* opCtx, const BSONOb opCtx->recoveryUnit()->onCommit([]() { serverGlobalParams.featureCompatibility.setVersion( ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34); + updateMinWireVersion(); }); } @@ -384,9 +389,35 @@ void FeatureCompatibilityVersion::onDropCollection(OperationContext* opCtx) { opCtx->recoveryUnit()->onCommit([]() { serverGlobalParams.featureCompatibility.setVersion( ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34); + updateMinWireVersion(); }); } +void FeatureCompatibilityVersion::updateMinWireVersion() { + WireSpec& spec = WireSpec::instance(); + + switch (serverGlobalParams.featureCompatibility.getVersion()) { + case ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36: + case ServerGlobalParams::FeatureCompatibility::Version::kUpgradingTo36: + case ServerGlobalParams::FeatureCompatibility::Version::kDowngradingTo34: + spec.incomingInternalClient.minWireVersion = LATEST_WIRE_VERSION; + spec.outgoing.minWireVersion = LATEST_WIRE_VERSION; + return; + case ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34: + // It would be preferable to set 'incomingInternalClient.minWireVersion' and + // 'outgoing.minWireVersion' to LATEST_WIRE_VERSION - 1, but this is not possible due to + // a bug in 3.4, where if the receiving node says it supports wire version range + // [COMMANDS_ACCEPT_WRITE_CONCERN, SUPPORTS_OP_MSG], the initiating node will think it + // only supports OP_QUERY. + spec.incomingInternalClient.minWireVersion = RELEASE_2_4_AND_BEFORE; + spec.outgoing.minWireVersion = RELEASE_2_4_AND_BEFORE; + return; + case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault34Behavior: + // getVersion() does not return this value. + MONGO_UNREACHABLE; + } +} + void FeatureCompatibilityVersion::_validateVersion(StringData version) { uassert(40284, str::stream() << "featureCompatibilityVersion must be '" @@ -471,7 +502,8 @@ public: FeatureCompatibilityVersion::kTargetVersionField, FeatureCompatibilityVersionCommandParser::kVersion34); return; - default: + case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault34Behavior: + // getVersion() does not return this value. MONGO_UNREACHABLE; } } diff --git a/src/mongo/db/commands/feature_compatibility_version.h b/src/mongo/db/commands/feature_compatibility_version.h index e1598756919..70acd034ef3 100644 --- a/src/mongo/db/commands/feature_compatibility_version.h +++ b/src/mongo/db/commands/feature_compatibility_version.h @@ -134,6 +134,12 @@ public: */ static void onDropCollection(OperationContext* opCtx); + /** + * Sets the server's outgoing and incomingInternalClient minWireVersions according to the + * current featureCompatibilityVersion value. + */ + static void updateMinWireVersion(); + private: /** * Validate version. Uasserts if invalid. diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index b18a5b40010..2d191c38220 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -546,6 +546,7 @@ StatusWith<bool> repairDatabasesAndCheckVersion(OperationContext* opCtx) { fcvDocumentExists = true; auto version = swVersion.getValue(); serverGlobalParams.featureCompatibility.setVersion(version); + FeatureCompatibilityVersion::updateMinWireVersion(); // On startup, if the version is in an upgrading or downrading state, print a // warning. @@ -662,6 +663,15 @@ StatusWith<bool> repairDatabasesAndCheckVersion(OperationContext* opCtx) { void initWireSpec() { WireSpec& spec = WireSpec::instance(); + // The featureCompatibilityVersion behavior defaults to the downgrade behavior while the + // in-memory version is unset. + + spec.incomingInternalClient.minWireVersion = RELEASE_2_4_AND_BEFORE; + spec.incomingInternalClient.maxWireVersion = LATEST_WIRE_VERSION; + + spec.outgoing.minWireVersion = RELEASE_2_4_AND_BEFORE; + spec.outgoing.maxWireVersion = LATEST_WIRE_VERSION; + spec.isInternalClient = true; } diff --git a/src/mongo/db/dbdirectclient.cpp b/src/mongo/db/dbdirectclient.cpp index c644f2dd631..132a01131ce 100644 --- a/src/mongo/db/dbdirectclient.cpp +++ b/src/mongo/db/dbdirectclient.cpp @@ -95,12 +95,12 @@ std::string DBDirectClient::getServerAddress() const { // Returned version should match the incoming connections restrictions. int DBDirectClient::getMinWireVersion() { - return WireSpec::instance().incoming.minWireVersion; + return WireSpec::instance().incomingExternalClient.minWireVersion; } // Returned version should match the incoming connections restrictions. int DBDirectClient::getMaxWireVersion() { - return WireSpec::instance().incoming.maxWireVersion; + return WireSpec::instance().incomingExternalClient.maxWireVersion; } bool DBDirectClient::isReplicaSetMember() const { diff --git a/src/mongo/db/repl/check_quorum_for_config_change.cpp b/src/mongo/db/repl/check_quorum_for_config_change.cpp index 83489872c63..e1a2321d91e 100644 --- a/src/mongo/db/repl/check_quorum_for_config_change.cpp +++ b/src/mongo/db/repl/check_quorum_for_config_change.cpp @@ -40,6 +40,7 @@ #include "mongo/db/repl/repl_set_heartbeat_response.h" #include "mongo/db/repl/scatter_gather_algorithm.h" #include "mongo/db/repl/scatter_gather_runner.h" +#include "mongo/db/server_options.h" #include "mongo/rpc/metadata/repl_set_metadata.h" #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" @@ -89,6 +90,10 @@ std::vector<RemoteCommandRequest> QuorumChecker::getRequests() const { hbArgs.setSetName(_rsConfig->getReplSetName()); hbArgs.setProtocolVersion(1); hbArgs.setConfigVersion(_rsConfig->getConfigVersion()); + if (serverGlobalParams.featureCompatibility.getVersion() != + ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) { + hbArgs.setHeartbeatVersion(1); + } hbArgs.setCheckEmpty(isInitialConfig); hbArgs.setSenderHost(myConfig.getHostAndPort()); hbArgs.setSenderId(myConfig.getId()); @@ -98,6 +103,10 @@ std::vector<RemoteCommandRequest> QuorumChecker::getRequests() const { ReplSetHeartbeatArgsV1 hbArgs; hbArgs.setSetName(_rsConfig->getReplSetName()); hbArgs.setConfigVersion(_rsConfig->getConfigVersion()); + if (serverGlobalParams.featureCompatibility.getVersion() != + ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) { + hbArgs.setHeartbeatVersion(1); + } if (isInitialConfig) { hbArgs.setCheckEmpty(); } diff --git a/src/mongo/db/repl/repl_set_heartbeat_args.cpp b/src/mongo/db/repl/repl_set_heartbeat_args.cpp index db88f7e47b6..5b75f97c516 100644 --- a/src/mongo/db/repl/repl_set_heartbeat_args.cpp +++ b/src/mongo/db/repl/repl_set_heartbeat_args.cpp @@ -42,6 +42,7 @@ namespace { const std::string kCheckEmptyFieldName = "checkEmpty"; const std::string kProtocolVersionFieldName = "pv"; const std::string kConfigVersionFieldName = "v"; +const std::string kHeartbeatVersionFieldName = "hbv"; const std::string kSenderIdFieldName = "fromId"; const std::string kSetNameFieldName = "replSetHeartbeat"; const std::string kSenderHostFieldName = "from"; @@ -49,6 +50,7 @@ const std::string kSenderHostFieldName = "from"; const std::string kLegalHeartbeatFieldNames[] = {kCheckEmptyFieldName, kProtocolVersionFieldName, kConfigVersionFieldName, + kHeartbeatVersionFieldName, kSenderIdFieldName, kSetNameFieldName, kSenderHostFieldName}; @@ -59,12 +61,14 @@ ReplSetHeartbeatArgs::ReplSetHeartbeatArgs() : _hasCheckEmpty(false), _hasProtocolVersion(false), _hasConfigVersion(false), + _hasHeartbeatVersion(false), _hasSenderId(false), _hasSetName(false), _hasSenderHost(false), _checkEmpty(false), _protocolVersion(-1), _configVersion(-1), + _heartbeatVersion(-1), _senderId(-1), _setName(""), _senderHost(HostAndPort()) {} @@ -90,6 +94,22 @@ Status ReplSetHeartbeatArgs::initialize(const BSONObj& argsObj) { return status; _hasConfigVersion = true; + long long tempHeartbeatVersion; + status = bsonExtractIntegerField(argsObj, kHeartbeatVersionFieldName, &tempHeartbeatVersion); + if (status.isOK()) { + if (tempHeartbeatVersion != 1) { + return Status(ErrorCodes::Error(40665), + str::stream() << "Found invalid value for field " + << kHeartbeatVersionFieldName + << ": " + << tempHeartbeatVersion); + } + _heartbeatVersion = tempHeartbeatVersion; + _hasHeartbeatVersion = true; + } else if (status.code() != ErrorCodes::NoSuchKey) { + return status; + } + status = bsonExtractIntegerFieldWithDefault(argsObj, kSenderIdFieldName, -1, &_senderId); if (!status.isOK()) return status; @@ -126,6 +146,10 @@ BSONObj ReplSetHeartbeatArgs::toBSON() const { builder.append("replSetHeartbeat", _setName); builder.appendIntOrLL("pv", _protocolVersion); builder.appendIntOrLL("v", _configVersion); + if (_hasHeartbeatVersion) { + builder.append("hbv", _heartbeatVersion); + } + builder.append("from", _hasSenderHost ? _senderHost.toString() : ""); if (_hasSenderId) { @@ -152,6 +176,11 @@ void ReplSetHeartbeatArgs::setConfigVersion(long long newVal) { _hasConfigVersion = true; } +void ReplSetHeartbeatArgs::setHeartbeatVersion(long long newVal) { + _heartbeatVersion = newVal; + _hasHeartbeatVersion = true; +} + void ReplSetHeartbeatArgs::setSenderId(long long newVal) { _senderId = newVal; _hasSenderId = true; diff --git a/src/mongo/db/repl/repl_set_heartbeat_args.h b/src/mongo/db/repl/repl_set_heartbeat_args.h index 1faa7d4bca0..40e8e180312 100644 --- a/src/mongo/db/repl/repl_set_heartbeat_args.h +++ b/src/mongo/db/repl/repl_set_heartbeat_args.h @@ -78,6 +78,14 @@ public: } /** + * Gets the heartbeat version number of the sender. This field was added to ensure that + * heartbeats sent from featureCompatibilityVersion 3.6 nodes to binary version 3.4 nodes fail. + */ + long long getHeartbeatVersion() const { + return _heartbeatVersion; + } + + /** * Gets the _id of the sender in their ReplSetConfig. */ long long getSenderId() const { @@ -110,6 +118,9 @@ public: bool hasConfigVersion() const { return _hasConfigVersion; } + bool hasHeartbeatVersion() const { + return _hasHeartbeatVersion; + } bool hasSenderId() const { return _hasSenderId; } @@ -126,6 +137,7 @@ public: void setCheckEmpty(bool newVal); void setProtocolVersion(long long newVal); void setConfigVersion(long long newVal); + void setHeartbeatVersion(long long newVal); void setSenderId(long long newVal); void setSetName(std::string newVal); void setSenderHost(HostAndPort newVal); @@ -141,6 +153,7 @@ private: bool _hasCheckEmpty; bool _hasProtocolVersion; bool _hasConfigVersion; + bool _hasHeartbeatVersion; bool _hasSenderId; bool _hasSetName; bool _hasSenderHost; @@ -149,6 +162,7 @@ private: bool _checkEmpty; long long _protocolVersion; long long _configVersion; + long long _heartbeatVersion; long long _senderId; std::string _setName; HostAndPort _senderHost; diff --git a/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp b/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp index 39bab8cdda7..4568e3ef89c 100644 --- a/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp +++ b/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp @@ -42,6 +42,7 @@ namespace { const std::string kCheckEmptyFieldName = "checkEmpty"; const std::string kConfigVersionFieldName = "configVersion"; +const std::string kHeartbeatVersionFieldName = "hbv"; const std::string kSenderHostFieldName = "from"; const std::string kSenderIdFieldName = "fromId"; const std::string kSetNameFieldName = "replSetHeartbeat"; @@ -49,6 +50,7 @@ const std::string kTermFieldName = "term"; const std::string kLegalHeartbeatFieldNames[] = {kCheckEmptyFieldName, kConfigVersionFieldName, + kHeartbeatVersionFieldName, kSenderHostFieldName, kSenderIdFieldName, kSetNameFieldName, @@ -70,6 +72,22 @@ Status ReplSetHeartbeatArgsV1::initialize(const BSONObj& argsObj) { if (!status.isOK()) return status; + long long tempHeartbeatVersion; + status = bsonExtractIntegerField(argsObj, kHeartbeatVersionFieldName, &tempHeartbeatVersion); + if (status.isOK()) { + if (tempHeartbeatVersion != 1) { + return Status(ErrorCodes::Error(40666), + str::stream() << "Found invalid value for field " + << kHeartbeatVersionFieldName + << ": " + << tempHeartbeatVersion); + } + _heartbeatVersion = tempHeartbeatVersion; + _hasHeartbeatVersion = true; + } else if (status.code() != ErrorCodes::NoSuchKey) { + return status; + } + status = bsonExtractIntegerFieldWithDefault(argsObj, kSenderIdFieldName, -1, &_senderId); if (!status.isOK()) return status; @@ -104,6 +122,11 @@ void ReplSetHeartbeatArgsV1::setConfigVersion(long long newVal) { _configVersion = newVal; } +void ReplSetHeartbeatArgsV1::setHeartbeatVersion(long long newVal) { + _heartbeatVersion = newVal; + _hasHeartbeatVersion = true; +} + void ReplSetHeartbeatArgsV1::setSenderHost(const HostAndPort& newVal) { _senderHost = newVal; _hasSender = true; @@ -138,6 +161,9 @@ void ReplSetHeartbeatArgsV1::addToBSON(BSONObjBuilder* builder) const { builder->append(kCheckEmptyFieldName, _checkEmpty); } builder->appendIntOrLL(kConfigVersionFieldName, _configVersion); + if (_hasHeartbeatVersion) { + builder->appendIntOrLL(kHeartbeatVersionFieldName, _hasHeartbeatVersion); + } builder->append(kSenderHostFieldName, _hasSender ? _senderHost.toString() : ""); builder->appendIntOrLL(kSenderIdFieldName, _senderId); builder->appendIntOrLL(kTermFieldName, _term); diff --git a/src/mongo/db/repl/repl_set_heartbeat_args_v1.h b/src/mongo/db/repl/repl_set_heartbeat_args_v1.h index 45a00ab8927..6f1cbb94af8 100644 --- a/src/mongo/db/repl/repl_set_heartbeat_args_v1.h +++ b/src/mongo/db/repl/repl_set_heartbeat_args_v1.h @@ -63,6 +63,14 @@ public: } /** + * Gets the heartbeat version number of the sender. This field was added to ensure that + * heartbeats sent from featureCompatibilityVersion 3.6 nodes to binary version 3.4 nodes fail. + */ + long long getHeartbeatVersion() const { + return _heartbeatVersion; + } + + /** * Gets the _id of the sender in their ReplSetConfig. */ long long getSenderId() const { @@ -105,9 +113,17 @@ public: } /** + * Returns whether or not the heartbeat version of the sender is set. + */ + bool hasHeartbeatVersion() const { + return _hasHeartbeatVersion; + } + + /** * The below methods set the value in the method name to 'newVal'. */ void setConfigVersion(long long newVal); + void setHeartbeatVersion(long long newVal); void setSenderId(long long newVal); void setSenderHost(const HostAndPort& newVal); void setSetName(const std::string& newVal); @@ -126,10 +142,12 @@ public: private: // look at the body of the isInitialized() function to see which fields are mandatory long long _configVersion = -1; + long long _heartbeatVersion = -1; long long _senderId = -1; long long _term = -1; bool _checkEmpty = false; bool _hasSender = false; + bool _hasHeartbeatVersion = false; std::string _setName; HostAndPort _senderHost; }; diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp index 192d7c67b22..7729eaccda3 100644 --- a/src/mongo/db/repl/replication_info.cpp +++ b/src/mongo/db/repl/replication_info.cpp @@ -309,7 +309,8 @@ public: // All incoming connections from mongod/mongos of earlier versions should be // closed if the featureCompatibilityVersion is bumped to 3.6. - if (elem.numberInt() >= WireSpec::instance().incoming.maxWireVersion) { + if (elem.numberInt() >= + WireSpec::instance().incomingInternalClient.maxWireVersion) { sessionTagsToSet |= transport::Session::kLatestVersionInternalClientKeepOpen; } else { @@ -361,18 +362,18 @@ public: result.appendNumber("maxMessageSizeBytes", MaxMessageSizeBytes); result.appendNumber("maxWriteBatchSize", write_ops::kMaxWriteBatchSize); result.appendDate("localTime", jsTime()); - result.append("maxWireVersion", WireSpec::instance().incoming.maxWireVersion); result.append("logicalSessionTimeoutMinutes", localLogicalSessionTimeoutMinutes); - // If the featureCompatibilityVersion is 3.6 (or upgrading or downgrading), respond with - // minWireVersion=maxWireVersion. Then if the connection is from a mongod/mongos of an - // earlier version, it will fail to connect. - if (internalClientElement && - serverGlobalParams.featureCompatibility.getVersion() != - ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) { - result.append("minWireVersion", WireSpec::instance().incoming.maxWireVersion); + if (internalClientElement) { + result.append("minWireVersion", + WireSpec::instance().incomingInternalClient.minWireVersion); + result.append("maxWireVersion", + WireSpec::instance().incomingInternalClient.maxWireVersion); } else { - result.append("minWireVersion", WireSpec::instance().incoming.minWireVersion); + result.append("minWireVersion", + WireSpec::instance().incomingExternalClient.minWireVersion); + result.append("maxWireVersion", + WireSpec::instance().incomingExternalClient.maxWireVersion); } result.append("readOnly", storageGlobalParams.readOnly); diff --git a/src/mongo/db/repl/topology_coordinator_impl.cpp b/src/mongo/db/repl/topology_coordinator_impl.cpp index 00ec2910226..07ec8c6a99d 100644 --- a/src/mongo/db/repl/topology_coordinator_impl.cpp +++ b/src/mongo/db/repl/topology_coordinator_impl.cpp @@ -902,6 +902,10 @@ std::pair<ReplSetHeartbeatArgs, Milliseconds> TopologyCoordinatorImpl::prepareHe hbArgs.setSetName(ourSetName); hbArgs.setConfigVersion(-2); } + if (serverGlobalParams.featureCompatibility.getVersion() != + ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) { + hbArgs.setHeartbeatVersion(1); + } const Milliseconds timeoutPeriod( _rsConfig.isInitialized() ? _rsConfig.getHeartbeatTimeoutPeriodMillis() @@ -938,6 +942,10 @@ std::pair<ReplSetHeartbeatArgsV1, Milliseconds> TopologyCoordinatorImpl::prepare hbArgs.setConfigVersion(-2); hbArgs.setTerm(OpTime::kInitialTerm); } + if (serverGlobalParams.featureCompatibility.getVersion() != + ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) { + hbArgs.setHeartbeatVersion(1); + } const Milliseconds timeoutPeriod( _rsConfig.isInitialized() ? _rsConfig.getHeartbeatTimeoutPeriodMillis() diff --git a/src/mongo/db/wire_version.h b/src/mongo/db/wire_version.h index 84b353a1d83..cc6050b8834 100644 --- a/src/mongo/db/wire_version.h +++ b/src/mongo/db/wire_version.h @@ -107,16 +107,34 @@ struct WireSpec { static void appendInternalClientWireVersion(WireVersionInfo wireVersionInfo, BSONObjBuilder* builder); - // incoming.minWireVersion - Minimum version that the server accepts on incoming requests. We - // should bump this whenever we don't want to allow incoming connections from clients that are - // too old. - - // incoming.maxWireVersion - Latest version that the server accepts on incoming requests. This - // should always be at the latest entry in WireVersion. - WireVersionInfo incoming = {RELEASE_2_4_AND_BEFORE, LATEST_WIRE_VERSION}; + // incomingExternalClient.minWireVersion - Minimum version that the server accepts on incoming + // requests from external clients. We should bump this whenever we don't want to allow incoming + // connections from clients that are too old. + + // incomingExternalClient.maxWireVersion - Latest version that the server accepts on incoming + // requests from external clients. This should always be at the latest entry in WireVersion. + WireVersionInfo incomingExternalClient = {RELEASE_2_4_AND_BEFORE, LATEST_WIRE_VERSION}; + + // incomingInternalClient.minWireVersion - Minimum version that the server accepts on incoming + // requests from internal clients. This should be incomingInternalClient.maxWireVersion - 1, + // when the featureCompatibilityVersion is equal to the downgrade version, and + // incomingInternalClient.maxWireVersion otherwise. However, in 3.6, this needs to be + // RELEASE_2_4_AND_BEFORE when the featureCompatibilityVersion is equal to the downgrade version + // due to a bug in 3.4, where if the receiving node says it supports wire version range + // [COMMANDS_ACCEPT_WRITE_CONCERN, SUPPORTS_OP_MSG] and it is a mongod, the initiating node will + // think it only supports OP_QUERY. + + // incomingInternalClient.maxWireVersion - Latest version that the server accepts on incoming + // requests. This should always be at the latest entry in WireVersion. + WireVersionInfo incomingInternalClient = {RELEASE_2_4_AND_BEFORE, LATEST_WIRE_VERSION}; // outgoing.minWireVersion - Minimum version allowed on remote nodes when the server sends - // requests. We should bump this whenever we don't want to connect to clients that are too old. + // requests. This should be outgoing.maxWireVersion - 1, when the featureCompatibilityVersion is + // equal to the downgrade version, and outgoing.maxWireVersion otherwise. However, in 3.6, this + // needs to be RELEASE_2_4_AND_BEFORE when the featureCompatibilityVersion is equal to the + // downgrade version due to a bug in 3.4, where if the receiving node says it supports wire + // version range [COMMANDS_ACCEPT_WRITE_CONCERN, SUPPORTS_OP_MSG] and it is a mongod, the + // initiating node will think it only supports OP_QUERY. // outgoing.maxWireVersion - Latest version allowed on remote nodes when the server sends // requests. |