From d0203b3decb087dd73c54e3e5de5987343fa50f6 Mon Sep 17 00:00:00 2001 From: dr7ana Date: Mon, 18 Mar 2024 08:56:44 -0700 Subject: [PATCH] config parsing cleaned up for owned ranges and addresses --- llarp/address/address.hpp | 15 ++++--- llarp/address/ip_range.cpp | 4 +- llarp/address/utils.hpp | 16 +------ llarp/config/config.cpp | 91 +++++++++++++------------------------- llarp/config/config.hpp | 25 ++++++----- llarp/handlers/remote.cpp | 2 +- llarp/service/name.hpp | 8 +++- 7 files changed, 66 insertions(+), 95 deletions(-) diff --git a/llarp/address/address.hpp b/llarp/address/address.hpp index 3100a6215..cc77961f7 100644 --- a/llarp/address/address.hpp +++ b/llarp/address/address.hpp @@ -3,6 +3,7 @@ #include "keys.hpp" #include "utils.hpp" +#include #include #include @@ -18,12 +19,14 @@ namespace llarp pubkey_t _pubkey; std::optional _name = std::nullopt; std::string _tld; + bool is_ons{false}; 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} { - _pubkey.from_string(*_name); + if (not is_ons) + _pubkey.from_string(*_name); if constexpr (std::is_same_v) _tld = std::string{TLD::CLIENT}; @@ -88,11 +91,13 @@ namespace llarp } }; - /// This function currently assumes the remote address string is a pubkey, rather than - /// an ONS name (TODO:) - template + template , int> = 0> std::optional> from_pubkey_addr(const std::string& arg) { + if (service::is_valid_ons(arg)) + { + return RemoteAddress(arg, true); + } if (auto maybe_addr = parse_addr_string(arg, TLD::CLIENT)) { return RemoteAddress(*maybe_addr); diff --git a/llarp/address/ip_range.cpp b/llarp/address/ip_range.cpp index 8a1e64ff8..a2c9c17eb 100644 --- a/llarp/address/ip_range.cpp +++ b/llarp/address/ip_range.cpp @@ -4,11 +4,13 @@ namespace llarp { + static auto logcat = log::Cat("iprange"); + ip_net IPRange::init_ip() { if (_is_ipv4) return ipv4_net{ipv4{oxenc::big_to_host(_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::from_string(std::string arg) diff --git a/llarp/address/utils.hpp b/llarp/address/utils.hpp index ccf920f67..330d1c499 100644 --- a/llarp/address/utils.hpp +++ b/llarp/address/utils.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -51,21 +52,6 @@ namespace llarp return ret; }; - template - 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 parse_addr( std::string_view addr, std::optional default_port) { diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 803d13e6a..ce7eec71f 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -458,7 +458,7 @@ namespace llarp ClientOnly, MultiValue, 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:", " exit-node=whatever.loki", "would map all exit traffic through whatever.loki; and", @@ -471,7 +471,7 @@ namespace llarp return; std::optional range; - ClientAddress remote; + RemoteAddress remote; const auto pos = arg.find(":"); @@ -483,22 +483,12 @@ namespace llarp throw std::invalid_argument("[network]:exit-node invalid ip range for exit provided"); if (pos != std::string::npos) - { arg = arg.substr(0, pos); - } - if (service::is_valid_name(arg)) - { - _ons_range_map.emplace(std::move(arg), std::move(*range)); - return; - } - - if (arg != "null" and not remote.from_pubkey_addr(arg)) - { + if (auto maybe_raddr = from_pubkey_addr(arg); maybe_raddr) + _range_map.emplace(std::move(*maybe_raddr), std::move(*range)); + else throw std::invalid_argument{"[network]:exit-node bad address: {}"_format(arg)}; - } - - _range_map.emplace(std::move(remote), std::move(*range)); }); conf.define_option( @@ -529,7 +519,7 @@ namespace llarp const auto exit_str = arg.substr(0, pos); 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); return; @@ -638,20 +628,18 @@ namespace llarp const auto pos = arg.find(":"); if (pos == std::string::npos) - { 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(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)); } - - oxen::quic::Address addr{arg.substr(pos + 1), 0}; - - _addr_map.emplace(std::move(remote), std::move(addr)); + else + throw std::invalid_argument{"[endpoint]:mapaddr invalid entry: {}"_format(arg)}; }); conf.define_option( @@ -780,56 +768,37 @@ namespace llarp for (const auto& [key, value] : parsed) { - ip ip{}; + oxen::quic::Address addr; - // TODO: this - // if (not ip.FromString(key)) - // { - // LogWarn(name(), " malformed IP in addr map data: ", key); - // continue; - // } - - AddressVariant_t addr; - - if (const auto* str = std::get_if(&value)) + try { - if (auto maybe = parse_address(*str)) - { - addr = *maybe; - } - else + addr = oxen::quic::Address{key, 0}; + + if (const auto* str = std::get_if(&value)) { + if (auto maybe_raddr = from_pubkey_addr(*str); maybe_raddr) + { + _persisting_addrs.emplace(std::move(*maybe_raddr), std::move(addr)); + continue; + } + log::warning(logcat, "Invalid address in addr map: {}", *str); continue; } - } - else - { + log::warning(logcat, "Invalid first entry in addr map: not a string"); continue; } - if (const auto* loki = std::get_if(&addr)) + catch (...) { - _ip_to_addr.emplace(ip, loki->data()); - _addr_to_ip.emplace(loki->data(), ip); - _is_snode_map[*loki] = false; - log::info(logcat, "Remapping {} to {}", ip, *loki); + log::warning( + logcat, "Exception caught parsing key:value pair in addr persist file (key:{})", key); + continue; } - if (const auto* snode = std::get_if(&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: diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 29d4457d0..df454466c 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -138,29 +138,34 @@ namespace llarp std::optional path_alignment_timeout; - // TODO: if this is provided, we should parse it in the config - // parse in the god damn config - std::optional addr_map_persist_file; - /* TESTNET: Under modification */ + std::optional addr_map_persist_file; + std::unordered_map, oxen::quic::Address> _persisting_addrs; + // only member that refers to an actual interface std::string _if_name; - IPRange _local_ip_range; // rename to _local_ip_range + IPRange _local_ip_range; std::optional _base_ipv6_range = std::nullopt; - std::unordered_map, oxen::quic::Address> _addr_map; + // Remote client exit addresses mapped to fixed local IP addresses + std::unordered_map, oxen::quic::Address> _addr_map; - std::unordered_map, IPRange> _range_map; - std::unordered_map _ons_range_map; + // Remote client exit addresses mapped to local IP ranges. Addresses can be populated via client + // PubKey or their ONS name + std::unordered_map, IPRange> _range_map; std::set _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 _ons_range_map; // IP_range_deprecated if_addr; // std::optional base_ipv6_range = std::nullopt; - std::unordered_map addr_map; + // std::unordered_map addr_map; // net::IPRangeMap range_map; // net::IPRangeMap ons_range_map; // std::set owned_ranges; diff --git a/llarp/handlers/remote.cpp b/llarp/handlers/remote.cpp index 68fff2c3d..08e84c891 100644 --- a/llarp/handlers/remote.cpp +++ b/llarp/handlers/remote.cpp @@ -28,7 +28,7 @@ namespace llarp::handlers void RemoteHandler::lookup_name(std::string target, std::function 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); return func(target, false); diff --git a/llarp/service/name.hpp b/llarp/service/name.hpp index 176a225ac..5164055f0 100644 --- a/llarp/service/name.hpp +++ b/llarp/service/name.hpp @@ -14,12 +14,13 @@ namespace llarp::service std::optional
Decrypt(std::string_view name) const; }; - /// check if an lns name complies with the registration rules - inline bool is_valid_name(std::string_view ons_name) + /// check if an ons name complies with the registration rules + inline bool is_valid_ons(std::string_view ons_name) { // make sure it ends with .loki because no fucking shit right? if (not ends_with(ons_name, ".loki")) return false; + // strip off .loki suffix ons_name = ons_name.substr(0, ons_name.find_last_of('.')); @@ -36,12 +37,15 @@ namespace llarp::service continue; return false; } + // split into domain parts const auto parts = split(ons_name, "."); + // get root domain const auto primaryName = parts[parts.size() - 1]; constexpr size_t MaxNameLen = 32; constexpr size_t MaxPunycodeNameLen = 63; + // check against lns name blacklist if (primaryName == "localhost") return false;