diff options
Diffstat (limited to 'test-dnsdistsvc_cc.cc')
-rw-r--r-- | test-dnsdistsvc_cc.cc | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/test-dnsdistsvc_cc.cc b/test-dnsdistsvc_cc.cc new file mode 100644 index 0000000..c15d07a --- /dev/null +++ b/test-dnsdistsvc_cc.cc @@ -0,0 +1,96 @@ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN + +#include <boost/test/unit_test.hpp> + +#include "dnsdist-svc.hh" +#include "svc-records.hh" +#include "dnsparser.hh" + +BOOST_AUTO_TEST_SUITE(dnsdistsvc_cc) + +BOOST_AUTO_TEST_CASE(test_Basic) +{ + DNSName target("powerdns.com."); + + { + std::vector<uint8_t> payload; + const uint16_t priority = 1; + BOOST_CHECK(generateSVCPayload(payload, priority, target, {SvcParam::SvcParamKey::port}, {"dot"}, false, 853, std::string(), {ComboAddress("192.0.2.1")}, {ComboAddress("2001:db8::1")}, {})); + /* 2 octet field for SvcPriority as an integer in network byte order */ + /* uncompressed, fully-qualified TargetName */ + /* list of SvcParams as: + - 2 octet field containing the SvcParamKey as an integer in network byte order + - 2 octet field containing the length of the SvcParamValue as an integer between 0 and 65535 in network byte order (but constrained by the RDATA and DNS message sizes) + - an octet string of this length whose contents are in a format determined by the SvcParamKey + SvcParamKeys SHALL appear in increasing numeric order + */ + size_t expectedSize = (/* priority */ 2) + target.wirelength() + (/* mandatory */ 2 + 2 + 2) + (/* alpns with 1-byte length field for each value */ 2 + 2 + 4) + (/* no-alpn-default is false */ 0) + (/* port */ 2 + 2 + 2) + (/* ech */ 0) + (/* v4 hints */ 2 + 2 + 9) + (/* v6 hints */ 2 + 2 + 11); + BOOST_CHECK_EQUAL(payload.size(), expectedSize); + + std::set<SvcParam> params; + PacketReader pr(std::string_view(reinterpret_cast<const char*>(payload.data()), payload.size()), 0); + BOOST_CHECK_EQUAL(pr.get16BitInt(), priority); + + /* we can't use getName() directly because it assumes that there has to be a dnsheader before the name */ + DNSName parsedTarget(reinterpret_cast<const char*>(payload.data()), payload.size(), pr.getPosition(), false /* uncompress */, nullptr /* qtype */, nullptr /* qclass */, nullptr /* consumed */, 0); + pr.skip(parsedTarget.wirelength()); + BOOST_CHECK_EQUAL(target.toString(), parsedTarget.toString()); + + pr.xfrSvcParamKeyVals(params); + BOOST_REQUIRE_EQUAL(params.size(), 5U); + auto param = params.begin(); + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::mandatory); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::alpn); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::port); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::ipv4hint); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::ipv6hint); + } + + { + std::vector<uint8_t> payload; + const uint16_t priority = 2; + const std::string ech("whatever"); + const std::string dohParam("/dns-query{?dns}"); + + BOOST_CHECK(generateSVCPayload(payload, priority, target, {SvcParam::SvcParamKey::port}, {"h2"}, true, 443, ech, {ComboAddress("192.0.2.2")}, {ComboAddress("2001:db8::2")}, {std::pair<uint16_t, std::string>(42, dohParam)})); + + size_t expectedSize = (/* priority */ 2) + target.wirelength() + (/* mandatory */ 2 + 2 + 2) + (/* alpns */ 2 + 2 + 3) + (/* no-alpn-default is true */ 2 + 2) + (/* port */ 2 + 2 + 2) + (/* ech */ 2 + 2 + ech.size()) + (/* v4 hints */ 2 + 2 + 9) + (/* v6 hints */ 2 + 2 + 11) + (/* doh parameter */ 2 + 2 + dohParam.size()); + BOOST_CHECK_EQUAL(payload.size(), expectedSize); + + std::set<SvcParam> params; + PacketReader pr(std::string_view(reinterpret_cast<const char*>(payload.data()), payload.size()), 0); + BOOST_CHECK_EQUAL(pr.get16BitInt(), priority); + + /* we can't use getName() directly because it assumes that there has to be a dnsheader before the name */ + DNSName parsedTarget(reinterpret_cast<const char*>(payload.data()), payload.size(), pr.getPosition(), false /* uncompress */, nullptr /* qtype */, nullptr /* qclass */, nullptr /* consumed */, 0); + pr.skip(parsedTarget.wirelength()); + BOOST_CHECK_EQUAL(target.toString(), parsedTarget.toString()); + + pr.xfrSvcParamKeyVals(params); + BOOST_REQUIRE_EQUAL(params.size(), 8U); + auto param = params.begin(); + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::mandatory); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::alpn); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::no_default_alpn); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::port); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::ipv4hint); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::ech); + ++param; + BOOST_CHECK(param->getKey() == SvcParam::SvcParamKey::ipv6hint); + ++param; + BOOST_CHECK_EQUAL(static_cast<uint16_t>(param->getKey()), 42U); + } +} + +BOOST_AUTO_TEST_SUITE_END() |