mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-03 23:15:52 +00:00
87 lines
2.1 KiB
C++
87 lines
2.1 KiB
C++
#include "address.hpp"
|
|
#include <llarp/crypto/crypto.hpp>
|
|
#include <oxenmq/base32z.h>
|
|
#include <algorithm>
|
|
|
|
namespace llarp::service
|
|
{
|
|
const std::set<std::string> Address::AllowedTLDs = {".loki", ".snode"};
|
|
|
|
bool
|
|
Address::PermitTLD(const char* tld)
|
|
{
|
|
std::string gtld(tld);
|
|
std::transform(gtld.begin(), gtld.end(), gtld.begin(), ::tolower);
|
|
return AllowedTLDs.count(gtld) != 0;
|
|
}
|
|
|
|
std::string
|
|
Address::ToString(const char* tld) const
|
|
{
|
|
if (!PermitTLD(tld))
|
|
return "";
|
|
std::string str;
|
|
if (subdomain.size())
|
|
{
|
|
str = subdomain;
|
|
str += '.';
|
|
}
|
|
str += oxenmq::to_base32z(begin(), end());
|
|
str += tld;
|
|
return str;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
// 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 || !oxenmq::is_base32z(str) || !(str.back() == 'o' || str.back() == 'y'))
|
|
return false;
|
|
|
|
oxenmq::from_base32z(str.begin(), str.end(), begin());
|
|
return true;
|
|
}
|
|
|
|
dht::Key_t
|
|
Address::ToKey() const
|
|
{
|
|
PubKey k;
|
|
CryptoManager::instance()->derive_subkey(k, PubKey(data()), 1);
|
|
return dht::Key_t{k.as_array()};
|
|
}
|
|
|
|
std::optional<std::variant<Address, RouterID>>
|
|
ParseAddress(std::string_view lokinet_addr)
|
|
{
|
|
RouterID router{};
|
|
service::Address addr{};
|
|
if (router.FromString(lokinet_addr))
|
|
return router;
|
|
if (addr.FromString(lokinet_addr))
|
|
return addr;
|
|
return std::nullopt;
|
|
}
|
|
|
|
} // namespace llarp::service
|