diff --git a/src/seeder/test/seeder_tests.cpp b/src/seeder/test/seeder_tests.cpp --- a/src/seeder/test/seeder_tests.cpp +++ b/src/seeder/test/seeder_tests.cpp @@ -4,12 +4,115 @@ #define BOOST_TEST_MODULE Bitcoin Seeder Test Suite +#include + #include +#include +#include +#include +#include +#include + 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 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(i - lastperiod); + while (lastperiod < i) { + querryhex << std::setw(1) + << static_cast(qname[lastperiod]); + lastperiod++; + } + lastperiod = i + 1; + } + i++; + } + querryhex << std::setw(1) << static_cast(i - lastperiod); + while (lastperiod < i) { + querryhex << std::setw(1) << static_cast(qname[lastperiod]); + lastperiod++; + } + // End of name field + querryhex << std::setw(1) << static_cast(0); + // QTYPE = A query + querryhex << std::setw(2) << static_cast(1); + // QCLASS = IN + querryhex << std::setw(2) << static_cast(1); + + std::array messageBuffer; + messageBuffer.fill(0); + querryhex >> std::hex >> messageBuffer.data(); + return messageBuffer; +} + BOOST_AUTO_TEST_CASE(parse_name_simple) { - BOOST_CHECK_EQUAL(true, true); + const std::string messageQName = "www.mydomain.com"; + std::array dnsMessage; + dnsMessage.fill(0); + dnsMessage = CreateDNSQuestion(messageQName); + std::array 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()