2018-10-11 11:51:13 +00:00
|
|
|
#include <gtest/gtest.h>
|
2018-12-10 14:14:55 +00:00
|
|
|
#include <llarp.h> // for llarp_main_init
|
|
|
|
#include <llarp/logic.hpp> // for threadpool/llarp::Logic
|
|
|
|
#include "llarp/net.hpp" // for llarp::Addr
|
2018-10-11 11:51:13 +00:00
|
|
|
#include "llarp/dns.hpp"
|
|
|
|
#include "llarp/dnsc.hpp"
|
|
|
|
|
|
|
|
struct DNSTest : public ::testing::Test
|
|
|
|
{
|
|
|
|
unsigned char buf[47] = {
|
2018-11-07 15:30:22 +00:00
|
|
|
0x00, 0x01, // first short
|
|
|
|
0x01, 0x00, 0x00, // combined fields
|
|
|
|
0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // last 4 shorts
|
|
|
|
// question (is 18 bytes long)
|
|
|
|
0x04, // 4 letters
|
|
|
|
0x6C, 0x6F, 0x6B, 0x69, // loki
|
|
|
|
0x07, // 7 letters
|
|
|
|
0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, // network
|
|
|
|
0x00, // end
|
|
|
|
0x00, 0x01, // type (a 1/ptr 12)
|
|
|
|
0x00, 0x01, // class (1 = internet)
|
|
|
|
// 30th byte
|
|
|
|
// Answer (is 16 bytes long)
|
|
|
|
0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, // name, type, class
|
|
|
|
0x00, 0x00, 0x08, 0x4b, // ttl 2123
|
|
|
|
0x00, 0x04, // rdLen
|
|
|
|
0x45, 0x10, 0xd1, 0x02, // an ip address
|
|
|
|
// extra
|
|
|
|
0x00 // null terminator (probably don't need this, just added it)
|
2018-10-11 11:51:13 +00:00
|
|
|
};
|
2018-11-21 23:47:11 +00:00
|
|
|
llarp_buffer_t buffer_t;
|
2018-10-11 11:51:13 +00:00
|
|
|
|
|
|
|
DNSTest()
|
|
|
|
{
|
2018-11-21 23:47:11 +00:00
|
|
|
this->buffer_t.base = (byte_t *)this->buf;
|
|
|
|
this->buffer_t.cur = buffer_t.base;
|
|
|
|
this->buffer_t.sz = 47;
|
2018-10-11 11:51:13 +00:00
|
|
|
}
|
2018-10-11 12:22:29 +00:00
|
|
|
|
2018-10-11 11:51:13 +00:00
|
|
|
void
|
|
|
|
SetUp()
|
|
|
|
{
|
2018-11-07 15:30:22 +00:00
|
|
|
llarp::SetLogLevel(
|
|
|
|
llarp::eLogNone); // turn off logging to keep gtest output pretty
|
2018-10-11 11:51:13 +00:00
|
|
|
/*
|
|
|
|
const char *url = "loki.network";
|
2018-11-07 15:30:22 +00:00
|
|
|
struct dns_query *packet = build_dns_packet((char *)url, 1, 1); // id 1,
|
|
|
|
type 1 (A)
|
2018-10-11 12:22:29 +00:00
|
|
|
|
2018-10-11 11:51:13 +00:00
|
|
|
unsigned int length = packet->length;
|
|
|
|
char *buffer = (char *)packet->request;
|
|
|
|
char hex_buffer[length * 5 + 1];
|
|
|
|
hex_buffer[length * 5] = 0;
|
|
|
|
for(unsigned int j = 0; j < length; j++)
|
|
|
|
sprintf(&hex_buffer[5 * j], "0x%02X,", ((const char *)buffer)[j]);
|
|
|
|
printf("Generated [%u] bytes: [%s]\n", length, hex_buffer);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// test puts/gets
|
|
|
|
// test code_domain / getDNSstring
|
|
|
|
TEST_F(DNSTest, TestDecodeDNSstring)
|
|
|
|
{
|
|
|
|
char *buffer = (char *)this->buf;
|
2018-11-07 15:30:22 +00:00
|
|
|
buffer += 12; // skip header
|
|
|
|
uint32_t pos = 0;
|
2018-11-03 13:19:18 +00:00
|
|
|
std::string res = getDNSstring(buffer, &pos);
|
2018-10-11 11:51:13 +00:00
|
|
|
ASSERT_TRUE(res == "loki.network");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DNSTest, TestCodeDomain)
|
|
|
|
{
|
|
|
|
char buffer[16];
|
2018-10-30 12:30:21 +00:00
|
|
|
llarp::Zero(buffer, 16);
|
2018-10-11 11:51:13 +00:00
|
|
|
char *write_buffer = buffer;
|
2018-11-07 15:30:22 +00:00
|
|
|
std::string url = "bob.com";
|
2018-10-11 11:51:13 +00:00
|
|
|
code_domain(write_buffer, url);
|
|
|
|
|
|
|
|
char hex_buffer[16 * 3 + 1];
|
|
|
|
hex_buffer[16 * 3] = 0;
|
|
|
|
for(unsigned int j = 0; j < 16; j++)
|
|
|
|
sprintf(&hex_buffer[3 * j], "%02X ", ((const char *)buffer)[j]);
|
2018-11-07 15:30:22 +00:00
|
|
|
// printf("first 16 [%s]", hex_buffer);
|
2018-10-11 12:22:29 +00:00
|
|
|
|
2018-11-07 15:30:22 +00:00
|
|
|
std::string expected_result =
|
|
|
|
"03 62 6F 62 03 63 6F 6D 00 00 00 00 00 00 00 00 ";
|
2018-10-11 11:51:13 +00:00
|
|
|
ASSERT_TRUE(hex_buffer == expected_result);
|
|
|
|
}
|
|
|
|
|
|
|
|
// test decoders
|
|
|
|
TEST_F(DNSTest, TestDecodeHdr)
|
|
|
|
{
|
2018-12-01 14:35:11 +00:00
|
|
|
dns_msg_header hdr;
|
|
|
|
ASSERT_TRUE(decode_hdr(&this->buffer_t, &hdr));
|
|
|
|
// rewind
|
|
|
|
buffer_t.cur = buffer_t.base;
|
2018-10-11 11:51:13 +00:00
|
|
|
/*
|
|
|
|
printf("id[%d]", hdr->id);
|
|
|
|
printf("qr[%d]", hdr->qr);
|
|
|
|
printf("oc[%d]", hdr->opcode);
|
|
|
|
printf("aa[%d]", hdr->aa);
|
|
|
|
printf("tc[%d]", hdr->tc);
|
|
|
|
printf("rd[%d]", hdr->rd);
|
|
|
|
printf("ra[%d]", hdr->ra);
|
|
|
|
printf("z [%d]", hdr->z);
|
|
|
|
printf("ad[%d]", hdr->ad);
|
2018-10-11 12:22:29 +00:00
|
|
|
printf("cd[%d]", hdr->cd);
|
2018-10-11 11:51:13 +00:00
|
|
|
printf("rc[%d]", hdr->rcode);
|
|
|
|
printf("qd[%d]", hdr->qdCount);
|
|
|
|
printf("an[%d]", hdr->anCount);
|
|
|
|
printf("ns[%d]", hdr->nsCount);
|
|
|
|
printf("ar[%d]", hdr->arCount);
|
|
|
|
*/
|
2018-12-01 14:35:11 +00:00
|
|
|
ASSERT_TRUE(hdr.id == 1);
|
|
|
|
ASSERT_TRUE(hdr.qr == 0);
|
|
|
|
ASSERT_TRUE(hdr.opcode == 0);
|
|
|
|
ASSERT_TRUE(hdr.aa == 0);
|
|
|
|
ASSERT_TRUE(hdr.tc == 0);
|
|
|
|
ASSERT_TRUE(hdr.rd == 0);
|
|
|
|
ASSERT_TRUE(hdr.ra == 0);
|
|
|
|
ASSERT_TRUE(hdr.z == 0);
|
|
|
|
ASSERT_TRUE(hdr.ad == 0);
|
|
|
|
ASSERT_TRUE(hdr.cd == 0);
|
|
|
|
ASSERT_TRUE(hdr.rcode == 0);
|
|
|
|
ASSERT_TRUE(hdr.qdCount == 1);
|
|
|
|
ASSERT_TRUE(hdr.anCount == 1);
|
|
|
|
ASSERT_TRUE(hdr.nsCount == 0);
|
|
|
|
ASSERT_TRUE(hdr.arCount == 0);
|
2018-10-11 11:51:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DNSTest, TestDecodeQuestion)
|
|
|
|
{
|
|
|
|
char *buffer = (char *)this->buf;
|
2018-11-07 15:30:22 +00:00
|
|
|
buffer += 12; // skip header
|
|
|
|
uint32_t pos = 0;
|
2018-11-03 13:19:18 +00:00
|
|
|
dns_msg_question *question = decode_question(buffer, &pos);
|
2018-11-07 15:30:22 +00:00
|
|
|
// printf("name[%s]", question->name.c_str());
|
|
|
|
// printf("type[%d]", question->type);
|
|
|
|
// printf("qClass[%d]", question->qClass);
|
2018-10-11 11:51:13 +00:00
|
|
|
std::string url = "loki.network";
|
|
|
|
ASSERT_TRUE(question->name == url);
|
|
|
|
ASSERT_TRUE(question->type == 1);
|
|
|
|
ASSERT_TRUE(question->qClass == 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DNSTest, TestDecodeAnswer)
|
|
|
|
{
|
2018-11-07 15:30:22 +00:00
|
|
|
const char *const buffer = (const char *)this->buf;
|
|
|
|
uint32_t pos = 12;
|
|
|
|
std::string url = "loki.network";
|
|
|
|
pos += url.length() + 2 + 4; // skip question (string + 2 shorts)
|
2018-11-03 13:19:18 +00:00
|
|
|
|
|
|
|
dns_msg_answer *answer = decode_answer(buffer, &pos);
|
2018-10-11 11:51:13 +00:00
|
|
|
/*
|
|
|
|
printf("type[%d]", answer->type);
|
|
|
|
printf("aClass[%d]", answer->aClass);
|
|
|
|
printf("ttl[%d]", answer->ttl);
|
|
|
|
printf("rdLen[%d]", answer->rdLen);
|
2018-11-07 15:30:22 +00:00
|
|
|
printf("[%hhu].[%hhu].[%hhu].[%hhu]", answer->rData[0], answer->rData[1],
|
|
|
|
answer->rData[2], answer->rData[3]);
|
2018-10-11 11:51:13 +00:00
|
|
|
*/
|
2018-11-03 13:19:18 +00:00
|
|
|
ASSERT_TRUE(answer->name == url);
|
2018-10-11 11:51:13 +00:00
|
|
|
ASSERT_TRUE(answer->type == 1);
|
|
|
|
ASSERT_TRUE(answer->aClass == 1);
|
|
|
|
ASSERT_TRUE(answer->ttl == 2123);
|
|
|
|
ASSERT_TRUE(answer->rdLen == 4);
|
|
|
|
ASSERT_TRUE(answer->rData[0] == 69);
|
|
|
|
ASSERT_TRUE(answer->rData[1] == 16);
|
|
|
|
ASSERT_TRUE(answer->rData[2] == 209);
|
|
|
|
ASSERT_TRUE(answer->rData[3] == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// UDP handling configuration
|
|
|
|
struct llarp_udp_io_mock
|
|
|
|
{
|
|
|
|
/// set after added
|
|
|
|
int fd;
|
|
|
|
void *user;
|
|
|
|
void *impl;
|
|
|
|
struct llarp_ev_loop *parent;
|
|
|
|
/// called every event loop tick after reads
|
|
|
|
void (*tick)(struct llarp_udp_io *);
|
|
|
|
// sockaddr * is the source
|
|
|
|
void (*recvfrom)(struct llarp_udp_io *, const struct sockaddr *, const void *,
|
|
|
|
ssize_t);
|
|
|
|
};
|
|
|
|
|
|
|
|
// will have to mock udp and intercept the sendto call...
|
|
|
|
// test llarp_handle_dns_recvfrom
|
|
|
|
TEST_F(DNSTest, handleDNSrecvFrom)
|
|
|
|
{
|
|
|
|
llarp_udp_io_mock udp;
|
|
|
|
sockaddr addr;
|
|
|
|
char buffer[16];
|
|
|
|
llarp::Zero(&buffer, 15);
|
|
|
|
ssize_t sz = 0;
|
|
|
|
// hdr->qr decides dnsc (1) or dnsd (0)
|
2018-12-10 14:14:55 +00:00
|
|
|
llarp_handle_dns_recvfrom((llarp_udp_io *)&udp, &addr,
|
|
|
|
llarp::InitBuffer(buffer, sz));
|
2018-10-11 11:51:13 +00:00
|
|
|
// llarp_handle_dnsc_recvfrom
|
|
|
|
// llarp_handle_dnsd_recvfrom
|
|
|
|
}
|