BIND 10 master, updated. 47620f164b9541ce3c62437ff31efd1c134f3f05 Merge branch 'master' of ssh://bind10.isc.org/var/bind10/git/bind10

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Mar 15 14:37:44 UTC 2011


The branch, master has been updated
       via  47620f164b9541ce3c62437ff31efd1c134f3f05 (commit)
       via  ab4d484d2d17a0a2e3c4fc99453f7e314aee3b7f (commit)
       via  82f0bc8ecd6b3ad6c1419b4339ed3584351aa636 (commit)
       via  629023f290c290441129c96b11ece7de299fb8a6 (commit)
       via  610400fa75aa44d15fdc95dc8b69e02b45698765 (commit)
      from  34dbbd16060884ef96b20d28c110c5682db388ac (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 47620f164b9541ce3c62437ff31efd1c134f3f05
Merge: ab4d484d2d17a0a2e3c4fc99453f7e314aee3b7f 34dbbd16060884ef96b20d28c110c5682db388ac
Author: Jelte Jansen <jelte at isc.org>
Date:   Tue Mar 15 15:37:39 2011 +0100

    Merge branch 'master' of ssh://bind10.isc.org/var/bind10/git/bind10

commit ab4d484d2d17a0a2e3c4fc99453f7e314aee3b7f
Author: Jelte Jansen <jelte at isc.org>
Date:   Tue Mar 15 15:37:09 2011 +0100

    [master] update to make a test in master work

commit 82f0bc8ecd6b3ad6c1419b4339ed3584351aa636
Merge: f1bb311e77e15b5e43e2acd11e257bca11db4a7b 629023f290c290441129c96b11ece7de299fb8a6
Author: Jelte Jansen <jelte at isc.org>
Date:   Tue Mar 15 14:37:47 2011 +0100

    Merge branch 'trac501'

-----------------------------------------------------------------------

Summary of changes:
 src/lib/nsas/Makefile.am                           |    1 +
 src/lib/nsas/glue_hints.cc                         |  164 ++++++++++++++++++++
 src/lib/nsas/glue_hints.h                          |   71 +++++++++
 src/lib/nsas/nameserver_address_store.cc           |    7 +-
 src/lib/nsas/nameserver_address_store.h            |    3 +-
 src/lib/nsas/zone_entry.cc                         |   14 ++-
 src/lib/nsas/zone_entry.h                          |    7 +-
 src/lib/resolve/recursive_query.cc                 |   36 +++--
 src/lib/resolve/tests/Makefile.am                  |    1 +
 .../resolve/tests/recursive_query_unittest_2.cc    |    7 +-
 10 files changed, 292 insertions(+), 19 deletions(-)
 create mode 100644 src/lib/nsas/glue_hints.cc
 create mode 100644 src/lib/nsas/glue_hints.h

-----------------------------------------------------------------------
diff --git a/src/lib/nsas/Makefile.am b/src/lib/nsas/Makefile.am
index 04a765b..43300f6 100644
--- a/src/lib/nsas/Makefile.am
+++ b/src/lib/nsas/Makefile.am
@@ -37,5 +37,6 @@ libnsas_la_SOURCES += zone_entry.cc zone_entry.h
 libnsas_la_SOURCES += fetchable.h
 libnsas_la_SOURCES += address_request_callback.h
 libnsas_la_SOURCES += random_number_generator.h
+libnsas_la_SOURCES += glue_hints.h glue_hints.cc
 
 CLEANFILES = *.gcno *.gcda
diff --git a/src/lib/nsas/glue_hints.cc b/src/lib/nsas/glue_hints.cc
new file mode 100644
index 0000000..96ef1a0
--- /dev/null
+++ b/src/lib/nsas/glue_hints.cc
@@ -0,0 +1,164 @@
+// Copyright (C) 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
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include "glue_hints.h"
+
+#include <dns/rrset.h>
+#include <dns/rdata.h>
+#include <dns/rrtype.h>
+#include <dns/rdataclass.h>
+
+#include <asiolink/io_address.h>
+#include <nsas/nameserver_entry.h>
+
+using namespace isc::dns;
+using namespace isc::nsas;
+
+// This is a simple implementation for finding glue
+//
+// It iterates over the AUTHORITY section of the given Message,
+// and for each NS RR it iterates over the ADDITIONAL section to
+// see if there are A or AAAA records.
+//
+// Of course, this could be done more efficiently. One option is to
+// reverse this; check for A and AAAA records (since those will only
+// be there if there actually is glue, while NS records will be present
+// in any delegation). However, it may be even better to let the
+// Response Classifier decide on glue, while it is validating the packet
+//
+// (er, TODO, so to speak. discuss.)
+
+// Helper functions
+namespace {
+    // Add the contents of the given A or AAAA rrset to the given
+    // addressvector
+    //
+    // This creates an 'dummy' NameserverEntry value, because that
+    // is enforced by NameserverAddress. We may want to reconsider
+    // the need for that (perhaps we can change it so that if it is
+    // NULL, all NSAS-related calls to the NameserverAddress object
+    // become nops)
+    void
+    addRRset(std::vector<NameserverAddress>& addresses,
+             const RRsetPtr rrset)
+    {
+        const std::string ns_name = rrset->getName().toText();
+        RdataIteratorPtr rdi = rrset->getRdataIterator();
+        while (!rdi->isLast()) {
+            AddressEntry entry(asiolink::IOAddress(rdi->getCurrent().toText()));
+            boost::shared_ptr<NameserverEntry> ns_entry(new NameserverEntry(ns_name, rrset->getClass()));
+            NameserverAddress ns_address(ns_entry, entry, V4_ONLY);
+            addresses.push_back(ns_address);
+            rdi->next();
+        }
+    }
+}
+
+namespace isc {
+namespace nsas {
+
+GlueHints::GlueHints(const std::string& zone_name,
+                     const isc::dns::Message& delegation_message)
+{
+    for (RRsetIterator rssi = delegation_message.beginSection(Message::SECTION_AUTHORITY);
+         rssi != delegation_message.endSection(Message::SECTION_AUTHORITY);
+         ++rssi) {
+        if ((*rssi)->getType() == RRType::NS() &&
+            (*rssi)->getName().toText() == zone_name) {
+            addGlueForRRset(*rssi, delegation_message);
+        }
+    }
+}
+
+
+bool
+GlueHints::hasGlue(AddressFamily family) const {
+    return ((addresses_v4.size() > 0 && (family == ANY_OK || family == V4_ONLY)) ||
+            (addresses_v6.size() > 0 && (family == ANY_OK || family == V6_ONLY)));
+}
+
+NameserverAddress
+GlueHints::getGlue(AddressFamily family) const {
+    // TODO: once we have a more general random lib, use that. Since
+    // this is simply glue, and we don't need a weighted selection,
+    // for now srandom should be good enough. Once #583 has been merged,
+    // (or better yet, once that one and the weighted random have gone
+    // together in a util lib), we can use that.
+    int max = 0;
+    size_t v4s = addresses_v4.size();
+    size_t v6s = addresses_v6.size();
+
+    if (family == ANY_OK || family == V4_ONLY) {
+        max += v4s;
+    }
+    if (family == ANY_OK || family == V6_ONLY) {
+        max += v6s;
+    }
+
+    assert(max > 0);
+    long int selection = random() % max;
+
+    if (family == ANY_OK) {
+        if (selection <= v4s) {
+            return addresses_v4[selection];
+        } else {
+            return addresses_v6[selection-v4s];
+        }
+    } else if (family == V4_ONLY) {
+        return addresses_v4[selection];
+    } else if (family == V6_ONLY) {
+        return addresses_v6[selection];
+    } else {
+        // Unknown family
+        assert(false);
+    }
+}
+
+// Add the A and AAAA records from the given message for the given
+// NS name to the relevant address vector
+// (A rrsets are added to addresses_v4, AAAA rrsets are added to
+// addresses_v6).
+void
+GlueHints::addGlueForName(const Name& name, const Message& message)
+{
+    for (RRsetIterator rssi = message.beginSection(Message::SECTION_ADDITIONAL);
+         rssi != message.endSection(Message::SECTION_ADDITIONAL);
+         ++rssi) {
+        if ((*rssi)->getName() == name) {
+            if ((*rssi)->getType() == RRType::A()) {
+                addRRset(addresses_v4, *rssi);
+            } else if ((*rssi)->getType() == RRType::AAAA()) {
+                addRRset(addresses_v6, *rssi);
+            }
+        }
+    }
+}
+
+// Add the glue for the given NS RRset in the message to the
+// relevant vectors.
+void
+GlueHints::addGlueForRRset(const RRsetPtr rrset, const Message& message)
+{
+    RdataIteratorPtr rdi = rrset->getRdataIterator();
+    while (!rdi->isLast()) {
+        isc::dns::Name name(dynamic_cast<const rdata::generic::NS&>(
+                        rdi->getCurrent()).getNSName());
+        addGlueForName(name, message);
+        rdi->next();
+    }
+}
+
+
+} // namespace nsas
+} // namespace isc
diff --git a/src/lib/nsas/glue_hints.h b/src/lib/nsas/glue_hints.h
new file mode 100644
index 0000000..8e6ecf1
--- /dev/null
+++ b/src/lib/nsas/glue_hints.h
@@ -0,0 +1,71 @@
+// Copyright (C) 2010  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
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __GLUE_HINTS_H
+#define __GLUE_HINTS_H
+
+#include <vector>
+
+#include <dns/message.h>
+
+#include "nsas_types.h"
+#include "nameserver_address.h"
+
+namespace isc {
+namespace nsas {
+
+class GlueHints {
+public:
+    /// \brief Empty constructor
+    GlueHints() {};
+
+    /// \brief Constructor
+    ///
+    /// Creates a glue hint object, with the glue data found in the
+    /// given packet.
+    ///
+    /// \param zone_name The name of the zone to find glue for
+    /// \param delegation_message The Message that may contain glue
+    GlueHints(const std::string& zone_name,
+              const isc::dns::Message& delegation_message);
+
+    /// \brief Check if there is glue for the given AddressFamily
+    ///
+    /// \param family the AddressFamily to check for glue for
+    /// \return true if there is glue for that family. false if not
+    bool hasGlue(AddressFamily family) const;
+
+    /// \brief Get a random glue address for the given family
+    ///
+    /// ONLY call this if hasGlue() returned true.
+    ///
+    /// \param family the AddressFamily to get glue for
+    /// \return a NameserverAddress specified by the glue
+    NameserverAddress getGlue(AddressFamily family) const;
+
+private:
+    void addGlueForName(const isc::dns::Name& name,
+                        const isc::dns::Message& message);
+    void addGlueForRRset(const isc::dns::RRsetPtr rrset,
+                         const isc::dns::Message& message);
+
+    std::vector<NameserverAddress> addresses_v4;
+    std::vector<NameserverAddress> addresses_v6;
+};
+
+}
+}
+
+
+#endif // __GLUE_HINTS_H
diff --git a/src/lib/nsas/nameserver_address_store.cc b/src/lib/nsas/nameserver_address_store.cc
index 4efe491..406f782 100644
--- a/src/lib/nsas/nameserver_address_store.cc
+++ b/src/lib/nsas/nameserver_address_store.cc
@@ -29,6 +29,7 @@
 #include "nameserver_entry.h"
 #include "nameserver_address_store.h"
 #include "zone_entry.h"
+#include "glue_hints.h"
 #include "address_request_callback.h"
 
 using namespace isc::dns;
@@ -80,7 +81,8 @@ newZone(
 
 void
 NameserverAddressStore::lookup(const string& zone, const RRClass& class_code,
-    boost::shared_ptr<AddressRequestCallback> callback, AddressFamily family)
+    boost::shared_ptr<AddressRequestCallback> callback, AddressFamily family,
+    const GlueHints glue_hints)
 {
     pair<bool, boost::shared_ptr<ZoneEntry> > zone_obj(zone_hash_->getOrAdd(HashKey(
         zone, class_code), boost::bind(newZone, &resolver_, &zone, &class_code,
@@ -90,7 +92,8 @@ NameserverAddressStore::lookup(const string& zone, const RRClass& class_code,
     } else {
         zone_lru_->touch(zone_obj.second);
     }
-    zone_obj.second->addCallback(callback, family);
+    
+    zone_obj.second->addCallback(callback, family, glue_hints);
 }
 
 void
diff --git a/src/lib/nsas/nameserver_address_store.h b/src/lib/nsas/nameserver_address_store.h
index 98eb2dd..b8080f2 100644
--- a/src/lib/nsas/nameserver_address_store.h
+++ b/src/lib/nsas/nameserver_address_store.h
@@ -23,6 +23,7 @@
 #include <resolve/resolver_interface.h>
 
 #include "nsas_types.h"
+#include "glue_hints.h"
 
 namespace isc {
 // Some forward declarations, so we do not need to include so many headers
@@ -85,7 +86,7 @@ public:
     /// \param family Which address is requested.
     void lookup(const std::string& zone, const dns::RRClass& class_code,
         boost::shared_ptr<AddressRequestCallback> callback, AddressFamily
-        family = ANY_OK);
+        family = ANY_OK, const GlueHints = GlueHints());
 
     /// \brief cancel the given lookup action
     ///
diff --git a/src/lib/nsas/zone_entry.cc b/src/lib/nsas/zone_entry.cc
index b0ad322..ece00c0 100644
--- a/src/lib/nsas/zone_entry.cc
+++ b/src/lib/nsas/zone_entry.cc
@@ -224,7 +224,8 @@ class ZoneEntry::ResolverCallback :
 };
 
 void
-ZoneEntry::addCallback(CallbackPtr callback, AddressFamily family) {
+ZoneEntry::addCallback(CallbackPtr callback, AddressFamily family,
+                       const GlueHints glue_hints) {
     Lock lock(mutex_);
 
     bool ask(false);
@@ -238,11 +239,18 @@ ZoneEntry::addCallback(CallbackPtr callback, AddressFamily family) {
     if (getState() == EXPIRED || getState() == NOT_ASKED) {
         ask = true;
     }
-
+    
     // We do not have the answer right away, just queue the callback
     bool execute(!ask && getState() != IN_PROGRESS &&
         callbacks_[family].empty());
-    callbacks_[family].push_back(callback);
+
+    // Unless there was glue
+    if (ask && glue_hints.hasGlue(family)) {
+        callback->success(glue_hints.getGlue(family));
+    } else {
+        callbacks_[family].push_back(callback);
+    }
+
     if (execute) {
         // Try to process it right away, store if not possible to handle
         process(family, NameserverPtr());
diff --git a/src/lib/nsas/zone_entry.h b/src/lib/nsas/zone_entry.h
index a1f12bc..7b29bb0 100644
--- a/src/lib/nsas/zone_entry.h
+++ b/src/lib/nsas/zone_entry.h
@@ -32,6 +32,7 @@
 #include "fetchable.h"
 #include "nsas_types.h"
 #include "random_number_generator.h"
+#include "glue_hints.h"
 
 namespace isc {
 namespace nsas {
@@ -97,9 +98,13 @@ public:
      *
      * \param callback The callback itself.
      * \param family Which address family is acceptable as an answer?
+     * \param glue_hints If a non-empty glue-hints object is passed,
+     *        and the NSAS does not have an immediate answer, it will
+     *        call back immediately with one of the glue hints.
      */
     void addCallback(boost::shared_ptr<AddressRequestCallback>
-        callback, AddressFamily family);
+        callback, AddressFamily family,
+        const GlueHints glue_hints = GlueHints());
 
     /**
      * \short Remove a callback from the list
diff --git a/src/lib/resolve/recursive_query.cc b/src/lib/resolve/recursive_query.cc
index eee98ca..485e607 100644
--- a/src/lib/resolve/recursive_query.cc
+++ b/src/lib/resolve/recursive_query.cc
@@ -254,11 +254,19 @@ private:
         current_ns_address = address;
         gettimeofday(&current_ns_qsent_time, NULL);
         ++outstanding_events_;
-        IOFetch query(protocol_, io_, question_,
-            current_ns_address.getAddress(),
-            53, buffer_, this,
-            query_timeout_);
-        io_.get_io_service().post(query);
+        if (test_server_.second != 0) {
+            IOFetch query(protocol_, io_, question_,
+                test_server_.first,
+                test_server_.second, buffer_, this,
+                query_timeout_);
+            io_.get_io_service().post(query);
+		} else {
+	        IOFetch query(protocol_, io_, question_,
+	            current_ns_address.getAddress(),
+	            53, buffer_, this,
+	            query_timeout_);
+	        io_.get_io_service().post(query);
+		}
     }
     
     // 'general' send; if we are in forwarder mode, send a query to
@@ -330,7 +338,7 @@ private:
             isc::resolve::ResponseClassifier::classify(
                 question_, incoming, cname_target, cname_count_);
 
-        bool found_ns_address = false;
+        bool found_ns = false;
             
         switch (category) {
         case isc::resolve::ResponseClassifier::ANSWER:
@@ -384,7 +392,7 @@ private:
             // classifier should have error'd)
             // TODO: should we check if it really is subzone?
             for (RRsetIterator rrsi = incoming.beginSection(Message::SECTION_AUTHORITY);
-                 rrsi != incoming.endSection(Message::SECTION_AUTHORITY) && !found_ns_address;
+                 rrsi != incoming.endSection(Message::SECTION_AUTHORITY) && !found_ns;
                  ++rrsi) {
                 ConstRRsetPtr rrs = *rrsi;
                 if (rrs->getType() == RRType::NS()) {
@@ -393,18 +401,26 @@ private:
                     // libraries, so as not to need many conversions)
                     cur_zone_ = rrs->getName().toText();
                     dlog("Referred to zone " + cur_zone_);
-                    found_ns_address = true;
+                    found_ns = true;
                     break;
                 }
             }
 
-            if (found_ns_address) {
+            if (found_ns) {
                 // next resolver round
                 // we do NOT use doLookup() here, but send() (i.e. we
                 // skip the cache), since if we had the final answer
                 // instead of a delegation cached, we would have been
                 // there by now.
-                send();
+                GlueHints glue_hints(cur_zone_, incoming);
+
+                // Ask the NSAS for an address, or glue.
+                // This will eventually result in either sendTo()
+                // or stop() being called by nsas_callback_
+                assert(!nsas_callback_out_);
+                nsas_callback_out_ = true;
+                nsas_.lookup(cur_zone_, question_.getClass(),
+                             nsas_callback_, ANY_OK, glue_hints);
                 return false;
             } else {
                 dlog("No NS RRset in referral?");
diff --git a/src/lib/resolve/tests/Makefile.am b/src/lib/resolve/tests/Makefile.am
index da28f78..a403272 100644
--- a/src/lib/resolve/tests/Makefile.am
+++ b/src/lib/resolve/tests/Makefile.am
@@ -29,6 +29,7 @@ run_unittests_LDADD +=  $(top_builddir)/src/lib/cache/libcache.la
 run_unittests_LDADD +=  $(top_builddir)/src/lib/asiolink/libasiolink.la
 run_unittests_LDADD +=  $(top_builddir)/src/lib/resolve/libresolve.la
 run_unittests_LDADD +=  $(top_builddir)/src/lib/dns/libdns++.la
+run_unittests_LDADD +=  $(top_builddir)/src/lib/log/liblog.la
 
 endif
 
diff --git a/src/lib/resolve/tests/recursive_query_unittest_2.cc b/src/lib/resolve/tests/recursive_query_unittest_2.cc
index 4799324..6248eb1 100644
--- a/src/lib/resolve/tests/recursive_query_unittest_2.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest_2.cc
@@ -21,6 +21,7 @@
 #include <gtest/gtest.h>
 #include <boost/bind.hpp>
 
+#include <log/dummylog.h>
 
 #include <asio.hpp>
 
@@ -82,7 +83,7 @@ const char* WWW_EXAMPLE_ORG = "192.0.2.254";    ///< Address of www.example.org
 // As the test is fairly long and complex, debugging "print" statements have
 // been left in although they are disabled.  Set the following to "true" to
 // enable them.
-const bool DEBUG_PRINT = false;
+const bool DEBUG_PRINT = true;
 
 class MockResolver : public isc::resolve::ResolverInterface {
     void resolve(const QuestionPtr& question,
@@ -538,6 +539,7 @@ public:
     virtual void success(const isc::dns::MessagePtr response) {
         if (debug_) {
             cout << "ResolverCallback::success(): answer received" << endl;
+            cout << response->toText() << endl;
         }
 
         // There should be one RR each  in the question and answer sections, and
@@ -606,7 +608,8 @@ private:
 // Sets up the UDP and TCP "servers", then tries a resolution.
 
 TEST_F(RecursiveQueryTest2, Resolve) {
-
+	isc::log::denabled = true;
+	
     // Set up the UDP server and issue the first read.  The endpoint from which
     // the query is sent is put in udp_endpoint_ when the read completes, which
     // is referenced in the callback as the place to which the response is sent.




More information about the bind10-changes mailing list