BIND 10 master, updated. a677ae91c9d7a5bd2ef8574f84e9f33f90c45e44 [master] ChangeLog for Trac 1383
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Dec 9 10:49:29 UTC 2011
The branch, master has been updated
via a677ae91c9d7a5bd2ef8574f84e9f33f90c45e44 (commit)
via 9b2b249d23576c999a65d8c338e008cabe45f0c9 (commit)
via c0be7a6c0e12c78a7e02a2a3b3b259a3382b52bf (commit)
via 982fc000a3064515ac30f5457b71802577fec90d (commit)
via eb08c5acb5deafa28ae37032910cce9a385d2030 (commit)
via b2186bf05d8d9858b0b58cf9dca5b215afe447f5 (commit)
via c44075a40764cbb5dc37e9dd3666ce46bb8c7955 (commit)
via d6d90c1976110dcfb94cba2c56086960054cdeae (commit)
from 45274924f3f25b70547809eeda5dbcbe230029b5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit a677ae91c9d7a5bd2ef8574f84e9f33f90c45e44
Author: Stephen Morris <stephen at isc.org>
Date: Fri Dec 9 10:48:57 2011 +0000
[master] ChangeLog for Trac 1383
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 7 ++
src/lib/asiodns/io_fetch.cc | 4 -
src/lib/nsas/nameserver_entry.cc | 24 ++++--
src/lib/nsas/nsas_messages.mes | 29 ++++---
src/lib/resolve/recursive_query.cc | 152 ++++++++++++++++++++++++---------
src/lib/resolve/resolve_messages.mes | 97 +++++++++++++++++++---
src/lib/resolve/response_classifier.h | 4 +-
7 files changed, 242 insertions(+), 75 deletions(-)
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index e8f57ba..c59c9ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+342. [bug] stephen
+ In the resolver, a FORMERR received from an upstream nameserver
+ now rsults in a SERVFAIL being returned as a response to the original
+ query. Additional debug messages added to distinguish between
+ different errors in packets received from upstream nameservers.
+ (Trac #1383, git 9b2b249d23576c999a65d8c338e008cabe45f0c9)
+
341. [func] tomek
libdhcp++: Support for handling both IPv4 and IPv6 added.
Also added support for binding IPv4 sockets.
diff --git a/src/lib/asiodns/io_fetch.cc b/src/lib/asiodns/io_fetch.cc
index 466be3e..8a91982 100644
--- a/src/lib/asiodns/io_fetch.cc
+++ b/src/lib/asiodns/io_fetch.cc
@@ -355,10 +355,6 @@ IOFetch::stop(Result result) {
// variable should be done inside a mutex (and the stopped_ variable
// declared as "volatile").
//
- // The numeric arguments indicate the debug level, with the lower
- // numbers indicating the most important information. The relative
- // values are somewhat arbitrary.
- //
// TODO: Update testing of stopped_ if threads are used.
data_->stopped = true;
switch (result) {
diff --git a/src/lib/nsas/nameserver_entry.cc b/src/lib/nsas/nameserver_entry.cc
index 553c35d..bca8f73 100644
--- a/src/lib/nsas/nameserver_entry.cc
+++ b/src/lib/nsas/nameserver_entry.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
@@ -223,7 +223,8 @@ class NameserverEntry::ResolverCallback :
* \short We received the address successfully.
*
* This extracts the addresses out from the response and puts them
- * inside the entry. It tries to reuse the address entries from before (if there were any), to keep their RTTs.
+ * inside the entry. It tries to reuse the address entries from before
+ * (if there were any), to keep their RTTs.
*/
virtual void success(MessagePtr response_message) {
time_t now = time(NULL);
@@ -231,10 +232,21 @@ class NameserverEntry::ResolverCallback :
Lock lock(entry_->mutex_);
// TODO: find the correct RRset, not simply the first
- if (!response_message ||
- response_message->getRcode() != isc::dns::Rcode::NOERROR() ||
+ if (!response_message) {
+ LOG_ERROR(nsas_logger, NSAS_NULL_RESPONSE).arg(entry_->getName());
+ failureInternal(lock);
+ return;
+
+ } else if (response_message->getRcode() != isc::dns::Rcode::NOERROR()) {
+ LOG_DEBUG(nsas_logger, NSAS_DBG_RESULTS, NSAS_ERROR_RESPONSE).
+ arg(response_message->getRcode()).arg(entry_->getName());
+ failureInternal(lock);
+ return;
+
+ } else if (
response_message->getRRCount(isc::dns::Message::SECTION_ANSWER) == 0) {
- LOG_ERROR(nsas_logger, NSAS_INVALID_RESPONSE).arg(entry_->getName());
+ LOG_DEBUG(nsas_logger, NSAS_DBG_RESULTS, NSAS_EMPTY_RESPONSE).
+ arg(entry_->getName());
failureInternal(lock);
return;
}
@@ -371,7 +383,7 @@ class NameserverEntry::ResolverCallback :
}
}
- // Handle a failure to optain data. Dispatches callbacks and leaves
+ // Handle a failure to obtain data. Dispatches callbacks and leaves
// lock unlocked
void failureInternal(Lock &lock) {
// Set state of the addresses
diff --git a/src/lib/nsas/nsas_messages.mes b/src/lib/nsas/nsas_messages.mes
index 512fcd5..6c35172 100644
--- a/src/lib/nsas/nsas_messages.mes
+++ b/src/lib/nsas/nsas_messages.mes
@@ -14,6 +14,16 @@
$NAMESPACE isc::nsas
+% NSAS_EMPTY_RESPONSE response to query for %1 returned an empty answer section
+The NSAS (nameserver address store - part of the resolver) made a query
+for information it needed. The query completed successfully but the
+answer section in the response was empty.
+
+% NSAS_ERROR_RESPONSE error response of %1 returned in query for %2
+The NSAS (nameserver address store - part of the resolver) made a query
+for information it needed. The query completed successfully but the
+RCODE in the response was something other than NOERROR.
+
% NSAS_FIND_NS_ADDRESS asking resolver to obtain A and AAAA records for %1
A debug message issued when the NSAS (nameserver address store - part
of the resolver) is making a callback into the resolver to retrieve the
@@ -24,17 +34,6 @@ A debug message issued when the NSAS (nameserver address store - part
of the resolver) has retrieved the given address for the specified
nameserver through an external query.
-% NSAS_INVALID_RESPONSE queried for %1 but got invalid response
-The NSAS (nameserver address store - part of the resolver) made a query
-for a RR for the specified nameserver but received an invalid response.
-Either the success function was called without a DNS message or the
-message was invalid on some way. (In the latter case, the error should
-have been picked up elsewhere in the processing logic, hence the raising
-of the error here.)
-
-This message indicates an internal error in the NSAS. Please raise a
-bug report.
-
% NSAS_LOOKUP_CANCEL lookup for zone %1 has been canceled
A debug message issued when an NSAS (nameserver address store - part of
the resolver) lookup for a zone has been canceled.
@@ -46,6 +45,14 @@ for the specified nameserver. This is not necessarily a problem - the
nameserver may be unreachable, in which case the NSAS will try other
nameservers in the zone.
+% NSAS_NULL_RESPONSE got null message in success callback for query for %1
+The NSAS (nameserver address store - part of the resolver) made a query
+for information it needed. The query completed successfully, but the
+message passed to the callback was null.
+
+This message indicates an internal error in the NSAS. Please raise a
+bug report.
+
% NSAS_SEARCH_ZONE_NS searching NSAS for nameservers for zone %1
A debug message output when a call is made to the NSAS (nameserver
address store - part of the resolver) to obtain the nameservers for
diff --git a/src/lib/resolve/recursive_query.cc b/src/lib/resolve/recursive_query.cc
index 0d3fb4c..1855f7a 100644
--- a/src/lib/resolve/recursive_query.cc
+++ b/src/lib/resolve/recursive_query.cc
@@ -28,9 +28,9 @@
#include <dns/opcode.h>
#include <dns/exceptions.h>
#include <dns/rdataclass.h>
-
#include <resolve/resolve.h>
#include <resolve/resolve_log.h>
+#include <resolve/resolve_messages.h>
#include <cache/resolver_cache.h>
#include <nsas/address_request_callback.h>
#include <nsas/nameserver_address.h>
@@ -39,6 +39,7 @@
#include <asiodns/dns_service.h>
#include <asiodns/io_fetch.h>
#include <asiolink/io_service.h>
+#include <resolve/response_classifier.h>
#include <resolve/recursive_query.h>
using namespace isc::dns;
@@ -430,7 +431,7 @@ private:
.arg(questionText(question_));
isc::resolve::copyResponseMessage(incoming, answer_message_);
cache_.update(*answer_message_);
- return true;
+ return (true);
break;
case isc::resolve::ResponseClassifier::CNAME:
@@ -444,7 +445,7 @@ private:
LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_LONG_CHAIN)
.arg(questionText(question_));
makeSERVFAIL();
- return true;
+ return (true);
}
LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_CNAME)
@@ -460,7 +461,7 @@ private:
LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_FOLLOW_CNAME)
.arg(questionText(question_));
doLookup();
- return false;
+ return (false);
break;
case isc::resolve::ResponseClassifier::NXDOMAIN:
@@ -471,7 +472,7 @@ private:
isc::resolve::copyResponseMessage(incoming, answer_message_);
// no negcache yet
//cache_.update(*answer_message_);
- return true;
+ return (true);
break;
case isc::resolve::ResponseClassifier::REFERRAL:
@@ -520,7 +521,7 @@ private:
nsas_callback_out_ = true;
nsas_.lookup(cur_zone_, question_.getClass(),
nsas_callback_, ANY_OK, glue_hints);
- return false;
+ return (false);
} else {
// Referral was received but did not contain an NS RRset.
LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_NO_NS_RRSET)
@@ -528,48 +529,122 @@ private:
// TODO this will result in answering with the delegation. oh well
isc::resolve::copyResponseMessage(incoming, answer_message_);
- return true;
+ return (true);
}
break;
+
case isc::resolve::ResponseClassifier::TRUNCATED:
// Truncated packet. If the protocol we used for the last one is
// UDP, re-query using TCP. Otherwise regard it as an error.
if (protocol_ == IOFetch::UDP) {
- LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_TRUNCATED)
- .arg(questionText(question_));
+ LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS,
+ RESLIB_TRUNCATED).arg(questionText(question_));
send(IOFetch::TCP);
- return false;
+ return (false);
+ }
+
+ // Was a TCP query so we have received a packet over TCP with the
+ // TC bit set: report an error by dropping down to the common
+ // error code.
+
+ default:
+ // Some error in received packet it. Report it and return SERVFAIL
+ // to the caller.
+ if (logger.isDebugEnabled()) {
+ reportResponseClassifierError(category, incoming.getRcode());
}
- // Was a TCP query so we have received a packet over TCP with the TC
- // bit set: drop through to common error processing.
- // TODO: Can we use what we have received instead of discarding it?
-
- case isc::resolve::ResponseClassifier::EMPTY:
- case isc::resolve::ResponseClassifier::EXTRADATA:
- case isc::resolve::ResponseClassifier::INVNAMCLASS:
- case isc::resolve::ResponseClassifier::INVTYPE:
- case isc::resolve::ResponseClassifier::MISMATQUEST:
- case isc::resolve::ResponseClassifier::MULTICLASS:
- case isc::resolve::ResponseClassifier::NOTONEQUEST:
- case isc::resolve::ResponseClassifier::NOTRESPONSE:
- case isc::resolve::ResponseClassifier::NOTSINGLE:
- case isc::resolve::ResponseClassifier::OPCODE:
- case isc::resolve::ResponseClassifier::RCODE:
- LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_RCODE_ERR)
- .arg(questionText(question_));
- // Should we try a different server rather than SERVFAIL?
makeSERVFAIL();
- return true;
- break;
+ return (true);
}
- // Since we do not have a default in the switch above,
- // the compiler should have errored on any missing case
- // statements.
+ // If we get here, there is some serious logic error (or a missing
+ // "return").
assert(false);
- return true;
+ return (true); // To keep the compiler happy
}
-
+
+ /// \brief Report classification-detected error
+ ///
+ /// When the response classifier has detected an error in the response from
+ /// an upstream query, this method is called to log a debug message giving
+ /// information about the problem.
+ ///
+ /// \param category Classification code for the packet
+ /// \param rcode RCODE value in the packet
+ void reportResponseClassifierError(ResponseClassifier::Category category,
+ const Rcode& rcode)
+ {
+ // We could set up a table of response classifications to message
+ // IDs here and index into that table. But given that (a) C++ does
+ // not have C's named initializers, (b) the codes for the
+ // response classifier are in another module and (c) not all messages
+ // have the same number of arguments, the setup of the table would be
+ // almost as long as the code here: it would need to include a number
+ // of assertions to ensure that any change to the the response
+ // classifier codes was detected, and the checking logic would need to
+ // check that the numeric value of the code lay within the defined
+ // limits of the table.
+
+ if (category == ResponseClassifier::RCODE) {
+
+ // Special case as this message takes two arguments.
+ LOG_DEBUG(logger, RESLIB_DBG_RESULTS, RESLIB_RCODE_ERROR).
+ arg(questionText(question_)).arg(rcode);
+
+ } else {
+
+ isc::log::MessageID message_id;
+ switch (category) {
+ case ResponseClassifier::TRUNCATED:
+ message_id = RESLIB_TCP_TRUNCATED;
+ break;
+
+ case ResponseClassifier::EMPTY:
+ message_id = RESLIB_EMPTY_RESPONSE;
+ break;
+
+ case ResponseClassifier::EXTRADATA:
+ message_id = RESLIB_EXTRADATA_RESPONSE;
+ break;
+
+ case ResponseClassifier::INVNAMCLASS:
+ message_id = RESLIB_INVALID_NAMECLASS_RESPONSE;
+ break;
+
+ case ResponseClassifier::INVTYPE:
+ message_id = RESLIB_INVALID_TYPE_RESPONSE;
+ break;
+
+ case ResponseClassifier::MISMATQUEST:
+ message_id = RESLIB_INVALID_QNAME_RESPONSE;
+ break;
+
+ case ResponseClassifier::MULTICLASS:
+ message_id = RESLIB_MULTIPLE_CLASS_RESPONSE;
+ break;
+
+ case ResponseClassifier::NOTONEQUEST:
+ message_id = RESLIB_NOT_ONE_QNAME_RESPONSE;
+ break;
+
+ case ResponseClassifier::NOTRESPONSE:
+ message_id = RESLIB_NOT_RESPONSE;
+ break;
+
+ case ResponseClassifier::NOTSINGLE:
+ message_id = RESLIB_NOTSINGLE_RESPONSE;
+
+ case ResponseClassifier::OPCODE:
+ message_id = RESLIB_OPCODE_RESPONSE;
+
+ default:
+ message_id = RESLIB_ERROR_RESPONSE;
+ }
+ LOG_DEBUG(logger, RESLIB_DBG_RESULTS, message_id).
+ arg(questionText(question_));
+ }
+ }
+
public:
RunningQuery(IOService& io,
const Question& question,
@@ -734,12 +809,7 @@ public:
incoming.fromWire(ibuf);
buffer_->clear();
- if (incoming.getRcode() == Rcode::NOERROR()) {
- done_ = handleRecursiveAnswer(incoming);
- } else {
- isc::resolve::copyResponseMessage(incoming, answer_message_);
- done_ = true;
- }
+ done_ = handleRecursiveAnswer(incoming);
if (done_) {
callCallback(true);
stop();
diff --git a/src/lib/resolve/resolve_messages.mes b/src/lib/resolve/resolve_messages.mes
index f702d9b..b59fd8c 100644
--- a/src/lib/resolve/resolve_messages.mes
+++ b/src/lib/resolve/resolve_messages.mes
@@ -15,22 +15,61 @@
$NAMESPACE isc::resolve
% RESLIB_ANSWER answer received in response to query for <%1>
-A debug message recording that an answer has been received to an upstream
-query for the specified question. Previous debug messages will have indicated
-the server to which the question was sent.
+A debug message reporting that an answer has been received to an upstream
+query for the specified question. Previous debug messages will have
+indicated the server to which the question was sent.
% RESLIB_CNAME CNAME received in response to query for <%1>
-A debug message recording that CNAME response has been received to an upstream
-query for the specified question. Previous debug messages will have indicated
-the server to which the question was sent.
+A debug message recording that CNAME response has been received to an
+upstream query for the specified question. Previous debug messages will
+have indicated the server to which the question was sent.
% RESLIB_DEEPEST did not find <%1> in cache, deepest delegation found is %2
-A debug message, a cache lookup did not find the specified <name, class,
-type> tuple in the cache; instead, the deepest delegation found is indicated.
+A debug message, a cache lookup did not find the specified <name,
+class, type> tuple in the cache; instead, the deepest delegation found
+is indicated.
+
+% RESLIB_EMPTY_RESPONSE empty response received to query for <%1>
+A debug message, the response to the specified query from an upstream
+nameserver did not contain anything in the answer or authority sections,
+although in all other respects it was a valid response. A SERVFAIL will
+be returned to the system making the original query.
+
+% RESLIB_ERROR_RESPONSE unspecified error received in response to query for <%1>
+A debug message, the response to the specified query to an upstream
+nameserver indicated that the response was classified as an erroneous
+response, but that the nature of the error cannot be identified.
+A SERVFAIL will be returned to the system making the original query.
+
+% RESLIB_EXTRADATA_RESPONSE extra data in response to query for <%1>
+A debug message indicating that the response to the specified query
+from an upstream nameserver contained too much data. This can happen if
+an ANY query was sent and the answer section in the response contained
+multiple RRs with different names. A SERVFAIL will be returned to the
+system making the original query.
% RESLIB_FOLLOW_CNAME following CNAME chain to <%1>
-A debug message, a CNAME response was received and another query is being issued
-for the <name, class, type> tuple.
+A debug message, a CNAME response was received and another query is
+being issued for the <name, class, type> tuple.
+
+% RESLIB_INVALID_NAMECLASS_RESPONSE invalid name or class in response to query for <%1>
+A debug message, the response to the specified query from an upstream
+nameserver (as identified by the ID of the response) contained either
+an answer not matching the query name or an answer having a different
+class to that queried for. A SERVFAIL will be returned to the system
+making the original query.
+
+% RESLIB_INVALID_QNAME_RESPONSE invalid name or class in response to query for <%1>
+A debug message, the response to the specified query from an upstream
+nameserver (as identified by the ID of the response) contained a name
+in the question section that did not match that of the query. A SERVFAIL
+will be returned to the system making the original query.
+
+% RESLIB_INVALID_TYPE_RESPONSE invalid name or class in response to query for <%1>
+A debug message, the response to the specified query from an upstream
+nameserver (as identified by the ID of the response) contained an
+invalid type field. A SERVFAIL will be returned to the system making
+the original query.
% RESLIB_LONG_CHAIN CNAME received in response to query for <%1>: CNAME chain length exceeded
A debug message recording that a CNAME response has been received to an upstream
@@ -39,16 +78,47 @@ the server to which the question was sent). However, receipt of this CNAME
has meant that the resolver has exceeded the CNAME chain limit (a CNAME chain
is where on CNAME points to another) and so an error is being returned.
+% RESLIB_MULTIPLE_CLASS_RESPONSE response to query for <%1> contained multiple RRsets with different classes
+A debug message reporting that the response to an upstream query for
+the specified name contained multiple RRsets in the answer and not all
+were of the same class. This is a violation of the standard and so a
+SERVFAIL will be returned.
+
% RESLIB_NO_NS_RRSET no NS RRSet in referral response received to query for <%1>
A debug message, this indicates that a response was received for the specified
query and was categorized as a referral. However, the received message did
not contain any NS RRsets. This may indicate a programming error in the
response classification code.
+% RESLIB_NOT_ONE_QNAME_RESPONSE not one question in response to query for <%1>
+A debug message, the response to the specified query from an upstream
+nameserver (as identified by the ID of the response) did not contain
+one name in the question section as required by the standard. A SERVFAIL
+will be returned to the system making the original query.
+
+% RESLIB_NOT_RESPONSE response to query for <%1> was not a response
+A debug message, the response to the specified query from an upstream
+nameserver (as identified by the ID of the response) did not have the QR
+bit set (thus indicating that the packet was a query, not a response).
+A SERVFAIL will be returned to the system making the original query.
+
+% RESLIB_NOTSINGLE_RESPONSE response to query for <%1> was not a response
+A debug message, the response to the specified query from an upstream
+nameserver was a CNAME that had mutiple RRs in the RRset. This is
+an invalid response according to the standards so a SERVFAIL will be
+returned to the system making the original query.
+
% RESLIB_NSAS_LOOKUP looking up nameserver for zone %1 in the NSAS
A debug message, the RunningQuery object is querying the NSAS for the
nameservers for the specified zone.
+% RESLIB_OPCODE_RESPONSE response to query for <%1> did not have query opcode
+A debug message, the response to the specified query from an upstream
+nameserver was a response that did not have the opcode set to that of
+a query. According to the standards, this is an invalid response to
+the query that was made, so a SERVFAIL will be returned to the system
+making the original query.
+
% RESLIB_NXDOM_NXRR NXDOMAIN/NXRRSET received in response to query for <%1>
A debug message recording that either a NXDOMAIN or an NXRRSET response has
been received to an upstream query for the specified question. Previous debug
@@ -63,7 +133,7 @@ A debug message indicating that a protocol error was received and that
the resolver is repeating the query to the same nameserver. After this
repeated query, there will be the indicated number of retries left.
-% RESLIB_RCODE_ERR RCODE indicates error in response to query for <%1>
+% RESLIB_RCODE_ERROR response to query for <%1> returns RCODE of %2
A debug message, the response to the specified query indicated an error
that is not covered by a specific code path. A SERVFAIL will be returned.
@@ -122,6 +192,11 @@ A debug message indicating that a RunningQuery's success callback has been
called because a nameserver has been found, and that a query is being sent
to the specified nameserver.
+% RESLIB_TCP_TRUNCATED TCP response to query for %1 was truncated
+This is a debug message logged when a response to the specified query to an
+upstream nameserver returned a response with the TC (truncation) bit set. This
+is treated as an error by the code.
+
% RESLIB_TEST_SERVER setting test server to %1(%2)
This is a warning message only generated in unit tests. It indicates
that all upstream queries from the resolver are being routed to the
diff --git a/src/lib/resolve/response_classifier.h b/src/lib/resolve/response_classifier.h
index 3821560..a027bd0 100644
--- a/src/lib/resolve/response_classifier.h
+++ b/src/lib/resolve/response_classifier.h
@@ -151,7 +151,7 @@ private:
size_t size);
};
-#endif // __RESPONSE_CLASSIFIER_H
-
} // namespace resolve
} // namespace isc
+
+#endif // __RESPONSE_CLASSIFIER_H
More information about the bind10-changes
mailing list