[svn] commit: r1071 - in /trunk/src: bin/auth/auth_srv.cc bin/host/host.cc lib/auth/cpp/datasrc_unittest.cc lib/dns/cpp/message.cc lib/dns/cpp/message.h lib/dns/cpp/tests/message_unittest.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Mar 2 18:39:43 UTC 2010
Author: jinmei
Date: Tue Mar 2 18:39:42 2010
New Revision: 1071
Log:
added support for basic level of EDNS0, and adjusted apps with the latest API.
Modified:
trunk/src/bin/auth/auth_srv.cc
trunk/src/bin/host/host.cc
trunk/src/lib/auth/cpp/datasrc_unittest.cc
trunk/src/lib/dns/cpp/message.cc
trunk/src/lib/dns/cpp/message.h
trunk/src/lib/dns/cpp/tests/message_unittest.cc
Modified: trunk/src/bin/auth/auth_srv.cc
==============================================================================
--- trunk/src/bin/auth/auth_srv.cc (original)
+++ trunk/src/bin/auth/auth_srv.cc Tue Mar 2 18:39:42 2010
@@ -89,7 +89,7 @@
int cc;
if ((cc = recvfrom(s, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) {
- Message msg;
+ Message msg(Message::PARSE);
InputBuffer buffer(recvbuf, cc);
try {
@@ -105,17 +105,22 @@
return;
}
+ bool dnssec_ok = msg.isDNSSECSupported();
+ uint16_t remote_bufsize = msg.getUDPSize();
+
QuestionPtr query = *msg.beginQuestion();
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
+ msg.setDNSSECSupported(dnssec_ok);
+ msg.setUDPSize(sizeof(recvbuf));
// do the DataSource call here
Query q = Query(msg, false);
data_src.doQuery(q);
- OutputBuffer obuffer(4096);
+ OutputBuffer obuffer(remote_bufsize);
MessageRenderer renderer(obuffer);
msg.toWire(renderer);
cout << "sending a response (" <<
Modified: trunk/src/bin/host/host.cc
==============================================================================
--- trunk/src/bin/host/host.cc (original)
+++ trunk/src/bin/host/host.cc Tue Mar 2 18:39:42 2010
@@ -31,7 +31,7 @@
host_lookup(char* name, std::string type)
{
- Message msg;
+ Message msg(Message::RENDER);
msg.setQid(0); // does this matter?
@@ -99,7 +99,7 @@
int cc;
if ((cc = recvfrom(s, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) {
try {
- Message rmsg;
+ Message rmsg(Message::PARSE);
InputBuffer ibuffer(recvbuf, cc);
rmsg.fromWire(ibuffer);
Modified: trunk/src/lib/auth/cpp/datasrc_unittest.cc
==============================================================================
--- trunk/src/lib/auth/cpp/datasrc_unittest.cc (original)
+++ trunk/src/lib/auth/cpp/datasrc_unittest.cc Tue Mar 2 18:39:42 2010
@@ -42,7 +42,8 @@
namespace {
class DataSrcTest : public ::testing::Test {
protected:
- DataSrcTest() : obuffer(0), renderer(obuffer) {}
+ DataSrcTest() : obuffer(0), renderer(obuffer), msg(Message::PARSE)
+ {}
TestDataSrc ds;
OutputBuffer obuffer;
MessageRenderer renderer;
Modified: trunk/src/lib/dns/cpp/message.cc
==============================================================================
--- trunk/src/lib/dns/cpp/message.cc (original)
+++ trunk/src/lib/dns/cpp/message.cc Tue Mar 2 18:39:42 2010
@@ -31,6 +31,7 @@
#include "messagerenderer.h"
#include "name.h"
#include "question.h"
+#include "rdataclass.h"
#include "rrclass.h"
#include "rrtype.h"
#include "rrttl.h"
@@ -59,7 +60,7 @@
static const flags_t FLAG_CD = 0x0010;
//
-// EDNS0 related constants
+// EDNS related constants
//
static const flags_t EXTFLAG_MASK = 0xffff;
static const flags_t EXTFLAG_DO = 0x8000;
@@ -189,9 +190,10 @@
class MessageImpl {
public:
- MessageImpl();
+ MessageImpl(Message::Mode mode);
// Open issues: should we rather have a header in wire-format
// for efficiency?
+ Message::Mode mode_;
qid_t qid_;
Rcode rcode_;
const Opcode* opcode_;
@@ -202,7 +204,9 @@
int counts_[SECTION_MAX]; // TODO: revisit this definition
vector<QuestionPtr> questions_;
vector<RRsetPtr> rrsets_[SECTION_MAX];
- RRsetPtr edns_;
+ RRsetPtr remote_edns_;
+ uint16_t remote_udpsize_;
+ RRsetPtr local_edns_;
uint16_t udpsize_;
#ifdef notyet
@@ -211,13 +215,13 @@
#endif
void init();
- void parseQuestion(Message& message, InputBuffer& buffer);
- void parseSection(Message& messge, const Section& section,
- InputBuffer& buffer);
+ int parseQuestion(Message& message, InputBuffer& buffer);
+ int parseSection(Message& messge, const Section& section,
+ InputBuffer& buffer);
};
-MessageImpl::MessageImpl() :
- rcode_(Rcode::NOERROR())
+MessageImpl::MessageImpl(Message::Mode mode) :
+ mode_(mode), rcode_(Rcode::NOERROR())
{
init();
}
@@ -230,7 +234,9 @@
rcode_ = Rcode::NOERROR(); // XXX
opcode_ = NULL;
dnssec_ok_ = false;
- edns_ = RRsetPtr();
+ remote_edns_ = RRsetPtr();
+ remote_udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
+ local_edns_ = RRsetPtr();
udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
for (int i = 0; i < SECTION_MAX; i++) {
@@ -243,8 +249,8 @@
rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
}
-Message::Message() :
- impl_(new MessageImpl())
+Message::Message(Mode mode) :
+ impl_(new MessageImpl(mode))
{
}
@@ -277,10 +283,34 @@
return (impl_->dnssec_ok_);
}
+void
+Message::setDNSSECSupported(bool on)
+{
+ if (impl_->mode_ != Message::RENDER) {
+ dns_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) {
+ dns_throw(InvalidMessageOperation,
+ "setUDPSize performed in non-render mode");
+ }
+ if (size < DEFAULT_MAX_UDPSIZE) {
+ dns_throw(InvalidMessageUDPSize,
+ "Specified UDP message size is too small");
+ }
+ impl_->udpsize_ = size;
}
qid_t
@@ -370,6 +400,44 @@
};
}
+namespace {
+bool
+addEDNS(MessageImpl* mimpl, MessageRenderer& renderer)
+{
+ bool is_query = ((mimpl->flags_ & MessageFlag::QR().getBit()) == 0);
+
+ // If this is a reply and the request didn't have EDNS, we shouldn't add it.
+ if (mimpl->remote_edns_ == NULL && !is_query) {
+ return (false);
+ }
+
+ // 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 (is_query && mimpl->udpsize_ == Message::DEFAULT_MAX_UDPSIZE &&
+ !mimpl->dnssec_ok_ &&
+ mimpl->rcode_.getCode() < 0x10) {
+ 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)
{
@@ -378,7 +446,7 @@
// reserve room for the header
renderer.skip(HEADERLEN);
- uint16_t qrcount =
+ uint16_t qdcount =
for_each(impl_->questions_.begin(), impl_->questions_.end(),
RenderSection<QuestionPtr>(renderer)).getTotalCount();
@@ -396,6 +464,12 @@
impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].end(),
RenderSection<RRsetPtr>(renderer)).getTotalCount();
+ // Added EDNS OPT RR if necessary (we want to avoid hardcoding specialized
+ // logic, see the parser case)
+ if (addEDNS(this->impl_, renderer)) {
+ ++arcount;
+ }
+
// TBD: EDNS, TSIG, etc.
// fill in the header
@@ -408,7 +482,7 @@
renderer.writeUint16At(codes_and_flags, header_pos);
header_pos += sizeof(uint16_t);
// XXX: should avoid repeated pattern (TODO)
- renderer.writeUint16At(qrcount, header_pos);
+ renderer.writeUint16At(qdcount, header_pos);
header_pos += sizeof(uint16_t);
renderer.writeUint16At(ancount, header_pos);
header_pos += sizeof(uint16_t);
@@ -435,15 +509,21 @@
impl_->counts_[Section::AUTHORITY().getCode()] = buffer.readUint16();
impl_->counts_[Section::ADDITIONAL().getCode()] = buffer.readUint16();
- impl_->parseQuestion(*this, buffer);
- impl_->parseSection(*this, Section::ANSWER(), buffer);
- impl_->parseSection(*this, Section::AUTHORITY(), buffer);
- impl_->parseSection(*this, Section::ADDITIONAL(), buffer);
-}
-
-void
+ impl_->counts_[Section::QUESTION().getCode()] =
+ impl_->parseQuestion(*this, buffer);
+ impl_->counts_[Section::ANSWER().getCode()] =
+ impl_->parseSection(*this, Section::ANSWER(), buffer);
+ impl_->counts_[Section::AUTHORITY().getCode()] =
+ impl_->parseSection(*this, Section::AUTHORITY(), buffer);
+ impl_->counts_[Section::ADDITIONAL().getCode()] =
+ impl_->parseSection(*this, Section::ADDITIONAL(), buffer);
+}
+
+int
MessageImpl::parseQuestion(Message& message, InputBuffer& buffer)
{
+ unsigned int added = 0;
+
for (unsigned int count = 0;
count < counts_[Section::QUESTION().getCode()];
count++) {
@@ -460,8 +540,11 @@
// algorithm that requires the question section contain exactly one
// RR.
- questions_.push_back(QuestionPtr(new Question(name, rrclass, rrtype)));
- }
+ questions_.push_back(QuestionPtr(new Question(name, rrclass, rrtype)));
+ ++added;
+ }
+
+ return (added);
}
namespace {
@@ -480,10 +563,12 @@
};
}
-void
+int
MessageImpl::parseSection(Message& message, const Section& section,
InputBuffer& buffer)
{
+ unsigned int added = 0;
+
for (unsigned int count = 0; count < counts_[section.getCode()]; count++) {
Name name(buffer);
@@ -507,17 +592,17 @@
dns_throw(DNSMessageFORMERR,
"EDNS OPT RR found in an invalid section");
}
- if (edns_ != NULL) {
+ if (remote_edns_ != NULL) {
dns_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.
- Message::EDNS0_SUPPORTED_VERSION) {
dns_throw(DNSMessageBADVERS, "unsupported EDNS version");
}
if (name != Name::ROOT_NAME()) {
@@ -525,8 +610,8 @@
"invalid owner name for EDNS OPT RR");
}
- edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
- edns_->addRdata(rdata);
+ 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) {
@@ -549,7 +634,10 @@
rrset->addRdata(rdata);
rrsets_[sectionCodeToId(section)].push_back(rrset);
}
- }
+ ++added;
+ }
+
+ return (added);
}
namespace {
@@ -609,9 +697,36 @@
lexical_cast<string>(impl_->counts_[Section::ANSWER().getCode()]);
s += ", AUTHORITY: " +
lexical_cast<string>(impl_->counts_[Section::AUTHORITY().getCode()]);
- s += ", ADDITIONAL: " +
- lexical_cast<string>(impl_->counts_[Section::ADDITIONAL().getCode()])
- + "\n";
+
+ unsigned int arcount = impl_->counts_[Section::ADDITIONAL().getCode()];
+ RRsetPtr edns_rrset;
+ if (!getHeaderFlag(MessageFlag::QR()) && impl_->remote_edns_ != NULL) {
+ edns_rrset = impl_->remote_edns_;
+ ++arcount;
+ } else if (getHeaderFlag(MessageFlag::QR()) && impl_->local_edns_ != NULL) {
+ edns_rrset = impl_->local_edns_;
+ ++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";
+ }
+ 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_->questions_.empty()) {
s += "\n;; " +
@@ -654,8 +769,20 @@
void
Message::makeResponse()
{
+ if (impl_->mode_ != Message::PARSE) {
+ dns_throw(InvalidMessageOperation,
+ "makeResponse() is performed in non-parse mode");
+ }
+
+ impl_->dnssec_ok_ = false;
+ impl_->remote_udpsize_ = impl_->udpsize_;
+ impl_->local_edns_ = RRsetPtr();
+ impl_->udpsize_ = DEFAULT_MAX_UDPSIZE;
+
impl_->flags_ &= MESSAGE_REPLYPRESERVE;
setHeaderFlag(MessageFlag::QR());
+
+ impl_->mode_ = Message::RENDER;
impl_->rrsets_[sectionCodeToId(Section::ANSWER())].clear();
impl_->counts_[Section::ANSWER().getCode()] = 0;
Modified: trunk/src/lib/dns/cpp/message.h
==============================================================================
--- trunk/src/lib/dns/cpp/message.h (original)
+++ trunk/src/lib/dns/cpp/message.h Tue Mar 2 18:39:42 2010
@@ -60,6 +60,18 @@
class InvalidMessageSection : public Exception {
public:
InvalidMessageSection(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
+class InvalidMessageOperation : public Exception {
+public:
+ InvalidMessageOperation(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
+class InvalidMessageUDPSize : public Exception {
+public:
+ InvalidMessageUDPSize(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
@@ -503,7 +515,12 @@
class Message {
public:
- Message();
+ enum Mode {
+ PARSE = 0,
+ RENDER = 1
+ };
+public:
+ Message(Mode mode);
~Message();
private:
Message(const Message& source);
@@ -513,8 +530,9 @@
void setHeaderFlag(const MessageFlag& flag);
void clearHeaderFlag(const MessageFlag& flag);
bool isDNSSECSupported() const;
- void setDNSSECSupported(bool on); // not yet
+ void setDNSSECSupported(bool on);
uint16_t getUDPSize() const;
+ void setUDPSize(uint16_t size);
qid_t getQid() const;
void setQid(qid_t qid);
const Rcode& getRcode() const;
@@ -566,11 +584,11 @@
/// \brief The default maximum size of UDP DNS messages that don't cause
/// truncation.
///
- /// With EDNS0 the maximum size can be increases per message.
+ /// With EDNS the maximum size can be increases per message.
static const uint16_t DEFAULT_MAX_UDPSIZE = 512;
- /// \brief The highest EDNS0 version this implementation supports.
- static const uint8_t EDNS0_SUPPORTED_VERSION = 0;
+ /// \brief The highest EDNS version this implementation supports.
+ static const uint8_t EDNS_SUPPORTED_VERSION = 0;
//@}
private:
Modified: trunk/src/lib/dns/cpp/tests/message_unittest.cc
==============================================================================
--- trunk/src/lib/dns/cpp/tests/message_unittest.cc (original)
+++ trunk/src/lib/dns/cpp/tests/message_unittest.cc Tue Mar 2 18:39:42 2010
@@ -39,11 +39,16 @@
namespace {
class MessageTest : public ::testing::Test {
protected:
- MessageTest() : obuffer(0), renderer(obuffer) {}
+ MessageTest() : obuffer(0), renderer(obuffer),
+ message_parse(Message::PARSE),
+ message_render(Message::RENDER)
+ {}
+
static Question factoryFromFile(const char* datafile);
OutputBuffer obuffer;
MessageRenderer renderer;
- Message message;
+ Message message_parse;
+ Message message_render;
static void factoryFromFile(Message& message, const char* datafile);
};
@@ -80,24 +85,24 @@
TEST_F(MessageTest, fromWire)
{
- factoryFromFile(message, "testdata/message_fromWire1");
- EXPECT_EQ(0x1035, message.getQid());
- EXPECT_EQ(Opcode::QUERY(), message.getOpcode());
- EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
- EXPECT_TRUE(message.getHeaderFlag(MessageFlag::QR()));
- EXPECT_TRUE(message.getHeaderFlag(MessageFlag::RD()));
- EXPECT_TRUE(message.getHeaderFlag(MessageFlag::AA()));
-
- QuestionPtr q = *message.beginQuestion();
+ factoryFromFile(message_parse, "testdata/message_fromWire1");
+ EXPECT_EQ(0x1035, message_parse.getQid());
+ EXPECT_EQ(Opcode::QUERY(), message_parse.getOpcode());
+ EXPECT_EQ(Rcode::NOERROR(), message_parse.getRcode());
+ EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::QR()));
+ EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::RD()));
+ EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::AA()));
+
+ QuestionPtr q = *message_parse.beginQuestion();
EXPECT_EQ(test_name, q->getName());
EXPECT_EQ(RRType::A(), q->getType());
EXPECT_EQ(RRClass::IN(), q->getClass());
- EXPECT_EQ(1, message.getRRCount(Section::QUESTION()));
- EXPECT_EQ(2, message.getRRCount(Section::ANSWER()));
- EXPECT_EQ(0, message.getRRCount(Section::AUTHORITY()));
- EXPECT_EQ(0, message.getRRCount(Section::ADDITIONAL()));
-
- RRsetPtr rrset = *message.beginSection(Section::ANSWER());
+ EXPECT_EQ(1, message_parse.getRRCount(Section::QUESTION()));
+ EXPECT_EQ(2, message_parse.getRRCount(Section::ANSWER()));
+ EXPECT_EQ(0, message_parse.getRRCount(Section::AUTHORITY()));
+ EXPECT_EQ(0, message_parse.getRRCount(Section::ADDITIONAL()));
+
+ RRsetPtr rrset = *message_parse.beginSection(Section::ANSWER());
EXPECT_EQ(test_name, rrset->getName());
EXPECT_EQ(RRType::A(), rrset->getType());
EXPECT_EQ(RRClass::IN(), rrset->getClass());
@@ -112,98 +117,144 @@
EXPECT_TRUE(it->isLast());
}
-TEST_F(MessageTest, EDNS0DOBit)
+TEST_F(MessageTest, GetEDNS0DOBit)
{
// Without EDNS0, DNSSEC is considered to be unsupported.
- factoryFromFile(message, "testdata/message_fromWire1");
- EXPECT_FALSE(message.isDNSSECSupported());
+ factoryFromFile(message_parse, "testdata/message_fromWire1");
+ EXPECT_FALSE(message_parse.isDNSSECSupported());
// If DO bit is on, DNSSEC is considered to be supported.
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire2");
- EXPECT_TRUE(message.isDNSSECSupported());
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/message_fromWire2");
+ EXPECT_TRUE(message_parse.isDNSSECSupported());
// If DO bit is off, DNSSEC is considered to be unsupported.
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire3");
- EXPECT_FALSE(message.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, EDNS0UDPSize)
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/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, "testdata/message_fromWire1");
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message.getUDPSize());
+ factoryFromFile(message_parse, "testdata/message_fromWire1");
+ EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
// If the size specified in EDNS0 > default max, use it.
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire2");
- EXPECT_EQ(4096, message.getUDPSize());
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/message_fromWire2");
+ EXPECT_EQ(4096, message_parse.getUDPSize());
// If the size specified in EDNS0 < default max, keep using the default.
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire8");
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message.getUDPSize());
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/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)
{
// Extended Rcode = BADVERS
- factoryFromFile(message, "testdata/message_fromWire10");
- EXPECT_EQ(Rcode::BADVERS(), message.getRcode());
+ factoryFromFile(message_parse, "testdata/message_fromWire10");
+ EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
// Maximum extended Rcode
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire11");
- EXPECT_EQ(0xfff, message.getRcode().getCode());
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/message_fromWire11");
+ EXPECT_EQ(0xfff, message_parse.getRcode().getCode());
}
TEST_F(MessageTest, BadEDNS0)
{
// OPT RR in the answer section
- EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire4"),
+ EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire4"),
DNSMessageFORMERR);
// multiple OPT RRs (in the additional section)
- message.clear();
- EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire5"),
+ message_parse.clear();
+ EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire5"),
DNSMessageFORMERR);
// OPT RR of a non root name
- message.clear();
- EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire6"),
+ message_parse.clear();
+ EXPECT_THROW(factoryFromFile(message_parse, "testdata/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.clear();
- EXPECT_NO_THROW(factoryFromFile(message, "testdata/message_fromWire7"));
+ message_parse.clear();
+ EXPECT_NO_THROW(factoryFromFile(message_parse,
+ "testdata/message_fromWire7"));
// Unsupported Version
- message.clear();
- EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire9"),
+ message_parse.clear();
+ EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire9"),
DNSMessageBADVERS);
}
TEST_F(MessageTest, toWire)
{
- message.setQid(0x1035);
- message.setOpcode(Opcode::QUERY());
- message.setRcode(Rcode::NOERROR());
- message.setHeaderFlag(MessageFlag::QR());
- message.setHeaderFlag(MessageFlag::RD());
- message.setHeaderFlag(MessageFlag::AA());
- message.addQuestion(Question(Name("test.example.com"), RRClass::IN(),
- RRType::A()));
+ message_render.setQid(0x1035);
+ message_render.setOpcode(Opcode::QUERY());
+ message_render.setRcode(Rcode::NOERROR());
+ message_render.setHeaderFlag(MessageFlag::QR());
+ message_render.setHeaderFlag(MessageFlag::RD());
+ message_render.setHeaderFlag(MessageFlag::AA());
+ message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(),
+ RRType::A()));
RRsetPtr rrset = RRsetPtr(new RRset(Name("test.example.com"), RRClass::IN(),
RRType::A(), RRTTL(3600)));
rrset->addRdata(in::A("192.0.2.1"));
rrset->addRdata(in::A("192.0.2.2"));
- message.addRRset(Section::ANSWER(), rrset);
-
- EXPECT_EQ(1, message.getRRCount(Section::QUESTION()));
- EXPECT_EQ(2, message.getRRCount(Section::ANSWER()));
- EXPECT_EQ(0, message.getRRCount(Section::AUTHORITY()));
- EXPECT_EQ(0, message.getRRCount(Section::ADDITIONAL()));
-
- message.toWire(renderer);
+ message_render.addRRset(Section::ANSWER(), rrset);
+
+ EXPECT_EQ(1, message_render.getRRCount(Section::QUESTION()));
+ EXPECT_EQ(2, message_render.getRRCount(Section::ANSWER()));
+ EXPECT_EQ(0, message_render.getRRCount(Section::AUTHORITY()));
+ EXPECT_EQ(0, message_render.getRRCount(Section::ADDITIONAL()));
+
+ message_render.toWire(renderer);
vector<unsigned char> data;
UnitTestUtil::readWireData("testdata/message_toWire1", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
More information about the bind10-changes
mailing list