[svn] commit: r2794 - in /branches/trac311: ./ src/bin/auth/ src/bin/auth/tests/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/tests/ src/lib/dns/tests/testdata/ src/lib/exceptions/
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Aug 24 18:44:00 UTC 2010
Author: jinmei
Date: Tue Aug 24 18:44:00 2010
New Revision: 2794
Log:
an initial cut of the EDNS class (code + tests), mainly for backup.
Added:
branches/trac311/src/lib/dns/edns.cc (with props)
branches/trac311/src/lib/dns/edns.h (with props)
branches/trac311/src/lib/dns/python/edns_python.cc (with props)
branches/trac311/src/lib/dns/python/tests/edns_python_test.py (with props)
branches/trac311/src/lib/dns/tests/edns_unittest.cc (with props)
branches/trac311/src/lib/dns/tests/testdata/edns_toWire1.spec
branches/trac311/src/lib/dns/tests/testdata/edns_toWire2.spec
branches/trac311/src/lib/dns/tests/testdata/edns_toWire3.spec
branches/trac311/src/lib/dns/tests/testdata/edns_toWire4.spec
Modified:
branches/trac311/configure.ac
branches/trac311/src/bin/auth/auth_srv.cc
branches/trac311/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac311/src/lib/dns/Makefile.am
branches/trac311/src/lib/dns/message.cc
branches/trac311/src/lib/dns/message.h
branches/trac311/src/lib/dns/python/Makefile.am
branches/trac311/src/lib/dns/python/libdns_python.cc
branches/trac311/src/lib/dns/python/message_python.cc
branches/trac311/src/lib/dns/python/messagerenderer_python.cc
branches/trac311/src/lib/dns/python/rdata_python.cc
branches/trac311/src/lib/dns/python/tests/Makefile.am
branches/trac311/src/lib/dns/python/tests/message_python_test.py
branches/trac311/src/lib/dns/python/tests/question_python_test.py
branches/trac311/src/lib/dns/tests/Makefile.am
branches/trac311/src/lib/dns/tests/message_unittest.cc
branches/trac311/src/lib/dns/tests/run_unittests.cc
branches/trac311/src/lib/exceptions/exceptions.h
Modified: branches/trac311/configure.ac
==============================================================================
--- branches/trac311/configure.ac (original)
+++ branches/trac311/configure.ac Tue Aug 24 18:44:00 2010
@@ -452,6 +452,7 @@
src/lib/config/testdata/Makefile
src/lib/dns/Makefile
src/lib/dns/tests/Makefile
+ src/lib/dns/tests/testdata/Makefile
src/lib/dns/python/Makefile
src/lib/dns/python/tests/Makefile
src/lib/exceptions/Makefile
Modified: branches/trac311/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac311/src/bin/auth/auth_srv.cc (original)
+++ branches/trac311/src/bin/auth/auth_srv.cc Tue Aug 24 18:44:00 2010
@@ -24,6 +24,7 @@
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
+#include <dns/edns.h>
#include <dns/exceptions.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
@@ -164,7 +165,6 @@
message.setQid(qid);
message.setOpcode(opcode);
message.setHeaderFlag(MessageFlag::QR());
- message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
if (rd) {
message.setHeaderFlag(MessageFlag::RD());
}
@@ -292,14 +292,21 @@
AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
MessageRenderer& response_renderer)
{
- const bool dnssec_ok = message.isDNSSECSupported();
- const uint16_t remote_bufsize = message.getUDPSize();
+ ConstEDNSPtr remote_edns = message.getEDNS();
+ const bool dnssec_ok = remote_edns && remote_edns->isDNSSECSupported();
+ const uint16_t remote_bufsize = remote_edns ? remote_edns->getUDPSize() :
+ Message::DEFAULT_MAX_UDPSIZE;
message.makeResponse();
message.setHeaderFlag(MessageFlag::AA());
message.setRcode(Rcode::NOERROR());
- message.setDNSSECSupported(dnssec_ok);
- message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+
+ if (remote_edns) {
+ EDNSPtr local_edns = EDNSPtr(new EDNS());
+ local_edns->setDNSSECSupported(dnssec_ok);
+ local_edns->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+ message.setEDNS(local_edns);
+ }
try {
Query query(message, cache_, dnssec_ok);
Modified: branches/trac311/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac311/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac311/src/bin/auth/tests/auth_srv_unittest.cc Tue Aug 24 18:44:00 2010
@@ -444,13 +444,20 @@
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
- // The response must have an EDNS OPT RR in the additional section.
+ // The response must have an EDNS OPT RR in the additional section, but
+ // it will be added automatically at the render time.
// Note that the DNSSEC DO bit is cleared even if this bit in the query
// is set. This is a limitation of the current implementation.
headerCheck(parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
QR_FLAG, 1, 0, 0, 1);
- EXPECT_EQ(4096, parse_message.getUDPSize());
- EXPECT_FALSE(parse_message.isDNSSECSupported());
+ EXPECT_FALSE(parse_message.getEDNS()); // EDNS isn't added at this point
+
+ parse_message.clear(Message::PARSE);
+ InputBuffer ib(response_renderer.getData(), response_renderer.getLength());
+ parse_message.fromWire(ib);
+ EXPECT_EQ(Rcode::BADVERS(), parse_message.getRcode());
+ EXPECT_TRUE(parse_message.getEDNS());
+ EXPECT_FALSE(parse_message.getEDNS()->isDNSSECSupported());
}
TEST_F(AuthSrvTest, AXFROverUDP) {
Modified: branches/trac311/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac311/src/lib/dns/Makefile.am (original)
+++ branches/trac311/src/lib/dns/Makefile.am Tue Aug 24 18:44:00 2010
@@ -63,6 +63,7 @@
libdns___la_SOURCES += util/base16_from_binary.h util/binary_from_base16.h
libdns___la_SOURCES += buffer.h
libdns___la_SOURCES += dnssectime.h dnssectime.cc
+libdns___la_SOURCES += edns.h edns.cc
libdns___la_SOURCES += exceptions.h exceptions.cc
libdns___la_SOURCES += util/hex.h
libdns___la_SOURCES += message.h message.cc
Modified: branches/trac311/src/lib/dns/message.cc
==============================================================================
--- branches/trac311/src/lib/dns/message.cc (original)
+++ branches/trac311/src/lib/dns/message.cc Tue Aug 24 18:44:00 2010
@@ -28,6 +28,7 @@
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
+#include <dns/edns.h>
#include <dns/exceptions.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
@@ -64,10 +65,7 @@
//
// EDNS related constants
//
-const flags_t EXTFLAG_MASK = 0xffff;
-const flags_t EXTFLAG_DO = 0x8000;
const uint32_t EXTRCODE_MASK = 0xff000000;
-const uint32_t EDNSVERSION_MASK = 0x00ff0000;
const unsigned int OPCODE_MASK = 0x7800;
const unsigned int OPCODE_SHIFT = 11;
@@ -167,10 +165,34 @@
return (opcodetext[code_]);
}
-Rcode::Rcode(uint16_t code) : code_(code) {
+namespace {
+// 0 3 11 15
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |UNUSED | EXTENDED-RCODE | RCODE |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// <= EXTRCODE_SHIFT
+const unsigned int EXTRCODE_SHIFT = 4;
+}
+
+Rcode::Rcode(const uint16_t code) : code_(code) {
if (code_ > MAX_RCODE) {
- isc_throw(OutOfRange, "Rcode is too large to construct");
- }
+ isc_throw(OutOfRange, "Rcode is too large to construct: " << code_);
+ }
+}
+
+Rcode::Rcode(const uint8_t code, const uint8_t extended_code) :
+ code_((extended_code << EXTRCODE_SHIFT) | (code & RCODE_MASK))
+{
+ if (code > RCODE_MASK) {
+ isc_throw(OutOfRange,
+ "Base Rcode is too large to construct: "
+ << static_cast<unsigned int>(code));
+ }
+}
+
+uint8_t
+Rcode::getExtendedCode() const {
+ return (code_ >> EXTRCODE_SHIFT);
}
string
@@ -203,17 +225,13 @@
Rcode rcode_;
const Opcode* opcode_;
flags_t flags_;
- bool dnssec_ok_;
bool header_parsed_;
static const unsigned int SECTION_MAX = 4; // TODO: revisit this design
int counts_[SECTION_MAX]; // TODO: revisit this definition
vector<QuestionPtr> questions_;
vector<RRsetPtr> rrsets_[SECTION_MAX];
- RRsetPtr remote_edns_;
- uint16_t remote_udpsize_;
- RRsetPtr local_edns_;
- uint16_t udpsize_;
+ ConstEDNSPtr edns_;
#ifdef notyet
// tsig/sig0: TODO
@@ -237,11 +255,7 @@
qid_ = 0;
rcode_ = Rcode::NOERROR(); // XXX
opcode_ = NULL;
- dnssec_ok_ = false;
- remote_edns_ = RRsetPtr();
- remote_udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
- local_edns_ = RRsetPtr();
- udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
+ edns_ = EDNSPtr();
for (int i = 0; i < SECTION_MAX; ++i) {
counts_[i] = 0;
@@ -285,38 +299,6 @@
impl_->flags_ &= ~flag.getBit();
}
-bool
-Message::isDNSSECSupported() const {
- return (impl_->dnssec_ok_);
-}
-
-void
-Message::setDNSSECSupported(bool on) {
- if (impl_->mode_ != Message::RENDER) {
- isc_throw(InvalidMessageOperation,
- "setDNSSECSupported performed in non-render mode");
- }
- impl_->dnssec_ok_ = on;
-}
-
-uint16_t
-Message::getUDPSize() const {
- return (impl_->udpsize_);
-}
-
-void
-Message::setUDPSize(uint16_t size) {
- if (impl_->mode_ != Message::RENDER) {
- isc_throw(InvalidMessageOperation,
- "setUDPSize performed in non-render mode");
- }
- if (size < DEFAULT_MAX_UDPSIZE) {
- isc_throw(InvalidMessageUDPSize,
- "Specified UDP message size is too small");
- }
- impl_->udpsize_ = size;
-}
-
qid_t
Message::getQid() const {
return (impl_->qid_);
@@ -357,6 +339,20 @@
"setOpcode performed in non-render mode");
}
impl_->opcode_ = &opcode;
+}
+
+ConstEDNSPtr
+Message::getEDNS() const {
+ return (impl_->edns_);
+}
+
+void
+Message::setEDNS(ConstEDNSPtr edns) {
+ if (impl_->mode_ != Message::RENDER) {
+ isc_throw(InvalidMessageOperation,
+ "setEDNS performed in non-render mode");
+ }
+ impl_->edns_ = edns;
}
unsigned int
@@ -441,54 +437,6 @@
};
}
-namespace {
-bool
-addEDNS(MessageImpl* mimpl, MessageRenderer& renderer) {
- const bool is_query = ((mimpl->flags_ & MessageFlag::QR().getBit()) == 0);
-
- // If this is a reply, add EDNS either when the request had it, or
- // if the Rcode is BADVERS, which is EDNS specific.
- // XXX: this logic is tricky. We should revisit this later.
- if (!is_query) {
- if (mimpl->remote_edns_ == NULL && mimpl->rcode_ != Rcode::BADVERS()) {
- return (false);
- }
- } else {
- // For queries, we add EDNS only when necessary:
- // Local UDP size is not the default value, or
- // DNSSEC DO bit is to be set, or
- // Extended Rcode is to be specified.
- if (mimpl->udpsize_ == Message::DEFAULT_MAX_UDPSIZE &&
- !mimpl->dnssec_ok_ &&
- mimpl->rcode_.getCode() < 0x10) {
- return (false);
- }
- }
-
- // If adding the OPT RR would exceed the size limit, don't do it.
- // 11 = len(".") + type(2byte) + class(2byte) + TTL(4byte) + RDLEN(2byte)
- // (RDATA is empty in this simple implementation)
- if (renderer.getLength() + 11 > renderer.getLengthLimit()) {
- return (false);
- }
-
- // Render EDNS OPT RR
- uint32_t extrcode_flags = ((mimpl->rcode_.getCode() & 0xff0) << 24);
- if (mimpl->dnssec_ok_) {
- extrcode_flags |= 0x8000; // set DO bit
- }
- mimpl->local_edns_ = RRsetPtr(new RRset(Name::ROOT_NAME(),
- RRClass(mimpl->udpsize_),
- RRType::OPT(),
- RRTTL(extrcode_flags)));
- // We don't support any options in this simple implementation
- mimpl->local_edns_->addRdata(ConstRdataPtr(new generic::OPT()));
- mimpl->local_edns_->toWire(renderer);
-
- return (true);
-}
-}
-
void
Message::toWire(MessageRenderer& renderer) {
if (impl_->mode_ != Message::RENDER) {
@@ -528,12 +476,20 @@
RenderSection<RRsetPtr>(renderer, false)).getTotalCount();
}
- // Added EDNS OPT RR if necessary (we want to avoid hardcoding specialized
- // logic, see the parser case)
- if (!renderer.isTruncated() && addEDNS(this->impl_, renderer)) {
- ++arcount;
- }
-
+ // Add EDNS OPT RR if necessary. Basically, we add it only when EDNS
+ // has been explicitly set. However, if the RCODE would require it and
+ // no EDNS has been set we generate a temporary local EDNS and use it.
+ if (!renderer.isTruncated()) {
+ ConstEDNSPtr local_edns = this->impl_->edns_;
+ if (!local_edns && impl_->rcode_.getExtendedCode() != 0) {
+ local_edns = ConstEDNSPtr(new EDNS());
+ }
+ if (local_edns) {
+ arcount += local_edns->toWire(renderer,
+ impl_->rcode_.getExtendedCode());
+ }
+ }
+
// Adjust the counter buffer.
// XXX: these may not be equal to the number of corresponding entries
// in rrsets_[] or questions_ if truncation occurred or an EDNS OPT RR
@@ -657,6 +613,34 @@
};
}
+// Note about design decision:
+// we need some type specific processing here, including EDNS and TSIG.
+// how much we should generalize/hardcode the special logic is subject
+// to discussion. In terms of modularity it would be ideal to introduce
+// an abstract class (say "MessageAttribute") and let other such
+// concrete notions as EDNS or TSIG inherit from it. Then we would
+// just do:
+// message->addAttribute(rrtype, rrclass, buffer);
+// to create and attach type-specific concrete object to the message.
+//
+// A major downside of this approach is, as usual, complexity due to
+// indirection and performance penalty. Also, it may not be so easy
+// to separate the processing logic because in many cases we'll need
+// parse context for which the message class is responsible (e.g.
+// to check the EDNS OPT RR only appears in the additional section,
+// and appears only once).
+//
+// Another point to consider is that we may not need so many special
+// types other than EDNS and TSIG (and when and if we implement it,
+// SIG(0)); newer optional attributes of the message would more likely
+// be standardized as new flags or options of EDNS. If that's the case,
+// introducing an abstract class with all the overhead and complexity
+// may not make much sense.
+//
+// Conclusion: don't over-generalize type-specific logic for now.
+// introduce separate concrete classes, and move context-independent
+// logic to that class; processing logic dependent on parse context
+// is hardcoded here.
int
MessageImpl::parseSection(const Section& section, InputBuffer& buffer) {
unsigned int added = 0;
@@ -678,60 +662,36 @@
const size_t rdlen = buffer.readUint16();
ConstRdataPtr rdata = createRdata(rrtype, rrclass, buffer, rdlen);
- // XXX: we wanted to avoid hardcoding type-specific logic here,
- // but this would be the fastest way for a proof-of-concept
- // implementation. We'll revisit this part later.
if (rrtype == RRType::OPT()) {
if (section != Section::ADDITIONAL()) {
isc_throw(DNSMessageFORMERR,
"EDNS OPT RR found in an invalid section");
}
- if (remote_edns_ != NULL) {
+ if (edns_) {
isc_throw(DNSMessageFORMERR, "multiple EDNS OPT RR found");
}
- if (((ttl.getValue() & EDNSVERSION_MASK) >> 16) >
- Message::EDNS_SUPPORTED_VERSION) {
- // XXX: we should probably not reject the message yet, because
- // it's better to let the requestor know the responder-side
- // highest version as indicated in Section 4.6 of RFC2671.
- // This is probably because why BIND 9 does the version check
- // in the client code.
- // This is a TODO item. Right now we simply reject it.
- const unsigned int ver =
- (ttl.getValue() & EDNSVERSION_MASK) >> 16;
- isc_throw(DNSMessageBADVERS, "unsupported EDNS version: " <<
- ver);
+
+ uint8_t extended_rcode;
+ edns_ = ConstEDNSPtr(createEDNSFromRR(name, rrclass, rrtype, ttl,
+ *rdata, extended_rcode));
+ rcode_ = Rcode(rcode_.getCode(), extended_rcode);
+ continue;
+ } else {
+ vector<RRsetPtr>::iterator it =
+ find_if(rrsets_[sectionCodeToId(section)].begin(),
+ rrsets_[sectionCodeToId(section)].end(),
+ MatchRR(name, rrtype, rrclass));
+ if (it != rrsets_[sectionCodeToId(section)].end()) {
+ (*it)->setTTL(min((*it)->getTTL(), ttl));
+ (*it)->addRdata(rdata);
+ } else {
+ RRsetPtr rrset =
+ RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
+ rrset->addRdata(rdata);
+ rrsets_[sectionCodeToId(section)].push_back(rrset);
}
- if (name != Name::ROOT_NAME()) {
- isc_throw(DNSMessageFORMERR,
- "invalid owner name for EDNS OPT RR");
- }
-
- remote_edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
- remote_edns_->addRdata(rdata);
-
- dnssec_ok_ = (((ttl.getValue() & EXTFLAG_MASK) & EXTFLAG_DO) != 0);
- if (rrclass.getCode() > Message::DEFAULT_MAX_UDPSIZE) {
- udpsize_ = rrclass.getCode();
- }
- rcode_ = Rcode(((ttl.getValue() & EXTRCODE_MASK) >> 20) |
- rcode_.getCode());
- continue;
+ ++added;
}
-
- vector<RRsetPtr>::iterator it =
- find_if(rrsets_[sectionCodeToId(section)].begin(),
- rrsets_[sectionCodeToId(section)].end(),
- MatchRR(name, rrtype, rrclass));
- if (it != rrsets_[sectionCodeToId(section)].end()) {
- (*it)->setTTL(min((*it)->getTTL(), ttl));
- (*it)->addRdata(rdata);
- } else {
- RRsetPtr rrset = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
- rrset->addRdata(rdata);
- rrsets_[sectionCodeToId(section)].push_back(rrset);
- }
- ++added;
}
return (added);
@@ -786,30 +746,13 @@
lexical_cast<string>(impl_->counts_[Section::AUTHORITY().getCode()]);
unsigned int arcount = impl_->counts_[Section::ADDITIONAL().getCode()];
- RRsetPtr edns_rrset;
- if (!getHeaderFlag(MessageFlag::QR()) && impl_->remote_edns_ != NULL) {
- edns_rrset = impl_->remote_edns_;
+ if (impl_->edns_ != NULL) {
++arcount;
}
s += ", ADDITIONAL: " + lexical_cast<string>(arcount) + "\n";
- if (edns_rrset != NULL) {
- s += "\n;; OPT PSEUDOSECTION:\n";
- s += "; EDNS: version: ";
- s += lexical_cast<string>(
- (edns_rrset->getTTL().getValue() & 0x00ff0000) >> 16);
- s += ", flags:";
- if ((edns_rrset->getTTL().getValue() & 0x8000) != 0) {
- s += " do";
- }
- const uint32_t mbz = edns_rrset->getTTL().getValue() & ~0x8000 & 0xffff;
- if (mbz != 0) {
- s += "; MBZ: " + lexical_cast<string>(mbz) + ", udp: ";
- } else {
- s += "; udp: " +
- lexical_cast<string>(edns_rrset->getClass().getCode());
- }
- s += "\n";
+ if (impl_->edns_ != NULL) {
+ s += impl_->edns_->toText();
}
if (!impl_->questions_.empty()) {
@@ -860,11 +803,7 @@
impl_->mode_ = Message::RENDER;
- impl_->dnssec_ok_ = false;
- impl_->remote_udpsize_ = impl_->udpsize_;
- impl_->local_edns_ = RRsetPtr();
- impl_->udpsize_ = DEFAULT_MAX_UDPSIZE;
-
+ impl_->edns_ = EDNSPtr();
impl_->flags_ &= MESSAGE_REPLYPRESERVE;
setHeaderFlag(MessageFlag::QR());
Modified: branches/trac311/src/lib/dns/message.h
==============================================================================
--- branches/trac311/src/lib/dns/message.h (original)
+++ branches/trac311/src/lib/dns/message.h Tue Aug 24 18:44:00 2010
@@ -25,6 +25,7 @@
#include <exceptions/exceptions.h>
+#include <dns/edns.h>
#include <dns/question.h>
#include <dns/rrset.h>
@@ -314,8 +315,10 @@
/// Constant objects are defined for standard flags.
class Rcode {
public:
- Rcode(uint16_t code);
+ Rcode(const uint16_t code);
+ Rcode(const uint8_t code, const uint8_t extended_code);
uint16_t getCode() const { return (code_); }
+ uint8_t getExtendedCode() const;
bool operator==(const Rcode& other) const { return (code_ == other.code_); }
bool operator!=(const Rcode& other) const { return (code_ != other.code_); }
std::string toText() const;
@@ -627,45 +630,6 @@
/// \c setHeaderFlag() with an additional argument.
void clearHeaderFlag(const MessageFlag& flag);
- /// \brief Return whether the message sender indicates DNSSEC is supported.
- /// If EDNS is included, this corresponds to the value of the DO bit.
- /// Otherwise, DNSSEC is considered not supported.
- bool isDNSSECSupported() const;
-
- /// \brief Specify whether DNSSEC is supported in the message.
- ///
- /// Only allowed in the \c RENDER mode.
- /// If EDNS is included in the message, the DO bit is set or cleared
- /// according to the specified value of this method.
- void setDNSSECSupported(bool on);
-
- /// \brief Return the maximum buffer size of UDP messages for the sender
- /// of the message.
- ///
- /// The semantics of this value is different based on the mode:
- /// In the \c PARSE mode, it means the buffer size of the remote node;
- /// in the \c RENDER mode, it means the buffer size of the local node.
- ///
- /// In either case, its value is the value of the UDP payload size field
- /// of EDNS (when it's included) or \c DEFAULT_MAX_UDPSIZE.
- ///
- /// Note: this interface may be confusing and may have to be revisited.
- uint16_t getUDPSize() const;
-
- /// \brief Specify the maximum buffer size of UDP messages of the local
- /// node.
- ///
- /// Only allowed in the \c RENDER mode.
- /// If EDNS OPT RR is included in the message, its UDP payload size field
- /// will be set to the specified value.
- ///
- /// Unless explicitly specified, \c DEFAULT_MAX_UDPSIZE will be assumed
- /// for the maximum buffer size, regardless of whether EDNS OPT RR is
- /// included or not. This means if an application wants to send a message
- /// with an EDNS OPT RR for specifying a larger UDP size, it must explicitly
- /// specify the value using this method.
- void setUDPSize(uint16_t size);
-
/// \brief Return the query ID given in the header section of the message.
qid_t getQid() const;
@@ -696,6 +660,14 @@
///
/// Only allowed in the \c RENDER mode.
void setOpcode(const Opcode& opcode);
+
+ /// \brief TBD
+ ConstEDNSPtr getEDNS() const;
+
+ /// \brief TBD
+ ///
+ /// Only allowed in the \c RENDER mode.
+ void setEDNS(ConstEDNSPtr edns);
/// \brief Returns the number of RRs contained in the given section.
unsigned int getRRCount(const Section& section) const;
Modified: branches/trac311/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac311/src/lib/dns/python/Makefile.am (original)
+++ branches/trac311/src/lib/dns/python/Makefile.am Tue Aug 24 18:44:00 2010
@@ -1,8 +1,11 @@
SUBDIRS = tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
if USE_GXX
-AM_CPPFLAGS += -Wno-write-strings
+AM_CXXFLAGS += -Wno-write-strings
endif
#lib_LTLIBRARIES = libdns_python_name.la libdns_python_rrset.la
@@ -19,6 +22,7 @@
# directly included from source files, so these don't have their own
# rules
EXTRA_DIST = libdns_python_common.h
+EXTRA_DIST += edns_python.h
EXTRA_DIST += messagerenderer_python.cc
EXTRA_DIST += message_python.cc
EXTRA_DIST += rrclass_python.cc
Modified: branches/trac311/src/lib/dns/python/libdns_python.cc
==============================================================================
--- branches/trac311/src/lib/dns/python/libdns_python.cc (original)
+++ branches/trac311/src/lib/dns/python/libdns_python.cc Tue Aug 24 18:44:00 2010
@@ -40,8 +40,9 @@
#include <dns/python/libdns_python_common.h>
-// For our 'general' isc::Exception
+// For our 'general' isc::Exceptions
static PyObject* po_IscException;
+static PyObject* po_InvalidParameter;
// order is important here!
#include <dns/python/messagerenderer_python.cc>
@@ -54,6 +55,7 @@
#include <dns/python/question_python.cc> // needs RRClass, RRType, RRTTL,
// Name
#include <dns/python/message_python.cc> // needs RRset, Question
+#include <dns/python/edns_python.cc> // needs Messagerenderer, Rcode
//
// Definition of the module
@@ -81,8 +83,14 @@
return (NULL);
}
- po_IscException = PyErr_NewException("libdns_python.IscException", NULL, NULL);
+ po_IscException = PyErr_NewException("libdns_python.IscException", NULL,
+ NULL);
PyModule_AddObject(mod, "IscException", po_IscException);
+
+ // Add the exceptions to the class
+ po_InvalidParameter = PyErr_NewException("libdns_python.InvalidParameter",
+ NULL, NULL);
+ PyModule_AddObject(mod, "InvalidParameter", po_InvalidParameter);
// for each part included above, we call its specific initializer
@@ -122,6 +130,10 @@
return (NULL);
}
+ if (!initModulePart_EDNS(mod)) {
+ return (NULL);
+ }
+
return (mod);
}
Modified: branches/trac311/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac311/src/lib/dns/python/message_python.cc (original)
+++ branches/trac311/src/lib/dns/python/message_python.cc Tue Aug 24 18:44:00 2010
@@ -120,7 +120,6 @@
0 // tp_version_tag
};
-
static int
MessageFlag_init(s_MessageFlag* self UNUSED_PARAM,
PyObject* args UNUSED_PARAM)
@@ -486,6 +485,7 @@
static void Rcode_destroy(s_Rcode* self);
static PyObject* Rcode_getCode(s_Rcode* self);
+static PyObject* Rcode_getExtendedCode(const s_Rcode* self);
static PyObject* Rcode_toText(s_Rcode* self);
static PyObject* Rcode_str(PyObject* self);
static PyObject* Rcode_NOERROR(s_Rcode* self);
@@ -509,6 +509,9 @@
static PyMethodDef Rcode_methods[] = {
{ "get_code", reinterpret_cast<PyCFunction>(Rcode_getCode), METH_NOARGS, "Returns the code value" },
+ { "get_extended_code",
+ reinterpret_cast<PyCFunction>(Rcode_getExtendedCode),
+ METH_NOARGS, "Returns the extended code value." },
{ "to_text", reinterpret_cast<PyCFunction>(Rcode_toText), METH_NOARGS, "Returns the text representation" },
{ "NOERROR", reinterpret_cast<PyCFunction>(Rcode_NOERROR), METH_NOARGS | METH_STATIC, "Creates a NOERROR Rcode" },
{ "FORMERR", reinterpret_cast<PyCFunction>(Rcode_FORMERR), METH_NOARGS | METH_STATIC, "Creates a FORMERR Rcode" },
@@ -617,6 +620,11 @@
}
static PyObject*
+Rcode_getExtendedCode(const s_Rcode* self) {
+ return (Py_BuildValue("B", self->rcode->getExtendedCode()));
+}
+
+static PyObject*
Rcode_toText(s_Rcode* self) {
return (Py_BuildValue("s", self->rcode->toText().c_str()));
}
@@ -973,10 +981,6 @@
static PyObject* Message_getHeaderFlag(s_Message* self, PyObject* args);
static PyObject* Message_setHeaderFlag(s_Message* self, PyObject* args);
static PyObject* Message_clearHeaderFlag(s_Message* self, PyObject* args);
-static PyObject* Message_isDNSSECSupported(s_Message* self);
-static PyObject* Message_setDNSSECSupported(s_Message* self, PyObject* args);
-static PyObject* Message_getUDPSize(s_Message* self);
-static PyObject* Message_setUDPSize(s_Message* self, PyObject* args);
static PyObject* Message_getQid(s_Message* self);
static PyObject* Message_setQid(s_Message* self, PyObject* args);
static PyObject* Message_getRcode(s_Message* self);
@@ -1019,35 +1023,6 @@
"Sets the specified header flag bit to 0. The message must be in "
"RENDER mode. If not, an InvalidMessageOperation is raised. "
"Takes a MessageFlag object as the only argument." },
- { "is_dnssec_supported", reinterpret_cast<PyCFunction>(Message_isDNSSECSupported), METH_NOARGS,
- "Returns True if the message sender indicates DNSSEC is supported. "
- "If EDNS is included, this corresponds to the value of the DO bit. "
- "Otherwise, DNSSEC is considered not supported." },
- { "set_dnssec_supported", reinterpret_cast<PyCFunction>(Message_setDNSSECSupported), METH_VARARGS,
- "Specify whether DNSSEC is supported in the message. "
- "The message must be in RENDER mode. If not, an "
- "InvalidMessageOperation is raised."
- "If EDNS is included in the message, the DO bit is set or cleared "
- "according to given argument (True or False) of this method."},
- { "get_udp_size", reinterpret_cast<PyCFunction>(Message_getUDPSize), METH_NOARGS,
- "Return the maximum buffer size of UDP messages for the sender "
- "of the message.\n\n"
- "The semantics of this value is different based on the mode:\n"
- "In the PARSE mode, it means the buffer size of the remote node;\n"
- "in the RENDER mode, it means the buffer size of the local node.\n\n"
- "In either case, its value is the value of the UDP payload size field "
- "of EDNS (when it's included) or DEFAULT_MAX_UDPSIZE." },
- { "set_udp_size", reinterpret_cast<PyCFunction>(Message_setUDPSize), METH_VARARGS,
- "Specify the maximum buffer size of UDP messages of the local "
- "node. If the message is not in RENDER mode, an "
- "InvalidMessageOperation is raised.\n\n"
- "If EDNS OPT RR is included in the message, its UDP payload size field "
- "will be set to the specified value.\n"
- "Unless explicitly specified, DEFAULT_MAX_UDPSIZE will be assumed "
- "for the maximum buffer size, regardless of whether EDNS OPT RR is "
- "included or not. This means if an application wants to send a message "
- "with an EDNS OPT RR for specifying a larger UDP size, it must explicitly "
- "specify the value using this method. "},
{ "get_qid", reinterpret_cast<PyCFunction>(Message_getQid), METH_NOARGS,
"Returns the query id" },
{ "set_qid", reinterpret_cast<PyCFunction>(Message_setQid), METH_VARARGS,
@@ -1248,57 +1223,6 @@
}
static PyObject*
-Message_isDNSSECSupported(s_Message* self) {
- if (self->message->isDNSSECSupported()) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-static PyObject*
-Message_setDNSSECSupported(s_Message* self, PyObject* args) {
- PyObject *b;
- if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &b)) {
- return (NULL);
- }
- try {
- if (b == Py_True) {
- self->message->setDNSSECSupported(true);
- } else {
- self->message->setDNSSECSupported(false);
- }
- Py_RETURN_NONE;
- } catch (const InvalidMessageOperation& imo) {
- PyErr_SetString(po_InvalidMessageOperation, imo.what());
- return (NULL);
- }
-}
-
-static PyObject*
-Message_getUDPSize(s_Message* self) {
- return (Py_BuildValue("I", self->message->getUDPSize()));
-}
-
-static PyObject*
-Message_setUDPSize(s_Message* self, PyObject* args) {
- uint16_t size;
- if (!PyArg_ParseTuple(args, "H", &size)) {
- return (NULL);
- }
- try {
- self->message->setUDPSize(size);
- Py_RETURN_NONE;
- } catch (const InvalidMessageUDPSize& imus) {
- PyErr_SetString(po_InvalidMessageUDPSize, imus.what());
- return (NULL);
- } catch (const InvalidMessageOperation& imo) {
- PyErr_SetString(po_InvalidMessageOperation, imo.what());
- return (NULL);
- }
-}
-
-static PyObject*
Message_getQid(s_Message* self) {
return (Py_BuildValue("I", self->message->getQid()));
}
Modified: branches/trac311/src/lib/dns/python/messagerenderer_python.cc
==============================================================================
--- branches/trac311/src/lib/dns/python/messagerenderer_python.cc (original)
+++ branches/trac311/src/lib/dns/python/messagerenderer_python.cc Tue Aug 24 18:44:00 2010
@@ -42,7 +42,7 @@
// TODO: set/get compressmode
static PyObject* MessageRenderer_setTruncated(s_MessageRenderer* self);
static PyObject* MessageRenderer_setLengthLimit(s_MessageRenderer* self, PyObject* args);
-
+static PyObject* MessageRenderer_clear(s_MessageRenderer* self);
static PyMethodDef MessageRenderer_methods[] = {
{ "get_data", reinterpret_cast<PyCFunction>(MessageRenderer_getData), METH_NOARGS,
@@ -57,6 +57,9 @@
"Sets truncated to true" },
{ "set_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_setLengthLimit), METH_VARARGS,
"Sets the length limit of the data to the given number" },
+ { "clear", reinterpret_cast<PyCFunction>(MessageRenderer_clear),
+ METH_NOARGS,
+ "Clear the internal buffer and other internal resources." },
{ NULL, NULL, 0, NULL }
};
@@ -175,6 +178,12 @@
Py_RETURN_NONE;
}
+static PyObject*
+MessageRenderer_clear(s_MessageRenderer* self) {
+ self->messagerenderer->clear();
+ Py_RETURN_NONE;
+}
+
// end of MessageRenderer
Modified: branches/trac311/src/lib/dns/python/rdata_python.cc
==============================================================================
--- branches/trac311/src/lib/dns/python/rdata_python.cc (original)
+++ branches/trac311/src/lib/dns/python/rdata_python.cc Tue Aug 24 18:44:00 2010
@@ -146,11 +146,20 @@
s_RRType* rrtype;
s_RRClass* rrclass;
const char* s;
-
+ const char* data;
+ Py_ssize_t len;
+
+ // Create from string
if (PyArg_ParseTuple(args, "O!O!s", &rrtype_type, &rrtype,
&rrclass_type, &rrclass,
&s)) {
self->rdata = createRdata(*rrtype->rrtype, *rrclass->rrclass, s);
+ return (0);
+ } else if (PyArg_ParseTuple(args, "O!O!y#", &rrtype_type, &rrtype,
+ &rrclass_type, &rrclass, &data, &len)) {
+ InputBuffer input_buffer(data, len);
+ self->rdata = createRdata(*rrtype->rrtype, *rrclass->rrclass,
+ input_buffer, len);
return (0);
}
Modified: branches/trac311/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac311/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac311/src/lib/dns/python/tests/Makefile.am Tue Aug 24 18:44:00 2010
@@ -1,4 +1,5 @@
-PYTESTS = message_python_test.py
+PYTESTS = edns_python_test.py
+PYTESTS += message_python_test.py
PYTESTS += messagerenderer_python_test.py
PYTESTS += name_python_test.py
PYTESTS += question_python_test.py
@@ -23,8 +24,8 @@
check-local:
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
- env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
- TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata \
+ env PYTHONPATH=$(abs_top_srcdir)/src/lib/dns/.libs:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
+ TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata:$(abs_top_builddir)/src/lib/dns/tests/testdata \
$(LIBRARY_PATH_PLACEHOLDER) \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac311/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac311/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac311/src/lib/dns/python/tests/message_python_test.py Tue Aug 24 18:44:00 2010
@@ -20,7 +20,7 @@
import unittest
import os
from libdns_python import *
-
+from testutil import *
class MessageFlagTest(unittest.TestCase):
def test_init(self):
@@ -240,19 +240,6 @@
else:
testdata_path = "../tests/testdata"
-def read_wire_data(filename):
- data = bytes()
- file = open(testdata_path + os.sep + filename, "r")
- for line in file:
- line = line.strip()
- if line == "" or line.startswith("#"):
- pass
- else:
- cur_data = bytes.fromhex(line)
- data += cur_data
-
- return data
-
def factoryFromFile(message, file):
data = read_wire_data(file)
message.from_wire(data)
@@ -316,28 +303,6 @@
self.assertRaises(InvalidMessageOperation,
self.p.clear_header_flag, MessageFlag.AA())
- def test_set_DNSSEC_supported(self):
- self.assertRaises(TypeError, self.r.set_dnssec_supported, "wrong")
-
- self.assertFalse(self.r.is_dnssec_supported())
- self.r.set_dnssec_supported(True)
- self.assertTrue(self.r.is_dnssec_supported())
- self.r.set_dnssec_supported(False)
- self.assertFalse(self.r.is_dnssec_supported())
-
- self.assertRaises(InvalidMessageOperation,
- self.p.set_dnssec_supported, True)
- self.assertRaises(InvalidMessageOperation,
- self.p.set_dnssec_supported, False)
-
- def test_set_udp_size(self):
- self.assertRaises(TypeError, self.r.set_udp_size, "wrong")
- self.assertRaises(InvalidMessageUDPSize, self.r.set_udp_size, 0)
- self.assertRaises(InvalidMessageUDPSize, self.r.set_udp_size, 65536)
- self.assertRaises(InvalidMessageOperation, self.p.set_udp_size, 1024)
- self.r.set_udp_size(2048)
- self.assertEqual(2048, self.r.get_udp_size())
-
def test_set_qid(self):
self.assertRaises(TypeError, self.r.set_qid, "wrong")
self.assertRaises(InvalidMessageOperation,
@@ -487,84 +452,6 @@
self.assertEqual("192.0.2.2", rdata[1].to_text())
self.assertEqual(2, len(rdata))
- def test_GetEDNS0DOBit(self):
- message_parse = Message(Message.PARSE)
- ## Without EDNS0, DNSSEC is considered to be unsupported.
- factoryFromFile(message_parse, "message_fromWire1")
- self.assertFalse(message_parse.is_dnssec_supported())
-
- ## If DO bit is on, DNSSEC is considered to be supported.
- message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire2")
- self.assertTrue(message_parse.is_dnssec_supported())
-
- ## If DO bit is off, DNSSEC is considered to be unsupported.
- message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire3")
- self.assertFalse(message_parse.is_dnssec_supported())
-
- def test_SetEDNS0DOBit(self):
- # By default, it's false, and we can enable/disable it.
- message_parse = Message(Message.PARSE)
- message_render = Message(Message.RENDER)
- self.assertFalse(message_render.is_dnssec_supported())
- message_render.set_dnssec_supported(True)
- self.assertTrue(message_render.is_dnssec_supported())
- message_render.set_dnssec_supported(False)
- self.assertFalse(message_render.is_dnssec_supported())
-
- ## A message in the parse mode doesn't allow this flag to be set.
- self.assertRaises(InvalidMessageOperation,
- message_parse.set_dnssec_supported,
- True)
- ## Once converted to the render mode, it works as above
- message_parse.make_response()
- self.assertFalse(message_parse.is_dnssec_supported())
- message_parse.set_dnssec_supported(True)
- self.assertTrue(message_parse.is_dnssec_supported())
- message_parse.set_dnssec_supported(False)
- self.assertFalse(message_parse.is_dnssec_supported())
-
- def test_GetEDNS0UDPSize(self):
- # Without EDNS0, the default max UDP size is used.
- message_parse = Message(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire1")
- self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_parse.get_udp_size())
-
- ## If the size specified in EDNS0 > default max, use it.
- message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire2")
- self.assertEqual(4096, message_parse.get_udp_size())
-
- ## If the size specified in EDNS0 < default max, keep using the default.
- message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire8")
- self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_parse.get_udp_size())
-
- def test_SetEDNS0UDPSize(self):
- # The default size if unspecified
- message_render = Message(Message.RENDER)
- message_parse = Message(Message.PARSE)
- self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_render.get_udp_size())
- # A common buffer size with EDNS, should succeed
- message_render.set_udp_size(4096)
- self.assertEqual(4096, message_render.get_udp_size())
- # Unusual large value, but accepted
- message_render.set_udp_size(0xffff)
- self.assertEqual(0xffff, message_render.get_udp_size())
- # Too small is value is rejected
- self.assertRaises(InvalidMessageUDPSize, message_render.set_udp_size, 511)
-
- # A message in the parse mode doesn't allow the set operation.
- self.assertRaises(InvalidMessageOperation, message_parse.set_udp_size, 4096)
- ## Once converted to the render mode, it works as above.
- message_parse.make_response()
- message_parse.set_udp_size(4096)
- self.assertEqual(4096, message_parse.get_udp_size())
- message_parse.set_udp_size(0xffff)
- self.assertEqual(0xffff, message_parse.get_udp_size())
- self.assertRaises(InvalidMessageUDPSize, message_parse.set_udp_size, 511)
-
def test_EDNS0ExtCode(self):
# Extended Rcode = BADVERS
message_parse = Message(Message.PARSE)
Modified: branches/trac311/src/lib/dns/python/tests/question_python_test.py
==============================================================================
--- branches/trac311/src/lib/dns/python/tests/question_python_test.py (original)
+++ branches/trac311/src/lib/dns/python/tests/question_python_test.py Tue Aug 24 18:44:00 2010
@@ -20,24 +20,12 @@
import unittest
import os
from libdns_python import *
+from testutil import *
if "TESTDATA_PATH" in os.environ:
testdata_path = os.environ["TESTDATA_PATH"]
else:
testdata_path = "../tests/testdata"
-
-def read_wire_data(filename):
- data = bytes()
- file = open(testdata_path + os.sep + filename, "r")
- for line in file:
- line = line.strip()
- if line == "" or line.startswith("#"):
- pass
- else:
- cur_data = bytes.fromhex(line)
- data += cur_data
-
- return data
def question_from_wire(file, position = 0):
data = read_wire_data(file)
@@ -102,7 +90,6 @@
wiredata = read_wire_data("question_toWire2")
self.assertEqual(renderer.get_data(), wiredata)
self.assertRaises(TypeError, self.test_question1.to_wire, 1)
-
if __name__ == '__main__':
unittest.main()
Modified: branches/trac311/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac311/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac311/src/lib/dns/tests/Makefile.am Tue Aug 24 18:44:00 2010
@@ -1,6 +1,9 @@
+SUBDIRS = testdata .
+
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_SRCDIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(top_builddir)/src/lib/dns/tests/testdata\"
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
@@ -14,6 +17,7 @@
TESTS += run_unittests
run_unittests_SOURCES = unittest_util.h unittest_util.cc
run_unittests_SOURCES += buffer_unittest.cc name_unittest.cc
+run_unittests_SOURCES += edns_unittest.cc
run_unittests_SOURCES += messagerenderer_unittest.cc
run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
run_unittests_SOURCES += rrttl_unittest.cc
@@ -53,6 +57,7 @@
# NOTE: keep this in sync with real file listing
# so is included in tarball
EXTRA_DIST = testdata/gen-wiredata.py.in
+EXTRA_DIST += testdata/edns_toWire1.spec
EXTRA_DIST += testdata/message_fromWire1
EXTRA_DIST += testdata/message_fromWire10
EXTRA_DIST += testdata/message_fromWire10.spec
Modified: branches/trac311/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac311/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac311/src/lib/dns/tests/message_unittest.cc Tue Aug 24 18:44:00 2010
@@ -127,82 +127,7 @@
EXPECT_TRUE(it->isLast());
}
-TEST_F(MessageTest, GetEDNS0DOBit) {
- // Without EDNS0, DNSSEC is considered to be unsupported.
- factoryFromFile(message_parse, "message_fromWire1");
- EXPECT_FALSE(message_parse.isDNSSECSupported());
-
- // If DO bit is on, DNSSEC is considered to be supported.
- message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire2");
- EXPECT_TRUE(message_parse.isDNSSECSupported());
-
- // If DO bit is off, DNSSEC is considered to be unsupported.
- message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire3");
- EXPECT_FALSE(message_parse.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, SetEDNS0DOBit) {
- // By default, it's false, and we can enable/disable it.
- EXPECT_FALSE(message_render.isDNSSECSupported());
- message_render.setDNSSECSupported(true);
- EXPECT_TRUE(message_render.isDNSSECSupported());
- message_render.setDNSSECSupported(false);
- EXPECT_FALSE(message_render.isDNSSECSupported());
-
- // A message in the parse mode doesn't allow this flag to be set.
- EXPECT_THROW(message_parse.setDNSSECSupported(true),
- InvalidMessageOperation);
- // Once converted to the render mode, it works as above
- message_parse.makeResponse();
- EXPECT_FALSE(message_parse.isDNSSECSupported());
- message_parse.setDNSSECSupported(true);
- EXPECT_TRUE(message_parse.isDNSSECSupported());
- message_parse.setDNSSECSupported(false);
- EXPECT_FALSE(message_parse.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, GetEDNS0UDPSize) {
- // Without EDNS0, the default max UDP size is used.
- factoryFromFile(message_parse, "message_fromWire1");
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
-
- // If the size specified in EDNS0 > default max, use it.
- message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire2");
- EXPECT_EQ(4096, message_parse.getUDPSize());
-
- // If the size specified in EDNS0 < default max, keep using the default.
- message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire8");
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
-}
-
-TEST_F(MessageTest, SetEDNS0UDPSize) {
- // The default size if unspecified
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_render.getUDPSize());
- // A common buffer size with EDNS, should succeed
- message_render.setUDPSize(4096);
- EXPECT_EQ(4096, message_render.getUDPSize());
- // Unusual large value, but accepted
- message_render.setUDPSize(0xffff);
- EXPECT_EQ(0xffff, message_render.getUDPSize());
- // Too small is value is rejected
- EXPECT_THROW(message_render.setUDPSize(511), InvalidMessageUDPSize);
-
- // A message in the parse mode doesn't allow the set operation.
- EXPECT_THROW(message_parse.setUDPSize(4096), InvalidMessageOperation);
- // Once converted to the render mode, it works as above.
- message_parse.makeResponse();
- message_parse.setUDPSize(4096);
- EXPECT_EQ(4096, message_parse.getUDPSize());
- message_parse.setUDPSize(0xffff);
- EXPECT_EQ(0xffff, message_parse.getUDPSize());
- EXPECT_THROW(message_parse.setUDPSize(511), InvalidMessageUDPSize);
-}
-
-TEST_F(MessageTest, EDNS0ExtCode) {
+TEST_F(MessageTest, EDNS0ExtRcode) {
// Extended Rcode = BADVERS
factoryFromFile(message_parse, "message_fromWire10");
EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
@@ -221,19 +146,6 @@
message_parse.clear(Message::PARSE);
EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire5"),
DNSMessageFORMERR);
- // OPT RR of a non root name
- message_parse.clear(Message::PARSE);
- EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire6"),
- DNSMessageFORMERR);
- // Compressed owner name of OPT RR points to a root name.
- // Not necessarily bogus, but very unusual and mostly pathological.
- // We accept it, but is it okay?
- message_parse.clear(Message::PARSE);
- EXPECT_NO_THROW(factoryFromFile(message_parse, "message_fromWire7"));
- // Unsupported Version
- message_parse.clear(Message::PARSE);
- EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire9"),
- DNSMessageBADVERS);
}
TEST_F(MessageTest, toWire) {
Modified: branches/trac311/src/lib/dns/tests/run_unittests.cc
==============================================================================
--- branches/trac311/src/lib/dns/tests/run_unittests.cc (original)
+++ branches/trac311/src/lib/dns/tests/run_unittests.cc Tue Aug 24 18:44:00 2010
@@ -21,7 +21,8 @@
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
- isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_SRCDIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
return (RUN_ALL_TESTS());
}
Modified: branches/trac311/src/lib/exceptions/exceptions.h
==============================================================================
--- branches/trac311/src/lib/exceptions/exceptions.h (original)
+++ branches/trac311/src/lib/exceptions/exceptions.h Tue Aug 24 18:44:00 2010
@@ -103,20 +103,25 @@
const std::string what_;
};
-///
/// \brief A generic exception that is thrown if a parameter given
/// to a method would refer to or modify out-of-range data.
-///
class OutOfRange : public Exception {
public:
OutOfRange(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
-///
+/// \brief A generic exception that is thrown if a parameter given
+/// to a method or function is considered invalid and no other specific
+/// exceptions are suitable to describe the error.
+class InvalidParameter : public Exception {
+public:
+ InvalidParameter(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
/// \brief A generic exception that is thrown if a parameter given
/// to a method is considered invalid in that context.
-///
class BadValue : public Exception {
public:
BadValue(const char* file, size_t line, const char* what) :
More information about the bind10-changes
mailing list