summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorADAM David Alan Martin <adam.martin@10gen.com>2018-02-09 16:35:52 -0500
committerADAM David Alan Martin <adam.martin@10gen.com>2018-02-09 16:39:03 -0500
commit9820063b4a88f685704385c13f4ee34aed31c1cd (patch)
tree6cd8204b7973bae9d68549393b8caa9edf75c7d7
parent3968e970161872b78fa88ad65a8785b54694c126 (diff)
downloadmongo-9820063b4a88f685704385c13f4ee34aed31c1cd.tar.gz
SERVER-33140 DNS must disregard irrelevant records
DNS Queries can return superfluous records of non-requested type in Windows DNSApi calls. Windows implementations will now ignore records of those types. (cherry picked from commit bf33c24ff0cf4018dfa94e3a349421ace28d1fac)
-rw-r--r--src/mongo/base/error_codes.err1
-rw-r--r--src/mongo/util/dns_query.cpp66
-rw-r--r--src/mongo/util/dns_query_windows-impl.h21
3 files changed, 60 insertions, 28 deletions
diff --git a/src/mongo/base/error_codes.err b/src/mongo/base/error_codes.err
index 38bc2ef862e..8bbd50ceaa4 100644
--- a/src/mongo/base/error_codes.err
+++ b/src/mongo/base/error_codes.err
@@ -232,6 +232,7 @@ error_code("DNSProtocolError", 231)
error_code("MaxSubPipelineDepthExceeded", 232)
error_code("TooManyDocumentSequences", 233)
error_code("RetryChangeStream", 234)
+error_code("DNSRecordTypeMismatch", 240)
# Error codes 4000-8999 are reserved.
diff --git a/src/mongo/util/dns_query.cpp b/src/mongo/util/dns_query.cpp
index 3eef7240851..d200b57e7bf 100644
--- a/src/mongo/util/dns_query.cpp
+++ b/src/mongo/util/dns_query.cpp
@@ -43,6 +43,8 @@
#include <boost/noncopyable.hpp>
+#include "mongo/bson/util/builder.h"
+
// It is safe to include the implementation "headers" in an anonymous namespace, as the code is
// meant to live in a single TU -- this one. Include one of these headers last.
#define MONGO_UTIL_DNS_QUERY_PLATFORM_INCLUDE_WHITELIST
@@ -66,15 +68,25 @@ std::vector<std::string> dns::lookupARecords(const std::string& service) {
DNSQueryState dnsQuery;
auto response = dnsQuery.lookup(service, DNSQueryClass::kInternet, DNSQueryType::kAddress);
- if (response.size() == 0) {
- uasserted(ErrorCodes::DNSProtocolError,
- "Looking up " + service + " A record yielded no results.");
+ std::vector<std::string> rv;
+
+ for (const auto& entry : response) {
+ try {
+ rv.push_back(entry.addressEntry());
+ } catch (const ExceptionFor<ErrorCodes::DNSRecordTypeMismatch>&) {
+ }
}
- std::vector<std::string> rv;
- std::transform(begin(response), end(response), back_inserter(rv), [](const auto& entry) {
- return entry.addressEntry();
- });
+ if (rv.empty()) {
+ StringBuilder oss;
+ oss << "Looking up " << service << " A record yielded ";
+ if (response.size() == 0) {
+ oss << "no results.";
+ } else {
+ oss << "no A records but " << response.size() << " other records";
+ }
+ uasserted(ErrorCodes::DNSProtocolError, oss.str());
+ }
return rv;
}
@@ -86,9 +98,24 @@ std::vector<dns::SRVHostEntry> dns::lookupSRVRecords(const std::string& service)
std::vector<SRVHostEntry> rv;
- std::transform(begin(response), end(response), back_inserter(rv), [](const auto& entry) {
- return entry.srvHostEntry();
- });
+ for (const auto& entry : response) {
+ try {
+ rv.push_back(entry.srvHostEntry());
+ } catch (const ExceptionFor<ErrorCodes::DNSRecordTypeMismatch>&) {
+ }
+ }
+
+ if (rv.empty()) {
+ StringBuilder oss;
+ oss << "Looking up " << service << " SRV record yielded ";
+ if (response.size() == 0) {
+ oss << "no results.";
+ } else {
+ oss << "no SRV records but " << response.size() << " other records";
+ }
+ uasserted(ErrorCodes::DNSProtocolError, oss.str());
+ }
+
return rv;
}
@@ -100,20 +127,21 @@ std::vector<std::string> dns::lookupTXTRecords(const std::string& service) {
std::vector<std::string> rv;
for (auto& entry : response) {
- auto txtEntry = entry.txtEntry();
- rv.insert(end(rv),
- std::make_move_iterator(begin(txtEntry)),
- std::make_move_iterator(end(txtEntry)));
+ try {
+ auto txtEntry = entry.txtEntry();
+ rv.insert(end(rv),
+ std::make_move_iterator(begin(txtEntry)),
+ std::make_move_iterator(end(txtEntry)));
+ } catch (const ExceptionFor<ErrorCodes::DNSRecordTypeMismatch>&) {
+ }
}
+
return rv;
}
std::vector<std::string> dns::getTXTRecords(const std::string& service) try {
return lookupTXTRecords(service);
-} catch (const DBException& ex) {
- if (ex.code() == ErrorCodes::DNSHostNotFound) {
- return {};
- }
- throw;
+} catch (const ExceptionFor<ErrorCodes::DNSHostNotFound>&) {
+ return {};
}
} // namespace mongo
diff --git a/src/mongo/util/dns_query_windows-impl.h b/src/mongo/util/dns_query_windows-impl.h
index f131bd76275..c7eb5e8d29a 100644
--- a/src/mongo/util/dns_query_windows-impl.h
+++ b/src/mongo/util/dns_query_windows-impl.h
@@ -78,10 +78,11 @@ public:
*/
std::vector<std::string> txtEntry() const {
if (this->_record->wType != DNS_TYPE_TEXT) {
- std::ostringstream oss;
+ StringBuilder oss;
oss << "Incorrect record format for \"" << this->_service
- << "\": expected TXT record, found something else";
- uasserted(ErrorCodes::DNSProtocolError, oss.str());
+ << "\": expected TXT record, found a record of type " << this->_record->wType
+ << " instead";
+ uasserted(ErrorCodes::DNSRecordTypeMismatch, oss.str());
}
std::vector<std::string> rv;
@@ -97,10 +98,11 @@ public:
*/
std::string addressEntry() const {
if (this->_record->wType != DNS_TYPE_A) {
- std::ostringstream oss;
+ StringBuilder oss;
oss << "Incorrect record format for \"" << this->_service
- << "\": expected A record, found something else";
- uasserted(ErrorCodes::DNSProtocolError, oss.str());
+ << "\": expected A record, found a record of type " << this->_record->wType
+ << " instead";
+ uasserted(ErrorCodes::DNSRecordTypeMismatch, oss.str());
}
std::string rv;
@@ -121,10 +123,11 @@ public:
*/
SRVHostEntry srvHostEntry() const {
if (this->_record->wType != DNS_TYPE_SRV) {
- std::ostringstream oss;
+ StringBuilder oss;
oss << "Incorrect record format for \"" << this->_service
- << "\": expected SRV record, found something else";
- uasserted(ErrorCodes::DNSProtocolError, oss.str());
+ << "\": expected SRV record, found a record of type " << this->_record->wType
+ << " instead";
+ uasserted(ErrorCodes::DNSRecordTypeMismatch, oss.str());
}
const auto& data = this->_record->Data.SRV;