dns features (#1404)

* add some dns txt records for stuff we want to expose

* fix txt records

* txt records for snode info

* dont send cname as it mangles the response

* check for 3 parts not 3 characters
pull/1406/head
Jeff 4 years ago committed by GitHub
parent d10fee87c7
commit 5b5bd6b44e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -322,6 +322,32 @@ namespace llarp
}
}
void
Message::AddTXTReply(std::string str, RR_TTL_t ttl)
{
auto& rec = answers.emplace_back();
rec.rr_name = questions[0].qname;
rec.rr_class = qClassIN;
rec.rr_type = qTypeTXT;
rec.ttl = ttl;
std::array<byte_t, 1024> tmp{};
llarp_buffer_t buf(tmp);
while (not str.empty())
{
const auto left = std::min(str.size(), size_t{256});
const auto sub = str.substr(0, left);
uint8_t byte = left;
*buf.cur = byte;
buf.cur++;
if (not buf.write(sub.begin(), sub.end()))
throw std::length_error("text record too big");
str = str.substr(left);
}
buf.sz = buf.cur - buf.base;
rec.rData.resize(buf.sz);
std::copy_n(buf.base, buf.sz, rec.rData.data());
}
void Message::AddNXReply(RR_TTL_t)
{
if (questions.size())

@ -74,6 +74,9 @@ namespace llarp
void
AddNSReply(std::string name, RR_TTL_t ttl = 1);
void
AddTXTReply(std::string value, RR_TTL_t ttl = 1);
bool
Encode(llarp_buffer_t* buf) const override;

@ -64,6 +64,13 @@ namespace llarp
return (qname == "localhost.loki." or llarp::ends_with(qname, ".localhost.loki."));
}
bool
Question::HasSubdomains() const
{
const auto parts = split(qname, ".", true);
return parts.size() >= 3;
}
std::string
Question::Subdomains() const
{

@ -44,6 +44,10 @@ namespace llarp
bool
IsLocalhost() const;
/// return true if we have subdomains in ths question
bool
HasSubdomains() const;
/// get subdomain(s), if any, from qname
std::string
Subdomains() const;

@ -387,8 +387,64 @@ namespace llarp
lnsName = nameparts[nameparts.size() - 2];
lnsName += ".loki"sv;
}
if (msg.questions[0].qtype == dns::qTypeTXT)
{
RouterID snode;
if (snode.FromString(qname))
{
m_router->LookupRouter(snode, [reply, msg = std::move(msg)](const auto& found) mutable {
if (found.empty())
{
msg.AddNXReply();
}
else
{
std::stringstream ss;
for (const auto& rc : found)
rc.ToTXTRecord(ss);
msg.AddTXTReply(ss.str());
}
reply(msg);
});
return true;
}
else if (msg.questions[0].IsLocalhost() and msg.questions[0].HasSubdomains())
{
const auto subdomain = msg.questions[0].Subdomains();
if (subdomain == "exit")
{
if (HasExit())
{
std::stringstream ss;
m_ExitMap.ForEachEntry([&ss](const auto& range, const auto& exit) {
ss << range.ToString() << "=" << exit.ToString() << "; ";
});
msg.AddTXTReply(ss.str());
}
else
{
msg.AddNXReply();
}
}
else if (subdomain == "netid")
{
std::stringstream ss;
ss << "netid=" << m_router->rc().netID.ToString() << ";";
msg.AddTXTReply(ss.str());
}
else
{
msg.AddNXReply();
}
}
else
{
msg.AddNXReply();
}
if (msg.questions[0].qtype == dns::qTypeMX)
reply(msg);
}
else if (msg.questions[0].qtype == dns::qTypeMX)
{
// mx record
service::Address addr;
@ -508,7 +564,6 @@ namespace llarp
return;
}
LogInfo(name, " ", lnsName, " resolved to ", maybe->ToString());
msg->AddCNAMEReply(maybe->ToString());
ReplyToLokiDNSWhenReady(*maybe, msg, isV6);
});
}

@ -105,6 +105,21 @@ namespace llarp
return false;
}
std::ostream&
RouterContact::ToTXTRecord(std::ostream& out) const
{
for (const auto& addr : addrs)
{
out << "ai_addr=" << addr.toIpAddress() << "; ";
out << "ai_pk=" << addr.pubkey.ToHex() << "; ";
}
out << "updated=" << last_updated.count() << "; ";
out << "onion_pk=" << enckey.ToHex() << "; ";
if (routerVersion.has_value())
out << "router_version=" << routerVersion->ToString() << "; ";
return out;
}
bool
RouterContact::BEncodeSignedSection(llarp_buffer_t* buf) const
{

@ -135,6 +135,9 @@ namespace llarp
bool
BEncodeSignedSection(llarp_buffer_t* buf) const;
std::ostream&
ToTXTRecord(std::ostream& out) const;
bool
operator==(const RouterContact& other) const
{

Loading…
Cancel
Save