config parsing cleaned up for owned ranges and addresses

This commit is contained in:
dr7ana 2024-03-18 08:56:44 -07:00
parent d8f97028b5
commit d0203b3dec
7 changed files with 66 additions and 95 deletions

View File

@ -3,6 +3,7 @@
#include "keys.hpp" #include "keys.hpp"
#include "utils.hpp" #include "utils.hpp"
#include <llarp/service/name.hpp>
#include <llarp/util/aligned.hpp> #include <llarp/util/aligned.hpp>
#include <llarp/util/fs.hpp> #include <llarp/util/fs.hpp>
@ -18,11 +19,13 @@ namespace llarp
pubkey_t _pubkey; pubkey_t _pubkey;
std::optional<std::string> _name = std::nullopt; std::optional<std::string> _name = std::nullopt;
std::string _tld; std::string _tld;
bool is_ons{false};
RemoteAddress() = default; RemoteAddress() = default;
explicit RemoteAddress(std::string addr) : _name{std::move(addr)} explicit RemoteAddress(std::string addr, bool _is_ons = false) : _name{std::move(addr)}, is_ons{_is_ons}
{ {
if (not is_ons)
_pubkey.from_string(*_name); _pubkey.from_string(*_name);
if constexpr (std::is_same_v<pubkey_t, ClientPubKey>) if constexpr (std::is_same_v<pubkey_t, ClientPubKey>)
@ -88,11 +91,13 @@ namespace llarp
} }
}; };
/// This function currently assumes the remote address string is a pubkey, rather than template <typename pubkey_t = PubKey, std::enable_if_t<std::is_base_of_v<PubKey, pubkey_t>, int> = 0>
/// an ONS name (TODO:)
template <typename pubkey_t>
std::optional<RemoteAddress<pubkey_t>> from_pubkey_addr(const std::string& arg) std::optional<RemoteAddress<pubkey_t>> from_pubkey_addr(const std::string& arg)
{ {
if (service::is_valid_ons(arg))
{
return RemoteAddress<ClientPubKey>(arg, true);
}
if (auto maybe_addr = parse_addr_string(arg, TLD::CLIENT)) if (auto maybe_addr = parse_addr_string(arg, TLD::CLIENT))
{ {
return RemoteAddress<ClientPubKey>(*maybe_addr); return RemoteAddress<ClientPubKey>(*maybe_addr);

View File

@ -4,11 +4,13 @@
namespace llarp namespace llarp
{ {
static auto logcat = log::Cat("iprange");
ip_net IPRange::init_ip() ip_net IPRange::init_ip()
{ {
if (_is_ipv4) if (_is_ipv4)
return ipv4_net{ipv4{oxenc::big_to_host<uint32_t>(_addr.in4().sin_addr.s_addr)}, _mask}; return ipv4_net{ipv4{oxenc::big_to_host<uint32_t>(_addr.in4().sin_addr.s_addr)}, _mask};
return ipv6_net{ipv6{_addr.in6().sin6_addr.s6_addr}, _mask}; return ipv6_net{ipv6{&_addr.in6().sin6_addr}, _mask};
} }
std::optional<IPRange> IPRange::from_string(std::string arg) std::optional<IPRange> IPRange::from_string(std::string arg)

View File

@ -4,6 +4,7 @@
#include <llarp/crypto/constants.hpp> #include <llarp/crypto/constants.hpp>
#include <llarp/util/logging.hpp> #include <llarp/util/logging.hpp>
#include <llarp/util/str.hpp>
#include <llarp/util/types.hpp> #include <llarp/util/types.hpp>
#include <charconv> #include <charconv>
@ -51,21 +52,6 @@ namespace llarp
return ret; return ret;
}; };
template <typename T>
static bool parse_int(const std::string_view str, T &value, int base = 10)
{
T tmp;
auto *strend = str.data() + str.size();
auto [p, ec] = std::from_chars(str.data(), strend, tmp, base);
if (ec != std::errc() || p != strend)
return false;
value = tmp;
return true;
}
inline static std::pair<std::string, uint16_t> parse_addr( inline static std::pair<std::string, uint16_t> parse_addr(
std::string_view addr, std::optional<uint16_t> default_port) std::string_view addr, std::optional<uint16_t> default_port)
{ {

View File

@ -458,7 +458,7 @@ namespace llarp
ClientOnly, ClientOnly,
MultiValue, MultiValue,
Comment{ Comment{
"Specify a `.loki` address and an optional ip range to use as an exit broker.", "Specify a `.loki` address and an ip range to use as an exit broker.",
"Examples:", "Examples:",
" exit-node=whatever.loki", " exit-node=whatever.loki",
"would map all exit traffic through whatever.loki; and", "would map all exit traffic through whatever.loki; and",
@ -471,7 +471,7 @@ namespace llarp
return; return;
std::optional<IPRange> range; std::optional<IPRange> range;
ClientAddress remote; RemoteAddress remote;
const auto pos = arg.find(":"); const auto pos = arg.find(":");
@ -483,22 +483,12 @@ namespace llarp
throw std::invalid_argument("[network]:exit-node invalid ip range for exit provided"); throw std::invalid_argument("[network]:exit-node invalid ip range for exit provided");
if (pos != std::string::npos) if (pos != std::string::npos)
{
arg = arg.substr(0, pos); arg = arg.substr(0, pos);
}
if (service::is_valid_name(arg)) if (auto maybe_raddr = from_pubkey_addr<ClientPubKey>(arg); maybe_raddr)
{ _range_map.emplace(std::move(*maybe_raddr), std::move(*range));
_ons_range_map.emplace(std::move(arg), std::move(*range)); else
return;
}
if (arg != "null" and not remote.from_pubkey_addr(arg))
{
throw std::invalid_argument{"[network]:exit-node bad address: {}"_format(arg)}; throw std::invalid_argument{"[network]:exit-node bad address: {}"_format(arg)};
}
_range_map.emplace(std::move(remote), std::move(*range));
}); });
conf.define_option<std::string>( conf.define_option<std::string>(
@ -529,7 +519,7 @@ namespace llarp
const auto exit_str = arg.substr(0, pos); const auto exit_str = arg.substr(0, pos);
auth.token = arg.substr(pos + 1); auth.token = arg.substr(pos + 1);
if (llarp::service::is_valid_name(exit_str)) if (llarp::service::is_valid_ons(exit_str))
{ {
ons_exit_auths.emplace(exit_str, auth); ons_exit_auths.emplace(exit_str, auth);
return; return;
@ -638,20 +628,18 @@ namespace llarp
const auto pos = arg.find(":"); const auto pos = arg.find(":");
if (pos == std::string::npos) if (pos == std::string::npos)
{
throw std::invalid_argument{"[endpoint]:mapaddr invalid entry: {}"_format(arg)}; throw std::invalid_argument{"[endpoint]:mapaddr invalid entry: {}"_format(arg)};
}
RemoteAddress remote; auto addr_arg = arg.substr(0, pos);
auto ip_arg = arg.substr(pos + 1);
if (not remote.from_pubkey_addr(arg.substr(0, pos))) if (auto maybe_raddr = from_pubkey_addr<ClientPubKey>(std::move(addr_arg)); maybe_raddr)
{ {
throw std::invalid_argument{"[endpoint]:mapaddr invalid entry: {}"_format(arg)}; oxen::quic::Address addr{std::move(ip_arg), 0};
_addr_map.emplace(std::move(*maybe_raddr), std::move(addr));
} }
else
oxen::quic::Address addr{arg.substr(pos + 1), 0}; throw std::invalid_argument{"[endpoint]:mapaddr invalid entry: {}"_format(arg)};
_addr_map.emplace(std::move(remote), std::move(addr));
}); });
conf.define_option<std::string>( conf.define_option<std::string>(
@ -780,56 +768,37 @@ namespace llarp
for (const auto& [key, value] : parsed) for (const auto& [key, value] : parsed)
{ {
ip ip{}; oxen::quic::Address addr;
// TODO: this try
// if (not ip.FromString(key)) {
// { addr = oxen::quic::Address{key, 0};
// LogWarn(name(), " malformed IP in addr map data: ", key);
// continue;
// }
AddressVariant_t addr;
if (const auto* str = std::get_if<std::string>(&value)) if (const auto* str = std::get_if<std::string>(&value))
{ {
if (auto maybe = parse_address(*str)) if (auto maybe_raddr = from_pubkey_addr(*str); maybe_raddr)
{ {
addr = *maybe; _persisting_addrs.emplace(std::move(*maybe_raddr), std::move(addr));
continue;
} }
else
{
log::warning(logcat, "Invalid address in addr map: {}", *str); log::warning(logcat, "Invalid address in addr map: {}", *str);
continue; continue;
} }
}
else
{
log::warning(logcat, "Invalid first entry in addr map: not a string"); log::warning(logcat, "Invalid first entry in addr map: not a string");
continue; continue;
} }
if (const auto* loki = std::get_if<service::Address>(&addr)) catch (...)
{ {
_ip_to_addr.emplace(ip, loki->data()); log::warning(
_addr_to_ip.emplace(loki->data(), ip); logcat, "Exception caught parsing key:value pair in addr persist file (key:{})", key);
_is_snode_map[*loki] = false; continue;
log::info(logcat, "Remapping {} to {}", ip, *loki);
} }
if (const auto* snode = std::get_if<RouterID>(&addr))
{
_ip_to_addr.emplace(ip, snode->data());
_addr_to_ip.emplace(snode->data(), ip);
_is_snode_map[*snode] = true;
log::info(logcat, "Remapping {} to {}", ip, *snode);
}
if (_next_ip < ip)
_next_ip = ip;
// make sure we dont unmap this guy
mark_ip_active(ip);
} }
} }
addr_map_persist_file = arg; addr_map_persist_file = file;
}); });
// Deprecated options: // Deprecated options:

View File

@ -138,29 +138,34 @@ namespace llarp
std::optional<llarp_time_t> path_alignment_timeout; std::optional<llarp_time_t> path_alignment_timeout;
// TODO: if this is provided, we should parse it in the config
// parse in the god damn config
std::optional<fs::path> addr_map_persist_file;
/* TESTNET: Under modification */ /* TESTNET: Under modification */
std::optional<fs::path> addr_map_persist_file;
std::unordered_map<RemoteAddress<PubKey>, oxen::quic::Address> _persisting_addrs;
// only member that refers to an actual interface // only member that refers to an actual interface
std::string _if_name; std::string _if_name;
IPRange _local_ip_range; // rename to _local_ip_range IPRange _local_ip_range;
std::optional<IPRange> _base_ipv6_range = std::nullopt; std::optional<IPRange> _base_ipv6_range = std::nullopt;
std::unordered_map<RemoteAddress<PubKey>, oxen::quic::Address> _addr_map; // Remote client exit addresses mapped to fixed local IP addresses
std::unordered_map<RemoteAddress<ClientPubKey>, oxen::quic::Address> _addr_map;
std::unordered_map<RemoteAddress<PubKey>, IPRange> _range_map; // Remote client exit addresses mapped to local IP ranges. Addresses can be populated via client
std::unordered_map<std::string, IPRange> _ons_range_map; // PubKey or their ONS name
std::unordered_map<RemoteAddress<ClientPubKey>, IPRange> _range_map;
std::set<IPRange> _owned_ranges; std::set<IPRange> _owned_ranges;
// DEPRECATED /* DEPRECATED */
// IP ranges mapped to remote client exits with an ONS name. Deprecating this because RemoteAddress
// can store and account for ONS names
// std::unordered_map<std::string, IPRange> _ons_range_map;
// IP_range_deprecated if_addr; // IP_range_deprecated if_addr;
// std::optional<huint128_t> base_ipv6_range = std::nullopt; // std::optional<huint128_t> base_ipv6_range = std::nullopt;
std::unordered_map<huint128_t, service::Address> addr_map; // std::unordered_map<huint128_t, service::Address> addr_map;
// net::IPRangeMap<service::Address> range_map; // net::IPRangeMap<service::Address> range_map;
// net::IPRangeMap<std::string> ons_range_map; // net::IPRangeMap<std::string> ons_range_map;
// std::set<IP_range_deprecated> owned_ranges; // std::set<IP_range_deprecated> owned_ranges;

View File

@ -28,7 +28,7 @@ namespace llarp::handlers
void RemoteHandler::lookup_name(std::string target, std::function<void(std::string res, bool success)> func) void RemoteHandler::lookup_name(std::string target, std::function<void(std::string res, bool success)> func)
{ {
if (not service::is_valid_name(target)) if (not service::is_valid_ons(target))
{ {
log::debug(logcat, "Invalid ONS name ({}) queried for lookup", target); log::debug(logcat, "Invalid ONS name ({}) queried for lookup", target);
return func(target, false); return func(target, false);

View File

@ -14,12 +14,13 @@ namespace llarp::service
std::optional<Address> Decrypt(std::string_view name) const; std::optional<Address> Decrypt(std::string_view name) const;
}; };
/// check if an lns name complies with the registration rules /// check if an ons name complies with the registration rules
inline bool is_valid_name(std::string_view ons_name) inline bool is_valid_ons(std::string_view ons_name)
{ {
// make sure it ends with .loki because no fucking shit right? // make sure it ends with .loki because no fucking shit right?
if (not ends_with(ons_name, ".loki")) if (not ends_with(ons_name, ".loki"))
return false; return false;
// strip off .loki suffix // strip off .loki suffix
ons_name = ons_name.substr(0, ons_name.find_last_of('.')); ons_name = ons_name.substr(0, ons_name.find_last_of('.'));
@ -36,12 +37,15 @@ namespace llarp::service
continue; continue;
return false; return false;
} }
// split into domain parts // split into domain parts
const auto parts = split(ons_name, "."); const auto parts = split(ons_name, ".");
// get root domain // get root domain
const auto primaryName = parts[parts.size() - 1]; const auto primaryName = parts[parts.size() - 1];
constexpr size_t MaxNameLen = 32; constexpr size_t MaxNameLen = 32;
constexpr size_t MaxPunycodeNameLen = 63; constexpr size_t MaxPunycodeNameLen = 63;
// check against lns name blacklist // check against lns name blacklist
if (primaryName == "localhost") if (primaryName == "localhost")
return false; return false;