Browse Source

Merge branch 'trac2391'

Paul Selkirk 12 years ago
parent
commit
8802d41424

+ 1 - 0
src/lib/dns/gen-rdatacode.py.in

@@ -33,6 +33,7 @@ import sys
 # Example:
 #     new_rdata_factory_users = [('a', 'in'), ('a', 'ch'), ('soa', 'generic')]
 new_rdata_factory_users = [('a', 'in'), ('aaaa', 'in'),
+                           ('afsdb', 'generic'),
                            ('cname', 'generic'),
                            ('dlv', 'generic'),
                            ('dname', 'generic'),

+ 52 - 15
src/lib/dns/rdata/generic/afsdb_18.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013  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
@@ -25,9 +25,12 @@
 
 #include <boost/lexical_cast.hpp>
 
+#include <dns/rdata/generic/detail/lexer_util.h>
+
 using namespace std;
+using boost::lexical_cast;
 using namespace isc::util;
-using namespace isc::util::str;
+using isc::dns::rdata::generic::detail::createNameFromLexer;
 
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
@@ -52,24 +55,58 @@ using namespace isc::util::str;
 AFSDB::AFSDB(const std::string& afsdb_str) :
     subtype_(0), server_(Name::ROOT_NAME())
 {
-    istringstream iss(afsdb_str);
-
     try {
-        const uint32_t subtype = tokenToNum<int32_t, 16>(getToken(iss));
-        const Name servername(getToken(iss));
+        std::istringstream ss(afsdb_str);
+        MasterLexer lexer;
+        lexer.pushSource(ss);
 
-        if (!iss.eof()) {
-            isc_throw(InvalidRdataText, "Unexpected input for AFSDB"
-                    "RDATA: " << afsdb_str);
+        createFromLexer(lexer, NULL);
+
+        if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+            isc_throw(InvalidRdataText, "extra input text for AFSDB: "
+                      << afsdb_str);
         }
+    } catch (const MasterLexer::LexerError& ex) {
+        isc_throw(InvalidRdataText, "Failed to construct AFSDB from '" <<
+                  afsdb_str << "': " << ex.what());
+    }
+}
 
-        subtype_ = subtype;
-        server_ = servername;
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual representation
+/// of an AFSDB RDATA.  The SERVER field can be non-absolute if \c origin
+/// is non-NULL, in which case \c origin is used to make it absolute.
+/// It must not be represented as a quoted string.
+///
+/// The SUBTYPE field must be a valid decimal representation of an
+/// unsigned 16-bit integer.
+///
+/// \throw MasterLexer::LexerError General parsing error such as missing field.
+/// \throw Other Exceptions from the Name and RRTTL constructors if
+/// construction of textual fields as these objects fail.
+///
+/// \param lexer A \c MasterLexer object parsing a master file for the
+/// RDATA to be created
+/// \param origin If non NULL, specifies the origin of SERVER when it
+/// is non-absolute.
+AFSDB::AFSDB(MasterLexer& lexer, const Name* origin,
+       MasterLoader::Options, MasterLoaderCallbacks&) :
+    subtype_(0), server_(".")
+{
+    createFromLexer(lexer, origin);
+}
 
-    } catch (const StringTokenError& ste) {
-        isc_throw(InvalidRdataText, "Invalid AFSDB text: " <<
-                  ste.what() << ": " << afsdb_str);
+void
+AFSDB::createFromLexer(MasterLexer& lexer, const Name* origin)
+{
+    const uint32_t num = lexer.getNextToken(MasterToken::NUMBER).getNumber();
+    if (num > 65535) {
+        isc_throw(InvalidRdataText, "Invalid AFSDB subtype: " << num);
     }
+    subtype_ = static_cast<uint16_t>(num);
+
+    server_ = createNameFromLexer(lexer, origin);
 }
 
 /// \brief Constructor from wire-format data.
@@ -111,7 +148,7 @@ AFSDB::operator=(const AFSDB& source) {
 /// \return A \c string object that represents the \c AFSDB object.
 string
 AFSDB::toText() const {
-    return (boost::lexical_cast<string>(subtype_) + " " + server_.toText());
+    return (lexical_cast<string>(subtype_) + " " + server_.toText());
 }
 
 /// \brief Render the \c AFSDB in the wire format without name compression.

+ 3 - 1
src/lib/dns/rdata/generic/afsdb_18.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013  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
@@ -61,6 +61,8 @@ public:
     uint16_t getSubtype() const;
 
 private:
+    void createFromLexer(MasterLexer& lexer, const Name* origin);
+
     uint16_t subtype_;
     Name server_;
 };

+ 30 - 7
src/lib/dns/tests/rdata_afsdb_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013  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
@@ -34,7 +34,7 @@ using namespace isc::dns::rdata;
 const char* const afsdb_text = "1 afsdb.example.com.";
 const char* const afsdb_text2 = "0 root.example.com.";
 const char* const too_long_label("012345678901234567890123456789"
-        "0123456789012345678901234567890123");
+        "0123456789012345678901234567890123.");
 
 namespace {
 class Rdata_AFSDB_Test : public RdataTest {
@@ -68,9 +68,17 @@ TEST_F(Rdata_AFSDB_Test, badText) {
     // number of fields (must be 2) is incorrect
     EXPECT_THROW(const generic::AFSDB rdata_afsdb("10 afsdb. example.com."),
                  InvalidRdataText);
+    // No origin and relative
+    EXPECT_THROW(const generic::AFSDB rdata_afsdb("1 afsdb.example.com"),
+                 MissingNameOrigin);
     // bad name
     EXPECT_THROW(const generic::AFSDB rdata_afsdb("1 afsdb.example.com." +
-                string(too_long_label)), TooLongLabel);
+                 string(too_long_label)), TooLongLabel);
+}
+
+TEST_F(Rdata_AFSDB_Test, copy) {
+    const generic::AFSDB rdata_afsdb2(rdata_afsdb);
+    EXPECT_EQ(0, rdata_afsdb.compare(rdata_afsdb2));
 }
 
 TEST_F(Rdata_AFSDB_Test, assignment) {
@@ -119,9 +127,24 @@ TEST_F(Rdata_AFSDB_Test, createFromLexer) {
         *test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(),
                                      afsdb_text)));
 
+    // test::createRdataUsingLexer() constructs relative to
+    // "example.org." origin.
+    generic::AFSDB tmp = generic::AFSDB("1 afsdb2.example.org.");
+    EXPECT_EQ(0, tmp.compare(
+        *test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(),
+                                     "1 afsdb2")));
+
     // Exceptions cause NULL to be returned.
     EXPECT_FALSE(test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(),
                                              "1root.example.com."));
+
+    // 65536 is larger than maximum possible subtype
+    EXPECT_FALSE(test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(),
+                                             "65536 afsdb.example.com."));
+
+    // Extra text at end of line
+    EXPECT_FALSE(test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(),
+                                             "1 afsdb.example.com. extra."));
 }
 
 TEST_F(Rdata_AFSDB_Test, toWireBuffer) {
@@ -197,9 +220,9 @@ TEST_F(Rdata_AFSDB_Test, compare) {
     EXPECT_EQ(0, rdata_afsdb.compare(generic::AFSDB("1 "
                                 "AFSDB.example.com.")));
 
-    const generic::AFSDB small1("10 afsdb.example.com");
-    const generic::AFSDB large1("65535 afsdb.example.com");
-    const generic::AFSDB large2("256 afsdb.example.com");
+    const generic::AFSDB small1("10 afsdb.example.com.");
+    const generic::AFSDB large1("65535 afsdb.example.com.");
+    const generic::AFSDB large2("256 afsdb.example.com.");
 
     // confirm these are compared as unsigned values
     EXPECT_GT(0, rdata_afsdb.compare(large1));
@@ -210,7 +233,7 @@ TEST_F(Rdata_AFSDB_Test, compare) {
     EXPECT_LT(0, large2.compare(small1));
 
     // another AFSDB whose server name is larger than that of rdata_afsdb.
-    const generic::AFSDB large3("256 zzzzz.example.com");
+    const generic::AFSDB large3("256 zzzzz.example.com.");
     EXPECT_GT(0, large2.compare(large3));
     EXPECT_LT(0, large3.compare(large2));