diff --git a/Makefile b/Makefile index d25ab3134..6bbd9985b 100644 --- a/Makefile +++ b/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 diff --git a/include/llarp/dns/message.hpp b/include/llarp/dns/message.hpp index 4f9915f93..94d7ced93 100644 --- a/include/llarp/dns/message.hpp +++ b/include/llarp/dns/message.hpp @@ -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; diff --git a/include/llarp/dns/question.hpp b/include/llarp/dns/question.hpp index b44130b4d..440540a08 100644 --- a/include/llarp/dns/question.hpp +++ b/include/llarp/dns/question.hpp @@ -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; diff --git a/include/llarp/dns/rr.hpp b/include/llarp/dns/rr.hpp index 4fde191c8..0f122b6bc 100644 --- a/include/llarp/dns/rr.hpp +++ b/include/llarp/dns/rr.hpp @@ -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; diff --git a/include/llarp/dns/serialize.hpp b/include/llarp/dns/serialize.hpp index e76ee5c71..d5df5a97c 100644 --- a/include/llarp/dns/serialize.hpp +++ b/include/llarp/dns/serialize.hpp @@ -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); diff --git a/llarp/buffer.cpp b/llarp/buffer.cpp index 2345e0e79..684c51e56 100644 --- a/llarp/buffer.cpp +++ b/llarp/buffer.cpp @@ -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; -} diff --git a/llarp/config.cpp b/llarp/config.cpp index 27625f963..3640b62cc 100644 --- a/llarp/config.cpp +++ b/llarp/config.cpp @@ -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; diff --git a/llarp/dns/message.cpp b/llarp/dns/message.cpp index b9f209a47..4204e5e75 100644 --- a/llarp/dns/message.cpp +++ b/llarp/dns/message.cpp @@ -1,5 +1,7 @@ #include #include +#include + 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 diff --git a/llarp/dns/name.cpp b/llarp/dns/name.cpp index c0561395f..e9726139c 100644 --- a/llarp/dns/name.cpp +++ b/llarp/dns/name.cpp @@ -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; } diff --git a/llarp/dns/question.cpp b/llarp/dns/question.cpp index 8b89bebf2..1c32c3c65 100644 --- a/llarp/dns/question.cpp +++ b/llarp/dns/question.cpp @@ -1,27 +1,50 @@ #include +#include 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(!llarp_buffer_read_uint16(buf, &qtype)) + { + llarp::LogError("failed to decode type"); return false; - if(!DecodeInt(buf, qtype)) + } + if(!llarp_buffer_read_uint16(buf, &qclass)) + { + llarp::LogError("failed to decode class"); return false; - return DecodeInt(buf, qclass); + } + return true; } } // namespace dns } // namespace llarp diff --git a/llarp/dns/rr.cpp b/llarp/dns/rr.cpp index 959a8a757..c4044c9a5 100644 --- a/llarp/dns/rr.cpp +++ b/llarp/dns/rr.cpp @@ -1,35 +1,83 @@ #include +#include 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(!llarp_buffer_read_uint16(buf, &rr_type)) + { + llarp::LogError("failed to decode rr type"); return false; - if(!DecodeInt(buf, rr_type)) + } + if(!llarp_buffer_read_uint16(buf, &rr_class)) + { + llarp::LogError("failed to decode rr class"); return false; - if(!DecodeInt(buf, rr_class)) + } + if(!llarp_buffer_read_uint32(buf, &ttl)) + { + llarp::LogError("failed to decode ttl"); return false; - if(!DecodeInt(buf, ttl)) + } + if(!DecodeRData(buf, rData)) + { + llarp::LogError("failed to decode rr rdata"); return false; - return DecodeRData(buf, rData); + } + return true; } } // namespace dns } // namespace llarp diff --git a/llarp/dns/serialize.cpp b/llarp/dns/serialize.cpp index 7f485e10c..e1b195f92 100644 --- a/llarp/dns/serialize.cpp +++ b/llarp/dns/serialize.cpp @@ -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; } diff --git a/llarp/dns/server.cpp b/llarp/dns/server.cpp index f3dab2b57..81105be86 100644 --- a/llarp/dns/server.cpp +++ b/llarp/dns/server.cpp @@ -74,17 +74,38 @@ namespace llarp void Proxy::HandlePkt(llarp::Addr from, llarp_buffer_t* pkt) { - Message msg; + MessageHeader hdr; + if(!hdr.Decode(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 handle dns message from ", from); - llarp::DumpBuffer(*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 (?) } } diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 83167bb77..1c0172366 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -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()); diff --git a/llarp/router.cpp b/llarp/router.cpp index 78c8e0465..5c52a6a82 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -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; diff --git a/test/test_dnsd_unit.cpp b/test/test_dnsd_unit.cpp index c16e5c3c4..cca1e4d43 100644 --- a/test/test_dnsd_unit.cpp +++ b/test/test_dnsd_unit.cpp @@ -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 } }; diff --git a/test/test_dnslib.cpp b/test/test_dnslib.cpp index d750554f3..2a760d5e7 100644 --- a/test/test_dnslib.cpp +++ b/test/test_dnslib.cpp @@ -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,59 +22,117 @@ struct DNSLibTest : public ::testing::Test } }; -TEST_F(DNSLibTest, TestEncodeDecode_RData) +TEST_F(DNSLibTest, TestSerializeHeader) { - static constexpr size_t rdatasize = 32; - llarp::dns::RR_RData_t rdata(rdatasize); - std::fill(rdata.begin(), rdata.end(), 'a'); - - llarp::dns::RR_RData_t other_rdata; - - ASSERT_TRUE(llarp::dns::EncodeRData(&buf, rdata)); - ASSERT_TRUE(buf.cur - buf.base == rdatasize + sizeof(uint16_t)); + 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(llarp::dns::DecodeRData(&buf, other_rdata)); - ASSERT_TRUE(rdata == other_rdata); + ASSERT_TRUE(other.Decode(&buf)); + ASSERT_TRUE(hdr == other); + ASSERT_TRUE(other.id == 0x1234); + ASSERT_TRUE(other.fields == (1 << 15)); }; -TEST_F(DNSLibTest, TestEncode_huint16) +TEST_F(DNSLibTest, TestSerializeName) { - 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); + 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, TestEncode_huint32) +TEST_F(DNSLibTest, TestSerializeQuestion) { - 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); + 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, TestDecode_huint16) +TEST_F(DNSLibTest, TestSerializeMessage) { - 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); + 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, TestDecode_huint32) +TEST_F(DNSLibTest, TestEncodeDecode_RData) { - 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); + static constexpr size_t rdatasize = 32; + llarp::dns::RR_RData_t rdata(rdatasize); + std::fill(rdata.begin(), rdata.end(), 'a'); + + llarp::dns::RR_RData_t other_rdata; + + ASSERT_TRUE(llarp::dns::EncodeRData(&buf, rdata)); + ASSERT_TRUE(buf.cur - buf.base == rdatasize + sizeof(uint16_t)); + Rewind(); + ASSERT_TRUE(llarp::dns::DecodeRData(&buf, other_rdata)); + ASSERT_TRUE(rdata == other_rdata); };