Changeset View
Changeset View
Standalone View
Standalone View
src/seeder/test/seeder_tests.cpp
// Copyright (c) 2019 The Bitcoin developers | // Copyright (c) 2019 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#define BOOST_TEST_MODULE Bitcoin Seeder Test Suite | #define BOOST_TEST_MODULE Bitcoin Seeder Test Suite | ||||
#include <seeder/dns.h> | |||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
#include <array> | |||||
#include <iomanip> | |||||
#include <iostream> | |||||
#include <sstream> | |||||
#include <string> | |||||
BOOST_AUTO_TEST_SUITE(seeder) | BOOST_AUTO_TEST_SUITE(seeder) | ||||
const int BUFFER_LENGTH = 512; | |||||
const int QNAME_BUFFER_LENGTH = 256; | |||||
const int SIZE_OF_QTYPE = 2; | |||||
const int SIZE_OF_QCLASS = 2; | |||||
// Builds dummy DNS query message | |||||
std::array<uint8_t, BUFFER_LENGTH> CreateDNSQuestion(const std::string &qname) { | |||||
std::stringstream querryhex; | |||||
querryhex.clear(); | |||||
querryhex << std::hex << std::setfill('0'); | |||||
// Build the DNS message question section | |||||
size_t i = 0; | |||||
size_t lastperiod = 0; | |||||
while (i < qname.size()) { | |||||
if (qname[i] == '.') { | |||||
querryhex << std::setw(1) << static_cast<uint8_t>(i - lastperiod); | |||||
while (lastperiod < i) { | |||||
querryhex << std::setw(1) | |||||
<< static_cast<uint8_t>(qname[lastperiod]); | |||||
lastperiod++; | |||||
} | |||||
lastperiod = i + 1; | |||||
} | |||||
i++; | |||||
} | |||||
querryhex << std::setw(1) << static_cast<uint8_t>(i - lastperiod); | |||||
while (lastperiod < i) { | |||||
querryhex << std::setw(1) << static_cast<uint8_t>(qname[lastperiod]); | |||||
lastperiod++; | |||||
} | |||||
// End of name field | |||||
querryhex << std::setw(1) << static_cast<uint8_t>(0); | |||||
// QTYPE = A query | |||||
querryhex << std::setw(2) << static_cast<uint8_t>(1); | |||||
// QCLASS = IN | |||||
querryhex << std::setw(2) << static_cast<uint8_t>(1); | |||||
std::array<uint8_t, BUFFER_LENGTH> messageBuffer; | |||||
messageBuffer.fill(0); | |||||
querryhex >> std::hex >> messageBuffer.data(); | |||||
return messageBuffer; | |||||
} | |||||
BOOST_AUTO_TEST_CASE(parse_name_simple) { | BOOST_AUTO_TEST_CASE(parse_name_simple) { | ||||
BOOST_CHECK_EQUAL(true, true); | const std::string messageQName = "www.mydomain.com"; | ||||
std::array<uint8_t, BUFFER_LENGTH> dnsMessage; | |||||
dnsMessage.fill(0); | |||||
dnsMessage = CreateDNSQuestion(messageQName); | |||||
std::array<char, QNAME_BUFFER_LENGTH> qname; | |||||
qname.fill(0); | |||||
size_t writeBufferSize = QNAME_BUFFER_LENGTH; | |||||
const uint8_t *messageBegin = dnsMessage.data(); | |||||
// +1 for the last octet ending the field name | |||||
const uint8_t *messageEnd = dnsMessage.data() + messageQName.size() + 1 + | |||||
SIZE_OF_QTYPE + SIZE_OF_QCLASS; | |||||
int ret = parse_name(&messageBegin, messageEnd, dnsMessage.data(), | |||||
qname.data(), writeBufferSize); | |||||
BOOST_CHECK_EQUAL(ret, 0); | |||||
BOOST_CHECK_EQUAL(qname.data(), messageQName); | |||||
// Test for insufficient output buffer size | |||||
qname.fill(0); | |||||
messageBegin = dnsMessage.data(); | |||||
// The size of the buffer being written to is 1 octect too small | |||||
ret = parse_name(&messageBegin, messageEnd, dnsMessage.data(), qname.data(), | |||||
messageQName.size()); | |||||
BOOST_CHECK_EQUAL(ret, -2); | |||||
BOOST_CHECK_EQUAL(qname.data(), | |||||
messageQName.substr(0, messageQName.size() - 1)); | |||||
// Test for premature end of input buffer | |||||
qname.fill(0); | |||||
messageBegin = dnsMessage.data(); | |||||
// The end index pointer for the DNS message buffer passed is located two | |||||
// octets away from the beginning | |||||
ret = parse_name(&messageBegin, messageBegin + 2, dnsMessage.data(), | |||||
qname.data(), writeBufferSize); | |||||
BOOST_CHECK_EQUAL(ret, -1); | |||||
BOOST_CHECK_EQUAL(qname.data(), messageQName.substr(0, 1)); | |||||
// Test for when name field is too long | |||||
std::string tooLongQName = "www."; | |||||
for (size_t i = 0; i < 65; i++) { | |||||
tooLongQName += 'a'; | |||||
} | |||||
tooLongQName += ".com"; | |||||
qname.fill(0); | |||||
dnsMessage = CreateDNSQuestion(tooLongQName); | |||||
messageBegin = dnsMessage.data(); | |||||
messageEnd = dnsMessage.data() + tooLongQName.size() + 1 + SIZE_OF_QTYPE + | |||||
SIZE_OF_QCLASS; | |||||
ret = parse_name(&messageBegin, messageEnd, dnsMessage.data(), qname.data(), | |||||
writeBufferSize); | |||||
BOOST_CHECK_EQUAL(ret, -1); | |||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |