BIND 10 trac2429, updated. 8b616d0d3fbf1da3533c9836687f7fa12a7da1c6 [2429] use boost::optional instead of homebrew and less clean interface
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Dec 18 04:14:44 UTC 2012
The branch, trac2429 has been updated
via 8b616d0d3fbf1da3533c9836687f7fa12a7da1c6 (commit)
via f277a67977c700be9e205c6af2c29f2b0764b19c (commit)
via 862d60332f64f7bb357cf8f300fd0faf610ef638 (commit)
via b9fa6ce6e6ba2d491096bc5c632e80c70a73614e (commit)
via 2aa24772e0d3c790ab2127933159747f30bd5430 (commit)
via ed49f68cc90984e065b40a0100e154956403fb35 (commit)
via 62f943fe6baa7a99990856bb03be039e54341ad3 (commit)
via 525af02fc521561f117064cfee06288798236287 (commit)
via c8f37fef053d256ba32adc921cf677059f61117f (commit)
from be2fccd2405459f3b421d2f7a7bec11103710f4c (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 8b616d0d3fbf1da3533c9836687f7fa12a7da1c6
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 19:37:22 2012 -0800
[2429] use boost::optional instead of homebrew and less clean interface
at the cost of increasing dependency, it will provide a cleaner and
more intuitive interface without sacrificing efficiency (much).
commit f277a67977c700be9e205c6af2c29f2b0764b19c
Merge: 862d603 be2fccd
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 19:36:28 2012 -0800
[2429] Merge branch 'trac2429' of ssh://git.bind10.isc.org/var/bind10/git/bind10 into trac2429
commit 862d60332f64f7bb357cf8f300fd0faf610ef638
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 18:55:13 2012 -0800
[2429] fixed a minor typo in test code
commit b9fa6ce6e6ba2d491096bc5c632e80c70a73614e
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 18:42:16 2012 -0800
[2429] on second thought, define max rrttl as an object
commit 2aa24772e0d3c790ab2127933159747f30bd5430
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 18:30:32 2012 -0800
[2429] define MAX_TTL in rrttl.h, as its bare value, not in form of RRTTL
commit ed49f68cc90984e065b40a0100e154956403fb35
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 18:20:16 2012 -0800
[2429] more clarified the max TTL handling in terms of RFC compliance.
commit 62f943fe6baa7a99990856bb03be039e54341ad3
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 14:59:25 2012 -0800
[2429] clarified the RFC1035-TTL semantics warning further
commit 525af02fc521561f117064cfee06288798236287
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 14:50:24 2012 -0800
[2429] renamed one of setCurrentTTL to clarify it only sets it to the default.
also clarified the function description comment a bit further.
commit c8f37fef053d256ba32adc921cf677059f61117f
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Dec 17 14:44:35 2012 -0800
[2429] clarified some comments
-----------------------------------------------------------------------
Summary of changes:
src/lib/dns/master_loader.cc | 52 +++++++++--------------
src/lib/dns/rrttl.cc | 18 ++++----
src/lib/dns/rrttl.h | 78 ++++++++++++++++++++++++-----------
src/lib/dns/tests/rrttl_unittest.cc | 28 ++++++-------
4 files changed, 93 insertions(+), 83 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/dns/master_loader.cc b/src/lib/dns/master_loader.cc
index 8309e6f..9101612 100644
--- a/src/lib/dns/master_loader.cc
+++ b/src/lib/dns/master_loader.cc
@@ -52,7 +52,6 @@ public:
const MasterLoaderCallbacks& callbacks,
const AddRRCallback& add_callback,
MasterLoader::Options options) :
- MAX_TTL(0x7fffffff),
lexer_(),
zone_origin_(zone_origin),
zone_class_(zone_class),
@@ -145,18 +144,20 @@ private:
// Upper limit check when recognizing a specific TTL value from the
// zone file ($TTL, the RR's TTL field, or the SOA minimum). RFC2181
- // Section 8 limits the range of TTL values to unsigned 32-bit integers,
+ // Section 8 limits the range of TTL values to 2^31-1 (0x7fffffff),
// and prohibits transmitting a TTL field exceeding this range. We
// guarantee that by limiting the value at the time of zone
// parsing/loading, following what BIND 9 does. Resetting it to 0
- // at this point may not be exactly what the RFC states, but the end
- // result would be the same. Again, we follow the BIND 9's behavior here.
+ // at this point may not be exactly what the RFC states (depending on
+ // the meaning of 'received'), but the end result would be the same (i.e.,
+ // the guarantee on transmission). Again, we follow the BIND 9's behavior
+ // here.
//
// post_parsing is true iff this method is called after parsing the entire
// RR and the lexer is positioned at the next line. It's just for
// calculating the accurate source line when callback is necessary.
void limitTTL(RRTTL& ttl, bool post_parsing) {
- if (ttl > MAX_TTL) {
+ if (ttl > RRTTL::MAX()) {
const size_t src_line = lexer_.getSourceLine() -
(post_parsing ? 1 : 0);
callbacks_.warning(lexer_.getSourceName(), src_line,
@@ -166,8 +167,10 @@ private:
}
}
- // Set/reset the default TTL. Either from $TTL or SOA minimum TTL.
- // see LimitTTL() for parameter post_parsing.
+ // Set/reset the default TTL. This should be from either $TTL or SOA
+ // minimum TTL (it's the caller's responsibility; this method doesn't
+ // care about where it comes from). see LimitTTL() for parameter
+ // post_parsing.
void setDefaultTTL(const RRTTL& ttl, bool post_parsing) {
if (!default_ttl_) {
default_ttl_.reset(new RRTTL(ttl));
@@ -177,16 +180,6 @@ private:
limitTTL(*default_ttl_, post_parsing);
}
- // Set/reset the TTL currently being used. This can be used the last
- // resort TTL when no other TTL is known for an RR.
- void setCurrentTTL(const RRTTL& ttl) {
- if (!current_ttl_) {
- current_ttl_.reset(new RRTTL(ttl));
- } else {
- *current_ttl_ = ttl;
- }
- }
-
// Try to set/reset the current TTL from candidate TTL text. It's possible
// it does not actually represent a TTL (which is not immediately
// considered an error). Return true iff it's recognized as a valid TTL
@@ -195,11 +188,9 @@ private:
// We use the factory version instead of RRTTL constructor as we
// need to expect cases where ttl_txt does not actually represent a TTL
// but an RR class or type.
- RRTTL* ttl = RRTTL::createFromText(ttl_txt, current_ttl_.get());
- if (ttl != NULL) {
- if (!current_ttl_) {
- current_ttl_.reset(ttl);
- }
+ const MaybeRRTTL maybe_ttl = RRTTL::createFromText(ttl_txt);
+ if (maybe_ttl) {
+ current_ttl_ = maybe_ttl;
limitTTL(*current_ttl_, false);
return (true);
}
@@ -230,7 +221,7 @@ private:
dynamic_cast<const rdata::generic::SOA&>(*rdata).
getMinimum();
setDefaultTTL(RRTTL(ttl_val), true);
- setCurrentTTL(*default_ttl_);
+ current_ttl_ = *default_ttl_;
} else {
// On catching the exception we'll try to reach EOL again,
// so we need to unget it now.
@@ -239,12 +230,13 @@ private:
"no TTL specified; load rejected");
}
} else if (!explicit_ttl && default_ttl_) {
- setCurrentTTL(*default_ttl_);
+ current_ttl_ = *default_ttl_;
} else if (!explicit_ttl && warn_rfc1035_ttl_) {
// Omitted (class and) TTL values are default to the last
// explicitly stated values (RFC 1035, Sec. 5.1).
callbacks_.warning(lexer_.getSourceName(), current_line,
- "using RFC1035 TTL semantics");
+ "using RFC1035 TTL semantics; default to the "
+ "last explicitly stated TTL");
warn_rfc1035_ttl_ = false; // we only warn about this once
}
assert(current_ttl_);
@@ -297,11 +289,6 @@ private:
}
private:
- // RFC2181 Section 8 specifies TTLs are unsigned 32-bit integer,
- // effectively limiting the maximum value to 2^32-1. This constant
- // represent a TTL of the max value.
- const RRTTL MAX_TTL;
-
MasterLexer lexer_;
const Name zone_origin_;
const RRClass zone_class_;
@@ -310,9 +297,8 @@ private:
boost::scoped_ptr<RRTTL> default_ttl_; // Default TTL of RRs used when
// unspecified. If NULL no default
// is known.
- boost::scoped_ptr<RRTTL> current_ttl_; // The TTL used most recently.
- // Initially set to NULL. Once set
- // always non NULL.
+ MaybeRRTTL current_ttl_; // The TTL used most recently. Initially unset.
+ // Once set always stores a valid RRTTL.
const MasterLoader::Options options_;
const std::string master_file_;
std::string string_token_;
diff --git a/src/lib/dns/rrttl.cc b/src/lib/dns/rrttl.cc
index d0ae576..e7f8441 100644
--- a/src/lib/dns/rrttl.cc
+++ b/src/lib/dns/rrttl.cc
@@ -59,7 +59,7 @@ namespace dns {
namespace {
bool
-parseTTLStr(const string& ttlstr, uint32_t& ttlval, string* error_txt) {
+parseTTLString(const string& ttlstr, uint32_t& ttlval, string* error_txt) {
if (ttlstr.empty()) {
if (error_txt != NULL) {
*error_txt = "Empty TTL string";
@@ -161,22 +161,18 @@ parseTTLStr(const string& ttlstr, uint32_t& ttlval, string* error_txt) {
RRTTL::RRTTL(const std::string& ttlstr) {
string error_txt;
- if (!parseTTLStr(ttlstr, ttlval_, &error_txt)) {
+ if (!parseTTLString(ttlstr, ttlval_, &error_txt)) {
isc_throw(InvalidRRTTL, error_txt);
}
}
-RRTTL*
-RRTTL::createFromText(const string& ttlstr, RRTTL* placeholder) {
+MaybeRRTTL
+RRTTL::createFromText(const string& ttlstr) {
uint32_t ttlval;
- if (parseTTLStr(ttlstr, ttlval, NULL)) {
- if (placeholder != NULL) {
- *placeholder = RRTTL(ttlval);
- return (placeholder);
- }
- return (new RRTTL(ttlval));
+ if (parseTTLString(ttlstr, ttlval, NULL)) {
+ return (MaybeRRTTL(ttlval));
}
- return (NULL);
+ return (MaybeRRTTL());
}
RRTTL::RRTTL(InputBuffer& buffer) {
diff --git a/src/lib/dns/rrttl.h b/src/lib/dns/rrttl.h
index 4c32c89..ed51206 100644
--- a/src/lib/dns/rrttl.h
+++ b/src/lib/dns/rrttl.h
@@ -15,10 +15,12 @@
#ifndef RRTTL_H
#define RRTTL_H 1
-#include <stdint.h>
-
#include <exceptions/exceptions.h>
+#include <boost/optional.hpp>
+
+#include <stdint.h>
+
namespace isc {
namespace util {
class InputBuffer;
@@ -30,6 +32,16 @@ namespace dns {
// forward declarations
class AbstractMessageRenderer;
+class RRTTL; // forward declaration to define MaybeRRTTL
+
+/// \brief A shortcut for a compound type to represent RRTTL-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 RRTTL object.
+/// And, if it contains a valid RRTTL object, its value is accessible
+/// using \c operator*, just like a bare pointer to \c RRTTL.
+typedef boost::optional<RRTTL> MaybeRRTTL;
+
///
/// \brief A standard DNS module exception that is thrown if an RRTTL object
/// is being constructed from an unrecognized string.
@@ -104,31 +116,35 @@ public:
/// A separate factory of RRTTL 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 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.
- ///
- /// When the \c placeholder parameter is NULL, it creates a new RRTTL
- /// object, allocating memory for it; the caller is responsible for
- /// releasing the memory using the \c delete operator. If \c placeholder
- /// is non NULL, it will override the placeholder object with an RRTTL
- /// corresponding to the given text and return a pointer to the placeholder
- /// object. This way, the caller can also minimize the overhead of memory
- /// allocation if it needs to call this method many times.
- ///
- /// If the given text does not represent a valid RRTTL, it returns NULL;
- /// if \c placeholder is non NULL, it will be intact.
+ /// 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.
+ ///
+ /// If the given text represents a valid RRTTL, it returns a \c MaybeRRTTL
+ /// object that stores a corresponding \c RRTTL 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 RRTTL, it returns a \c MaybeRRTTL 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 TTL. For this
+ /// reason this function intentionally omits the capability of delivering
+ /// details 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 InvalidRRTTL exception.
///
/// \param ttlstr A string representation of the \c RRTTL.
- /// \param placeholder If non NULL, an RRTTL object to be overridden
- /// with an RRTTL for \c ttlstr.
- /// \return A pointer to the created or overridden RRTTL object.
- static RRTTL* createFromText(const std::string& ttlstr,
- RRTTL* placeholder);
+ /// \return An MaybeRRTTL object either storing an RRTTL object for
+ /// the given text or a \c false value.
+ static MaybeRRTTL createFromText(const std::string& ttlstr);
///
//@}
@@ -267,6 +283,22 @@ public:
{ return (ttlval_ > other.ttlval_); }
//@}
+ ///
+ /// \name Protocol constants
+ ///
+ //@{
+ /// \brief The TTL of the max allowable value, per RFC2181 Section 8.
+ ///
+ /// The max value is the largest unsigned 31 bit integer, 2^31-1.
+ ///
+ /// \note At the moment an RRTTL object can have a value larger than
+ /// this limit. We may revisit it in a future version.
+ static const RRTTL MAX() {
+ static const RRTTL max_ttl(0x7fffffff);
+ return (max_ttl);
+ }
+ //@}
+
private:
uint32_t ttlval_;
};
diff --git a/src/lib/dns/tests/rrttl_unittest.cc b/src/lib/dns/tests/rrttl_unittest.cc
index cd8f8a5..4c0ff4d 100644
--- a/src/lib/dns/tests/rrttl_unittest.cc
+++ b/src/lib/dns/tests/rrttl_unittest.cc
@@ -88,22 +88,14 @@ TEST_F(RRTTLTest, fromText) {
}
TEST_F(RRTTLTest, createFromText) {
- // If placeholder is NULL, a new RRTTL object is allocated
- boost::scoped_ptr<RRTTL> ttl_ptr;
- ttl_ptr.reset(RRTTL::createFromText("3600", NULL));
- ASSERT_TRUE(ttl_ptr);
- EXPECT_EQ(RRTTL(3600), *ttl_ptr);
-
- // If placeholder is non NULL, it will be overwritten
- RRTTL ttl(3600);
- EXPECT_NE(static_cast<RRTTL*>(NULL), RRTTL::createFromText("1800", &ttl));
- EXPECT_EQ(RRTTL(1800), ttl);
-
- // If text parsing fails, NULL is returned; if placeholder is given,
- // it will be intact.
- EXPECT_EQ(static_cast<RRTTL*>(NULL), RRTTL::createFromText("bad", NULL));
- EXPECT_EQ(static_cast<RRTTL*>(NULL), RRTTL::createFromText("bad", &ttl));
- EXPECT_EQ(RRTTL(1800), ttl);
+ // It returns an actual RRTT iff the given text is recognized as a
+ // valid RR TTL.
+ MaybeRRTTL maybe_ttl = RRTTL::createFromText("3600");
+ EXPECT_TRUE(maybe_ttl);
+ EXPECT_EQ(RRTTL(3600), *maybe_ttl);
+
+ maybe_ttl = RRTTL::createFromText("bad");
+ EXPECT_FALSE(maybe_ttl);
}
void
@@ -273,6 +265,10 @@ TEST_F(RRTTLTest, gthan) {
EXPECT_FALSE(ttl_small > ttl_large);
}
+TEST_F(RRTTLTest, maxTTL) {
+ EXPECT_EQ((1 << 31) - 1, RRTTL::MAX().getValue());
+}
+
// test operator<<. We simply confirm it appends the result of toText().
TEST_F(RRTTLTest, LeftShiftOperator) {
ostringstream oss;
More information about the bind10-changes
mailing list