mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-15 12:13:24 +00:00
7caa87862e
All #ifndef guards on headers have been removed, I think, in favor of #pragma once Headers are now included as `#include "filename"` if the included file resides in the same directory as the file including it, or any subdirectory therein. Otherwise they are included as `#include <project/top/dir/relative/path/filename>` The above does not include system/os headers.
141 lines
3.3 KiB
C++
141 lines
3.3 KiB
C++
#define __USE_MINGW_ANSI_STDIO 1
|
|
#include "name.hpp"
|
|
#include <llarp/net/net.hpp>
|
|
#include <llarp/net/ip.hpp>
|
|
#include <llarp/util/str.hpp>
|
|
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
|
|
namespace llarp
|
|
{
|
|
namespace dns
|
|
{
|
|
bool
|
|
DecodeName(llarp_buffer_t* buf, Name_t& name, bool trimTrailingDot)
|
|
{
|
|
if (buf->size_left() < 1)
|
|
return false;
|
|
std::stringstream ss;
|
|
size_t l;
|
|
do
|
|
{
|
|
l = *buf->cur;
|
|
buf->cur++;
|
|
if (l)
|
|
{
|
|
if (buf->size_left() < l)
|
|
return false;
|
|
|
|
ss << Name_t((const char*)buf->cur, l);
|
|
ss << ".";
|
|
}
|
|
buf->cur = buf->cur + l;
|
|
} while (l);
|
|
name = ss.str();
|
|
/// trim off last dot
|
|
if (trimTrailingDot)
|
|
name = name.substr(0, name.find_last_of('.'));
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
EncodeName(llarp_buffer_t* buf, Name_t name)
|
|
{
|
|
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, '.'))
|
|
{
|
|
size_t l = part.length();
|
|
if (l > 63)
|
|
return false;
|
|
*(buf->cur) = l;
|
|
buf->cur++;
|
|
if (buf->size_left() < l)
|
|
return false;
|
|
if (l)
|
|
{
|
|
memcpy(buf->cur, part.data(), l);
|
|
buf->cur += l;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
*buf->cur = 0;
|
|
buf->cur++;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
DecodePTR(Name_t name, huint128_t& ip)
|
|
{
|
|
bool isV6 = false;
|
|
auto pos = name.find(".in-addr.arpa");
|
|
if (pos == std::string::npos)
|
|
{
|
|
pos = name.find(".ip6.arpa");
|
|
isV6 = true;
|
|
}
|
|
if (pos == std::string::npos)
|
|
return false;
|
|
std::string sub = name.substr(0, pos + 1);
|
|
const auto numdots = std::count(sub.begin(), sub.end(), '.');
|
|
if (numdots == 4 && !isV6)
|
|
{
|
|
uint8_t a, b, c, d;
|
|
pos = sub.find('.');
|
|
d = atoi(sub.substr(0, pos).c_str());
|
|
sub = sub.substr(pos + 1);
|
|
pos = sub.find('.');
|
|
c = atoi(sub.substr(0, pos).c_str());
|
|
sub = sub.substr(pos + 1);
|
|
pos = sub.find('.');
|
|
b = atoi(sub.substr(0, pos).c_str());
|
|
sub = sub.substr(pos + 1);
|
|
pos = sub.find('.');
|
|
a = atoi(sub.substr(0, pos).c_str());
|
|
ip = net::ExpandV4(llarp::ipaddr_ipv4_bits(a, b, c, d));
|
|
return true;
|
|
}
|
|
if (numdots == 32 && isV6)
|
|
{
|
|
size_t idx = 0;
|
|
uint8_t lo, hi;
|
|
auto* ptr = (uint8_t*)&ip.h;
|
|
while (idx < 16)
|
|
{
|
|
pos = sub.find('.');
|
|
lo = (*sub.substr(0, pos).c_str()) - 'a';
|
|
sub = sub.substr(pos + 1);
|
|
pos = sub.find('.');
|
|
hi = (*sub.substr(0, pos).c_str()) - 'a';
|
|
sub = sub.substr(pos + 1);
|
|
ptr[idx] = lo | (hi << 4);
|
|
++idx;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
NameIsReserved(Name_t name)
|
|
{
|
|
const std::vector<std::string_view> reserved_names = {
|
|
"snode.loki"sv, "loki.loki"sv, "snode.loki."sv, "loki.loki."sv};
|
|
for (const auto& reserved : reserved_names)
|
|
{
|
|
if (ends_with(name, reserved))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
} // namespace dns
|
|
} // namespace llarp
|