Commit 21b837ca authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

checkpoint: more support for incoming EDNS0 (unsupported version handling,

UDP buffer size)


git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1047 e5f2f494-b856-4b98-b285-d166d9295462
parent f21f0086
......@@ -179,6 +179,7 @@ public:
vector<QuestionPtr> questions_;
vector<RRsetPtr> rrsets_[SECTION_MAX];
RRsetPtr edns_;
uint16_t udpsize_;
#ifdef notyet
// tsig/sig0: TODO
......@@ -191,12 +192,9 @@ public:
InputBuffer& buffer);
};
MessageImpl::MessageImpl() :
qid_(0), rcode_(NULL), opcode_(NULL), flags_(0), dnssec_ok_(false)
MessageImpl::MessageImpl()
{
for (int i = 0; i < SECTION_MAX; i++) {
counts_[i] = 0;
}
init();
}
void
......@@ -208,6 +206,7 @@ MessageImpl::init()
opcode_ = NULL;
dnssec_ok_ = false;
edns_ = RRsetPtr();
udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
for (int i = 0; i < SECTION_MAX; i++) {
counts_[i] = 0;
......@@ -253,6 +252,12 @@ Message::isDNSSECSupported() const
return (impl_->dnssec_ok_);
}
uint16_t
Message::getUDPSize() const
{
return (impl_->udpsize_);
}
qid_t
Message::getQid() const
{
......@@ -479,16 +484,22 @@ MessageImpl::parseSection(Message& messge, const Section& section,
if (edns_ != NULL) {
dns_throw(DNSMessageFORMERR, "multiple EDNS OPT RR found");
}
if (((ttl.getValue() & 0x00ff0000) >> 16) >
Message::EDNS0_SUPPORTED_VERSION) {
dns_throw(DNSMessageBADVERS, "unsupported EDNS version");
}
if (name != Name::ROOT_NAME()) {
dns_throw(DNSMessageFORMERR,
"invalid owner name for EDNS OPT RR");
"invalid owner name for EDNS OPT RR");
}
edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
edns_->addRdata(rdata);
dnssec_ok_ = (((ttl.getValue() & 0xffff) & EXTFLAG_DO) != 0);
if (rrclass.getCode() > Message::DEFAULT_MAX_UDPSIZE) {
udpsize_ = rrclass.getCode();
}
continue;
}
......
......@@ -42,6 +42,12 @@ public:
DNSProtocolError(file, line, what) {}
};
class DNSMessageBADVERS : public DNSProtocolError {
public:
DNSMessageBADVERS(const char* file, size_t line, const char* what) :
DNSProtocolError(file, line, what) {}
};
///
/// \brief A standard DNS module exception ...[TBD]
///
......@@ -495,7 +501,8 @@ public:
void setHeaderFlag(const MessageFlag& flag);
void clearHeaderFlag(const MessageFlag& flag);
bool isDNSSECSupported() const;
void setDNSSECSupported(bool on);
void setDNSSECSupported(bool on); // not yet
uint16_t getUDPSize() const;
qid_t getQid() const;
void setQid(qid_t qid);
const Rcode& getRcode() const;
......@@ -540,6 +547,20 @@ public:
/// \brief Parse a DNS message.
void fromWire(InputBuffer& buffer);
///
/// \name Protocol constants
///
//@{
/// \brief The default maximum size of UDP DNS messages that don't cause
/// truncation.
///
/// With EDNS0 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;
//@}
private:
MessageImpl* impl_;
};
......
......@@ -32,11 +32,12 @@ using namespace std;
using namespace isc::dns;
using namespace isc::dns::rdata;
const uint16_t Message::DEFAULT_MAX_UDPSIZE;
namespace {
class MessageTest : public ::testing::Test {
protected:
MessageTest() : obuffer(0), renderer(obuffer)
{}
MessageTest() : obuffer(0), renderer(obuffer) {}
static Question factoryFromFile(const char* datafile);
OutputBuffer obuffer;
MessageRenderer renderer;
......@@ -92,18 +93,38 @@ TEST_F(MessageTest, fromWire)
TEST_F(MessageTest, EDNS0DOBit)
{
// Without EDNS0, DNSSEC is considered to be unsupported.
factoryFromFile(message, "testdata/message_fromWire1");
EXPECT_FALSE(message.isDNSSECSupported());
// If DO bit is on, DNSSEC is considered to be supported.
message.clear();
factoryFromFile(message, "testdata/message_fromWire2");
EXPECT_TRUE(message.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)
{
// Without EDNS0, the default max UDP size is used.
factoryFromFile(message, "testdata/message_fromWire1");
EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message.getUDPSize());
// If the size specified in EDNS0 > default max, use it.
message.clear();
factoryFromFile(message, "testdata/message_fromWire2");
EXPECT_EQ(4096, message.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());
}
TEST_F(MessageTest, BadEDNS0)
{
// OPT RR in the answer section
......@@ -122,6 +143,10 @@ TEST_F(MessageTest, BadEDNS0)
// We accept it, but is it okay?
message.clear();
EXPECT_NO_THROW(factoryFromFile(message, "testdata/message_fromWire7"));
// Unsupported Version
message.clear();
EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire9"),
DNSMessageBADVERS);
}
TEST_F(MessageTest, toWire)
......
#
# A simple DNS query message with a valid EDNS0 OPT RR (but unusual UDP size)
# ID = 0x1035
# QR=0 (query), Opcode=0, RD=1 (other fields are 0)
# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=1
# Question: test.example.com. IN A
1035 0100
0001 0000 0000 0001
#(4) t e s t (7) e x a m p l e (3) c o m .
04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
0001 0001
# EDNS0 OPT RR
# owner name: "."
00
# TYPE: OPT (41 = 0x29)
00 29
# CLASS (= UDP size): 500
01f4
# TTL (extended RCODE and flags): RCODE=0, version=0, flags=DO
0000 8000
# RDLEN = 0
0000
#
# A simple DNS query message with an unsupported version of EDNS0
# ID = 0x1035
# QR=0 (query), Opcode=0, RD=1 (other fields are 0)
# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=1
# Question: test.example.com. IN A
1035 0100
0001 0000 0000 0001
#(4) t e s t (7) e x a m p l e (3) c o m .
04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
0001 0001
# EDNS0 OPT RR
# owner name: "."
00
# TYPE: OPT (41 = 0x29)
00 29
# CLASS (= UDP size): 4096
1000
# TTL (extended RCODE and flags): RCODE=0, version=1, flags=DO
0001 8000
# RDLEN = 0
0000
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment