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 <array> | |||||
#include <string> | |||||
#include <vector> | |||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
BOOST_AUTO_TEST_SUITE(seeder_tests) | BOOST_AUTO_TEST_SUITE(seeder_tests) | ||||
BOOST_AUTO_TEST_CASE(test_stub) { | static const int QUERY_NAME_BUFFER_LENGTH = 256; | ||||
BOOST_CHECK_EQUAL(true, true); | static const int QUERY_TYPE_SIZE = 2; | ||||
static const int QUERY_CLASS_SIZE = 2; | |||||
static const uint16_t QUERY_CLASS_IN = 1; | |||||
static const uint16_t QUERY_TYPE_A = 1; | |||||
static const uint8_t END_OF_NAME_FIELD = 0; | |||||
static const size_t MAX_LABEL_LENGTH = 63; | |||||
std::vector<uint8_t> CreateDNSQuestion(const std::string &queryName) { | |||||
deadalnix: Query not Question. | |||||
nakihitoAuthorUnsubmitted Done Inline ActionsThis is actually only building the Question section of the DNS message (see sections 4.1 and 4.1.2 of https://www.zytrax.com/books/dns/apd/rfc1035.txt). I have adjusted other variable names to better reflect this. nakihito: This is actually only building the Question section of the DNS message (see sections 4.1 and 4. | |||||
std::vector<uint8_t> queryhex; | |||||
deadalnixUnsubmitted Not Done Inline ActionsThis is not hex. deadalnix: This is not hex. | |||||
// Build the DNS message question section | |||||
size_t i = 0; | |||||
size_t lastPeriod = 0; | |||||
while (i < queryName.size()) { | |||||
if (queryName[i] == '.') { | |||||
uint8_t labelLength = i - lastPeriod; | |||||
queryhex.push_back(labelLength); | |||||
while (lastPeriod < i) { | |||||
queryhex.push_back(queryName[lastPeriod]); | |||||
lastPeriod++; | |||||
} | |||||
lastPeriod = i + 1; | |||||
} | |||||
i++; | |||||
} | |||||
uint8_t labelLength = i - lastPeriod; | |||||
queryhex.push_back(labelLength); | |||||
while (lastPeriod < i) { | |||||
queryhex.push_back(queryName[lastPeriod]); | |||||
lastPeriod++; | |||||
} | |||||
queryhex.push_back(END_OF_NAME_FIELD); | |||||
queryhex.push_back(QUERY_TYPE_A); | |||||
queryhex.push_back(QUERY_CLASS_IN); | |||||
return queryhex; | |||||
} | |||||
BOOST_AUTO_TEST_CASE(parse_name_happy_path) { | |||||
const std::string messageQueryName = "www.mydomain.com"; | |||||
std::vector<uint8_t> dnsMessage = CreateDNSQuestion(messageQueryName); | |||||
std::array<char, QUERY_NAME_BUFFER_LENGTH> queryName; | |||||
queryName.fill(0); | |||||
const uint8_t *messageBegin = dnsMessage.data(); | |||||
// +1 for the last octet ending the field name | |||||
const size_t messageEndIndex = | |||||
messageQueryName.size() + 1 + QUERY_TYPE_SIZE + QUERY_CLASS_SIZE; | |||||
int ret = parse_name(&messageBegin, messageBegin + messageEndIndex, | |||||
dnsMessage.data(), queryName.data(), | |||||
QUERY_NAME_BUFFER_LENGTH); | |||||
BOOST_CHECK_EQUAL(ret, 0); | |||||
BOOST_CHECK_EQUAL(queryName.data(), messageQueryName); | |||||
} | |||||
// Test for insufficient output buffer size | |||||
BOOST_AUTO_TEST_CASE(parse_name_insufficient_output_buffer_size) { | |||||
const std::string messageQueryName = "www.mydomain.com"; | |||||
std::vector<uint8_t> dnsMessage = CreateDNSQuestion(messageQueryName); | |||||
std::array<char, QUERY_NAME_BUFFER_LENGTH> queryName; | |||||
queryName.fill(0); | |||||
const uint8_t *messageBegin = dnsMessage.data(); | |||||
// +1 for the last octet ending the field name | |||||
const size_t messageEndIndex = | |||||
messageQueryName.size() + 1 + QUERY_TYPE_SIZE + QUERY_CLASS_SIZE; | |||||
// The size of the buffer being written to is 1 octect too small | |||||
int ret = parse_name(&messageBegin, messageBegin + messageEndIndex, | |||||
dnsMessage.data(), queryName.data(), | |||||
messageQueryName.size()); | |||||
BOOST_CHECK_EQUAL(ret, -2); | |||||
BOOST_CHECK_EQUAL(queryName.data(), | |||||
messageQueryName.substr(0, messageQueryName.size() - 1)); | |||||
} | |||||
// Test for premature end of input buffer | |||||
BOOST_AUTO_TEST_CASE(parse_name_premature_end_of_input_buffer) { | |||||
const std::string messageQueryName = "www.mydomain.com"; | |||||
std::vector<uint8_t> dnsMessage = CreateDNSQuestion(messageQueryName); | |||||
std::array<char, QUERY_NAME_BUFFER_LENGTH> queryName; | |||||
queryName.fill(0); | |||||
const uint8_t *messageBegin = dnsMessage.data(); | |||||
// The end index pointer for the DNS message buffer passed is located two | |||||
// octets away from the beginning | |||||
int ret = parse_name(&messageBegin, messageBegin + 2, dnsMessage.data(), | |||||
queryName.data(), QUERY_NAME_BUFFER_LENGTH); | |||||
BOOST_CHECK_EQUAL(ret, -1); | |||||
BOOST_CHECK_EQUAL(queryName.data(), messageQueryName.substr(0, 1)); | |||||
} | |||||
// Test for when name field is too long | |||||
BOOST_AUTO_TEST_CASE(parse_name_field_name_too_long) { | |||||
std::string tooLongQName = "www."; | |||||
for (size_t i = 0; i < MAX_LABEL_LENGTH + 1; i++) { | |||||
tooLongQName += 'a'; | |||||
} | |||||
tooLongQName += ".com"; | |||||
std::vector<uint8_t> dnsMessage = CreateDNSQuestion(tooLongQName); | |||||
std::array<char, QUERY_NAME_BUFFER_LENGTH> queryName; | |||||
queryName.fill(0); | |||||
const uint8_t *messageBegin = dnsMessage.data(); | |||||
size_t messageEndIndex = | |||||
tooLongQName.size() + 1 + QUERY_TYPE_SIZE + QUERY_CLASS_SIZE; | |||||
int ret = parse_name(&messageBegin, messageBegin + messageEndIndex, | |||||
dnsMessage.data(), queryName.data(), | |||||
QUERY_NAME_BUFFER_LENGTH); | |||||
BOOST_CHECK_EQUAL(ret, -1); | |||||
BOOST_CHECK_EQUAL(queryName.data(), tooLongQName.substr(0, 4)); | |||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |
Query not Question.