lokinet/llarp/service/address.cpp

90 lines
2.1 KiB
C++
Raw Normal View History

#include "address.hpp"
#include <llarp/crypto/crypto.hpp>
#include <oxenc/base32z.h>
#include <algorithm>
2018-07-16 03:32:13 +00:00
namespace llarp::service
2018-07-16 03:32:13 +00:00
{
const std::set<std::string> Address::AllowedTLDs = {".loki", ".snode"};
bool
Address::PermitTLD(const char* tld)
2018-07-16 03:32:13 +00:00
{
std::string gtld(tld);
std::transform(gtld.begin(), gtld.end(), gtld.begin(), ::tolower);
return AllowedTLDs.count(gtld) != 0;
}
2019-04-26 12:11:34 +00:00
std::string
Address::ToString(const char* tld) const
{
if (!PermitTLD(tld))
return "";
std::string str;
if (subdomain.size())
2019-04-26 12:11:34 +00:00
{
str = subdomain;
str += '.';
2019-04-26 12:11:34 +00:00
}
str += oxenc::to_base32z(begin(), end());
str += tld;
return str;
}
2019-04-26 12:11:34 +00:00
bool
Address::FromString(std::string_view str, const char* tld)
{
if (!PermitTLD(tld))
return false;
// Find, validate, and remove the .tld
const auto pos = str.find_last_of('.');
if (pos == std::string::npos)
return false;
if (str.substr(pos) != tld)
return false;
str = str.substr(0, pos);
// copy subdomains if they are there (and strip them off)
const auto idx = str.find_last_of('.');
if (idx != std::string::npos)
{
subdomain = str.substr(0, idx);
str.remove_prefix(idx + 1);
}
2020-01-27 21:30:41 +00:00
// Ensure we have something valid:
// - must end in a 1-bit value: 'o' or 'y' (i.e. 10000 or 00000)
// - must have 51 preceeding base32z chars
// - thus we get 51*5+1 = 256 bits = 32 bytes of output
if (str.size() != 52 || !oxenc::is_base32z(str) || !(str.back() == 'o' || str.back() == 'y'))
return false;
oxenc::from_base32z(str.begin(), str.end(), begin());
return true;
}
2020-01-27 21:30:41 +00:00
dht::Key_t
Address::ToKey() const
{
PubKey k;
crypto::derive_subkey(k, PubKey(data()), 1);
return dht::Key_t{k.as_array()};
}
2021-03-16 19:17:02 +00:00
std::optional<std::variant<Address, RouterID>>
parse_address(std::string_view lokinet_addr)
2021-03-16 19:17:02 +00:00
{
RouterID router{};
service::Address addr{};
if (router.from_string(lokinet_addr))
2021-03-16 19:17:02 +00:00
return router;
if (addr.FromString(lokinet_addr))
return addr;
return std::nullopt;
}
} // namespace llarp::service