BIND 10 master, updated. a01569277cda3f78b1171bbf79f15ecf502e81e2 Merge branch 'master' into trac2390_2
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Feb 1 10:37:55 UTC 2013
The branch, master has been updated
via a01569277cda3f78b1171bbf79f15ecf502e81e2 (commit)
via 814eb8ad33d8f85621d3daacd4c64c4d7e3dc43d (commit)
via 11f5ae7cddca20ae003331cd69b817be4aea790c (commit)
via bc42c4b3d31ed960581808d76e7150e0fc3eb1d9 (commit)
via 691f87a3076fba4d5ce60a0960c1c07a35055e05 (commit)
via e6603386c50335787bca7443a9716414cf68c7bc (commit)
via 5d1563f963952af222030a404b21a0bc8171e2ac (commit)
via 859b69891fe1fc3be67bbd293397fbe7b989eb26 (commit)
via 3ca5de640a863aa8b84e5d34b241a26a63992e11 (commit)
via ff930eca8ab894a76eb0a695ebde98a7bf117d45 (commit)
via 3d35bcb14cbe4eba0cf2a2605bad4ede5ae6c338 (commit)
via e8c5250c5b3924c34159c92b2e3a23b8878572e6 (commit)
via b8e8e7ed5ff301eb18db71ff83c46479984f5fde (commit)
via 9c42816e5f405de02ef30728d82fcb045cf6a803 (commit)
via f18d297fd5b1651ebf61d5d72ca0d64b92fece30 (commit)
via a5a7f330f48cf6a63e7f67d690ea3487c11c2cce (commit)
via e1ed220b645ea62b01d9a467f8724be4fd59a696 (commit)
via adb9e821ff8fa75c3ecc1ecc853ff3e90d1edfd7 (commit)
from 971ac6698f44e468f072fab7baaea5eb6f6b77a3 (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 a01569277cda3f78b1171bbf79f15ecf502e81e2
Merge: 814eb8a 971ac66
Author: Mukund Sivaraman <muks at isc.org>
Date: Fri Feb 1 15:59:55 2013 +0530
Merge branch 'master' into trac2390_2
-----------------------------------------------------------------------
Summary of changes:
src/bin/ddns/tests/ddns_test.py | 2 +-
src/bin/loadzone/tests/correct/example.db | 14 +---
src/bin/loadzone/tests/correct/include.db | 4 +-
src/bin/loadzone/tests/correct/mix1.db | 4 +-
src/bin/loadzone/tests/correct/mix2.db | 4 +-
src/bin/loadzone/tests/correct/ttl1.db | 4 +-
src/bin/loadzone/tests/correct/ttl2.db | 4 +-
src/bin/loadzone/tests/correct/ttlext.db | 4 +-
src/bin/xfrin/tests/xfrin_test.py | 4 +-
src/bin/xfrout/tests/xfrout_test.py.in | 2 +-
src/lib/datasrc/tests/database_unittest.cc | 4 +-
.../tests/memory/rdata_serialization_unittest.cc | 6 +-
.../datasrc/tests/memory/zone_finder_unittest.cc | 2 +-
src/lib/dns/gen-rdatacode.py.in | 3 +
src/lib/dns/python/tests/rrset_python_test.py | 8 +-
.../dns/python/tests/zone_checker_python_test.py | 2 +-
src/lib/dns/rdata/generic/mx_15.cc | 81 +++++++++++++++++---
src/lib/dns/rdata/generic/ns_2.cc | 58 +++++++++++++-
src/lib/dns/rdata/generic/ptr_12.cc | 56 +++++++++++++-
src/lib/dns/tests/rdata_mx_unittest.cc | 26 ++++++-
src/lib/dns/tests/rdata_ns_unittest.cc | 35 ++++++---
src/lib/dns/tests/rdata_ptr_unittest.cc | 33 +++++---
src/lib/dns/tests/rrset_unittest.cc | 2 +-
src/lib/dns/tests/zone_checker_unittest.cc | 12 +--
.../tests/nameserver_address_store_unittest.cc | 2 +-
src/lib/nsas/tests/nsas_test.h | 4 +-
src/lib/python/isc/ddns/tests/session_tests.py | 10 +--
27 files changed, 296 insertions(+), 94 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/ddns/tests/ddns_test.py b/src/bin/ddns/tests/ddns_test.py
index 0f5ca9b..9119a89 100755
--- a/src/bin/ddns/tests/ddns_test.py
+++ b/src/bin/ddns/tests/ddns_test.py
@@ -1129,7 +1129,7 @@ class TestDDNSSession(unittest.TestCase):
# them as separate RRs.
dummy_record = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.NS(),
RRTTL(0))
- dummy_record.add_rdata(Rdata(RRType.NS(), TEST_RRCLASS, "ns.example"))
+ dummy_record.add_rdata(Rdata(RRType.NS(), TEST_RRCLASS, "ns.example."))
self.server.handle_request((self.__sock, TEST_SERVER6, TEST_CLIENT6,
create_msg(prereq=[dummy_record,
dummy_record])))
diff --git a/src/bin/loadzone/tests/correct/example.db b/src/bin/loadzone/tests/correct/example.db
index 38d1329..fe012cf 100644
--- a/src/bin/loadzone/tests/correct/example.db
+++ b/src/bin/loadzone/tests/correct/example.db
@@ -2,17 +2,11 @@
$ORIGIN example.com.
$TTL 60
@ IN SOA ns1.example.com. hostmaster.example.com. (1 43200 900 1814400 7200)
-; these need #2390
-; IN 20 NS ns1
-; NS ns2
- IN 20 NS ns1.example.com.
- NS ns2.example.com.
+ IN 20 NS ns1
+ NS ns2
ns1 IN 30 A 192.168.1.102
-; these need #2390
-; 70 NS ns3
-; IN NS ns4
- 70 NS ns3.example.com.
- IN NS ns4.example.com.
+ 70 NS ns3
+ IN NS ns4
10 IN MX 10 mail.example.com.
ns2 80 A 1.1.1.1
ns3 IN A 2.2.2.2
diff --git a/src/bin/loadzone/tests/correct/include.db b/src/bin/loadzone/tests/correct/include.db
index 53871bb..f60a240 100644
--- a/src/bin/loadzone/tests/correct/include.db
+++ b/src/bin/loadzone/tests/correct/include.db
@@ -7,9 +7,7 @@ $TTL 300
1814400
3600
)
-; this needs #2390
-; NS ns
- NS ns.include.
+ NS ns
ns A 127.0.0.1
diff --git a/src/bin/loadzone/tests/correct/mix1.db b/src/bin/loadzone/tests/correct/mix1.db
index 059fde7..a9d58a8 100644
--- a/src/bin/loadzone/tests/correct/mix1.db
+++ b/src/bin/loadzone/tests/correct/mix1.db
@@ -6,9 +6,7 @@ $ORIGIN mix1.
1814400
3
)
-; this needs #2390
-; NS ns
- NS ns.mix1.
+ NS ns
ns A 10.53.0.1
a TXT "soa minttl 3"
b 2 TXT "explicit ttl 2"
diff --git a/src/bin/loadzone/tests/correct/mix2.db b/src/bin/loadzone/tests/correct/mix2.db
index e89c2af..2c8153d 100644
--- a/src/bin/loadzone/tests/correct/mix2.db
+++ b/src/bin/loadzone/tests/correct/mix2.db
@@ -6,9 +6,7 @@ $ORIGIN mix2.
1814400
3
)
-; this needs #2390
-; NS ns
- NS ns.mix2.
+ NS ns
ns A 10.53.0.1
a TXT "inherited ttl 1"
$INCLUDE mix2sub1.txt
diff --git a/src/bin/loadzone/tests/correct/ttl1.db b/src/bin/loadzone/tests/correct/ttl1.db
index 7f04ff8..aa6e2bb 100644
--- a/src/bin/loadzone/tests/correct/ttl1.db
+++ b/src/bin/loadzone/tests/correct/ttl1.db
@@ -6,9 +6,7 @@ $ORIGIN ttl1.
1814400
3
)
-; this needs #2390
-; NS ns
- NS ns.ttl1.
+ NS ns
ns A 10.53.0.1
a TXT "soa minttl 3"
b 2 TXT "explicit ttl 2"
diff --git a/src/bin/loadzone/tests/correct/ttl2.db b/src/bin/loadzone/tests/correct/ttl2.db
index b7df040..f7f6eee 100644
--- a/src/bin/loadzone/tests/correct/ttl2.db
+++ b/src/bin/loadzone/tests/correct/ttl2.db
@@ -6,9 +6,7 @@ $ORIGIN ttl2.
1814400
3
)
-; this needs #2390
-; NS ns
- NS ns.ttl2.
+ NS ns
ns A 10.53.0.1
a TXT "inherited ttl 1"
b 2 TXT "explicit ttl 2"
diff --git a/src/bin/loadzone/tests/correct/ttlext.db b/src/bin/loadzone/tests/correct/ttlext.db
index 844f452..f8b96ea 100644
--- a/src/bin/loadzone/tests/correct/ttlext.db
+++ b/src/bin/loadzone/tests/correct/ttlext.db
@@ -6,9 +6,7 @@ $ORIGIN ttlext.
1814400
3
)
-; this needs #2390
-; NS ns
- NS ns.ttlext.
+ NS ns
ns A 10.53.0.1
a TXT "soa minttl 3"
b 2S TXT "explicit ttl 2"
diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py
index 2370708..899747f 100644
--- a/src/bin/xfrin/tests/xfrin_test.py
+++ b/src/bin/xfrin/tests/xfrin_test.py
@@ -373,7 +373,7 @@ class TestXfrinState(unittest.TestCase):
self.ns_rrset = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.NS(),
RRTTL(3600))
self.ns_rrset.add_rdata(Rdata(RRType.NS(), TEST_RRCLASS,
- 'ns.example.com'))
+ 'ns.example.com.'))
self.a_rrset = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.A(),
RRTTL(3600))
self.a_rrset.add_rdata(Rdata(RRType.A(), TEST_RRCLASS, '192.0.2.1'))
@@ -1197,7 +1197,7 @@ class TestAXFR(TestXfrinConnection):
def test_soacheck_referral_response(self):
self.conn.response_generator = self._create_soa_response_data
self.soa_response_params['answers'] = []
- self.soa_response_params['authorities'] = [create_ns('ns.example.com')]
+ self.soa_response_params['authorities'] = [create_ns('ns.example.com.')]
self.assertRaises(XfrinProtocolError, self.conn._check_soa_serial)
def test_soacheck_nodata_response(self):
diff --git a/src/bin/xfrout/tests/xfrout_test.py.in b/src/bin/xfrout/tests/xfrout_test.py.in
index 774187f..7bc395e 100644
--- a/src/bin/xfrout/tests/xfrout_test.py.in
+++ b/src/bin/xfrout/tests/xfrout_test.py.in
@@ -1144,7 +1144,7 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
self.xfrsess._request_data = self.mdata
self.xfrsess._server.get_db_file = lambda : TESTDATA_SRCDIR + \
'test.sqlite3'
- self.ns_name = 'a.dns.example.com'
+ self.ns_name = 'a.dns.example.com.'
def check_axfr_stream(self, response):
'''Common checks for AXFR(-style) response for the test zone.
diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc
index e52d9e9..cb8ed41 100644
--- a/src/lib/datasrc/tests/database_unittest.cc
+++ b/src/lib/datasrc/tests/database_unittest.cc
@@ -2466,7 +2466,7 @@ TYPED_TEST(DatabaseClientTest, findDelegation) {
// It should normally just result in DELEGATION; if GLUE_OK is specified,
// the other RR should be visible.
this->expected_rdatas_.clear();
- this->expected_rdatas_.push_back("ns.example.com");
+ this->expected_rdatas_.push_back("ns.example.com.");
doFindTest(*finder, Name("brokenns1.example.org"), this->qtype_,
RRType::NS(), this->rrttl_, ZoneFinder::DELEGATION,
this->expected_rdatas_, this->empty_rdatas_,
@@ -2515,7 +2515,7 @@ TYPED_TEST(DatabaseClientTest, findDS) {
// Some insane case: DS under a zone cut. It's included in the DB, but
// shouldn't be visible via finder.
this->expected_rdatas_.clear();
- this->expected_rdatas_.push_back("ns.example.com");
+ this->expected_rdatas_.push_back("ns.example.com.");
doFindTest(*finder, Name("child.insecdelegation.example.org"),
RRType::DS(), RRType::NS(), this->rrttl_,
ZoneFinder::DELEGATION, this->expected_rdatas_,
diff --git a/src/lib/datasrc/tests/memory/rdata_serialization_unittest.cc b/src/lib/datasrc/tests/memory/rdata_serialization_unittest.cc
index a45c2bd..1e70900 100644
--- a/src/lib/datasrc/tests/memory/rdata_serialization_unittest.cc
+++ b/src/lib/datasrc/tests/memory/rdata_serialization_unittest.cc
@@ -632,9 +632,9 @@ addRdataMultiCommon(const vector<ConstRdataPtr>& rrsigs) {
checkEncode(RRClass::IN(), RRType::A(), rdata_list_, 0, rrsigs);
ConstRdataPtr mx_rdata1 = createRdata(RRType::MX(), RRClass::IN(),
- "5 mx1.example.com");
+ "5 mx1.example.com.");
ConstRdataPtr mx_rdata2 = createRdata(RRType::MX(), RRClass::IN(),
- "10 mx2.example.com");
+ "10 mx2.example.com.");
rdata_list_.clear();
rdata_list_.push_back(mx_rdata1);
rdata_list_.push_back(mx_rdata2);
@@ -767,7 +767,7 @@ TEST_F(RdataSerializationTest, badAddRdata) {
// Likewise. Inconsistent name compression policy.
const ConstRdataPtr ns_rdata =
- createRdata(RRType::NS(), RRClass::IN(), "ns.example");
+ createRdata(RRType::NS(), RRClass::IN(), "ns.example.");
encoder_.start(RRClass::IN(), RRType::DNAME());
EXPECT_THROW(encoder_.addRdata(*ns_rdata), isc::BadValue);
diff --git a/src/lib/datasrc/tests/memory/zone_finder_unittest.cc b/src/lib/datasrc/tests/memory/zone_finder_unittest.cc
index 055708d..2ce2c67 100644
--- a/src/lib/datasrc/tests/memory/zone_finder_unittest.cc
+++ b/src/lib/datasrc/tests/memory/zone_finder_unittest.cc
@@ -110,7 +110,7 @@ protected:
{"example.org. 300 IN A 192.0.2.1", &rr_a_},
{"ns.example.org. 300 IN A 192.0.2.2", &rr_ns_a_},
// This one will place rr_ns_a_ at a zone cut, making it a glue:
- {"ns.example.org. 300 IN NS 192.0.2.2", &rr_ns_ns_},
+ {"ns.example.org. 300 IN NS 192.0.2.2.", &rr_ns_ns_},
{"ns.example.org. 300 IN AAAA 2001:db8::2", &rr_ns_aaaa_},
{"cname.example.org. 300 IN CNAME canonical.example.org",
&rr_cname_},
diff --git a/src/lib/dns/gen-rdatacode.py.in b/src/lib/dns/gen-rdatacode.py.in
index fc63d73..b653126 100755
--- a/src/lib/dns/gen-rdatacode.py.in
+++ b/src/lib/dns/gen-rdatacode.py.in
@@ -35,6 +35,9 @@ import sys
new_rdata_factory_users = [('aaaa', 'in'),
('hinfo', 'generic'),
('naptr', 'generic'),
+ ('mx', 'generic'),
+ ('ns', 'generic'),
+ ('ptr', 'generic'),
('soa', 'generic'),
('spf', 'generic'),
('txt', 'generic')
diff --git a/src/lib/dns/python/tests/rrset_python_test.py b/src/lib/dns/python/tests/rrset_python_test.py
index 0544872..010b60c 100644
--- a/src/lib/dns/python/tests/rrset_python_test.py
+++ b/src/lib/dns/python/tests/rrset_python_test.py
@@ -23,7 +23,7 @@ import os
from pydnspp import *
class TestModuleSpec(unittest.TestCase):
-
+
def setUp(self):
self.test_name = Name("test.example.com")
self.test_domain = Name("example.com")
@@ -78,8 +78,8 @@ class TestModuleSpec(unittest.TestCase):
def test_add_rdata(self):
# no iterator to read out yet (TODO: add addition test once implemented)
- self.assertRaises(TypeError, self.rrset_a.add_rdata, Rdata(RRType("NS"), RRClass("IN"), "test.name"))
- pass
+ self.assertRaises(TypeError, self.rrset_a.add_rdata,
+ Rdata(RRType("NS"), RRClass("IN"), "test.name."))
def test_to_text(self):
self.assertEqual("test.example.com. 3600 IN A 192.0.2.1\n"
@@ -126,6 +126,6 @@ class TestModuleSpec(unittest.TestCase):
# they would leak.
self.assertEqual(1, sys.getrefcount(self.rrset_a.get_rdata()))
self.assertEqual(1, sys.getrefcount(self.rrset_a.get_rdata()[0]))
-
+
if __name__ == '__main__':
unittest.main()
diff --git a/src/lib/dns/python/tests/zone_checker_python_test.py b/src/lib/dns/python/tests/zone_checker_python_test.py
index 66b6c47..ec3a3b0 100644
--- a/src/lib/dns/python/tests/zone_checker_python_test.py
+++ b/src/lib/dns/python/tests/zone_checker_python_test.py
@@ -142,7 +142,7 @@ class ZoneCheckerTest(unittest.TestCase):
ns = RRset(Name('example'), RRClass.IN(), rrtype,
RRTTL(0))
ns.add_rdata(Rdata(RRType.NS(), RRClass.IN(),
- 'example.org'))
+ 'example.org.'))
return ns
return None
diff --git a/src/lib/dns/rdata/generic/mx_15.cc b/src/lib/dns/rdata/generic/mx_15.cc
index b95ba05..f306870 100644
--- a/src/lib/dns/rdata/generic/mx_15.cc
+++ b/src/lib/dns/rdata/generic/mx_15.cc
@@ -26,6 +26,8 @@
#include <dns/rdata.h>
#include <dns/rdataclass.h>
+#include <dns/rdata/generic/detail/lexer_util.h>
+
using namespace std;
using boost::lexical_cast;
using namespace isc::util;
@@ -40,21 +42,80 @@ MX::MX(InputBuffer& buffer, size_t) :
// check consistency.
}
+/// \brief Constructor from string.
+///
+/// The given string must represent a valid MX RDATA. There can be extra
+/// space characters at the beginning or end of the text (which are simply
+/// ignored), but other extra text, including a new line, will make the
+/// construction fail with an exception.
+///
+/// The EXCHANGE name must be absolute since there's no parameter that
+/// specifies the origin name; if it is not absolute, \c MissingNameOrigin
+/// exception will be thrown. It must not be represented as a quoted
+/// string.
+///
+/// See the construction that takes \c MasterLexer for other fields.
+///
+/// \throw Others Exception from the Name and RRTTL constructors.
+/// \throw InvalidRdataText Other general syntax errors.
MX::MX(const std::string& mx_str) :
- preference_(0), mxname_(".")
+ // Fill in dummy name and replace them soon below.
+ preference_(0), mxname_(Name::ROOT_NAME())
{
- istringstream iss(mx_str);
- uint16_t pref;
- string mxname;
-
- iss >> pref >> mxname;
+ try {
+ std::istringstream ss(mx_str);
+ MasterLexer lexer;
+ lexer.pushSource(ss);
+
+ const uint32_t num =
+ lexer.getNextToken(MasterToken::NUMBER).getNumber();
+ if (num > 65535) {
+ isc_throw(InvalidRdataText, "Invalid MX preference in: "
+ << mx_str);
+ }
+ preference_ = static_cast<uint16_t>(num);
+
+ mxname_ = createNameFromLexer(lexer, NULL);
+
+ if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+ isc_throw(InvalidRdataText, "extra input text for MX: "
+ << mx_str);
+ }
+ } catch (const MasterLexer::LexerError& ex) {
+ isc_throw(InvalidRdataText, "Failed to construct MX from '" <<
+ mx_str << "': " << ex.what());
+ }
+}
- if (iss.bad() || iss.fail() || !iss.eof()) {
- isc_throw(InvalidRdataText, "Invalid MX text format");
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual representation
+/// of an MX RDATA. The EXCHANGE 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 PREFERENCE 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 EXCHANGE when it
+/// is non-absolute.
+MX::MX(MasterLexer& lexer, const Name* origin,
+ MasterLoader::Options, MasterLoaderCallbacks&) :
+ preference_(0), mxname_(".")
+{
+ const uint32_t num = lexer.getNextToken(MasterToken::NUMBER).getNumber();
+ if (num > 65535) {
+ isc_throw(InvalidRdataText, "Invalid MX preference: " << num);
}
+ preference_ = static_cast<uint16_t>(num);
- preference_ = pref;
- mxname_ = Name(mxname);
+ mxname_ = createNameFromLexer(lexer, origin);
}
MX::MX(uint16_t preference, const Name& mxname) :
diff --git a/src/lib/dns/rdata/generic/ns_2.cc b/src/lib/dns/rdata/generic/ns_2.cc
index 631da9d..2f0278f 100644
--- a/src/lib/dns/rdata/generic/ns_2.cc
+++ b/src/lib/dns/rdata/generic/ns_2.cc
@@ -22,15 +22,48 @@
#include <dns/rdata.h>
#include <dns/rdataclass.h>
+#include <dns/rdata/generic/detail/lexer_util.h>
+
using namespace std;
using namespace isc::util;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
+/// \brief Constructor from string.
+///
+/// The given string must represent a valid NS RDATA. There can be extra
+/// space characters at the beginning or end of the text (which are simply
+/// ignored), but other extra text, including a new line, will make the
+/// construction fail with an exception.
+///
+/// The NSDNAME must be absolute since there's no parameter that
+/// specifies the origin name; if it is not absolute, \c
+/// MissingNameOrigin exception will be thrown. These must not be
+/// represented as a quoted string.
+///
+/// \throw Others Exception from the Name and RRTTL constructors.
+/// \throw InvalidRdataText Other general syntax errors.
NS::NS(const std::string& namestr) :
- nsname_(namestr)
-{}
+ // Fill in dummy name and replace them soon below.
+ nsname_(Name::ROOT_NAME())
+{
+ try {
+ std::istringstream ss(namestr);
+ MasterLexer lexer;
+ lexer.pushSource(ss);
+
+ nsname_ = createNameFromLexer(lexer, NULL);
+
+ if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+ isc_throw(InvalidRdataText, "extra input text for NS: "
+ << namestr);
+ }
+ } catch (const MasterLexer::LexerError& ex) {
+ isc_throw(InvalidRdataText, "Failed to construct NS from '" <<
+ namestr << "': " << ex.what());
+ }
+}
NS::NS(InputBuffer& buffer, size_t) :
nsname_(buffer)
@@ -39,6 +72,27 @@ NS::NS(InputBuffer& buffer, size_t) :
// check consistency.
}
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual
+/// representation of an NS RDATA. The NSDNAME 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.
+///
+/// \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 NSDNAME when it
+/// is non-absolute.
+NS::NS(MasterLexer& lexer, const Name* origin,
+ MasterLoader::Options, MasterLoaderCallbacks&) :
+ nsname_(createNameFromLexer(lexer, origin))
+{}
+
NS::NS(const NS& other) :
Rdata(), nsname_(other.nsname_)
{}
diff --git a/src/lib/dns/rdata/generic/ptr_12.cc b/src/lib/dns/rdata/generic/ptr_12.cc
index b76fc7f..beec038 100644
--- a/src/lib/dns/rdata/generic/ptr_12.cc
+++ b/src/lib/dns/rdata/generic/ptr_12.cc
@@ -28,9 +28,40 @@ using namespace isc::util;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
+/// \brief Constructor from string.
+///
+/// The given string must represent a valid PTR RDATA. There can be
+/// extra space characters at the beginning or end of the text (which
+/// are simply ignored), but other extra text, including a new line,
+/// will make the construction fail with an exception.
+///
+/// The PTRDNAME must be absolute since there's no parameter that
+/// specifies the origin name; if it is not absolute, \c
+/// MissingNameOrigin exception will be thrown. These must not be
+/// represented as a quoted string.
+///
+/// \throw Others Exception from the Name and RRTTL constructors.
+/// \throw InvalidRdataText Other general syntax errors.
PTR::PTR(const std::string& type_str) :
- ptr_name_(type_str)
-{}
+ // Fill in dummy name and replace them soon below.
+ ptr_name_(Name::ROOT_NAME())
+{
+ try {
+ std::istringstream ss(type_str);
+ MasterLexer lexer;
+ lexer.pushSource(ss);
+
+ ptr_name_ = createNameFromLexer(lexer, NULL);
+
+ if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+ isc_throw(InvalidRdataText, "extra input text for PTR: "
+ << type_str);
+ }
+ } catch (const MasterLexer::LexerError& ex) {
+ isc_throw(InvalidRdataText, "Failed to construct PTR from '" <<
+ type_str << "': " << ex.what());
+ }
+}
PTR::PTR(InputBuffer& buffer, size_t) :
ptr_name_(buffer)
@@ -39,6 +70,27 @@ PTR::PTR(InputBuffer& buffer, size_t) :
// check consistency.
}
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual
+/// representation of a PTR RDATA. The PTRDNAME 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.
+///
+/// \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 PTRDNAME when it
+/// is non-absolute.
+PTR::PTR(MasterLexer& lexer, const Name* origin,
+ MasterLoader::Options, MasterLoaderCallbacks&) :
+ ptr_name_(createNameFromLexer(lexer, origin))
+{}
+
PTR::PTR(const PTR& source) :
Rdata(), ptr_name_(source.ptr_name_)
{}
diff --git a/src/lib/dns/tests/rdata_mx_unittest.cc b/src/lib/dns/tests/rdata_mx_unittest.cc
index 6c6039a..f4d0abb 100644
--- a/src/lib/dns/tests/rdata_mx_unittest.cc
+++ b/src/lib/dns/tests/rdata_mx_unittest.cc
@@ -38,7 +38,7 @@ class Rdata_MX_Test : public RdataTest {
const generic::MX rdata_mx(10, Name("mx.example.com"));
TEST_F(Rdata_MX_Test, createFromText) {
- const generic::MX rdata_mx2("10 mx.example.com");
+ const generic::MX rdata_mx2("10 mx.example.com.");
EXPECT_EQ(0, rdata_mx2.compare(rdata_mx));
}
@@ -48,6 +48,12 @@ TEST_F(Rdata_MX_Test, badText) {
EXPECT_THROW(const generic::MX rdata_mx("SPOON"), InvalidRdataText);
EXPECT_THROW(const generic::MX rdata_mx("10 mx. example.com."),
InvalidRdataText);
+ // No origin and relative
+ EXPECT_THROW(const generic::MX rdata_mx("10 mx.example.com"),
+ MissingNameOrigin);
+ // Extra text at end of line
+ EXPECT_THROW(const generic::MX rdata_mx("10 mx.example.com. extra."),
+ InvalidRdataText);
}
TEST_F(Rdata_MX_Test, copy) {
@@ -65,11 +71,25 @@ TEST_F(Rdata_MX_Test, createFromWire) {
TEST_F(Rdata_MX_Test, createFromLexer) {
EXPECT_EQ(0, rdata_mx.compare(
*test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
- "10 mx.example.com")));
+ "10 mx.example.com.")));
+
+ // test::createRdataUsingLexer() constructs relative to
+ // "example.org." origin.
+ EXPECT_EQ(0, generic::MX("10 mx2.example.org.").compare(
+ *test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
+ "10 mx2")));
// Exceptions cause NULL to be returned.
EXPECT_FALSE(test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
- "10 mx. example.com"));
+ "10 mx. example.com."));
+
+ // 65536 is larger than maximum possible preference
+ EXPECT_FALSE(test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
+ "65536 mx.example.com."));
+
+ // Extra text at end of line
+ EXPECT_FALSE(test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
+ "10 mx.example.com. extra."));
}
TEST_F(Rdata_MX_Test, toWireRenderer) {
diff --git a/src/lib/dns/tests/rdata_ns_unittest.cc b/src/lib/dns/tests/rdata_ns_unittest.cc
index d536393..a6f5a98 100644
--- a/src/lib/dns/tests/rdata_ns_unittest.cc
+++ b/src/lib/dns/tests/rdata_ns_unittest.cc
@@ -36,8 +36,8 @@ class Rdata_NS_Test : public RdataTest {
// there's nothing to specialize
};
-const generic::NS rdata_ns("ns.example.com");
-const generic::NS rdata_ns2("ns2.example.com");
+const generic::NS rdata_ns("ns.example.com.");
+const generic::NS rdata_ns2("ns2.example.com.");
const uint8_t wiredata_ns[] = {
0x02, 0x6e, 0x73, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00 };
@@ -50,15 +50,20 @@ const uint8_t wiredata_ns2[] = {
0x03, 0x6e, 0x73, 0x32, 0xc0, 0x03 };
TEST_F(Rdata_NS_Test, createFromText) {
- EXPECT_EQ(0, rdata_ns.compare(generic::NS("ns.example.com")));
+ EXPECT_EQ(0, rdata_ns.compare(generic::NS("ns.example.com.")));
// explicitly add a trailing dot. should be the same RDATA.
EXPECT_EQ(0, rdata_ns.compare(generic::NS("ns.example.com.")));
// should be case sensitive.
- EXPECT_EQ(0, rdata_ns.compare(generic::NS("NS.EXAMPLE.COM")));
+ EXPECT_EQ(0, rdata_ns.compare(generic::NS("NS.EXAMPLE.COM.")));
// RDATA of a class-independent type should be recognized for any
// "unknown" class.
EXPECT_EQ(0, rdata_ns.compare(*createRdata(RRType("NS"), RRClass(65000),
- "ns.example.com")));
+ "ns.example.com.")));
+}
+
+TEST_F(Rdata_NS_Test, badText) {
+ // Extra input at end of line
+ EXPECT_THROW(generic::NS("ns.example.com. extra."), InvalidRdataText);
}
TEST_F(Rdata_NS_Test, createFromWire) {
@@ -78,7 +83,7 @@ TEST_F(Rdata_NS_Test, createFromWire) {
"rdata_ns_fromWire", 71),
DNSMessageFORMERR);
- EXPECT_EQ(0, generic::NS("ns2.example.com").compare(
+ EXPECT_EQ(0, generic::NS("ns2.example.com.").compare(
*rdataFactoryFromFile(RRType("NS"), RRClass("IN"),
"rdata_ns_fromWire", 55)));
EXPECT_THROW(*rdataFactoryFromFile(RRType("NS"), RRClass("IN"),
@@ -89,11 +94,21 @@ TEST_F(Rdata_NS_Test, createFromWire) {
TEST_F(Rdata_NS_Test, createFromLexer) {
EXPECT_EQ(0, rdata_ns.compare(
*test::createRdataUsingLexer(RRType::NS(), RRClass::IN(),
- "ns.example.com")));
+ "ns.example.com.")));
+
+ // test::createRdataUsingLexer() constructs relative to
+ // "example.org." origin.
+ EXPECT_EQ(0, generic::NS("ns8.example.org.").compare(
+ *test::createRdataUsingLexer(RRType::NS(), RRClass::IN(),
+ "ns8")));
// Exceptions cause NULL to be returned.
EXPECT_FALSE(test::createRdataUsingLexer(RRType::NS(), RRClass::IN(),
""));
+
+ // Extra input at end of line
+ EXPECT_FALSE(test::createRdataUsingLexer(RRType::NS(), RRClass::IN(),
+ "ns.example.com. extra."));
}
TEST_F(Rdata_NS_Test, toWireBuffer) {
@@ -119,13 +134,13 @@ TEST_F(Rdata_NS_Test, toText) {
}
TEST_F(Rdata_NS_Test, compare) {
- generic::NS small("a.example");
- generic::NS large("example");
+ generic::NS small("a.example.");
+ generic::NS large("example.");
EXPECT_TRUE(Name("a.example") > Name("example"));
EXPECT_GT(0, small.compare(large));
}
TEST_F(Rdata_NS_Test, getNSName) {
- EXPECT_EQ(Name("ns.example.com"), rdata_ns.getNSName());
+ EXPECT_EQ(Name("ns.example.com."), rdata_ns.getNSName());
}
}
diff --git a/src/lib/dns/tests/rdata_ptr_unittest.cc b/src/lib/dns/tests/rdata_ptr_unittest.cc
index 44b849a..9378c5e 100644
--- a/src/lib/dns/tests/rdata_ptr_unittest.cc
+++ b/src/lib/dns/tests/rdata_ptr_unittest.cc
@@ -40,8 +40,8 @@ class Rdata_PTR_Test : public RdataTest {
// there's nothing to specialize
};
-const generic::PTR rdata_ptr("ns.example.com");
-const generic::PTR rdata_ptr2("ns2.example.com");
+const generic::PTR rdata_ptr("ns.example.com.");
+const generic::PTR rdata_ptr2("ns2.example.com.");
const uint8_t wiredata_ptr[] = {
0x02, 0x6e, 0x73, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00 };
@@ -54,15 +54,20 @@ const uint8_t wiredata_ptr2[] = {
0x03, 0x6e, 0x73, 0x32, 0xc0, 0x03 };
TEST_F(Rdata_PTR_Test, createFromText) {
- EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("ns.example.com")));
+ EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("ns.example.com.")));
// explicitly add a trailing dot. should be the same RDATA.
EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("ns.example.com.")));
// should be case sensitive.
- EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("NS.EXAMPLE.COM")));
+ EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("NS.EXAMPLE.COM.")));
// RDATA of a class-independent type should be recognized for any
// "unknown" class.
EXPECT_EQ(0, rdata_ptr.compare(*createRdata(RRType("PTR"), RRClass(65000),
- "ns.example.com")));
+ "ns.example.com.")));
+}
+
+TEST_F(Rdata_PTR_Test, badText) {
+ // Extra text at end of line
+ EXPECT_THROW(generic::PTR("foo.example.com. extra."), InvalidRdataText);
}
TEST_F(Rdata_PTR_Test, createFromWire) {
@@ -82,7 +87,7 @@ TEST_F(Rdata_PTR_Test, createFromWire) {
"rdata_ns_fromWire", 71),
DNSMessageFORMERR);
- EXPECT_EQ(0, generic::PTR("ns2.example.com").compare(
+ EXPECT_EQ(0, generic::PTR("ns2.example.com.").compare(
*rdataFactoryFromFile(RRType("PTR"), RRClass("IN"),
"rdata_ns_fromWire", 55)));
EXPECT_THROW(*rdataFactoryFromFile(RRType("PTR"), RRClass("IN"),
@@ -93,7 +98,17 @@ TEST_F(Rdata_PTR_Test, createFromWire) {
TEST_F(Rdata_PTR_Test, createFromLexer) {
EXPECT_EQ(0, rdata_ptr.compare(
*test::createRdataUsingLexer(RRType::PTR(), RRClass::IN(),
- "ns.example.com")));
+ "ns.example.com.")));
+
+ // test::createRdataUsingLexer() constructs relative to
+ // "example.org." origin.
+ EXPECT_EQ(0, generic::PTR("foo0.example.org.").compare(
+ *test::createRdataUsingLexer(RRType::PTR(), RRClass::IN(),
+ "foo0")));
+
+ // Extra text at end of line
+ EXPECT_FALSE(test::createRdataUsingLexer(RRType::PTR(), RRClass::IN(),
+ "foo.example.com. extra."));
}
TEST_F(Rdata_PTR_Test, toWireBuffer) {
@@ -119,8 +134,8 @@ TEST_F(Rdata_PTR_Test, toText) {
}
TEST_F(Rdata_PTR_Test, compare) {
- generic::PTR small("a.example");
- generic::PTR large("example");
+ generic::PTR small("a.example.");
+ generic::PTR large("example.");
EXPECT_TRUE(Name("a.example") > Name("example"));
EXPECT_GT(0, small.compare(large));
}
diff --git a/src/lib/dns/tests/rrset_unittest.cc b/src/lib/dns/tests/rrset_unittest.cc
index 725eea7..1b4abfd 100644
--- a/src/lib/dns/tests/rrset_unittest.cc
+++ b/src/lib/dns/tests/rrset_unittest.cc
@@ -168,7 +168,7 @@ TEST_F(RRsetTest, addRdataPtr) {
// Pointer version of addRdata() doesn't type check and does allow to
//add a different type of Rdata as a result.
rrset_a_empty.addRdata(createRdata(RRType::NS(), RRClass::IN(),
- "ns.example.com"));
+ "ns.example.com."));
EXPECT_EQ(3, rrset_a_empty.getRdataCount());
}
diff --git a/src/lib/dns/tests/zone_checker_unittest.cc b/src/lib/dns/tests/zone_checker_unittest.cc
index dbe204d..115587f 100644
--- a/src/lib/dns/tests/zone_checker_unittest.cc
+++ b/src/lib/dns/tests/zone_checker_unittest.cc
@@ -160,7 +160,7 @@ TEST_F(ZoneCheckerTest, checkSOA) {
// Likewise, if the SOA RRset contains non SOA Rdata, it should be a bug.
rrsets_->removeRRset(zname_, zclass_, RRType::SOA());
soa_.reset(new RRset(zname_, zclass_, RRType::SOA(), RRTTL(60)));
- soa_->addRdata(createRdata(RRType::NS(), zclass_, "ns.example.com"));
+ soa_->addRdata(createRdata(RRType::NS(), zclass_, "ns.example.com."));
rrsets_->addRRset(soa_);
EXPECT_THROW(checkZone(zname_, zclass_, *rrsets_, callbacks_), Unexpected);
checkIssues(); // no error/warning should be reported
@@ -245,7 +245,7 @@ TEST_F(ZoneCheckerTest, checkNSData) {
rrsets_->removeRRset(ns_name, zclass_, RRType::CNAME());
rrsets_->removeRRset(zname_, zclass_, RRType::NS());
ns_.reset(new RRset(zname_, zclass_, RRType::NS(), RRTTL(60)));
- ns_->addRdata(generic::NS("ns.example.org"));
+ ns_->addRdata(generic::NS("ns.example.org."));
rrsets_->addRRset(ns_);
EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_));
checkIssues();
@@ -274,7 +274,7 @@ TEST_F(ZoneCheckerTest, checkNSWithDelegation) {
rrsets_->addRRset(ns_);
RRsetPtr child_ns(new RRset(Name("child.example.com"), zclass_,
RRType::NS(), RRTTL(60)));
- child_ns->addRdata(generic::NS("ns.example.org"));
+ child_ns->addRdata(generic::NS("ns.example.org."));
rrsets_->addRRset(child_ns);
EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_));
checkIssues();
@@ -282,7 +282,7 @@ TEST_F(ZoneCheckerTest, checkNSWithDelegation) {
// Zone cut at the NS name. Same result.
rrsets_->removeRRset(child_ns->getName(), zclass_, RRType::NS());
child_ns.reset(new RRset(ns_name, zclass_, RRType::NS(), RRTTL(60)));
- child_ns->addRdata(generic::NS("ns.example.org"));
+ child_ns->addRdata(generic::NS("ns.example.org."));
rrsets_->addRRset(child_ns);
EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_));
checkIssues();
@@ -291,7 +291,7 @@ TEST_F(ZoneCheckerTest, checkNSWithDelegation) {
rrsets_->removeRRset(child_ns->getName(), zclass_, RRType::NS());
child_ns.reset(new RRset(Name("another.ns.child.example.com"), zclass_,
RRType::NS(), RRTTL(60)));
- child_ns->addRdata(generic::NS("ns.example.org"));
+ child_ns->addRdata(generic::NS("ns.example.org."));
rrsets_->addRRset(child_ns);
EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_));
expected_warns_.push_back("zone example.com/IN: NS has no address");
@@ -332,7 +332,7 @@ TEST_F(ZoneCheckerTest, checkNSWithDNAME) {
// this implementation prefers the NS and skips further checks.
ns_.reset(new RRset(Name("child.example.com"), zclass_, RRType::NS(),
RRTTL(60)));
- ns_->addRdata(generic::NS("ns.example.org"));
+ ns_->addRdata(generic::NS("ns.example.org."));
rrsets_->addRRset(ns_);
EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_));
checkIssues();
diff --git a/src/lib/nsas/tests/nameserver_address_store_unittest.cc b/src/lib/nsas/tests/nameserver_address_store_unittest.cc
index 6ddae72..ceb5775 100644
--- a/src/lib/nsas/tests/nameserver_address_store_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_address_store_unittest.cc
@@ -386,7 +386,7 @@ TEST_F(NameserverAddressStoreTest, CombinedTest) {
// But we do not answer it right away. We create a new zone and
// let this nameserver entry get out.
- rrns_->addRdata(rdata::generic::NS("example.cz"));
+ rrns_->addRdata(rdata::generic::NS("example.cz."));
nsas.lookupAndAnswer(EXAMPLE_CO_UK, RRClass::IN(), rrns_, getCallback());
// It really should ask something, one of the nameservers
diff --git a/src/lib/nsas/tests/nsas_test.h b/src/lib/nsas/tests/nsas_test.h
index d6b4d92..9f92149 100644
--- a/src/lib/nsas/tests/nsas_test.h
+++ b/src/lib/nsas/tests/nsas_test.h
@@ -264,8 +264,8 @@ protected:
rrch_->addRdata(ConstRdataPtr(new RdataTest<A>("1324")));
// NS records take a single name
- rrns_->addRdata(rdata::generic::NS("example.fr"));
- rrns_->addRdata(rdata::generic::NS("example.de"));
+ rrns_->addRdata(rdata::generic::NS("example.fr."));
+ rrns_->addRdata(rdata::generic::NS("example.de."));
// Single NS record with 0 TTL
rr_single_->addRdata(rdata::generic::NS(ns_name_));
diff --git a/src/lib/python/isc/ddns/tests/session_tests.py b/src/lib/python/isc/ddns/tests/session_tests.py
index f7c2d3c..6a67c3a 100644
--- a/src/lib/python/isc/ddns/tests/session_tests.py
+++ b/src/lib/python/isc/ddns/tests/session_tests.py
@@ -543,7 +543,7 @@ class SessionTest(SessionTestBase):
self.__prereq_helper(method, False, rrset)
add_rdata(rrset, "ns1.example.org.")
self.__prereq_helper(method, False, rrset)
- add_rdata(rrset, "ns2.example.org")
+ add_rdata(rrset, "ns2.example.org.")
self.__prereq_helper(method, False, rrset)
add_rdata(rrset, "ns3.example.org.")
self.__prereq_helper(method, True, rrset)
@@ -703,13 +703,13 @@ class SessionTest(SessionTestBase):
rrset_exists_value_1 = create_rrset("example.org", RRClass.IN(),
RRType.NS(), 0,
- [ "ns1.example.org" ])
+ [ "ns1.example.org." ])
rrset_exists_value_2 = create_rrset("example.org", RRClass.IN(),
RRType.NS(), 0,
- [ "ns2.example.org" ])
+ [ "ns2.example.org." ])
rrset_exists_value_3 = create_rrset("example.org", RRClass.IN(),
RRType.NS(), 0,
- [ "ns3.example.org" ])
+ [ "ns3.example.org." ])
# and a number that should not
rrset_exists_no = create_rrset("foo.example.org", RRClass.ANY(),
@@ -1339,7 +1339,7 @@ class SessionTest(SessionTestBase):
# should not keep any
self.__initialize_update_rrsets()
new_ns = create_rrset("example.org", TEST_RRCLASS, RRType.NS(), 3600,
- [ "newns1.example.org", "newns2.example.org" ])
+ [ "newns1.example.org.", "newns2.example.org." ])
self.check_full_handle_result(Rcode.NOERROR(),
[ new_ns,
More information about the bind10-changes
mailing list