diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 21:14:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 21:14:49 +0000 |
commit | 2f230033794fafdf10822568e763d4db68cf6c6b (patch) | |
tree | 39ca5c2325b7b43c9a28ca6d4ad4026a61e7eb97 /test-dnsdistedns.cc | |
parent | Adding debian version 1.8.3-3. (diff) | |
download | dnsdist-2f230033794fafdf10822568e763d4db68cf6c6b.tar.xz dnsdist-2f230033794fafdf10822568e763d4db68cf6c6b.zip |
Merging upstream version 1.9.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test-dnsdistedns.cc')
-rw-r--r-- | test-dnsdistedns.cc | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/test-dnsdistedns.cc b/test-dnsdistedns.cc new file mode 100644 index 0000000..603bc3e --- /dev/null +++ b/test-dnsdistedns.cc @@ -0,0 +1,202 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef BOOST_TEST_DYN_LINK +#define BOOST_TEST_DYN_LINK +#endif + +#define BOOST_TEST_NO_MAIN + +#include <boost/test/unit_test.hpp> + +#include "dnsdist-edns.hh" +#include "dnsname.hh" +#include "dnswriter.hh" +#include "ednscookies.hh" +#include "ednsextendederror.hh" +#include "ednsoptions.hh" +#include "ednssubnet.hh" + +BOOST_AUTO_TEST_SUITE(test_dnsdist_edns) + +BOOST_AUTO_TEST_CASE(getExtendedDNSError) +{ + const DNSName name("www.powerdns.com."); + + { + /* no EDNS */ + PacketBuffer query; + GenericDNSPacketWriter<PacketBuffer> pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(!infoCode); + BOOST_CHECK(!extraText); + } + + { + /* EDNS but no EDE */ + PacketBuffer query; + GenericDNSPacketWriter<PacketBuffer> pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + pw.addOpt(512, 0, 0); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(!infoCode); + BOOST_CHECK(!extraText); + } + + { + /* EDE with a numerical code but no text */ + PacketBuffer query; + GenericDNSPacketWriter<PacketBuffer> pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter<PacketBuffer>::optvect_t opts; + const EDNSExtendedError ede{ + .infoCode = static_cast<uint16_t>(EDNSExtendedError::code::NetworkError), + .extraText = ""}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(!extraText); + } + + { + /* EDE with both code and text */ + PacketBuffer query; + GenericDNSPacketWriter<PacketBuffer> pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter<PacketBuffer>::optvect_t opts; + const EDNSExtendedError ede{ + .infoCode = static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(extraText); + BOOST_CHECK_EQUAL(*extraText, ede.extraText); + } + + { + /* EDE with truncated text */ + PacketBuffer query; + GenericDNSPacketWriter<PacketBuffer> pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter<PacketBuffer>::optvect_t opts; + const EDNSExtendedError ede{ + .infoCode = static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + /* truncate the EDE text by one byte */ + query.resize(query.size() - 1U); + + BOOST_CHECK_THROW(dnsdist::edns::getExtendedDNSError(query), std::range_error); + } + + { + /* EDE before ECS */ + PacketBuffer query; + GenericDNSPacketWriter<PacketBuffer> pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter<PacketBuffer>::optvect_t opts; + const EDNSExtendedError ede{ + .infoCode = static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + EDNSSubnetOpts ecsOpt; + ecsOpt.source = Netmask(ComboAddress("192.0.2.1"), 24U); + const auto ecsOptStr = makeEDNSSubnetOptsString(ecsOpt); + opts.emplace_back(EDNSOptionCode::ECS, ecsOptStr); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(extraText); + BOOST_CHECK_EQUAL(*extraText, ede.extraText); + } + + { + /* EDE after ECS */ + PacketBuffer query; + GenericDNSPacketWriter<PacketBuffer> pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter<PacketBuffer>::optvect_t opts; + EDNSSubnetOpts ecsOpt; + ecsOpt.source = Netmask(ComboAddress("192.0.2.1"), 24U); + const auto ecsOptStr = makeEDNSSubnetOptsString(ecsOpt); + opts.emplace_back(EDNSOptionCode::ECS, ecsOptStr); + const EDNSExtendedError ede{ + .infoCode = static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(extraText); + BOOST_CHECK_EQUAL(*extraText, ede.extraText); + } + + { + /* Cookie, EDE, padding */ + PacketBuffer query; + GenericDNSPacketWriter<PacketBuffer> pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter<PacketBuffer>::optvect_t opts; + const EDNSCookiesOpt cookieOpt("deadbeefdeadbeef"); + const auto cookieOptStr = cookieOpt.makeOptString(); + opts.emplace_back(EDNSOptionCode::COOKIE, cookieOptStr); + const EDNSExtendedError ede{ + .infoCode = static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + std::string paddingOptStr; + paddingOptStr.resize(42U); + opts.emplace_back(EDNSOptionCode::PADDING, paddingOptStr); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(extraText); + BOOST_CHECK_EQUAL(*extraText, ede.extraText); + } +} + +BOOST_AUTO_TEST_SUITE_END(); |