123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
- //
- // Permission to use, copy, modify, and/or distribute this software for any
- // purpose with or without fee is hereby granted, provided that the above
- // copyright notice and this permission notice appear in all copies.
- //
- // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- // $Id$
- #include <sstream>
- #include <exceptions/exceptions.h>
- #include <dns/buffer.h>
- #include <dns/edns.h>
- #include <dns/exceptions.h>
- #include <dns/message.h>
- #include <dns/messagerenderer.h>
- #include <dns/name.h>
- #include <dns/rcode.h>
- #include <dns/rdataclass.h>
- #include <dns/rrclass.h>
- #include <dns/rrttl.h>
- #include <dns/rrtype.h>
- #include <gtest/gtest.h>
- #include <dns/tests/unittest_util.h>
- using isc::UnitTestUtil;
- using namespace std;
- using namespace isc::dns;
- using namespace isc::dns::rdata;
- const uint8_t EDNS::SUPPORTED_VERSION;
- namespace {
- class EDNSTest : public ::testing::Test {
- protected:
- EDNSTest() : rrtype(RRType::OPT()), buffer(NULL, 0), obuffer(0),
- renderer(obuffer), rcode(0)
- {
- opt_rdata = ConstRdataPtr(new generic::OPT());
- edns_base.setUDPSize(4096);
- }
- RRType rrtype;
- EDNS edns_base;
- ConstEDNSPtr edns;
- InputBuffer buffer;
- OutputBuffer obuffer;
- MessageRenderer renderer;
- ConstRdataPtr opt_rdata;
- Rcode rcode;
- vector<unsigned char> wiredata;
- };
- // RRClass of EDNS OPT means UDP buffer size
- const RRClass rrclass(4096);
- // RRTTL of EDNS OPT encodes extended-rcode, version, and DO bit
- const RRTTL rrttl_do_on(0x00008000); // DO=on
- const RRTTL rrttl_do_off(0); // DO=off
- const RRTTL rrttl_badver(0x00018000); // version=1, DO=on
- TEST_F(EDNSTest, badVerConstruct) {
- EXPECT_THROW(EDNS(1), isc::InvalidParameter);
- }
- TEST_F(EDNSTest, DNSSECDOBit) {
- // tests for EDNS from RR
- // DO bit is on, so DNSSEC should be considered to be supported.
- EXPECT_TRUE(EDNS(Name::ROOT_NAME(), rrclass, rrtype,
- rrttl_do_on, *opt_rdata).getDNSSECAwareness());
- // DO bit is off. DNSSEC should be considered to be unsupported.
- EXPECT_FALSE(EDNS(Name::ROOT_NAME(), rrclass, rrtype,
- rrttl_do_off, *opt_rdata).getDNSSECAwareness());
- // tests for EDNS constructed by hand
- EXPECT_FALSE(edns_base.getDNSSECAwareness()); // false by default
- edns_base.setDNSSECAwareness(true); // enable by hand
- EXPECT_TRUE(edns_base.getDNSSECAwareness());
- edns_base.setDNSSECAwareness(false); // disable by hand
- EXPECT_FALSE(edns_base.getDNSSECAwareness());
- }
- TEST_F(EDNSTest, UDPSize) {
- EXPECT_EQ(4096, EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on,
- *opt_rdata).getUDPSize());
- // EDNS UDP size smaller than the traditional max, 512. Unusual, but
- // not prohibited.
- edns_base.setUDPSize(511);
- EXPECT_EQ(511, edns_base.getUDPSize());
- // Even 0 is okay.
- edns_base.setUDPSize(0);
- EXPECT_EQ(0, edns_base.getUDPSize());
- // Possible max value is also okay, although the higher layer app may
- // adjust it to a reasonably lower value
- edns_base.setUDPSize(65535);
- EXPECT_EQ(65535, edns_base.getUDPSize());
- }
- TEST_F(EDNSTest, getVersion) {
- // Constructed by hand
- EXPECT_EQ(EDNS::SUPPORTED_VERSION, EDNS().getVersion());
- // From RR
- EXPECT_EQ(EDNS::SUPPORTED_VERSION,
- EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on,
- *opt_rdata).getVersion());
- }
- TEST_F(EDNSTest, BadWireData) {
- // Incompatible RR type
- EXPECT_THROW(EDNS(Name::ROOT_NAME(), rrclass, RRType::A(),
- rrttl_do_on, *opt_rdata), isc::InvalidParameter);
- // OPT RR of a non root name
- EXPECT_THROW(EDNS(Name("example.com"), rrclass, rrtype,
- rrttl_do_on, *opt_rdata), DNSMessageFORMERR);
-
- // Unsupported Version
- EXPECT_THROW(EDNS(Name::ROOT_NAME(), rrclass, rrtype,
- rrttl_badver, *opt_rdata), DNSMessageBADVERS);
- }
- TEST_F(EDNSTest, toText) {
- // Typical case, disabling DNSSEC
- EXPECT_EQ("; EDNS: version: 0, flags:; udp: 4096\n",
- EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_off,
- *opt_rdata).toText());
- // Typical case, enabling DNSSEC
- EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n",
- EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on,
- *opt_rdata).toText());
- // Non-0 extended Rcode: ignored in the toText() output.
- EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n",
- EDNS(Name::ROOT_NAME(), rrclass, rrtype,
- RRTTL(0x01008000), *opt_rdata).toText());
- // Unknown flag: ignored in the toText() output.
- EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n",
- EDNS(Name::ROOT_NAME(), rrclass, rrtype,
- RRTTL(0x00008001), *opt_rdata).toText());
- }
- TEST_F(EDNSTest, toWireRenderer) {
- // Typical case, (explicitly) disabling DNSSEC
- edns_base.setDNSSECAwareness(false);
- EXPECT_EQ(1, edns_base.toWire(renderer,
- Rcode::NOERROR().getExtendedCode()));
- UnitTestUtil::readWireData("edns_toWire1.wire", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
- renderer.getLength(), &wiredata[0], wiredata.size());
- // Typical case, enabling DNSSEC
- renderer.clear();
- wiredata.clear();
- edns_base.setDNSSECAwareness(true);
- EXPECT_EQ(1, edns_base.toWire(renderer,
- Rcode::NOERROR().getExtendedCode()));
- UnitTestUtil::readWireData("edns_toWire2.wire", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
- renderer.getLength(), &wiredata[0], wiredata.size());
- // Non-0 extended Rcode
- renderer.clear();
- wiredata.clear();
- edns_base.setDNSSECAwareness(true);
- EXPECT_EQ(1, edns_base.toWire(renderer,
- Rcode::BADVERS().getExtendedCode()));
- UnitTestUtil::readWireData("edns_toWire3.wire", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
- renderer.getLength(), &wiredata[0], wiredata.size());
- // Uncommon UDP buffer size
- renderer.clear();
- wiredata.clear();
- edns_base.setDNSSECAwareness(true);
- edns_base.setUDPSize(511);
- EXPECT_EQ(1, edns_base.toWire(renderer,
- Rcode::NOERROR().getExtendedCode()));
- UnitTestUtil::readWireData("edns_toWire4.wire", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
- renderer.getLength(), &wiredata[0], wiredata.size());
- // From RR with unknown flag. If used for toWire(), the unknown flag
- // should disappear.
- renderer.clear();
- wiredata.clear();
- EXPECT_EQ(1, EDNS(Name::ROOT_NAME(), rrclass, rrtype, RRTTL(0x00008001),
- *opt_rdata).toWire(renderer,
- Rcode::NOERROR().getExtendedCode()));
- UnitTestUtil::readWireData("edns_toWire2.wire", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
- renderer.getLength(), &wiredata[0], wiredata.size());
- // If the available length in the renderer is not sufficient for the OPT
- // RR, it shouldn't be inserted.
- renderer.clear();
- renderer.setLengthLimit(10); // 10 = minimum length of OPT RR - 1
- edns_base.setDNSSECAwareness(true);
- edns_base.setUDPSize(4096);
- EXPECT_EQ(0, edns_base.toWire(renderer,
- Rcode::NOERROR().getExtendedCode()));
- // renderer should be intact
- EXPECT_EQ(0, renderer.getLength());
- }
- TEST_F(EDNSTest, toWireBuffer) {
- // "to renderer" and "to buffer" should generally produce the same result.
- // for simplicity we only check one typical case to confirm that.
- EXPECT_EQ(1, edns_base.toWire(obuffer,
- Rcode::NOERROR().getExtendedCode()));
- UnitTestUtil::readWireData("edns_toWire1.wire", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
- obuffer.getLength(), &wiredata[0], wiredata.size());
- }
- TEST_F(EDNSTest, createFromRR) {
- uint8_t extended_rcode;
- // normal case
- edns = ConstEDNSPtr(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype,
- rrttl_do_on, *opt_rdata,
- extended_rcode));
- EXPECT_EQ(EDNS::SUPPORTED_VERSION, edns->getVersion());
- EXPECT_TRUE(edns->getDNSSECAwareness());
- EXPECT_EQ(4096, edns->getUDPSize());
- EXPECT_EQ(0, static_cast<int>(extended_rcode));
- // non-0 extended rcode
- extended_rcode = 0;
- ConstEDNSPtr(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype,
- RRTTL(0x01008000), *opt_rdata,
- extended_rcode));
- EXPECT_EQ(1, static_cast<int>(extended_rcode));
- // creation triggers an exception. extended_rcode must be intact.
- extended_rcode = 0;
- EXPECT_THROW(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype,
- rrttl_badver, *opt_rdata, extended_rcode),
- DNSMessageBADVERS);
- EXPECT_EQ(0, static_cast<int>(extended_rcode));
- }
- // test operator<<. We simply confirm it appends the result of toText().
- TEST_F(EDNSTest, LeftShiftOperator) {
- ostringstream oss;
- oss << edns_base;
- EXPECT_EQ(edns_base.toText(), oss.str());
- }
- }
|