BIND 10 master, updated. bef01123fb5dfaee927bc58da465109240811a18 Merge branch 'master' into trac2565

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Dec 31 04:14:56 UTC 2012


The branch, master has been updated
       via  bef01123fb5dfaee927bc58da465109240811a18 (commit)
       via  025db8d7a207b39174362981868742f1b80bdf69 (commit)
       via  00845ee8d7366b80e23e349b7cf8cd9d52551785 (commit)
       via  080d47deb3088adddd96434acfd1c82bd14779c9 (commit)
       via  9f5102a30e4cb8da4697b3561206957b9a2aae05 (commit)
       via  0758ead7f4044e0867d4f953427b6c10f7afab45 (commit)
       via  9ab72138d43cb21a620c021a24e6a248b3dd77ab (commit)
       via  ffe973e3df51ab36e17087eda23b1042500d39b5 (commit)
       via  857d7fbf031d29b5b66ebe38fec725dde35008fd (commit)
       via  514b87c307fc834f39f0be155fc9bac9a6508d70 (commit)
       via  6d28690c67369927bb0806618f23533a1457eb6f (commit)
       via  029be672c7bf1b936859e811a17d45d04215ecd4 (commit)
       via  5ec876c98d10dfdb0675ffcde709b5ce9871465b (commit)
       via  09dc37b8319af571d2e7afb0bf5b6da82cd174f6 (commit)
       via  b0bc2d360163be4126f6a88b73a3c17a18714736 (commit)
       via  1b69710afed58b9f7ebff61229f3f29e487f4026 (commit)
       via  4d6495aa80132d3a67ad4ef9aa76d75683772a80 (commit)
       via  530e62ba1a41f63a8dbcd0838fb5cfa95cb3816a (commit)
       via  ed7622df90ee865b5be03b0d13ed5977466bebfc (commit)
      from  6c20066d5613dfda246d598f47b9e779eef9c70b (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 bef01123fb5dfaee927bc58da465109240811a18
Merge: 025db8d 6c20066
Author: Mukund Sivaraman <muks at isc.org>
Date:   Mon Dec 31 08:57:15 2012 +0530

    Merge branch 'master' into trac2565

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

Summary of changes:
 src/lib/dns/master_loader.cc                |   21 ++++------
 src/lib/dns/rrclass-placeholder.h           |   55 ++++++++++++++++++++++++++-
 src/lib/dns/rrclass.cc                      |   17 ++++++++-
 src/lib/dns/rrparamregistry-placeholder.cc  |   35 ++++++++++-------
 src/lib/dns/rrparamregistry.h               |   45 ++++++++++++++--------
 src/lib/dns/rrttl.h                         |    2 +-
 src/lib/dns/rrtype.cc                       |    7 +++-
 src/lib/dns/tests/master_loader_unittest.cc |    3 +-
 src/lib/dns/tests/rrclass_unittest.cc       |   10 ++++-
 9 files changed, 143 insertions(+), 52 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dns/master_loader.cc b/src/lib/dns/master_loader.cc
index 7ad6c0f..88846f0 100644
--- a/src/lib/dns/master_loader.cc
+++ b/src/lib/dns/master_loader.cc
@@ -219,28 +219,23 @@ private:
             // after the RR class below.
         }
 
-        boost::scoped_ptr<RRClass> rrclass;
-        try {
-            rrclass.reset(new RRClass(rrparam_token.getString()));
+        const MaybeRRClass rrclass =
+            RRClass::createFromText(rrparam_token.getString());
+        if (rrclass) {
+            if (*rrclass != zone_class_) {
+                isc_throw(InternalException, "Class mismatch: " << *rrclass <<
+                          " vs. " << zone_class_);
+            }
             rrparam_token = lexer_.getNextToken(MasterToken::STRING);
-        } catch (const InvalidRRClass&) {
-            // If it's not an rrclass here, use the zone's class.
-            rrclass.reset(new RRClass(zone_class_));
         }
 
         // If we couldn't parse TTL earlier in the stream (above), try
         // again at current location.
-        if (!explicit_ttl &&
-            setCurrentTTL(rrparam_token.getString())) {
+        if (!explicit_ttl && setCurrentTTL(rrparam_token.getString())) {
             explicit_ttl = true;
             rrparam_token = lexer_.getNextToken(MasterToken::STRING);
         }
 
-        if (*rrclass != zone_class_) {
-            isc_throw(InternalException, "Class mismatch: " << *rrclass <<
-                      "vs. " << zone_class_);
-        }
-
         // Return the current string token's value as the RRType.
         return (RRType(rrparam_token.getString()));
     }
diff --git a/src/lib/dns/rrclass-placeholder.h b/src/lib/dns/rrclass-placeholder.h
index 70d6b78..1ff4163 100644
--- a/src/lib/dns/rrclass-placeholder.h
+++ b/src/lib/dns/rrclass-placeholder.h
@@ -22,6 +22,8 @@
 
 #include <exceptions/exceptions.h>
 
+#include <boost/optional.hpp>
+
 namespace isc {
 namespace util {
 class InputBuffer;
@@ -33,6 +35,16 @@ namespace dns {
 // forward declarations
 class AbstractMessageRenderer;
 
+class RRClass; // forward declaration to define MaybeRRClass.
+
+/// \brief A shortcut for a compound type to represent RRClass-or-not.
+///
+/// A value of this type can be interpreted in a boolean context, whose
+/// value is \c true if and only if it contains a valid RRClass object.
+/// And, if it contains a valid RRClass object, its value is accessible
+/// using \c operator*, just like a bare pointer to \c RRClass.
+typedef boost::optional<RRClass> MaybeRRClass;
+
 ///
 /// \brief A standard DNS module exception that is thrown if an RRClass object
 /// is being constructed from an unrecognized string.
@@ -123,8 +135,8 @@ public:
     /// If the given string is not recognized as a valid representation of
     /// an RR class, an exception of class \c InvalidRRClass will be thrown.
     ///
-    /// \param classstr A string representation of the \c RRClass
-    explicit RRClass(const std::string& classstr);
+    /// \param class_str A string representation of the \c RRClass
+    explicit RRClass(const std::string& class_str);
     /// Constructor from wire-format data.
     ///
     /// The \c buffer parameter normally stores a complete DNS message
@@ -136,6 +148,45 @@ public:
     ///
     /// \param buffer A buffer storing the wire format data.
     explicit RRClass(isc::util::InputBuffer& buffer);
+
+    /// A separate factory of RRClass from text.
+    ///
+    /// This static method is similar to the constructor that takes a
+    /// string object, but works as a factory and reports parsing
+    /// failure in the form of the return value.  Normally the
+    /// constructor version should suffice, but in some cases the caller
+    /// may have to expect mixture of valid and invalid input, and may
+    /// want to minimize the overhead of possible exception handling.
+    /// This version is provided for such purpose.
+    ///
+    /// For the format of the \c class_str argument, see the
+    /// <code>RRClass(const std::string&)</code> constructor.
+    ///
+    /// If the given text represents a valid RRClass, it returns a
+    /// \c MaybeRRClass object that stores a corresponding \c RRClass
+    /// object, which is accessible via \c operator*().  In this case
+    /// the returned object will be interpreted as \c true in a boolean
+    /// context.  If the given text does not represent a valid RRClass,
+    /// it returns a \c MaybeRRClass object which is interpreted as
+    /// \c false in a boolean context.
+    ///
+    /// One main purpose of this function is to minimize the overhead
+    /// when the given text does not represent a valid RR class.  For
+    /// this reason this function intentionally omits the capability of
+    /// delivering a detailed reason for the parse failure, such as in the
+    /// \c want() string when exception is thrown from the constructor
+    /// (it will internally require a creation of string object, which
+    /// is relatively expensive).  If such detailed information is
+    /// necessary, the constructor version should be used to catch the
+    /// resulting exception.
+    ///
+    /// This function never throws the \c InvalidRRClass exception.
+    ///
+    /// \param class_str A string representation of the \c RRClass.
+    /// \return A MaybeRRClass object either storing an RRClass object
+    /// for the given text or a \c false value.
+    static MaybeRRClass createFromText(const std::string& class_str);
+
     ///
     /// We use the default copy constructor intentionally.
     //@}
diff --git a/src/lib/dns/rrclass.cc b/src/lib/dns/rrclass.cc
index ac5823c..76a2e73 100644
--- a/src/lib/dns/rrclass.cc
+++ b/src/lib/dns/rrclass.cc
@@ -30,8 +30,11 @@ using namespace isc::util;
 namespace isc {
 namespace dns {
 
-RRClass::RRClass(const std::string& classstr) {
-    classcode_ = RRParamRegistry::getRegistry().textToClassCode(classstr);
+RRClass::RRClass(const std::string& class_str) {
+    if (!RRParamRegistry::getRegistry().textToClassCode(class_str, classcode_)) {
+        isc_throw(InvalidRRClass,
+                  "Unrecognized RR class string: " + class_str);
+    }
 }
 
 RRClass::RRClass(InputBuffer& buffer) {
@@ -56,6 +59,16 @@ RRClass::toWire(AbstractMessageRenderer& renderer) const {
     renderer.writeUint16(classcode_);
 }
 
+MaybeRRClass
+RRClass::createFromText(const string& class_str) {
+    uint16_t class_code;
+    if (RRParamRegistry::getRegistry().textToClassCode(class_str,
+                                                       class_code)) {
+        return (MaybeRRClass(class_code));
+    }
+    return (MaybeRRClass());
+}
+
 ostream&
 operator<<(ostream& os, const RRClass& rrclass) {
     os << rrclass.toText();
diff --git a/src/lib/dns/rrparamregistry-placeholder.cc b/src/lib/dns/rrparamregistry-placeholder.cc
index 16ec23c..5960759 100644
--- a/src/lib/dns/rrparamregistry-placeholder.cc
+++ b/src/lib/dns/rrparamregistry-placeholder.cc
@@ -421,14 +421,15 @@ removeParam(uint16_t code, MC& codemap, MS& stringmap) {
     return (false);
 }
 
-template <typename PT, typename MS, typename ET>
-inline uint16_t
-textToCode(const string& code_str, MS& stringmap) {
+template <typename PT, typename MS>
+inline bool
+textToCode(const string& code_str, MS& stringmap, uint16_t& ret_code) {
     typename MS::const_iterator found;
 
     found = stringmap.find(code_str);
     if (found != stringmap.end()) {
-        return (found->second->code_);
+        ret_code = found->second->code_;
+        return (true);
     }
 
     size_t l = code_str.size();
@@ -441,10 +442,12 @@ textToCode(const string& code_str, MS& stringmap) {
                                           l - PT::UNKNOWN_PREFIXLEN()));
         iss >> dec >> code;
         if (iss.rdstate() == ios::eofbit && code <= PT::MAX_CODE) {
-            return (code);
+            ret_code = code;
+            return (true);
         }
     }
-    isc_throw(ET, "Unrecognized RR parameter string: " + code_str);
+
+    return (false);
 }
 
 template <typename PT, typename MC>
@@ -475,10 +478,12 @@ RRParamRegistry::removeType(uint16_t code) {
                                                      impl_->str2typemap));
 }
 
-uint16_t
-RRParamRegistry::textToTypeCode(const string& type_string) const {
-    return (textToCode<RRTypeParam, StrRRTypeMap,
-            InvalidRRType>(type_string, impl_->str2typemap));
+bool
+RRParamRegistry::textToTypeCode(const string& type_string,
+                                uint16_t& type_code) const
+{
+    return (textToCode<RRTypeParam, StrRRTypeMap>
+            (type_string, impl_->str2typemap, type_code));
 }
 
 string
@@ -499,10 +504,12 @@ RRParamRegistry::removeClass(uint16_t code) {
                                                        impl_->str2classmap));
 }
 
-uint16_t
-RRParamRegistry::textToClassCode(const string& class_string) const {
-    return (textToCode<RRClassParam, StrRRClassMap,
-            InvalidRRClass>(class_string, impl_->str2classmap));
+bool
+RRParamRegistry::textToClassCode(const string& class_string,
+                                 uint16_t& class_code) const
+{
+    return (textToCode<RRClassParam, StrRRClassMap>
+            (class_string, impl_->str2classmap, class_code));
 }
 
 string
diff --git a/src/lib/dns/rrparamregistry.h b/src/lib/dns/rrparamregistry.h
index 56ae981..bf86436 100644
--- a/src/lib/dns/rrparamregistry.h
+++ b/src/lib/dns/rrparamregistry.h
@@ -384,16 +384,22 @@ public:
     /// \brief Convert a textual representation of an RR type to the
     /// corresponding 16-bit integer code.
     ///
-    /// This method searches the \c RRParamRegistry for the mapping from the
-    /// given textual representation of RR type to the corresponding integer
-    /// code.  If a mapping is found, it returns the associated type code;
-    /// otherwise, if the given string is in the form of "TYPEnnnn", it returns
-    /// the corresponding number as the type code; otherwise, it throws an
-    /// exception of class \c InvalidRRType.
+    /// This method searches the \c RRParamRegistry for the mapping from
+    /// the given textual representation of RR type to the corresponding
+    /// integer code. If a mapping is found, it returns true with the
+    /// associated type code in \c type_code; otherwise, if the given
+    /// string is in the form of "TYPEnnnn", it returns true with the
+    /// corresponding number as the type code in \c type_code;
+    /// otherwise, it returns false and \c type_code is untouched.
+    ///
+    /// It returns \c false and avoids throwing an exception in the case
+    /// of an error to avoid the exception overhead in some situations.
     ///
     /// \param type_string The textual representation of the RR type.
-    /// \return The RR type code for \c type_string.
-    uint16_t textToTypeCode(const std::string& type_string) const;
+    /// \param type_code Returns the RR type code in this argument.
+    /// \return true if conversion is successful, false otherwise.
+    bool textToTypeCode(const std::string& type_string,
+                        uint16_t& type_code) const;
 
     /// \brief Convert type code into its textual representation.
     ///
@@ -415,16 +421,23 @@ public:
     /// \brief Convert a textual representation of an RR class to the
     /// corresponding 16-bit integer code.
     ///
-    /// This method searches the \c RRParamRegistry for the mapping from the
-    /// given textual representation of RR class to the corresponding integer
-    /// code.  If a mapping is found, it returns the associated class code;
-    /// otherwise, if the given string is in the form of "CLASSnnnn", it returns
-    /// the corresponding number as the class code; otherwise, it throws an
-    /// exception of class \c InvalidRRClass.
+    /// This method searches the \c RRParamRegistry for the mapping from
+    /// the given textual representation of RR class to the
+    /// corresponding integer code.  If a mapping is found, it returns
+    /// true with the associated class code in \c class_code; otherwise,
+    /// if the given string is in the form of "CLASSnnnn", it returns
+    /// true with the corresponding number as the class code in
+    /// \c class_code; otherwise, it returns false and \c class_code is
+    /// untouched.
+    ///
+    /// It returns \c false and avoids throwing an exception in the case
+    /// of an error to avoid the exception overhead in some situations.
     ///
     /// \param class_string The textual representation of the RR class.
-    /// \return The RR class code for \c class_string.
-    uint16_t textToClassCode(const std::string& class_string) const;
+    /// \param class_code Returns the RR class code in this argument.
+    /// \return true if conversion is successful, false otherwise.
+    bool textToClassCode(const std::string& class_string,
+                         uint16_t& class_code) const;
 
     /// \brief Convert class code into its textual representation.
     ///
diff --git a/src/lib/dns/rrttl.h b/src/lib/dns/rrttl.h
index 7904d84..23d57f4 100644
--- a/src/lib/dns/rrttl.h
+++ b/src/lib/dns/rrttl.h
@@ -133,7 +133,7 @@ public:
     /// One main purpose of this function is to minimize the overhead
     /// when the given text does not represent a valid RR TTL.  For this
     /// reason this function intentionally omits the capability of delivering
-    /// details reason for the parse failure, such as in the \c want()
+    /// a detailed reason for the parse failure, such as in the \c want()
     /// string when exception is thrown from the constructor (it will
     /// internally require a creation of string object, which is relatively
     /// expensive).  If such detailed information is necessary, the constructor
diff --git a/src/lib/dns/rrtype.cc b/src/lib/dns/rrtype.cc
index 4ef4e67..84892bf 100644
--- a/src/lib/dns/rrtype.cc
+++ b/src/lib/dns/rrtype.cc
@@ -31,8 +31,11 @@ using isc::dns::RRType;
 namespace isc {
 namespace dns {
 
-RRType::RRType(const std::string& typestr) {
-    typecode_ = RRParamRegistry::getRegistry().textToTypeCode(typestr);
+RRType::RRType(const std::string& type_str) {
+    if (!RRParamRegistry::getRegistry().textToTypeCode(type_str, typecode_)) {
+        isc_throw(InvalidRRType,
+                  "Unrecognized RR type string: " + type_str);
+    }
 }
 
 RRType::RRType(InputBuffer& buffer) {
diff --git a/src/lib/dns/tests/master_loader_unittest.cc b/src/lib/dns/tests/master_loader_unittest.cc
index 89a1440..051c662 100644
--- a/src/lib/dns/tests/master_loader_unittest.cc
+++ b/src/lib/dns/tests/master_loader_unittest.cc
@@ -391,7 +391,8 @@ struct ErrorCase {
       "Missing Rdata" },
 
     { "www      3600    IN", NULL, "Unexpected EOLN" },
-    { "www      3600    CH  TXT nothing", NULL, "Class mismatch" },
+    { "www      3600    CH  TXT nothing", "Class mismatch: CH vs. IN",
+      "Class mismatch" },
     { "www      \"3600\"  IN  A   192.0.2.1", NULL, "Quoted TTL" },
     { "www      3600    \"IN\"  A   192.0.2.1", NULL, "Quoted class" },
     { "www      3600    IN  \"A\"   192.0.2.1", NULL, "Quoted type" },
diff --git a/src/lib/dns/tests/rrclass_unittest.cc b/src/lib/dns/tests/rrclass_unittest.cc
index 6156be5..11f1c54 100644
--- a/src/lib/dns/tests/rrclass_unittest.cc
+++ b/src/lib/dns/tests/rrclass_unittest.cc
@@ -59,7 +59,7 @@ RRClassTest::rrclassFactoryFromWire(const char* datafile) {
     return (RRClass(buffer));
 }
 
-TEST_F(RRClassTest, fromText) {
+TEST_F(RRClassTest, fromTextConstructor) {
     EXPECT_EQ("IN", RRClass("IN").toText());
     EXPECT_EQ("CH", RRClass("CH").toText());
 
@@ -96,6 +96,14 @@ TEST_F(RRClassTest, toText) {
     EXPECT_EQ("CLASS65000", RRClass(65000).toText());
 }
 
+TEST_F(RRClassTest, createFromText) {
+    const MaybeRRClass rrclass("IN");
+    EXPECT_TRUE(rrclass);
+    EXPECT_EQ("IN", rrclass->toText());
+    EXPECT_TRUE(RRClass::createFromText("CH"));
+    EXPECT_FALSE(RRClass::createFromText("ZZ"));
+}
+
 TEST_F(RRClassTest, toWireBuffer) {
     rrclass_1.toWire(obuffer);
     rrclass_0x80.toWire(obuffer);



More information about the bind10-changes mailing list