mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
add dnslib unit test coverage
This commit is contained in:
parent
1d1bde2e88
commit
40678f9019
17 changed files with 468 additions and 229 deletions
2
Makefile
2
Makefile
|
@ -10,7 +10,7 @@ prefix = $(DESTDIR)/usr/local
|
|||
CC ?= cc
|
||||
CXX ?= c++
|
||||
|
||||
SETCAP ?= which setcap && setcap cap_net_bind_service,cap_net_admin=+eip
|
||||
SETCAP ?= which setcap && setcap cap_net_admin,cap_net_bind_service=+eip
|
||||
|
||||
SHADOW_ROOT ?= $(HOME)/.shadow
|
||||
SHADOW_BIN=$(SHADOW_ROOT)/bin/shadow
|
||||
|
|
|
@ -14,6 +14,10 @@ namespace llarp
|
|||
|
||||
struct MessageHeader : public Serialize
|
||||
{
|
||||
const static size_t Size = 12;
|
||||
|
||||
MessageHeader() = default;
|
||||
|
||||
MsgID_t id;
|
||||
Fields_t fields;
|
||||
Count_t qd_count;
|
||||
|
@ -26,20 +30,33 @@ namespace llarp
|
|||
|
||||
bool
|
||||
Decode(llarp_buffer_t* buf) override;
|
||||
|
||||
bool
|
||||
operator==(const MessageHeader& other) const
|
||||
{
|
||||
return id == other.id && fields == other.fields
|
||||
&& qd_count == other.qd_count && an_count == other.an_count
|
||||
&& ns_count == other.ns_count && ar_count == other.ar_count;
|
||||
}
|
||||
};
|
||||
|
||||
struct Message : public Serialize
|
||||
{
|
||||
Message(const MessageHeader& hdr);
|
||||
|
||||
Message(Message&& other);
|
||||
Message(const Message& other);
|
||||
|
||||
void
|
||||
UpdateHeader();
|
||||
|
||||
Message&
|
||||
void
|
||||
AddNXReply();
|
||||
|
||||
Message&
|
||||
void
|
||||
AddINReply(llarp::huint32_t addr);
|
||||
|
||||
Message&
|
||||
void
|
||||
AddAReply(std::string name);
|
||||
|
||||
bool
|
||||
|
@ -48,7 +65,27 @@ namespace llarp
|
|||
bool
|
||||
Decode(llarp_buffer_t* buf) override;
|
||||
|
||||
MessageHeader hdr;
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& out, const Message& msg)
|
||||
{
|
||||
out << "[dns message id=" << std::hex << msg.hdr_id
|
||||
<< " fields=" << msg.hdr_fields << " questions=[ ";
|
||||
for(const auto& qd : msg.questions)
|
||||
out << qd << ", ";
|
||||
out << "] answers=[ ";
|
||||
for(const auto& an : msg.answers)
|
||||
out << an << ", ";
|
||||
out << "] nameserver=[ ";
|
||||
for(const auto& ns : msg.authorities)
|
||||
out << ns << ", ";
|
||||
out << "] additional=[ ";
|
||||
for(const auto& ar : msg.additional)
|
||||
out << ar << ", ";
|
||||
return out << "]";
|
||||
}
|
||||
|
||||
MsgID_t hdr_id;
|
||||
Fields_t hdr_fields;
|
||||
std::vector< Question > questions;
|
||||
std::vector< ResourceRecord > answers;
|
||||
std::vector< ResourceRecord > authorities;
|
||||
|
|
|
@ -8,17 +8,34 @@ namespace llarp
|
|||
{
|
||||
namespace dns
|
||||
{
|
||||
using QType_t = llarp::huint16_t;
|
||||
using QClass_t = llarp::huint16_t;
|
||||
using QType_t = uint16_t;
|
||||
using QClass_t = uint16_t;
|
||||
|
||||
struct Question : public Serialize
|
||||
{
|
||||
Question() = default;
|
||||
Question(Question&& other);
|
||||
Question(const Question& other);
|
||||
bool
|
||||
Encode(llarp_buffer_t* buf) const override;
|
||||
|
||||
bool
|
||||
Decode(llarp_buffer_t* buf) override;
|
||||
|
||||
bool
|
||||
operator==(const Question& other) const
|
||||
{
|
||||
return qname == other.qname && qtype == other.qtype
|
||||
&& qclass == other.qclass;
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& out, const Question& q)
|
||||
{
|
||||
return out << "qname=" << q.qname << " qtype=" << (int)q.qtype
|
||||
<< " qclass=" << (int)q.qclass;
|
||||
}
|
||||
|
||||
Name_t qname;
|
||||
QType_t qtype;
|
||||
QClass_t qclass;
|
||||
|
|
|
@ -10,19 +10,31 @@ namespace llarp
|
|||
{
|
||||
namespace dns
|
||||
{
|
||||
using RRClass_t = llarp::huint16_t;
|
||||
using RRType_t = llarp::huint16_t;
|
||||
using RRClass_t = uint16_t;
|
||||
using RRType_t = uint16_t;
|
||||
using RR_RData_t = std::vector< byte_t >;
|
||||
using RR_TTL_t = llarp::huint32_t;
|
||||
using RR_TTL_t = uint32_t;
|
||||
|
||||
struct ResourceRecord : public Serialize
|
||||
{
|
||||
ResourceRecord() = default;
|
||||
ResourceRecord(const ResourceRecord& other);
|
||||
ResourceRecord(ResourceRecord&& other);
|
||||
|
||||
bool
|
||||
Encode(llarp_buffer_t* buf) const override;
|
||||
|
||||
bool
|
||||
Decode(llarp_buffer_t* buf) override;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& out, const ResourceRecord& rr)
|
||||
{
|
||||
return out << "[RR name=" << rr.rr_name << " type=" << rr.rr_type
|
||||
<< " class=" << rr.rr_class << " ttl=" << rr.ttl
|
||||
<< " rdata=[" << rr.rData.size() << " bytes]";
|
||||
}
|
||||
|
||||
Name_t rr_name;
|
||||
RRType_t rr_type;
|
||||
RRClass_t rr_class;
|
||||
|
|
|
@ -19,14 +19,6 @@ namespace llarp
|
|||
Decode(llarp_buffer_t* buf) = 0;
|
||||
};
|
||||
|
||||
template < typename Int_t >
|
||||
bool
|
||||
EncodeInt(llarp_buffer_t* buf, const Int_t& i);
|
||||
|
||||
template < typename Int_t >
|
||||
bool
|
||||
DecodeInt(llarp_buffer_t* buf, Int_t& i);
|
||||
|
||||
bool
|
||||
EncodeRData(llarp_buffer_t* buf, const std::vector< byte_t >& rdata);
|
||||
|
||||
|
|
|
@ -117,13 +117,3 @@ llarp_buffer_read_uint32(llarp_buffer_t* buf, uint32_t* i)
|
|||
buf->cur += sizeof(uint32_t);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_buffer_put_uint32(llarp_buffer_t* buf, uint32_t* i)
|
||||
{
|
||||
if(llarp_buffer_size_left(*buf) < sizeof(uint32_t))
|
||||
return false;
|
||||
*i = bufbe32toh(buf->cur);
|
||||
buf->cur += sizeof(uint32_t);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace llarp
|
|||
system = find_section(top, "system", section_t{});
|
||||
api = find_section(top, "api", section_t{});
|
||||
lokid = find_section(top, "lokid", section_t{});
|
||||
bootstrap = find_section(top, "bootstrap", section_t{});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <llarp/dns/message.hpp>
|
||||
#include <llarp/endian.hpp>
|
||||
#include <llarp/logger.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
|
@ -7,38 +9,76 @@ namespace llarp
|
|||
bool
|
||||
MessageHeader::Encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!EncodeInt(buf, id))
|
||||
if(!llarp_buffer_put_uint16(buf, id))
|
||||
return false;
|
||||
if(!EncodeInt(buf, fields))
|
||||
if(!llarp_buffer_put_uint16(buf, fields))
|
||||
return false;
|
||||
if(!EncodeInt(buf, qd_count))
|
||||
if(!llarp_buffer_put_uint16(buf, qd_count))
|
||||
return false;
|
||||
if(!EncodeInt(buf, an_count))
|
||||
if(!llarp_buffer_put_uint16(buf, an_count))
|
||||
return false;
|
||||
if(!EncodeInt(buf, ns_count))
|
||||
if(!llarp_buffer_put_uint16(buf, ns_count))
|
||||
return false;
|
||||
return EncodeInt(buf, ar_count);
|
||||
return llarp_buffer_put_uint16(buf, ar_count);
|
||||
}
|
||||
|
||||
bool
|
||||
MessageHeader::Decode(llarp_buffer_t* buf)
|
||||
{
|
||||
if(!DecodeInt(buf, id))
|
||||
if(!llarp_buffer_read_uint16(buf, &id))
|
||||
return false;
|
||||
if(!DecodeInt(buf, fields))
|
||||
if(!llarp_buffer_read_uint16(buf, &fields))
|
||||
return false;
|
||||
if(!DecodeInt(buf, qd_count))
|
||||
if(!llarp_buffer_read_uint16(buf, &qd_count))
|
||||
return false;
|
||||
if(!DecodeInt(buf, an_count))
|
||||
if(!llarp_buffer_read_uint16(buf, &an_count))
|
||||
return false;
|
||||
if(!DecodeInt(buf, ns_count))
|
||||
if(!llarp_buffer_read_uint16(buf, &ns_count))
|
||||
return false;
|
||||
return DecodeInt(buf, ar_count);
|
||||
return llarp_buffer_read_uint16(buf, &ar_count);
|
||||
}
|
||||
|
||||
Message::Message(Message&& other)
|
||||
: hdr_id(std::move(other.hdr_id))
|
||||
, hdr_fields(std::move(other.hdr_fields))
|
||||
, questions(std::move(other.questions))
|
||||
, answers(std::move(other.answers))
|
||||
, authorities(std::move(other.authorities))
|
||||
, additional(std::move(other.additional))
|
||||
{
|
||||
}
|
||||
|
||||
Message::Message(const Message& other)
|
||||
: hdr_id(other.hdr_id)
|
||||
, hdr_fields(other.hdr_fields)
|
||||
, questions(other.questions)
|
||||
, answers(other.answers)
|
||||
, authorities(other.authorities)
|
||||
, additional(other.additional)
|
||||
{
|
||||
}
|
||||
|
||||
Message::Message(const MessageHeader& hdr)
|
||||
: hdr_id(hdr.id)
|
||||
, hdr_fields(hdr.fields)
|
||||
, questions(size_t(hdr.qd_count))
|
||||
, answers(size_t(hdr.an_count))
|
||||
, authorities(size_t(hdr.ns_count))
|
||||
, additional(size_t(hdr.ar_count))
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Message::Encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
MessageHeader hdr;
|
||||
hdr.id = hdr_id;
|
||||
hdr.fields = hdr_fields;
|
||||
hdr.qd_count = questions.size();
|
||||
hdr.an_count = answers.size();
|
||||
hdr.ns_count = authorities.size();
|
||||
hdr.ar_count = additional.size();
|
||||
|
||||
if(!hdr.Encode(buf))
|
||||
return false;
|
||||
|
||||
|
@ -64,98 +104,100 @@ namespace llarp
|
|||
bool
|
||||
Message::Decode(llarp_buffer_t* buf)
|
||||
{
|
||||
if(!hdr.Decode(buf))
|
||||
return false;
|
||||
questions.resize(hdr.qd_count);
|
||||
answers.resize(hdr.an_count);
|
||||
authorities.resize(hdr.ns_count);
|
||||
additional.resize(hdr.ar_count);
|
||||
|
||||
for(auto& qd : questions)
|
||||
{
|
||||
if(!qd.Decode(buf))
|
||||
{
|
||||
llarp::LogError("failed to decode question");
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug(qd);
|
||||
}
|
||||
|
||||
for(auto& an : answers)
|
||||
{
|
||||
if(!an.Decode(buf))
|
||||
{
|
||||
llarp::LogError("failed to decode answer");
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug(an);
|
||||
}
|
||||
|
||||
for(auto& ns : authorities)
|
||||
{
|
||||
if(!ns.Decode(buf))
|
||||
{
|
||||
llarp::LogError("failed to decode authority");
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug(ns);
|
||||
}
|
||||
|
||||
for(auto& ar : additional)
|
||||
{
|
||||
if(!ar.Decode(buf))
|
||||
{
|
||||
llarp::LogError("failed to decode additonal");
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug(ar);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Message::UpdateHeader()
|
||||
{
|
||||
hdr.qd_count = questions.size();
|
||||
hdr.an_count = answers.size();
|
||||
hdr.ns_count = authorities.size();
|
||||
hdr.ar_count = additional.size();
|
||||
}
|
||||
|
||||
Message&
|
||||
Message::AddINReply(llarp::huint32_t ip)
|
||||
{
|
||||
if(questions.size())
|
||||
{
|
||||
hdr.fields |= (1 << 15);
|
||||
hdr_fields |= (1 << 15);
|
||||
const auto& question = questions[0];
|
||||
answers.emplace_back();
|
||||
auto& rec = answers.back();
|
||||
rec.rr_name = question.qname;
|
||||
rec.rr_type.h = 1;
|
||||
rec.rr_class = question.qclass;
|
||||
rec.ttl.h = 1;
|
||||
ResourceRecord rec;
|
||||
rec.rr_name = question.qname;
|
||||
rec.rr_type = 1;
|
||||
rec.rr_class = 1;
|
||||
rec.ttl = 1;
|
||||
rec.rData.resize(4);
|
||||
htobe32buf(rec.rData.data(), ip.h);
|
||||
UpdateHeader();
|
||||
answers.emplace_back(std::move(rec));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Message&
|
||||
void
|
||||
Message::AddAReply(std::string name)
|
||||
{
|
||||
if(questions.size())
|
||||
{
|
||||
hdr.fields |= (1 << 15);
|
||||
hdr_fields |= (1 << 15);
|
||||
const auto& question = questions[0];
|
||||
answers.emplace_back();
|
||||
auto& rec = answers.back();
|
||||
rec.rr_name = question.qname;
|
||||
rec.rr_type = question.qtype;
|
||||
rec.rr_class.h = 1;
|
||||
rec.ttl.h = 1;
|
||||
auto& rec = answers.back();
|
||||
rec.rr_name = question.qname;
|
||||
rec.rr_type = question.qtype;
|
||||
rec.rr_class = 1;
|
||||
rec.ttl = 1;
|
||||
rec.rData.resize(name.size());
|
||||
memcpy(rec.rData.data(), name.c_str(), rec.rData.size());
|
||||
UpdateHeader();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Message&
|
||||
void
|
||||
Message::AddNXReply()
|
||||
{
|
||||
if(questions.size())
|
||||
{
|
||||
hdr.fields |= (1 << 15) | (1 << 3);
|
||||
hdr_fields |= (1 << 15) | (1 << 3);
|
||||
const auto& question = questions[0];
|
||||
answers.emplace_back();
|
||||
auto& nx = answers.back();
|
||||
nx.rr_name = question.qname;
|
||||
nx.rr_type = question.qtype;
|
||||
nx.rr_class = question.qclass;
|
||||
nx.ttl.h = 1;
|
||||
nx.ttl = 1;
|
||||
nx.rData.resize(1);
|
||||
nx.rData.data()[0] = 0;
|
||||
UpdateHeader();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace dns
|
||||
|
|
|
@ -18,11 +18,21 @@ namespace llarp
|
|||
{
|
||||
l = *buf->cur;
|
||||
buf->cur++;
|
||||
if(llarp_buffer_size_left(*buf) < l)
|
||||
return false;
|
||||
if(l)
|
||||
{
|
||||
if(l > 63)
|
||||
{
|
||||
llarp::LogError("decode name failed, field too big: ", l, " > 63");
|
||||
llarp::DumpBuffer(*buf);
|
||||
return false;
|
||||
}
|
||||
if(llarp_buffer_size_left(*buf) < l)
|
||||
return false;
|
||||
|
||||
ss << Name_t((const char*)buf->cur, l);
|
||||
ss << ".";
|
||||
ss << ".";
|
||||
}
|
||||
buf->cur = buf->cur + l;
|
||||
} while(l);
|
||||
name = ss.str();
|
||||
return true;
|
||||
|
@ -31,22 +41,32 @@ namespace llarp
|
|||
bool
|
||||
EncodeName(llarp_buffer_t* buf, const Name_t& name)
|
||||
{
|
||||
std::stringstream ss(name);
|
||||
if(name.size() == 0 || name[name.size() - 1] != '.')
|
||||
ss << ".";
|
||||
std::stringstream ss;
|
||||
if(name.size() && name[name.size() - 1] == '.')
|
||||
ss << name.substr(0, name.size() - 1);
|
||||
else
|
||||
ss << name;
|
||||
|
||||
std::string part;
|
||||
while(std::getline(ss, part, '.'))
|
||||
{
|
||||
uint8_t l;
|
||||
if(part.size() > 63)
|
||||
size_t l = part.length();
|
||||
if(l > 63)
|
||||
return false;
|
||||
l = part.size();
|
||||
*buf->cur = l;
|
||||
*(buf->cur) = l;
|
||||
buf->cur++;
|
||||
if(llarp_buffer_size_left(*buf) < l)
|
||||
return false;
|
||||
memcpy(buf->cur, part.c_str(), l);
|
||||
if(l)
|
||||
{
|
||||
memcpy(buf->cur, part.data(), l);
|
||||
buf->cur += l;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*buf->cur = 0;
|
||||
buf->cur++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,50 @@
|
|||
#include <llarp/dns/question.hpp>
|
||||
#include <llarp/logger.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
Question::Question(Question&& other)
|
||||
: qname(std::move(other.qname))
|
||||
, qtype(std::move(other.qtype))
|
||||
, qclass(std::move(other.qclass))
|
||||
{
|
||||
}
|
||||
Question::Question(const Question& other)
|
||||
: qname(other.qname), qtype(other.qtype), qclass(other.qclass)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Question::Encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!EncodeName(buf, qname))
|
||||
return false;
|
||||
if(!EncodeInt(buf, qtype))
|
||||
if(!llarp_buffer_put_uint16(buf, qtype))
|
||||
return false;
|
||||
return EncodeInt(buf, qclass);
|
||||
return llarp_buffer_put_uint16(buf, qclass);
|
||||
}
|
||||
|
||||
bool
|
||||
Question::Decode(llarp_buffer_t* buf)
|
||||
{
|
||||
if(!DecodeName(buf, qname))
|
||||
{
|
||||
llarp::LogError("failed to decode name");
|
||||
return false;
|
||||
if(!DecodeInt(buf, qtype))
|
||||
}
|
||||
if(!llarp_buffer_read_uint16(buf, &qtype))
|
||||
{
|
||||
llarp::LogError("failed to decode type");
|
||||
return false;
|
||||
return DecodeInt(buf, qclass);
|
||||
}
|
||||
if(!llarp_buffer_read_uint16(buf, &qclass))
|
||||
{
|
||||
llarp::LogError("failed to decode class");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
|
|
@ -1,35 +1,83 @@
|
|||
#include <llarp/dns/rr.hpp>
|
||||
#include <llarp/logger.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dns
|
||||
{
|
||||
ResourceRecord::ResourceRecord(const ResourceRecord& other)
|
||||
: rr_name(other.rr_name)
|
||||
, rr_type(other.rr_type)
|
||||
, rr_class(other.rr_class)
|
||||
, ttl(other.ttl)
|
||||
, rData(other.rData)
|
||||
{
|
||||
}
|
||||
|
||||
ResourceRecord::ResourceRecord(ResourceRecord&& other)
|
||||
: rr_name(std::move(other.rr_name))
|
||||
, rr_type(std::move(other.rr_type))
|
||||
, rr_class(std::move(other.rr_class))
|
||||
, ttl(std::move(other.ttl))
|
||||
, rData(std::move(other.rData))
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ResourceRecord::Encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!EncodeName(buf, rr_name))
|
||||
{
|
||||
return false;
|
||||
if(!EncodeInt(buf, rr_type))
|
||||
}
|
||||
if(!llarp_buffer_put_uint16(buf, rr_type))
|
||||
{
|
||||
return false;
|
||||
if(!EncodeInt(buf, rr_class))
|
||||
}
|
||||
if(!llarp_buffer_put_uint16(buf, rr_class))
|
||||
{
|
||||
return false;
|
||||
if(!EncodeInt(buf, ttl))
|
||||
}
|
||||
if(!llarp_buffer_put_uint32(buf, ttl))
|
||||
{
|
||||
return false;
|
||||
return EncodeRData(buf, rData);
|
||||
}
|
||||
if(!EncodeRData(buf, rData))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ResourceRecord::Decode(llarp_buffer_t* buf)
|
||||
{
|
||||
if(!DecodeName(buf, rr_name))
|
||||
{
|
||||
llarp::LogError("failed to decode rr name");
|
||||
return false;
|
||||
if(!DecodeInt(buf, rr_type))
|
||||
}
|
||||
if(!llarp_buffer_read_uint16(buf, &rr_type))
|
||||
{
|
||||
llarp::LogError("failed to decode rr type");
|
||||
return false;
|
||||
if(!DecodeInt(buf, rr_class))
|
||||
}
|
||||
if(!llarp_buffer_read_uint16(buf, &rr_class))
|
||||
{
|
||||
llarp::LogError("failed to decode rr class");
|
||||
return false;
|
||||
if(!DecodeInt(buf, ttl))
|
||||
}
|
||||
if(!llarp_buffer_read_uint32(buf, &ttl))
|
||||
{
|
||||
llarp::LogError("failed to decode ttl");
|
||||
return false;
|
||||
return DecodeRData(buf, rData);
|
||||
}
|
||||
if(!DecodeRData(buf, rData))
|
||||
{
|
||||
llarp::LogError("failed to decode rr rdata");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace dns
|
||||
} // namespace llarp
|
||||
|
|
|
@ -5,70 +5,36 @@ namespace llarp
|
|||
{
|
||||
namespace dns
|
||||
{
|
||||
template <>
|
||||
bool
|
||||
DecodeInt(llarp_buffer_t* buf, llarp::huint32_t& i)
|
||||
{
|
||||
return llarp_buffer_read_uint32(buf, &i.h);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
EncodeInt(llarp_buffer_t* buf, const llarp::huint32_t& i)
|
||||
{
|
||||
return llarp_buffer_put_uint32(buf, i.h);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
DecodeInt(llarp_buffer_t* buf, llarp::huint16_t& i)
|
||||
{
|
||||
return llarp_buffer_read_uint16(buf, &i.h);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
EncodeInt(llarp_buffer_t* buf, const llarp::huint16_t& i)
|
||||
{
|
||||
return llarp_buffer_put_uint16(buf, i.h);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
DecodeInt(llarp_buffer_t* buf, uint16_t& i)
|
||||
{
|
||||
return llarp_buffer_read_uint16(buf, &i);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
EncodeInt(llarp_buffer_t* buf, const uint16_t& i)
|
||||
{
|
||||
return llarp_buffer_put_uint16(buf, i);
|
||||
}
|
||||
|
||||
bool
|
||||
EncodeRData(llarp_buffer_t* buf, const std::vector< byte_t >& v)
|
||||
{
|
||||
if(v.size() > 65536)
|
||||
return false;
|
||||
llarp::huint16_t len;
|
||||
len.h = v.size();
|
||||
return EncodeInt(buf, len) && llarp_buffer_write(buf, v.data(), v.size());
|
||||
uint16_t len = v.size();
|
||||
if(!llarp_buffer_put_uint16(buf, len))
|
||||
return false;
|
||||
if(llarp_buffer_size_left(*buf) < len)
|
||||
return false;
|
||||
memcpy(buf->cur, v.data(), len);
|
||||
buf->cur += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DecodeRData(llarp_buffer_t* buf, std::vector< byte_t >& v)
|
||||
{
|
||||
llarp::huint16_t len = {0};
|
||||
if(!DecodeInt(buf, len))
|
||||
uint16_t len;
|
||||
if(!llarp_buffer_read_uint16(buf, &len))
|
||||
return false;
|
||||
size_t left = llarp_buffer_size_left(*buf);
|
||||
if(left < len.h)
|
||||
if(left < len)
|
||||
return false;
|
||||
v.resize(size_t(len.h));
|
||||
memcpy(v.data(), buf->cur, len.h);
|
||||
buf->cur += len.h;
|
||||
v.resize(size_t(len));
|
||||
if(len)
|
||||
{
|
||||
memcpy(v.data(), buf->cur, len);
|
||||
buf->cur += len;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,17 +74,38 @@ namespace llarp
|
|||
void
|
||||
Proxy::HandlePkt(llarp::Addr from, llarp_buffer_t* pkt)
|
||||
{
|
||||
Message msg;
|
||||
if(!msg.Decode(pkt))
|
||||
MessageHeader hdr;
|
||||
if(!hdr.Decode(pkt))
|
||||
{
|
||||
llarp::LogWarn("failed to handle dns message from ", from);
|
||||
llarp::DumpBuffer(*pkt);
|
||||
llarp::LogWarn("failed to parse dns header from ", from);
|
||||
return;
|
||||
}
|
||||
TX tx = {hdr.id, from};
|
||||
auto itr = m_Forwarded.find(tx);
|
||||
if(itr != m_Forwarded.end())
|
||||
{
|
||||
llarp_buffer_t buf;
|
||||
buf.sz = pkt->sz;
|
||||
buf.base = pkt->base;
|
||||
buf.cur = buf.base;
|
||||
// forward
|
||||
llarp_ev_udp_sendto(&m_UDP, itr->second, buf);
|
||||
// remove pending
|
||||
m_Forwarded.erase(itr);
|
||||
return;
|
||||
}
|
||||
|
||||
Message msg(hdr);
|
||||
if(!msg.Decode(pkt))
|
||||
{
|
||||
llarp::LogWarn("failed to parse dns message from ", from);
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_QueryHandler && m_QueryHandler->ShouldHookDNSMessage(msg))
|
||||
{
|
||||
if(!m_QueryHandler->HandleHookedDNSMessage(
|
||||
msg,
|
||||
std::move(msg),
|
||||
std::bind(&Proxy::SendMessageTo, this, from,
|
||||
std::placeholders::_1)))
|
||||
{
|
||||
|
@ -92,19 +113,21 @@ namespace llarp
|
|||
}
|
||||
return;
|
||||
}
|
||||
TX tx = {msg.hdr.id, from};
|
||||
auto itr = m_Forwarded.find(tx);
|
||||
if(itr == m_Forwarded.end())
|
||||
else if(itr == m_Forwarded.end())
|
||||
{
|
||||
// new forwarded query
|
||||
tx.from = PickRandomResolver();
|
||||
m_Forwarded[tx] = from;
|
||||
SendMessageTo(tx.from, msg);
|
||||
llarp_buffer_t buf;
|
||||
buf.sz = pkt->sz;
|
||||
buf.base = pkt->base;
|
||||
buf.cur = buf.base;
|
||||
// do query
|
||||
llarp_ev_udp_sendto(&m_UDP, tx.from, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessageTo(itr->second, msg);
|
||||
m_Forwarded.erase(itr);
|
||||
// drop (?)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -184,8 +184,9 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
std::string qname = msg.questions[0].qname;
|
||||
if(msg.questions[0].qtype.h == 1)
|
||||
if(msg.questions[0].qtype == 1)
|
||||
{
|
||||
// forward dns
|
||||
llarp::service::Address addr;
|
||||
|
||||
if(addr.FromString(qname, ".loki"))
|
||||
|
@ -198,39 +199,50 @@ namespace llarp
|
|||
}
|
||||
else if(addr.FromString(qname, ".snode"))
|
||||
{
|
||||
// TODO: add hook to EnsurePathToSNode
|
||||
EnsurePathToSNode(addr.data());
|
||||
huint32_t ip = ObtainIPForAddr(addr.data(), true);
|
||||
reply(msg.AddINReply(ip));
|
||||
msg.AddINReply(ip);
|
||||
}
|
||||
else
|
||||
reply(msg.AddNXReply());
|
||||
msg.AddNXReply();
|
||||
|
||||
reply(msg);
|
||||
}
|
||||
else if(msg.questions[0].qtype.h == 12)
|
||||
else if(msg.questions[0].qtype == 12)
|
||||
{
|
||||
// reverse dns
|
||||
huint32_t ip = {0};
|
||||
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
||||
{
|
||||
reply(msg.AddNXReply());
|
||||
msg.AddNXReply();
|
||||
reply(msg);
|
||||
return true;
|
||||
}
|
||||
llarp::service::Address addr =
|
||||
ObtainAddrForIP< llarp::service::Address >(ip, true);
|
||||
if(!addr.IsZero())
|
||||
{
|
||||
reply(msg.AddAReply(addr.ToString(".snode")));
|
||||
msg.AddAReply(addr.ToString(".snode"));
|
||||
reply(msg);
|
||||
return true;
|
||||
}
|
||||
addr = ObtainAddrForIP< llarp::service::Address >(ip, false);
|
||||
if(!addr.IsZero())
|
||||
{
|
||||
reply(msg.AddAReply(addr.ToString(".loki")));
|
||||
msg.AddAReply(addr.ToString(".loki"));
|
||||
reply(msg);
|
||||
return true;
|
||||
}
|
||||
reply(msg.AddNXReply());
|
||||
msg.AddNXReply();
|
||||
reply(msg);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
reply(msg.AddNXReply());
|
||||
{
|
||||
msg.AddNXReply();
|
||||
reply(msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -244,7 +256,7 @@ namespace llarp
|
|||
return true;
|
||||
if(addr.FromString(msg.questions[0].qname, ".snode"))
|
||||
return true;
|
||||
if(msg.questions[0].qtype.h == 12)
|
||||
if(msg.questions[0].qtype == 12)
|
||||
{
|
||||
huint32_t ip = {0};
|
||||
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
||||
|
@ -264,10 +276,13 @@ namespace llarp
|
|||
if(ctx)
|
||||
{
|
||||
huint32_t ip = ObtainIPForAddr(addr.data(), false);
|
||||
reply(request.AddINReply(ip));
|
||||
llarp::LogInfo("mapped ", addr, " to ", ip);
|
||||
request.AddINReply(ip);
|
||||
}
|
||||
else
|
||||
reply(request.AddNXReply());
|
||||
request.AddNXReply();
|
||||
|
||||
reply(request);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -368,7 +383,6 @@ namespace llarp
|
|||
m_OurRange.addr = m_OurIP;
|
||||
m_MaxIP = m_OurIP | (~m_OurRange.netmask_bits);
|
||||
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ", lAddr);
|
||||
|
||||
llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ",
|
||||
m_OurRange);
|
||||
MapAddress(m_Identity.pub.Addr(), m_OurIP, IsSNode());
|
||||
|
|
|
@ -858,6 +858,7 @@ llarp_router::Run()
|
|||
|
||||
if(!SaveRC())
|
||||
{
|
||||
llarp::LogError("failed to save RC");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1177,6 +1178,7 @@ namespace llarp
|
|||
router_iter_config(llarp_config_iterator *iter, const char *section,
|
||||
const char *key, const char *val)
|
||||
{
|
||||
llarp::LogDebug(section, " ", key, "=", val);
|
||||
llarp_router *self = static_cast< llarp_router * >(iter->user);
|
||||
|
||||
int af;
|
||||
|
|
|
@ -43,8 +43,6 @@ struct llarpDNSdTest : public ::testing::Test
|
|||
test_request.question.qClass = 1;
|
||||
g_result = ""; // reset test global
|
||||
g_length = 0;
|
||||
llarp::SetLogLevel(
|
||||
llarp::eLogNone); // turn off logging to keep gtest output pretty
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,19 +4,15 @@
|
|||
|
||||
struct DNSLibTest : public ::testing::Test
|
||||
{
|
||||
byte_t mem[1500] = {0};
|
||||
llarp_buffer_t buf;
|
||||
byte_t mem[1500];
|
||||
llarp_buffer_t buf = llarp::StackBuffer< decltype(mem) >(mem);
|
||||
|
||||
void
|
||||
SetUp()
|
||||
{
|
||||
buf = llarp::StackBuffer< decltype(mem) >(mem);
|
||||
}
|
||||
|
||||
void
|
||||
TearDown()
|
||||
{
|
||||
buf.sz = sizeof(mem);
|
||||
Rewind();
|
||||
memset(mem, '$', sizeof(mem));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -26,6 +22,106 @@ struct DNSLibTest : public ::testing::Test
|
|||
}
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestSerializeHeader)
|
||||
{
|
||||
llarp::dns::MessageHeader hdr, other;
|
||||
hdr.id = 0x1234;
|
||||
hdr.fields = (1 << 15);
|
||||
hdr.qd_count = 1;
|
||||
hdr.an_count = 1;
|
||||
hdr.ns_count = 0;
|
||||
hdr.ar_count = 0;
|
||||
ASSERT_TRUE(hdr.Encode(&buf));
|
||||
ASSERT_TRUE((buf.cur - buf.base) == llarp::dns::MessageHeader::Size);
|
||||
Rewind();
|
||||
ASSERT_TRUE(other.Decode(&buf));
|
||||
ASSERT_TRUE(hdr == other);
|
||||
ASSERT_TRUE(other.id == 0x1234);
|
||||
ASSERT_TRUE(other.fields == (1 << 15));
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestSerializeName)
|
||||
{
|
||||
const llarp::dns::Name_t name = "whatever.tld";
|
||||
const llarp::dns::Name_t expected = "whatever.tld.";
|
||||
llarp::dns::Name_t other;
|
||||
Rewind();
|
||||
ASSERT_TRUE(llarp::dns::EncodeName(&buf, name));
|
||||
Rewind();
|
||||
ASSERT_EQ(buf.base[0], 8);
|
||||
ASSERT_EQ(buf.base[1], 'w');
|
||||
ASSERT_EQ(buf.base[2], 'h');
|
||||
ASSERT_EQ(buf.base[3], 'a');
|
||||
ASSERT_EQ(buf.base[4], 't');
|
||||
ASSERT_EQ(buf.base[5], 'e');
|
||||
ASSERT_EQ(buf.base[6], 'v');
|
||||
ASSERT_EQ(buf.base[7], 'e');
|
||||
ASSERT_EQ(buf.base[8], 'r');
|
||||
ASSERT_EQ(buf.base[9], 3);
|
||||
ASSERT_EQ(buf.base[10], 't');
|
||||
ASSERT_EQ(buf.base[11], 'l');
|
||||
ASSERT_EQ(buf.base[12], 'd');
|
||||
ASSERT_EQ(buf.base[13], 0);
|
||||
ASSERT_TRUE(llarp::dns::DecodeName(&buf, other));
|
||||
ASSERT_EQ(expected, other);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestSerializeQuestion)
|
||||
{
|
||||
const std::string name = "whatever.tld";
|
||||
const std::string expected_name = name + ".";
|
||||
llarp::dns::Question q, other;
|
||||
q.qname = name;
|
||||
q.qclass = 1;
|
||||
q.qtype = 1;
|
||||
ASSERT_TRUE(q.Encode(&buf));
|
||||
Rewind();
|
||||
ASSERT_TRUE(other.Decode(&buf));
|
||||
ASSERT_EQ(other.qname, expected_name);
|
||||
ASSERT_EQ(q.qclass, other.qclass);
|
||||
ASSERT_EQ(q.qtype, other.qtype);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestSerializeMessage)
|
||||
{
|
||||
llarp::dns::Question expected_question;
|
||||
expected_question.qname = "whatever.tld.";
|
||||
expected_question.qclass = 1;
|
||||
expected_question.qtype = 1;
|
||||
llarp::dns::MessageHeader hdr, otherHdr;
|
||||
hdr.id = 0xfeed;
|
||||
hdr.fields = (1 << 15);
|
||||
hdr.qd_count = 1;
|
||||
hdr.an_count = 0;
|
||||
hdr.ns_count = 0;
|
||||
hdr.ar_count = 0;
|
||||
llarp::dns::Message m(hdr);
|
||||
m.hdr_id = 0x1234;
|
||||
m.hdr_fields = (1 << 15);
|
||||
auto& q = m.questions[0];
|
||||
q.qname = "whatever.tld";
|
||||
q.qclass = 1;
|
||||
q.qtype = 1;
|
||||
m.AddINReply({1});
|
||||
ASSERT_EQ(m.questions.size(), 1U);
|
||||
ASSERT_EQ(m.answers.size(), 1U);
|
||||
ASSERT_TRUE(m.Encode(&buf));
|
||||
|
||||
Rewind();
|
||||
|
||||
ASSERT_TRUE(otherHdr.Decode(&buf));
|
||||
llarp::dns::Message other(otherHdr);
|
||||
ASSERT_TRUE(buf.cur - buf.base == llarp::dns::MessageHeader::Size);
|
||||
ASSERT_TRUE(other.Decode(&buf));
|
||||
ASSERT_EQ(other.questions.size(), 1U);
|
||||
ASSERT_EQ(expected_question.qname, other.questions[0].qname);
|
||||
ASSERT_EQ(expected_question.qclass, other.questions[0].qclass);
|
||||
ASSERT_EQ(expected_question.qtype, other.questions[0].qtype);
|
||||
ASSERT_TRUE(expected_question == other.questions[0]);
|
||||
ASSERT_EQ(other.answers.size(), 1U);
|
||||
ASSERT_EQ(other.answers[0].rData.size(), 4U);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestEncodeDecode_RData)
|
||||
{
|
||||
static constexpr size_t rdatasize = 32;
|
||||
|
@ -40,45 +136,3 @@ TEST_F(DNSLibTest, TestEncodeDecode_RData)
|
|||
ASSERT_TRUE(llarp::dns::DecodeRData(&buf, other_rdata));
|
||||
ASSERT_TRUE(rdata == other_rdata);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestEncode_huint16)
|
||||
{
|
||||
llarp::huint16_t i = {0x1122};
|
||||
ASSERT_TRUE(llarp::dns::EncodeInt(&buf, i));
|
||||
ASSERT_TRUE(buf.cur - buf.base == sizeof(uint16_t));
|
||||
ASSERT_TRUE(buf.base[0] == 0x11);
|
||||
ASSERT_TRUE(buf.base[1] == 0x22);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestEncode_huint32)
|
||||
{
|
||||
llarp::huint32_t i = {0x11223344};
|
||||
ASSERT_TRUE(llarp::dns::EncodeInt(&buf, i));
|
||||
ASSERT_TRUE(buf.cur - buf.base == sizeof(uint32_t));
|
||||
ASSERT_TRUE(buf.base[0] == 0x11);
|
||||
ASSERT_TRUE(buf.base[1] == 0x22);
|
||||
ASSERT_TRUE(buf.base[2] == 0x33);
|
||||
ASSERT_TRUE(buf.base[3] == 0x44);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestDecode_huint16)
|
||||
{
|
||||
llarp::huint16_t i = {0};
|
||||
buf.base[0] = 0x11;
|
||||
buf.base[1] = 0x22;
|
||||
ASSERT_TRUE(llarp::dns::DecodeInt(&buf, i));
|
||||
ASSERT_TRUE(buf.cur - buf.base == sizeof(uint16_t));
|
||||
ASSERT_TRUE(i.h == 0x1122);
|
||||
};
|
||||
|
||||
TEST_F(DNSLibTest, TestDecode_huint32)
|
||||
{
|
||||
llarp::huint32_t i = {0};
|
||||
buf.base[0] = 0x11;
|
||||
buf.base[1] = 0x22;
|
||||
buf.base[2] = 0x33;
|
||||
buf.base[3] = 0x44;
|
||||
ASSERT_TRUE(llarp::dns::DecodeInt(&buf, i));
|
||||
ASSERT_TRUE(buf.cur - buf.base == sizeof(uint32_t));
|
||||
ASSERT_TRUE(i.h == 0x11223344);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue