Compare commits

...

5 Commits

Author SHA1 Message Date
Jason Rhinelander 1ef77cccbd
Merge pull request #2221 from dr7ana/config-refactor-11-23
Config Refactor
6 months ago
dr7ana 826ef2bbe6 libquic bump 6 months ago
dr7ana 2ee70921bc review fixes 6 months ago
dr7ana 39c70b575d config addr change
- the one addr to rule them all, and its name was oxen::quic::Address
- no more vectors of inbound/outbound junk
7 months ago
dr7ana 5a628007e1 A soothing re-nomenclatura 7 months ago

@ -14,28 +14,42 @@ option(WITH_WINDOWS_32 "build 32 bit windows" OFF)
# to .r[o]data section one after the other! # to .r[o]data section one after the other!
add_compile_options(-fno-ident -Wa,-mbig-obj) add_compile_options(-fno-ident -Wa,-mbig-obj)
function(expand_urls output source_file)
set(expanded)
foreach(mirror ${ARGN})
list(APPEND expanded "${mirror}/${source_file}")
endforeach()
set(${output} "${expanded}" PARENT_SCOPE)
endfunction()
function(add_static_target target ext_target libname)
add_library(${target} STATIC IMPORTED GLOBAL)
add_dependencies(${target} ${ext_target})
set_target_properties(${target} PROPERTIES
IMPORTED_LOCATION ${DEPS_DESTDIR}/lib/${libname}
)
endfunction()
if(EMBEDDED_CFG) if(EMBEDDED_CFG)
link_libatomic() link_libatomic()
endif() endif()
set(WINTUN_VERSION 0.14.1 CACHE STRING "wintun version") set(WINTUN_VERSION 0.14.1 CACHE STRING "wintun version")
set(WINTUN_MIRROR https://www.wintun.net/builds set(WINTUN_MIRROR ${LOCAL_MIRROR} https://www.wintun.net/builds
CACHE STRING "wintun mirror(s)") CACHE STRING "wintun mirror(s)")
set(WINTUN_SOURCE wintun-${WINTUN_VERSION}.zip) set(WINTUN_SOURCE wintun-${WINTUN_VERSION}.zip)
set(WINTUN_HASH SHA256=07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51 set(WINTUN_HASH SHA256=07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51
CACHE STRING "wintun source hash") CACHE STRING "wintun source hash")
set(WINDIVERT_VERSION 2.2.2-A CACHE STRING "windivert version") set(WINDIVERT_VERSION 2.2.2-A CACHE STRING "windivert version")
set(WINDIVERT_MIRROR https://reqrypt.org/download set(WINDIVERT_MIRROR ${LOCAL_MIRROR} https://reqrypt.org/download
CACHE STRING "windivert mirror(s)") CACHE STRING "windivert mirror(s)")
set(WINDIVERT_SOURCE WinDivert-${WINDIVERT_VERSION}.zip) set(WINDIVERT_SOURCE WinDivert-${WINDIVERT_VERSION}.zip)
set(WINDIVERT_HASH SHA512=92eb2ef98ced175d44de1cdb7c52f2ebc534b6a997926baeb83bfe94cba9287b438f796aff11f6163918bcdbc25bcd4e3383715f139f690d207ce219f846a345 set(WINDIVERT_HASH SHA512=92eb2ef98ced175d44de1cdb7c52f2ebc534b6a997926baeb83bfe94cba9287b438f796aff11f6163918bcdbc25bcd4e3383715f139f690d207ce219f846a345
CACHE STRING "windivert source hash") CACHE STRING "windivert source hash")
set(WINTUN_URL ${WINTUN_MIRROR}/${WINTUN_SOURCE} expand_urls(WINTUN_URL ${WINTUN_SOURCE} ${WINTUN_MIRROR})
CACHE STRING "wintun download url") expand_urls(WINDIVERT_URL ${WINDIVERT_SOURCE} ${WINDIVERT_MIRROR})
set(WINDIVERT_URL ${WINDIVERT_MIRROR}/${WINDIVERT_SOURCE}
CACHE STRING "windivert download url")
message(STATUS "Downloading wintun from ${WINTUN_URL}") message(STATUS "Downloading wintun from ${WINTUN_URL}")
file(DOWNLOAD ${WINTUN_URL} ${CMAKE_BINARY_DIR}/wintun.zip EXPECTED_HASH ${WINTUN_HASH}) file(DOWNLOAD ${WINTUN_URL} ${CMAKE_BINARY_DIR}/wintun.zip EXPECTED_HASH ${WINTUN_HASH})

@ -450,7 +450,7 @@ namespace
{ {
try try
{ {
llarp::ensureConfig(basedir, *configFile, options.overwrite, opts.isSNode); llarp::ensure_config(basedir, *configFile, options.overwrite, opts.isSNode);
} }
catch (std::exception& ex) catch (std::exception& ex)
{ {
@ -479,7 +479,7 @@ namespace
{ {
try try
{ {
llarp::ensureConfig( llarp::ensure_config(
llarp::GetDefaultDataDir(), llarp::GetDefaultDataDir(),
llarp::GetDefaultConfigPath(), llarp::GetDefaultConfigPath(),
options.overwrite, options.overwrite,
@ -562,7 +562,7 @@ namespace
{ {
conf = std::make_shared<llarp::Config>(llarp::GetDefaultDataDir()); conf = std::make_shared<llarp::Config>(llarp::GetDefaultDataDir());
} }
if (not conf->Load(confFile, opts.isSNode)) if (not conf->load(confFile, opts.isSNode))
{ {
llarp::LogError("failed to parse configuration"); llarp::LogError("failed to parse configuration");
exit_code.set_value(1); exit_code.set_value(1);
@ -570,7 +570,7 @@ namespace
} }
// change cwd to dataDir to support relative paths in config // change cwd to dataDir to support relative paths in config
fs::current_path(conf->router.m_dataDir); fs::current_path(conf->router.data_dir);
ctx = std::make_shared<llarp::Context>(); ctx = std::make_shared<llarp::Context>();
ctx->Configure(std::move(conf)); ctx->Configure(std::move(conf));

@ -1 +1 @@
Subproject commit 6ee6ed398d00043d862466a56279b5c502513bff Subproject commit 3ced484e8cc543b90c5fc554ccc0ea2e54ec8d37

@ -52,12 +52,12 @@ llarp_apple_init(llarp_apple_config* appleconf)
auto config = std::make_shared<llarp::Config>(config_dir); auto config = std::make_shared<llarp::Config>(config_dir);
fs::path config_path = config_dir / "lokinet.ini"; fs::path config_path = config_dir / "lokinet.ini";
if (!fs::exists(config_path)) if (!fs::exists(config_path))
llarp::ensureConfig(config_dir, config_path, /*overwrite=*/false, /*asRouter=*/false); llarp::ensure_config(config_dir, config_path, /*overwrite=*/false, /*asRouter=*/false);
config->Load(config_path); config->load(config_path);
// If no range is specified then go look for a free one, set that in the config, and then return // If no range is specified then go look for a free one, set that in the config, and then return
// it to the caller via the char* parameters. // it to the caller via the char* parameters.
auto& range = config->network.m_ifaddr; auto& range = config->network.if_addr;
if (!range.addr.h) if (!range.addr.h)
{ {
if (auto maybe = llarp::net::Platform::Default_ptr()->FindFreeRange()) if (auto maybe = llarp::net::Platform::Default_ptr()->FindFreeRange())
@ -84,7 +84,7 @@ llarp_apple_init(llarp_apple_config* appleconf)
appleconf->tunnel_ipv6_prefix = 48; appleconf->tunnel_ipv6_prefix = 48;
appleconf->upstream_dns[0] = '\0'; appleconf->upstream_dns[0] = '\0';
for (auto& upstream : config->dns.m_upstreamDNS) for (auto& upstream : config->dns.upstream_dns)
{ {
if (upstream.isIPv4()) if (upstream.isIPv4())
{ {

@ -35,7 +35,7 @@ namespace llarp::apple
if (enable) if (enable)
tun->ReconfigureDNS({SockAddr{127, 0, 0, 1, {dns_trampoline_port}}}); tun->ReconfigureDNS({SockAddr{127, 0, 0, 1, {dns_trampoline_port}}});
else else
tun->ReconfigureDNS(router->config()->dns.m_upstreamDNS); tun->ReconfigureDNS(router->config()->dns.upstream_dns);
trampoline_active = enable; trampoline_active = enable;
} }

File diff suppressed because it is too large Load Diff

@ -31,8 +31,10 @@
namespace llarp namespace llarp
{ {
using SectionValues_t = llarp::ConfigParser::SectionValues_t; using SectionValues = llarp::ConfigParser::SectionValues;
using Config_impl_t = llarp::ConfigParser::Config_impl_t; using ConfigMap = llarp::ConfigParser::ConfigMap;
inline static constexpr uint16_t DEFAULT_LISTEN_PORT{1090};
// TODO: don't use these maps. they're sloppy and difficult to follow // TODO: don't use these maps. they're sloppy and difficult to follow
/// Small struct to gather all parameters needed for config generation to reduce the number of /// Small struct to gather all parameters needed for config generation to reduce the number of
@ -45,8 +47,8 @@ namespace llarp
ConfigGenParameters(const ConfigGenParameters&) = delete; ConfigGenParameters(const ConfigGenParameters&) = delete;
ConfigGenParameters(ConfigGenParameters&&) = delete; ConfigGenParameters(ConfigGenParameters&&) = delete;
bool isRelay = false; bool is_relay = false;
fs::path defaultDataDir; fs::path default_data_dir;
/// get network platform (virtual for unit test mocks) /// get network platform (virtual for unit test mocks)
virtual const llarp::net::Platform* virtual const llarp::net::Platform*
@ -55,33 +57,33 @@ namespace llarp
struct RouterConfig struct RouterConfig
{ {
size_t m_minConnectedRouters = 0; size_t min_connected_routers = 0;
size_t m_maxConnectedRouters = 0; size_t max_connected_routers = 0;
std::string m_netId; std::string net_id;
fs::path m_dataDir; fs::path data_dir;
bool m_blockBogons = false; bool block_bogons = false;
int m_workerThreads = -1; int worker_threads = -1;
int m_numNetThreads = -1; int net_threads = -1;
size_t m_JobQueueSize = 0; size_t job_que_size = 0;
std::string m_routerContactFile; std::string rc_file;
std::string m_encryptionKeyFile; std::string enckey_file;
std::string m_identityKeyFile; std::string idkey_file;
std::string m_transportKeyFile; std::string transkey_file;
bool m_isRelay = false; bool is_relay = false;
/// deprecated /// deprecated
std::optional<net::ipaddr_t> PublicIP; std::optional<net::ipaddr_t> public_ip;
/// deprecated /// deprecated
std::optional<net::port_t> PublicPort; std::optional<net::port_t> public_port;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
/// config for path hop selection /// config for path hop selection
@ -90,91 +92,92 @@ namespace llarp
/// in our hops what netmask will we use for unique ips for hops /// in our hops what netmask will we use for unique ips for hops
/// i.e. 32 for every hop unique ip, 24 unique /24 per hop, etc /// i.e. 32 for every hop unique ip, 24 unique /24 per hop, etc
/// ///
int m_UniqueHopsNetmaskSize; int unique_hop_netmask;
/// set of countrys to exclude from path building (2 char country code) /// set of countrys to exclude from path building (2 char country code)
std::unordered_set<std::string> m_ExcludeCountries; std::unordered_set<std::string> exclude_countries;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
/// return true if this set of router contacts is acceptable against this config /// return true if this set of router contacts is acceptable against this config
bool bool
Acceptable(const std::set<RemoteRC>& hops) const; check_rcs(const std::set<RemoteRC>& hops) const;
}; };
struct NetworkConfig struct NetworkConfig
{ {
std::optional<bool> m_enableProfiling; std::optional<bool> enable_profiling;
bool m_saveProfiles; bool save_profiles;
std::set<RouterID> m_strictConnect; std::set<RouterID> strict_connect;
std::string m_ifname; std::string if_name;
IPRange m_ifaddr; IPRange if_addr;
std::optional<fs::path> m_keyfile; std::optional<fs::path> keyfile;
std::string m_endpointType; std::string endpoint_type;
bool m_reachable = false; bool is_reachable = false;
std::optional<int> m_Hops; std::optional<int> hops;
std::optional<int> m_Paths; std::optional<int> paths;
bool m_AllowExit = false; bool allow_exit = false;
std::set<RouterID> m_snodeBlacklist; std::set<RouterID> snode_blacklist;
net::IPRangeMap<service::Address> m_ExitMap; net::IPRangeMap<service::Address> exit_map;
net::IPRangeMap<std::string> m_LNSExitMap; net::IPRangeMap<std::string> ons_exit_map;
std::unordered_map<service::Address, service::AuthInfo> m_ExitAuths; std::unordered_map<service::Address, service::AuthInfo> exit_auths;
std::unordered_map<std::string, service::AuthInfo> m_LNSExitAuths; std::unordered_map<std::string, service::AuthInfo> ons_exit_auths;
std::unordered_map<huint128_t, service::Address> m_mapAddrs; std::unordered_map<huint128_t, service::Address> map_addrs;
service::AuthType m_AuthType = service::AuthType::eAuthTypeNone; service::AuthType auth_type = service::AuthType::NONE;
service::AuthFileType m_AuthFileType = service::AuthFileType::eAuthFileHashes; service::AuthFileType auth_file_type = service::AuthFileType::HASHES;
std::optional<std::string> m_AuthUrl; std::optional<std::string> auth_url;
std::optional<std::string> m_AuthMethod; std::optional<std::string> auth_method;
std::unordered_set<service::Address> m_AuthWhitelist; std::unordered_set<service::Address> auth_whitelist;
std::unordered_set<std::string> m_AuthStaticTokens; std::unordered_set<std::string> auth_static_tokens;
std::set<fs::path> m_AuthFiles; std::set<fs::path> auth_files;
std::vector<llarp::dns::SRVData> m_SRVRecords; std::vector<llarp::dns::SRVData> srv_records;
std::optional<huint128_t> m_baseV6Address; std::optional<huint128_t> base_ipv6_addr;
std::set<IPRange> m_OwnedRanges; std::set<IPRange> owned_ranges;
std::optional<net::TrafficPolicy> m_TrafficPolicy; std::optional<net::TrafficPolicy> traffic_policy;
std::optional<llarp_time_t> m_PathAlignmentTimeout; std::optional<llarp_time_t> path_alignment_timeout;
std::optional<fs::path> m_AddrMapPersistFile; std::optional<fs::path> addr_map_persist_file;
bool m_EnableRoutePoker; bool enable_route_poker;
bool m_BlackholeRoutes; bool blackhole_routes;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
struct DnsConfig struct DnsConfig
{ {
bool m_raw_dns; bool raw;
std::vector<SockAddr> m_bind; std::vector<SockAddr> bind_addr;
std::vector<SockAddr> m_upstreamDNS; std::vector<SockAddr> upstream_dns;
std::vector<fs::path> m_hostfiles; std::vector<fs::path> hostfiles;
std::optional<SockAddr> m_QueryBind; std::optional<SockAddr> query_bind;
std::unordered_multimap<std::string, std::string> m_ExtraOpts; std::unordered_multimap<std::string, std::string> extra_opts;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
struct LinksConfig struct LinksConfig
{ {
std::optional<net::ipaddr_t> PublicAddress; std::optional<net::ipaddr_t> public_addr;
std::optional<net::port_t> PublicPort; std::optional<net::port_t> public_port;
std::vector<SockAddr> OutboundLinks;
std::vector<SockAddr> InboundListenAddrs; std::optional<oxen::quic::Address> addr;
bool using_new_api = false;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
struct ConnectConfig struct ConnectConfig
@ -182,26 +185,26 @@ namespace llarp
std::vector<fs::path> routers; std::vector<fs::path> routers;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
// TODO: remove oxenmq from this header // TODO: remove oxenmq from this header
struct ApiConfig struct ApiConfig
{ {
bool m_enableRPCServer = false; bool enable_rpc_server = false;
std::vector<oxenmq::address> m_rpcBindAddresses; std::vector<oxenmq::address> rpc_bind_addrs;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
struct LokidConfig struct LokidConfig
{ {
fs::path ident_keyfile; fs::path id_keyfile;
oxenmq::address lokidRPCAddr; oxenmq::address rpc_addr;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
struct BootstrapConfig struct BootstrapConfig
@ -209,18 +212,19 @@ namespace llarp
std::vector<fs::path> files; std::vector<fs::path> files;
BootstrapList routers; BootstrapList routers;
bool seednode; bool seednode;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
struct LoggingConfig struct LoggingConfig
{ {
log::Type m_logType = log::Type::Print; log::Type type = log::Type::Print;
log::Level m_logLevel = log::Level::off; log::Level level = log::Level::off;
std::string m_logFile; std::string file;
void void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params); define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
}; };
struct Config struct Config
@ -231,7 +235,7 @@ namespace llarp
/// create generation params (virtual for unit test mock) /// create generation params (virtual for unit test mock)
virtual std::unique_ptr<ConfigGenParameters> virtual std::unique_ptr<ConfigGenParameters>
MakeGenParams() const; make_gen_params() const;
RouterConfig router; RouterConfig router;
NetworkConfig network; NetworkConfig network;
@ -246,41 +250,41 @@ namespace llarp
// Initialize config definition // Initialize config definition
void void
initializeConfig(ConfigDefinition& conf, const ConfigGenParameters& params); init_config(ConfigDefinition& conf, const ConfigGenParameters& params);
/// Insert config entries for backwards-compatibility (e.g. so that the config system will /// Insert config entries for backwards-compatibility (e.g. so that the config system will
/// tolerate old values that are no longer accepted) /// tolerate old values that are no longer accepted)
/// ///
/// @param conf is the config to modify /// @param conf is the config to modify
void void
addBackwardsCompatibleConfigOptions(ConfigDefinition& conf); add_backcompat_opts(ConfigDefinition& conf);
// Load a config from the given file if the config file is not provided LoadDefault is called // Load a config from the given file if the config file is not provided LoadDefault is called
bool bool
Load(std::optional<fs::path> fname = std::nullopt, bool isRelay = false); load(std::optional<fs::path> fname = std::nullopt, bool isRelay = false);
// Load a config from a string of ini, same effects as Config::Load // Load a config from a string of ini, same effects as Config::Load
bool bool
LoadString(std::string_view ini, bool isRelay = false); load_string(std::string_view ini, bool isRelay = false);
std::string std::string
generateBaseClientConfig(); generate_client_config_base();
std::string std::string
generateBaseRouterConfig(); generate_router_config_base();
void void
Save(); save();
void void
Override(std::string section, std::string key, std::string value); override(std::string section, std::string key, std::string value);
void void
AddDefault(std::string section, std::string key, std::string value); add_default(std::string section, std::string key, std::string value);
/// create a config with the default parameters for an embedded lokinet /// create a config with the default parameters for an embedded lokinet
static std::shared_ptr<Config> static std::shared_ptr<Config>
EmbeddedConfig(); make_embedded_config();
private: private:
/// Load (initialize) a default config. /// Load (initialize) a default config.
@ -295,21 +299,21 @@ namespace llarp
/// @param dataDir is a path representing a directory to be used as the data dir /// @param dataDir is a path representing a directory to be used as the data dir
/// @return true on success, false otherwise /// @return true on success, false otherwise
bool bool
LoadDefault(bool isRelay); load_default_config(bool isRelay);
bool bool
LoadConfigData( load_config_data(
std::string_view ini, std::optional<fs::path> fname = std::nullopt, bool isRelay = false); std::string_view ini, std::optional<fs::path> fname = std::nullopt, bool isRelay = false);
void void
LoadOverrides(ConfigDefinition& conf) const; load_overrides(ConfigDefinition& conf) const;
std::vector<std::array<std::string, 3>> m_Additional; std::vector<std::array<std::string, 3>> additional;
ConfigParser m_Parser; ConfigParser parser;
const fs::path m_DataDir; const fs::path data_dir;
}; };
void void
ensureConfig(fs::path dataDir, fs::path confFile, bool overwrite, bool asRouter); ensure_config(fs::path dataDir, fs::path confFile, bool overwrite, bool asRouter);
} // namespace llarp } // namespace llarp

@ -10,25 +10,24 @@ namespace llarp
{ {
template <> template <>
bool bool
OptionDefinition<bool>::fromString(const std::string& input) OptionDefinition<bool>::from_string(const std::string& input)
{ {
if (input == "false" || input == "off" || input == "0" || input == "no") if (input == "false" || input == "off" || input == "0" || input == "no")
return false; return false;
else if (input == "true" || input == "on" || input == "1" || input == "yes") if (input == "true" || input == "on" || input == "1" || input == "yes")
return true; return true;
else throw std::invalid_argument{fmt::format("{} is not a valid bool", input)};
throw std::invalid_argument{fmt::format("{} is not a valid bool", input)};
} }
ConfigDefinition& ConfigDefinition&
ConfigDefinition::defineOption(OptionDefinition_ptr def) ConfigDefinition::define_option(std::unique_ptr<OptionDefinitionBase> def)
{ {
using namespace config; using namespace config;
// If explicitly deprecated or is a {client,relay} option in a {relay,client} config then add a // If explicitly deprecated or is a {client,relay} option in a {relay,client} config then add a
// dummy, warning option instead of this one. // dummy, warning option instead of this one.
if (def->deprecated || (relay ? def->clientOnly : def->relayOnly)) if (def->deprecated || (relay ? def->clientOnly : def->relay_only))
{ {
return defineOption<std::string>( return define_option<std::string>(
def->section, def->section,
def->name, def->name,
MultiValue, MultiValue,
@ -46,36 +45,36 @@ namespace llarp
}); });
} }
auto [sectionItr, newSect] = m_definitions.try_emplace(def->section); auto [sectionItr, newSect] = definitions.try_emplace(def->section);
if (newSect) if (newSect)
m_sectionOrdering.push_back(def->section); section_ordering.push_back(def->section);
auto& section = sectionItr->first; auto& section = sectionItr->first;
auto [it, added] = m_definitions[section].try_emplace(std::string{def->name}, std::move(def)); auto [it, added] = definitions[section].try_emplace(std::string{def->name}, std::move(def));
if (!added) if (!added)
throw std::invalid_argument{ throw std::invalid_argument{
fmt::format("definition for [{}]:{} already exists", def->section, def->name)}; fmt::format("definition for [{}]:{} already exists", def->section, def->name)};
m_definitionOrdering[section].push_back(it->first); definition_ordering[section].push_back(it->first);
if (!it->second->comments.empty()) if (!it->second->comments.empty())
addOptionComments(section, it->first, std::move(it->second->comments)); add_option_comments(section, it->first, std::move(it->second->comments));
return *this; return *this;
} }
ConfigDefinition& ConfigDefinition&
ConfigDefinition::addConfigValue( ConfigDefinition::add_config_value(
std::string_view section, std::string_view name, std::string_view value) std::string_view section, std::string_view name, std::string_view value)
{ {
// see if we have an undeclared handler to fall back to in case section or section:name is // see if we have an undeclared handler to fall back to in case section or section:name is
// absent // absent
auto undItr = m_undeclaredHandlers.find(std::string(section)); auto undItr = undeclared_handlers.find(std::string(section));
bool haveUndeclaredHandler = (undItr != m_undeclaredHandlers.end()); bool haveUndeclaredHandler = (undItr != undeclared_handlers.end());
// get section, falling back to undeclared handler if needed // get section, falling back to undeclared handler if needed
auto secItr = m_definitions.find(std::string(section)); auto secItr = definitions.find(std::string(section));
if (secItr == m_definitions.end()) if (secItr == definitions.end())
{ {
// fallback to undeclared handler if available // fallback to undeclared handler if available
if (not haveUndeclaredHandler) if (not haveUndeclaredHandler)
@ -91,8 +90,8 @@ namespace llarp
auto defItr = sectionDefinitions.find(std::string(name)); auto defItr = sectionDefinitions.find(std::string(name));
if (defItr != sectionDefinitions.end()) if (defItr != sectionDefinitions.end())
{ {
OptionDefinition_ptr& definition = defItr->second; std::unique_ptr<OptionDefinitionBase>& definition = defItr->second;
definition->parseValue(std::string(value)); definition->parse_value(std::string(value));
return *this; return *this;
} }
@ -105,63 +104,67 @@ namespace llarp
} }
void void
ConfigDefinition::addUndeclaredHandler(const std::string& section, UndeclaredValueHandler handler) ConfigDefinition::add_undeclared_handler(
const std::string& section, UndeclaredValueHandler handler)
{ {
auto itr = m_undeclaredHandlers.find(section); auto itr = undeclared_handlers.find(section);
if (itr != m_undeclaredHandlers.end()) if (itr != undeclared_handlers.end())
throw std::logic_error{fmt::format("section {} already has a handler", section)}; throw std::logic_error{fmt::format("section {} already has a handler", section)};
m_undeclaredHandlers[section] = std::move(handler); undeclared_handlers[section] = std::move(handler);
} }
void void
ConfigDefinition::removeUndeclaredHandler(const std::string& section) ConfigDefinition::remove_undeclared_handler(const std::string& section)
{ {
auto itr = m_undeclaredHandlers.find(section); auto itr = undeclared_handlers.find(section);
if (itr != m_undeclaredHandlers.end()) if (itr != undeclared_handlers.end())
m_undeclaredHandlers.erase(itr); undeclared_handlers.erase(itr);
} }
void void
ConfigDefinition::validateRequiredFields() ConfigDefinition::validate_required_fields()
{ {
visitSections([&](const std::string& section, const DefinitionMap&) { visit_sections([&](const std::string& section, const DefinitionMap&) {
visitDefinitions(section, [&](const std::string&, const OptionDefinition_ptr& def) { visit_definitions(
if (def->required and def->getNumberFound() < 1) section, [&](const std::string&, const std::unique_ptr<OptionDefinitionBase>& def) {
{ if (def->required and def->get_number_found() < 1)
throw std::invalid_argument{ {
fmt::format("[{}]:{} is required but missing", section, def->name)}; throw std::invalid_argument{
} fmt::format("[{}]:{} is required but missing", section, def->name)};
}
// should be handled earlier in OptionDefinition::parseValue()
assert(def->getNumberFound() <= 1 or def->multiValued); // should be handled earlier in OptionDefinition::parse_value()
}); assert(def->get_number_found() <= 1 or def->multi_valued);
});
}); });
} }
void void
ConfigDefinition::acceptAllOptions() ConfigDefinition::accept_all_options()
{ {
visitSections([this](const std::string& section, const DefinitionMap&) { visit_sections([this](const std::string& section, const DefinitionMap&) {
visitDefinitions( visit_definitions(
section, [](const std::string&, const OptionDefinition_ptr& def) { def->tryAccept(); }); section, [](const std::string&, const std::unique_ptr<OptionDefinitionBase>& def) {
def->try_accept();
});
}); });
} }
void void
ConfigDefinition::addSectionComments( ConfigDefinition::add_section_comments(
const std::string& section, std::vector<std::string> comments) const std::string& section, std::vector<std::string> comments)
{ {
auto& sectionComments = m_sectionComments[section]; auto& sectionComments = section_comments[section];
for (auto& c : comments) for (auto& c : comments)
sectionComments.emplace_back(std::move(c)); sectionComments.emplace_back(std::move(c));
} }
void void
ConfigDefinition::addOptionComments( ConfigDefinition::add_option_comments(
const std::string& section, const std::string& name, std::vector<std::string> comments) const std::string& section, const std::string& name, std::vector<std::string> comments)
{ {
auto& defComments = m_definitionComments[section][name]; auto& defComments = definition_comments[section][name];
if (defComments.empty()) if (defComments.empty())
defComments = std::move(comments); defComments = std::move(comments);
else else
@ -172,48 +175,49 @@ namespace llarp
} }
std::string std::string
ConfigDefinition::generateINIConfig(bool useValues) ConfigDefinition::generate_ini_config(bool useValues)
{ {
std::string ini; std::string ini;
auto ini_append = std::back_inserter(ini); auto ini_append = std::back_inserter(ini);
int sectionsVisited = 0; int sectionsVisited = 0;
visitSections([&](const std::string& section, const DefinitionMap&) { visit_sections([&](const std::string& section, const DefinitionMap&) {
std::string sect_str; std::string sect_str;
auto sect_append = std::back_inserter(sect_str); auto sect_append = std::back_inserter(sect_str);
visitDefinitions(section, [&](const std::string& name, const OptionDefinition_ptr& def) { visit_definitions(
bool has_comment = false; section, [&](const std::string& name, const std::unique_ptr<OptionDefinitionBase>& def) {
// TODO: as above, this will create empty objects bool has_comment = false;
// TODO: as above (but more important): this won't handle definitions with no entries // TODO: as above, this will create empty objects
// (i.e. those handled by UndeclaredValueHandler's) // TODO: as above (but more important): this won't handle definitions with no entries
for (const std::string& comment : m_definitionComments[section][name]) // (i.e. those handled by UndeclaredValueHandler's)
{ for (const std::string& comment : definition_comments[section][name])
fmt::format_to(sect_append, "\n# {}", comment); {
has_comment = true; fmt::format_to(sect_append, "\n# {}", comment);
} has_comment = true;
}
if (useValues and def->getNumberFound() > 0)
{ if (useValues and def->get_number_found() > 0)
for (const auto& val : def->valuesAsString()) {
fmt::format_to(sect_append, "\n{}={}", name, val); for (const auto& val : def->values_as_string())
*sect_append = '\n'; fmt::format_to(sect_append, "\n{}={}", name, val);
} *sect_append = '\n';
else if (not def->hidden) }
{ else if (not def->hidden)
if (auto defaults = def->defaultValuesAsString(); not defaults.empty()) {
for (const auto& val : defaults) if (auto defaults = def->default_values_as_string(); not defaults.empty())
fmt::format_to(sect_append, "\n{}{}={}", def->required ? "" : "#", name, val); for (const auto& val : defaults)
else fmt::format_to(sect_append, "\n{}{}={}", def->required ? "" : "#", name, val);
// We have no defaults so we append it as "#opt-name=" so that we show the option name, else
// and make it simple to uncomment and edit to the desired value. // We have no defaults so we append it as "#opt-name=" so that we show the option
fmt::format_to(sect_append, "\n#{}=", name); // name, and make it simple to uncomment and edit to the desired value.
*sect_append = '\n'; fmt::format_to(sect_append, "\n#{}=", name);
} *sect_append = '\n';
else if (has_comment) }
*sect_append = '\n'; else if (has_comment)
}); *sect_append = '\n';
});
if (sect_str.empty()) if (sect_str.empty())
return; // Skip sections with no options return; // Skip sections with no options
@ -225,7 +229,7 @@ namespace llarp
// TODO: this will create empty objects as a side effect of map's operator[] // TODO: this will create empty objects as a side effect of map's operator[]
// TODO: this also won't handle sections which have no definition // TODO: this also won't handle sections which have no definition
for (const std::string& comment : m_sectionComments[section]) for (const std::string& comment : section_comments[section])
{ {
fmt::format_to(ini_append, "# {}\n", comment); fmt::format_to(ini_append, "# {}\n", comment);
} }
@ -238,11 +242,12 @@ namespace llarp
return ini; return ini;
} }
const OptionDefinition_ptr& const std::unique_ptr<OptionDefinitionBase>&
ConfigDefinition::lookupDefinitionOrThrow(std::string_view section, std::string_view name) const ConfigDefinition::lookup_definition_or_throw(
std::string_view section, std::string_view name) const
{ {
const auto sectionItr = m_definitions.find(std::string(section)); const auto sectionItr = definitions.find(std::string(section));
if (sectionItr == m_definitions.end()) if (sectionItr == definitions.end())
throw std::invalid_argument{fmt::format("No config section [{}]", section)}; throw std::invalid_argument{fmt::format("No config section [{}]", section)};
auto& sectionDefinitions = sectionItr->second; auto& sectionDefinitions = sectionItr->second;
@ -254,28 +259,28 @@ namespace llarp
return definitionItr->second; return definitionItr->second;
} }
OptionDefinition_ptr& std::unique_ptr<OptionDefinitionBase>&
ConfigDefinition::lookupDefinitionOrThrow(std::string_view section, std::string_view name) ConfigDefinition::lookup_definition_or_throw(std::string_view section, std::string_view name)
{ {
return const_cast<OptionDefinition_ptr&>( return const_cast<std::unique_ptr<OptionDefinitionBase>&>(
const_cast<const ConfigDefinition*>(this)->lookupDefinitionOrThrow(section, name)); const_cast<const ConfigDefinition*>(this)->lookup_definition_or_throw(section, name));
} }
void void
ConfigDefinition::visitSections(SectionVisitor visitor) const ConfigDefinition::visit_sections(SectionVisitor visitor) const
{ {
for (const std::string& section : m_sectionOrdering) for (const std::string& section : section_ordering)
{ {
const auto itr = m_definitions.find(section); const auto itr = definitions.find(section);
assert(itr != m_definitions.end()); assert(itr != definitions.end());
visitor(section, itr->second); visitor(section, itr->second);
} }
}; };
void void
ConfigDefinition::visitDefinitions(const std::string& section, DefVisitor visitor) const ConfigDefinition::visit_definitions(const std::string& section, DefVisitor visitor) const
{ {
const auto& defs = m_definitions.at(section); const auto& defs = definitions.at(section);
const auto& defOrdering = m_definitionOrdering.at(section); const auto& defOrdering = definition_ordering.at(section);
for (const std::string& name : defOrdering) for (const std::string& name : defOrdering)
{ {
const auto itr = defs.find(name); const auto itr = defs.find(name);

@ -22,42 +22,45 @@ namespace llarp
{ {
namespace config namespace config
{ {
// Base class for the following option flag types namespace flag
struct option_flag {
{}; // Base class for the following option flag types
struct opt
struct Required_t : option_flag {};
{};
struct Hidden_t : option_flag struct REQUIRED : opt
{}; {};
struct MultiValue_t : option_flag struct HIDDEN : opt
{}; {};
struct RelayOnly_t : option_flag struct MULTIVALUE : opt
{}; {};
struct ClientOnly_t : option_flag struct RELAYONLY : opt
{}; {};
struct Deprecated_t : option_flag struct CLIENTONLY : opt
{}; {};
struct DEPRECATED : opt
{};
} // namespace flag
/// Value to pass for an OptionDefinition to indicate that the option is required /// Value to pass for an OptionDefinition to indicate that the option is required
inline constexpr Required_t Required{}; inline constexpr flag::REQUIRED Required{};
/// Value to pass for an OptionDefinition to indicate that the option should be hidden from the /// Value to pass for an OptionDefinition to indicate that the option should be hidden from the
/// generate config file if it is unset (and has no comment). Typically for deprecated, renamed /// generate config file if it is unset (and has no comment). Typically for deprecated, renamed
/// options that still do something, and for internal dev options that aren't usefully exposed. /// options that still do something, and for internal dev options that aren't usefully exposed.
/// (For do-nothing deprecated options use Deprecated instead). /// (For do-nothing deprecated options use Deprecated instead).
inline constexpr Hidden_t Hidden{}; inline constexpr flag::HIDDEN Hidden{};
/// Value to pass for an OptionDefinition to indicate that the option takes multiple values /// Value to pass for an OptionDefinition to indicate that the option takes multiple values
inline constexpr MultiValue_t MultiValue{}; inline constexpr flag::MULTIVALUE MultiValue{};
/// Value to pass for an option that should only be set for relay configs. If found in a client /// Value to pass for an option that should only be set for relay configs. If found in a client
/// config it be ignored (but will produce a warning). /// config it be ignored (but will produce a warning).
inline constexpr RelayOnly_t RelayOnly{}; inline constexpr flag::RELAYONLY RelayOnly{};
/// Value to pass for an option that should only be set for client configs. If found in a relay /// Value to pass for an option that should only be set for client configs. If found in a relay
/// config it will be ignored (but will produce a warning). /// config it will be ignored (but will produce a warning).
inline constexpr ClientOnly_t ClientOnly{}; inline constexpr flag::CLIENTONLY ClientOnly{};
/// Value to pass for an option that is deprecated and does nothing and should be ignored (with /// Value to pass for an option that is deprecated and does nothing and should be ignored (with
/// a deprecation warning) if specified. Note that Deprecated implies Hidden, and that /// a deprecation warning) if specified. Note that Deprecated implies Hidden, and that
/// {client,relay}-only options in a {relay,client} config are also considered Deprecated. /// {client,relay}-only options in a {relay,client} config are also considered Deprecated.
inline constexpr Deprecated_t Deprecated{}; inline constexpr flag::DEPRECATED Deprecated{};
/// Wrapper to specify a default value to an OptionDefinition /// Wrapper to specify a default value to an OptionDefinition
template <typename T> template <typename T>
@ -82,7 +85,7 @@ namespace llarp
/// particular, a reference to a local variable may be problematic. /// particular, a reference to a local variable may be problematic.
template <typename T> template <typename T>
auto auto
AssignmentAcceptor(T& ref) assignment_acceptor(T& ref)
{ {
return [&ref](T arg) { ref = std::move(arg); }; return [&ref](T arg) { ref = std::move(arg); };
} }
@ -106,7 +109,7 @@ namespace llarp
constexpr bool is_default_array<U&> = is_default_array<remove_cvref_t<U>>; constexpr bool is_default_array<U&> = is_default_array<remove_cvref_t<U>>;
template <typename T, typename Option> template <typename T, typename Option>
constexpr bool is_option = std::is_base_of_v<option_flag, remove_cvref_t<Option>> constexpr bool is_option = std::is_base_of_v<flag::opt, remove_cvref_t<Option>>
or std::is_same_v<Comment, Option> or is_default<Option> or is_default_array<Option> or std::is_same_v<Comment, Option> or is_default<Option> or is_default_array<Option>
or std::is_invocable_v<remove_cvref_t<Option>, T>; or std::is_invocable_v<remove_cvref_t<Option>, T>;
} // namespace config } // namespace config
@ -121,12 +124,12 @@ namespace llarp
OptionDefinitionBase(std::string section_, std::string name_, const T&...) OptionDefinitionBase(std::string section_, std::string name_, const T&...)
: section(std::move(section_)) : section(std::move(section_))
, name(std::move(name_)) , name(std::move(name_))
, required{(std::is_same_v<T, config::Required_t> || ...)} , required{(std::is_same_v<T, config::flag::REQUIRED> || ...)}
, multiValued{(std::is_same_v<T, config::MultiValue_t> || ...)} , multi_valued{(std::is_same_v<T, config::flag::MULTIVALUE> || ...)}
, deprecated{(std::is_same_v<T, config::Deprecated_t> || ...)} , deprecated{(std::is_same_v<T, config::flag::DEPRECATED> || ...)}
, hidden{deprecated || (std::is_same_v<T, config::Hidden_t> || ...)} , hidden{deprecated || (std::is_same_v<T, config::flag::HIDDEN> || ...)}
, relayOnly{(std::is_same_v<T, config::RelayOnly_t> || ...)} , relay_only{(std::is_same_v<T, config::flag::RELAYONLY> || ...)}
, clientOnly{(std::is_same_v<T, config::ClientOnly_t> || ...)} , clientOnly{(std::is_same_v<T, config::flag::CLIENTONLY> || ...)}
{} {}
virtual ~OptionDefinitionBase() = default; virtual ~OptionDefinitionBase() = default;
@ -135,39 +138,39 @@ namespace llarp
/// ///
/// @return the option's default value represented as a string /// @return the option's default value represented as a string
virtual std::vector<std::string> virtual std::vector<std::string>
defaultValuesAsString() = 0; default_values_as_string() = 0;
/// Subclasses should parse and store the provided input /// Subclasses should parse and store the provided input
/// ///
/// @param input is the string input to interpret /// @param input is the string input to interpret
virtual void virtual void
parseValue(const std::string& input) = 0; parse_value(const std::string& input) = 0;
/// Subclasses should provide the number of values found. /// Subclasses should provide the number of values found.
/// ///
/// @return number of values found /// @return number of values found
virtual size_t virtual size_t
getNumberFound() const = 0; get_number_found() const = 0;
/// Subclasess should write their parsed values as strings. /// Subclasess should write their parsed values as strings.
/// ///
/// @return the option's value(s) as strings /// @return the option's value(s) as strings
virtual std::vector<std::string> virtual std::vector<std::string>
valuesAsString() = 0; values_as_string() = 0;
/// Subclassess should call their acceptor, if present. See OptionDefinition for more details. /// Subclassess should call their acceptor, if present. See OptionDefinition for more details.
/// ///
/// @throws if the acceptor throws or the option is required but missing /// @throws if the acceptor throws or the option is required but missing
virtual void virtual void
tryAccept() const = 0; try_accept() const = 0;
std::string section; std::string section;
std::string name; std::string name;
bool required = false; bool required = false;
bool multiValued = false; bool multi_valued = false;
bool deprecated = false; bool deprecated = false;
bool hidden = false; bool hidden = false;
bool relayOnly = false; bool relay_only = false;
bool clientOnly = false; bool clientOnly = false;
// Temporarily holds comments given during construction until the option is actually added to // Temporarily holds comments given during construction until the option is actually added to
// the owning ConfigDefinition. // the owning ConfigDefinition.
@ -188,7 +191,7 @@ namespace llarp
/// ///
/// @param defaultValue_ is used in the following situations: /// @param defaultValue_ is used in the following situations:
/// 1) as the return value for getValue() if there is no parsed value and required==false /// 1) as the return value for getValue() if there is no parsed value and required==false
/// 2) as the output in defaultValuesAsString(), used to generate config files /// 2) as the output in default_values_as_string(), used to generate config files
/// 3) as the output in valueAsString(), used to generate config files /// 3) as the output in valueAsString(), used to generate config files
/// ///
/// @param opts - 0 or more of config::Required, config::Hidden, config::Default{...}, etc. /// @param opts - 0 or more of config::Required, config::Hidden, config::Default{...}, etc.
@ -204,40 +207,40 @@ namespace llarp
constexpr bool has_default = constexpr bool has_default =
((config::is_default_array<Options> || config::is_default<Options>) || ...); ((config::is_default_array<Options> || config::is_default<Options>) || ...);
constexpr bool has_required = constexpr bool has_required =
(std::is_same_v<config::remove_cvref_t<Options>, config::Required_t> || ...); (std::is_same_v<config::remove_cvref_t<Options>, config::flag::REQUIRED> || ...);
constexpr bool has_hidden = constexpr bool has_hidden =
(std::is_same_v<config::remove_cvref_t<Options>, config::Hidden_t> || ...); (std::is_same_v<config::remove_cvref_t<Options>, config::flag::HIDDEN> || ...);
static_assert( static_assert(
not(has_default and has_required), "Default{...} and Required are mutually exclusive"); not(has_default and has_required), "Default{...} and Required are mutually exclusive");
static_assert(not(has_hidden and has_required), "Hidden and Required are mutually exclusive"); static_assert(not(has_hidden and has_required), "Hidden and Required are mutually exclusive");
(extractDefault(std::forward<Options>(opts)), ...); (extract_default(std::forward<Options>(opts)), ...);
(extractAcceptor(std::forward<Options>(opts)), ...); (extract_acceptor(std::forward<Options>(opts)), ...);
(extractComments(std::forward<Options>(opts)), ...); (extract_comments(std::forward<Options>(opts)), ...);
} }
/// Extracts a default value from an config::Default<U> or an array of defaults (for /// Extracts a default value from an config::Default<U> or an array of defaults (for
/// multi-valued options with multi-value default); ignores anything else. /// multi-valued options with multi-value default); ignores anything else.
template <typename U> template <typename U>
void void
extractDefault(U&& defaultValue_) extract_default(U&& defaultValue_)
{ {
if constexpr (config::is_default_array<U>) if constexpr (config::is_default_array<U>)
{ {
if (!multiValued) if (!multi_valued)
throw std::logic_error{"Array config defaults require multiValue mode"}; throw std::logic_error{"Array config defaults require multiValue mode"};
defaultValues.clear(); default_values.clear();
defaultValues.reserve(defaultValue_.size()); default_values.reserve(defaultValue_.size());
for (const auto& def : defaultValue_) for (const auto& def : defaultValue_)
defaultValues.push_back(def.val); default_values.push_back(def.val);
} }
else if constexpr (config::is_default<U>) else if constexpr (config::is_default<U>)
{ {
static_assert( static_assert(
std::is_convertible_v<decltype(std::forward<U>(defaultValue_).val), T>, std::is_convertible_v<decltype(std::forward<U>(defaultValue_).val), T>,
"Cannot convert given llarp::config::Default to the required value type"); "Cannot convert given llarp::config::Default to the required value type");
defaultValues = {std::forward<U>(defaultValue_).val}; default_values = {std::forward<U>(defaultValue_).val};
} }
} }
@ -245,7 +248,7 @@ namespace llarp
/// that isn't callable. /// that isn't callable.
template <typename U> template <typename U>
void void
extractAcceptor(U&& acceptor_) extract_acceptor(U&& acceptor_)
{ {
if constexpr (std::is_invocable_v<U, T>) if constexpr (std::is_invocable_v<U, T>)
acceptor = std::forward<U>(acceptor_); acceptor = std::forward<U>(acceptor_);
@ -254,7 +257,7 @@ namespace llarp
/// Extracts option Comments and forwards them addOptionComments. /// Extracts option Comments and forwards them addOptionComments.
template <typename U> template <typename U>
void void
extractComments(U&& comment) extract_comments(U&& comment)
{ {
if constexpr (std::is_same_v<config::remove_cvref_t<U>, config::Comment>) if constexpr (std::is_same_v<config::remove_cvref_t<U>, config::Comment>)
comments = std::forward<U>(comment).comments; comments = std::forward<U>(comment).comments;
@ -265,38 +268,38 @@ namespace llarp
/// ///
/// @return an optional with the parsed value, the (first) default value, or no value. /// @return an optional with the parsed value, the (first) default value, or no value.
std::optional<T> std::optional<T>
getValue() const get_value() const
{ {
if (parsedValues.empty()) if (parsed_values.empty())
{ {
if (required || defaultValues.empty()) if (required || default_values.empty())
return std::nullopt; return std::nullopt;
return defaultValues.front(); return default_values.front();
} }
return parsedValues.front(); return parsed_values.front();
} }
/// Returns the number of values found. /// Returns the number of values found.
/// ///
/// @return number of values found /// @return number of values found
size_t size_t
getNumberFound() const override get_number_found() const override
{ {
return parsedValues.size(); return parsed_values.size();
} }
std::vector<std::string> std::vector<std::string>
defaultValuesAsString() override default_values_as_string() override
{ {
if (defaultValues.empty()) if (default_values.empty())
return {}; return {};
if constexpr (std::is_same_v<fs::path, T>) if constexpr (std::is_same_v<fs::path, T>)
return {{defaultValues.front().u8string()}}; return {{default_values.front().u8string()}};
else else
{ {
std::vector<std::string> def_strs; std::vector<std::string> def_strs;
def_strs.reserve(defaultValues.size()); def_strs.reserve(default_values.size());
for (const auto& v : defaultValues) for (const auto& v : default_values)
{ {
if constexpr (std::is_same_v<bool, T>) if constexpr (std::is_same_v<bool, T>)
def_strs.push_back(fmt::format("{}", (bool)v)); def_strs.push_back(fmt::format("{}", (bool)v));
@ -308,18 +311,18 @@ namespace llarp
} }
void void
parseValue(const std::string& input) override parse_value(const std::string& input) override
{ {
if (not multiValued and parsedValues.size() > 0) if (not multi_valued and parsed_values.size() > 0)
{ {
throw std::invalid_argument{fmt::format("duplicate value for {}", name)}; throw std::invalid_argument{fmt::format("duplicate value for {}", name)};
} }
parsedValues.emplace_back(fromString(input)); parsed_values.emplace_back(from_string(input));
} }
T T
fromString(const std::string& input) from_string(const std::string& input)
{ {
if constexpr (std::is_same_v<T, std::string>) if constexpr (std::is_same_v<T, std::string>)
{ {
@ -337,13 +340,13 @@ namespace llarp
} }
std::vector<std::string> std::vector<std::string>
valuesAsString() override values_as_string() override
{ {
if (parsedValues.empty()) if (parsed_values.empty())
return {}; return {};
std::vector<std::string> result; std::vector<std::string> result;
result.reserve(parsedValues.size()); result.reserve(parsed_values.size());
for (const auto& v : parsedValues) for (const auto& v : parsed_values)
{ {
if constexpr (std::is_same_v<bool, T>) if constexpr (std::is_same_v<bool, T>)
result.push_back(fmt::format("{}", (bool)v)); result.push_back(fmt::format("{}", (bool)v));
@ -354,46 +357,46 @@ namespace llarp
} }
/// Attempts to call the acceptor function, if present. This function may throw if the value /// Attempts to call the acceptor function, if present. This function may throw if the value
/// is not acceptable. Additionally, tryAccept should not be called if the option is required /// is not acceptable. Additionally, try_accept should not be called if the option is required
/// and no value has been provided. /// and no value has been provided.
/// ///
/// @throws if required and no value present or if the acceptor throws /// @throws if required and no value present or if the acceptor throws
void void
tryAccept() const override try_accept() const override
{ {
if (required and parsedValues.empty()) if (required and parsed_values.empty())
{ {
throw std::runtime_error{fmt::format( throw std::runtime_error{fmt::format(
"cannot call tryAccept() on [{}]:{} when required but no value available", "cannot call try_accept() on [{}]:{} when required but no value available",
section, section,
name)}; name)};
} }
if (acceptor) if (acceptor)
{ {
if (multiValued) if (multi_valued)
{ {
// add default value in multi value mode // add default value in multi value mode
if (parsedValues.empty() and not defaultValues.empty()) if (parsed_values.empty() and not default_values.empty())
for (const auto& v : defaultValues) for (const auto& v : default_values)
acceptor(v); acceptor(v);
for (auto value : parsedValues) for (auto value : parsed_values)
{ {
acceptor(value); acceptor(value);
} }
} }
else else
{ {
auto maybe = getValue(); auto maybe = get_value();
if (maybe) if (maybe)
acceptor(*maybe); acceptor(*maybe);
} }
} }
} }
std::vector<T> defaultValues; std::vector<T> default_values;
std::vector<T> parsedValues; std::vector<T> parsed_values;
std::function<void(T)> acceptor; std::function<void(T)> acceptor;
}; };
@ -401,15 +404,13 @@ namespace llarp
/// case because we want to accept "truthy" and "falsy" string values (e.g. "off" == false) /// case because we want to accept "truthy" and "falsy" string values (e.g. "off" == false)
template <> template <>
bool bool
OptionDefinition<bool>::fromString(const std::string& input); OptionDefinition<bool>::from_string(const std::string& input);
using UndeclaredValueHandler = using UndeclaredValueHandler =
std::function<void(std::string_view section, std::string_view name, std::string_view value)>; std::function<void(std::string_view section, std::string_view name, std::string_view value)>;
using OptionDefinition_ptr = std::unique_ptr<OptionDefinitionBase>;
// map of k:v pairs // map of k:v pairs
using DefinitionMap = std::unordered_map<std::string, OptionDefinition_ptr>; using DefinitionMap = std::unordered_map<std::string, std::unique_ptr<OptionDefinitionBase>>;
// map of section-name to map-of-definitions // map of section-name to map-of-definitions
using SectionMap = std::unordered_map<std::string, DefinitionMap>; using SectionMap = std::unordered_map<std::string, DefinitionMap>;
@ -443,15 +444,15 @@ namespace llarp
/// @return `*this` for chaining calls /// @return `*this` for chaining calls
/// @throws std::invalid_argument if the option already exists /// @throws std::invalid_argument if the option already exists
ConfigDefinition& ConfigDefinition&
defineOption(OptionDefinition_ptr def); define_option(std::unique_ptr<OptionDefinitionBase> def);
/// Convenience function which calls defineOption with a OptionDefinition of the specified /// Convenience function which calls defineOption with a OptionDefinition of the specified
/// type and with parameters passed through to OptionDefinition's constructor. /// type and with parameters passed through to OptionDefinition's constructor.
template <typename T, typename... Params> template <typename T, typename... Params>
ConfigDefinition& ConfigDefinition&
defineOption(Params&&... args) define_option(Params&&... args)
{ {
return defineOption(std::make_unique<OptionDefinition<T>>(std::forward<Params>(args)...)); return define_option(std::make_unique<OptionDefinition<T>>(std::forward<Params>(args)...));
} }
/// Specify a config value for the given section and name. The value should be a valid string /// Specify a config value for the given section and name. The value should be a valid string
@ -459,7 +460,7 @@ namespace llarp
/// called). /// called).
/// ///
/// If the specified option doesn't exist, an exception will be thrown. Otherwise, the /// If the specified option doesn't exist, an exception will be thrown. Otherwise, the
/// option's parseValue() will be invoked, and should throw an exception if the string can't /// option's parse_value() will be invoked, and should throw an exception if the string can't
/// be parsed. /// be parsed.
/// ///
/// @param section is the section this value resides in /// @param section is the section this value resides in
@ -467,7 +468,7 @@ namespace llarp
/// @return `*this` for chaining calls /// @return `*this` for chaining calls
/// @throws if the option doesn't exist or the provided string isn't parseable /// @throws if the option doesn't exist or the provided string isn't parseable
ConfigDefinition& ConfigDefinition&
addConfigValue(std::string_view section, std::string_view name, std::string_view value); add_config_value(std::string_view section, std::string_view name, std::string_view value);
/// Get a config value. If the value hasn't been provided but a default has, the default will /// Get a config value. If the value hasn't been provided but a default has, the default will
/// be returned. If no value and no default is provided, an empty optional will be returned. /// be returned. If no value and no default is provided, an empty optional will be returned.
@ -482,9 +483,9 @@ namespace llarp
// provided // provided
template <typename T> template <typename T>
std::optional<T> std::optional<T>
getConfigValue(std::string_view section, std::string_view name) get_config_value(std::string_view section, std::string_view name)
{ {
OptionDefinition_ptr& definition = lookupDefinitionOrThrow(section, name); std::unique_ptr<OptionDefinitionBase>& definition = lookup_definition_or_throw(section, name);
auto derived = dynamic_cast<const OptionDefinition<T>*>(definition.get()); auto derived = dynamic_cast<const OptionDefinition<T>*>(definition.get());
if (not derived) if (not derived)
@ -505,19 +506,19 @@ namespace llarp
/// @param handler /// @param handler
/// @throws if there is already a handler for this section /// @throws if there is already a handler for this section
void void
addUndeclaredHandler(const std::string& section, UndeclaredValueHandler handler); add_undeclared_handler(const std::string& section, UndeclaredValueHandler handler);
/// Removes an "undeclared" handler for the given section. /// Removes an "undeclared" handler for the given section.
/// ///
/// @param section is the section which we want to remove the handler for /// @param section is the section which we want to remove the handler for
void void
removeUndeclaredHandler(const std::string& section); remove_undeclared_handler(const std::string& section);
/// Validate that all required fields are present. /// Validate that all required fields are present.
/// ///
/// @throws std::invalid_argument if configuration constraints are not met /// @throws std::invalid_argument if configuration constraints are not met
void void
validateRequiredFields(); validate_required_fields();
/// Accept all options. This will call the acceptor (if present) on each option. Note that /// Accept all options. This will call the acceptor (if present) on each option. Note that
/// this should only be called if all required fields are present (that is, /// this should only be called if all required fields are present (that is,
@ -525,14 +526,14 @@ namespace llarp
/// ///
/// @throws if any option's acceptor throws /// @throws if any option's acceptor throws
void void
acceptAllOptions(); accept_all_options();
/// validates and accept all parsed options /// validates and accept all parsed options
inline void inline void
process() process()
{ {
validateRequiredFields(); validate_required_fields();
acceptAllOptions(); accept_all_options();
} }
/// Add comments for a given section. Comments are replayed in-order during config file /// Add comments for a given section. Comments are replayed in-order during config file
@ -542,7 +543,7 @@ namespace llarp
/// @param section /// @param section
/// @param comment /// @param comment
void void
addSectionComments(const std::string& section, std::vector<std::string> comments); add_section_comments(const std::string& section, std::vector<std::string> comments);
/// Add comments for a given option. Similar to addSectionComment, but applies to a specific /// Add comments for a given option. Similar to addSectionComment, but applies to a specific
/// [section]:name pair. /// [section]:name pair.
@ -551,7 +552,7 @@ namespace llarp
/// @param name /// @param name
/// @param comment /// @param comment
void void
addOptionComments( add_option_comments(
const std::string& section, const std::string& name, std::vector<std::string> comments); const std::string& section, const std::string& name, std::vector<std::string> comments);
/// Generate a config string from the current config definition, optionally using overridden /// Generate a config string from the current config definition, optionally using overridden
@ -566,38 +567,39 @@ namespace llarp
/// addConfigValue()) or only definitions /// addConfigValue()) or only definitions
/// @return a string containing the config in INI format /// @return a string containing the config in INI format
std::string std::string
generateINIConfig(bool useValues = false); generate_ini_config(bool useValues = false);
private: private:
// If true skip client-only options; if false skip relay-only options. // If true skip client-only options; if false skip relay-only options.
bool relay; bool relay;
OptionDefinition_ptr& std::unique_ptr<OptionDefinitionBase>&
lookupDefinitionOrThrow(std::string_view section, std::string_view name); lookup_definition_or_throw(std::string_view section, std::string_view name);
const OptionDefinition_ptr& const std::unique_ptr<OptionDefinitionBase>&
lookupDefinitionOrThrow(std::string_view section, std::string_view name) const; lookup_definition_or_throw(std::string_view section, std::string_view name) const;
using SectionVisitor = std::function<void(const std::string&, const DefinitionMap&)>; using SectionVisitor = std::function<void(const std::string&, const DefinitionMap&)>;
void void
visitSections(SectionVisitor visitor) const; visit_sections(SectionVisitor visitor) const;
using DefVisitor = std::function<void(const std::string&, const OptionDefinition_ptr&)>; using DefVisitor =
std::function<void(const std::string&, const std::unique_ptr<OptionDefinitionBase>&)>;
void void
visitDefinitions(const std::string& section, DefVisitor visitor) const; visit_definitions(const std::string& section, DefVisitor visitor) const;
SectionMap m_definitions; SectionMap definitions;
std::unordered_map<std::string, UndeclaredValueHandler> m_undeclaredHandlers; std::unordered_map<std::string, UndeclaredValueHandler> undeclared_handlers;
// track insertion order. the vector<string>s are ordered list of section/option names. // track insertion order. the vector<string>s are ordered list of section/option names.
std::vector<std::string> m_sectionOrdering; std::vector<std::string> section_ordering;
std::unordered_map<std::string, std::vector<std::string>> m_definitionOrdering; std::unordered_map<std::string, std::vector<std::string>> definition_ordering;
// comments for config file generation // comments for config file generation
using CommentList = std::vector<std::string>; using CommentList = std::vector<std::string>;
using CommentsMap = std::unordered_map<std::string, CommentList>; using CommentsMap = std::unordered_map<std::string, CommentList>;
CommentsMap m_sectionComments; CommentsMap section_comments;
std::unordered_map<std::string, CommentsMap> m_definitionComments; std::unordered_map<std::string, CommentsMap> definition_comments;
}; };
} // namespace llarp } // namespace llarp

@ -11,45 +11,45 @@
namespace llarp namespace llarp
{ {
bool bool
ConfigParser::LoadFile(const fs::path& fname) ConfigParser::load_file(const fs::path& fname)
{ {
try try
{ {
m_Data = util::file_to_string(fname); _data = util::file_to_string(fname);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
return false; return false;
} }
if (m_Data.empty()) if (_data.empty())
return false; return false;
m_FileName = fname; _filename = fname;
return Parse(); return parse();
} }
bool bool
ConfigParser::LoadNewFromStr(std::string_view str) ConfigParser::load_new_from_str(std::string_view str)
{ {
m_Data.resize(str.size()); _data.resize(str.size());
std::copy(str.begin(), str.end(), m_Data.begin()); std::copy(str.begin(), str.end(), _data.begin());
return ParseAll(); return parse_all();
} }
bool bool
ConfigParser::LoadFromStr(std::string_view str) ConfigParser::load_from_str(std::string_view str)
{ {
m_Data.resize(str.size()); _data.resize(str.size());
std::copy(str.begin(), str.end(), m_Data.begin()); std::copy(str.begin(), str.end(), _data.begin());
return Parse(); return parse();
} }
void void
ConfigParser::Clear() ConfigParser::clear()
{ {
m_Overrides.clear(); _overrides.clear();
m_Config.clear(); _config.clear();
m_Data.clear(); _data.clear();
} }
static bool static bool
@ -62,19 +62,19 @@ namespace llarp
/// ParseAll() is only used by RPC endpoint 'config' for /// ParseAll() is only used by RPC endpoint 'config' for
/// reading new .ini files from string and writing them /// reading new .ini files from string and writing them
bool bool
ConfigParser::ParseAll() ConfigParser::parse_all()
{ {
std::list<std::string_view> lines; std::list<std::string_view> lines;
{ {
auto itr = m_Data.begin(); auto itr = _data.begin();
// split into lines // split into lines
while (itr != m_Data.end()) while (itr != _data.end())
{ {
auto beg = itr; auto beg = itr;
while (itr != m_Data.end() && *itr != '\n' && *itr != '\r') while (itr != _data.end() && *itr != '\n' && *itr != '\r')
++itr; ++itr;
lines.emplace_back(std::addressof(*beg), std::distance(beg, itr)); lines.emplace_back(std::addressof(*beg), std::distance(beg, itr));
if (itr == m_Data.end()) if (itr == _data.end())
break; break;
++itr; ++itr;
} }
@ -116,34 +116,34 @@ namespace llarp
if (k.empty()) if (k.empty())
{ {
throw std::runtime_error( throw std::runtime_error(
fmt::format("{} invalid line ({}): '{}'", m_FileName, lineno, line)); fmt::format("{} invalid line ({}): '{}'", _filename, lineno, line));
} }
LogDebug(m_FileName, ": [", sectName, "]:", k, "=", v); LogDebug(_filename, ": [", sectName, "]:", k, "=", v);
m_Config[std::string{sectName}].emplace(k, v); _config[std::string{sectName}].emplace(k, v);
} }
else // malformed? else // malformed?
{ {
throw std::runtime_error( throw std::runtime_error(
fmt::format("{} invalid line ({}): '{}'", m_FileName, lineno, line)); fmt::format("{} invalid line ({}): '{}'", _filename, lineno, line));
} }
} }
return true; return true;
} }
bool bool
ConfigParser::Parse() ConfigParser::parse()
{ {
std::list<std::string_view> lines; std::list<std::string_view> lines;
{ {
auto itr = m_Data.begin(); auto itr = _data.begin();
// split into lines // split into lines
while (itr != m_Data.end()) while (itr != _data.end())
{ {
auto beg = itr; auto beg = itr;
while (itr != m_Data.end() && *itr != '\n' && *itr != '\r') while (itr != _data.end() && *itr != '\n' && *itr != '\r')
++itr; ++itr;
lines.emplace_back(std::addressof(*beg), std::distance(beg, itr)); lines.emplace_back(std::addressof(*beg), std::distance(beg, itr));
if (itr == m_Data.end()) if (itr == _data.end())
break; break;
++itr; ++itr;
} }
@ -185,53 +185,54 @@ namespace llarp
if (k.empty()) if (k.empty())
{ {
throw std::runtime_error( throw std::runtime_error(
fmt::format("{} invalid line ({}): '{}'", m_FileName, lineno, line)); fmt::format("{} invalid line ({}): '{}'", _filename, lineno, line));
} }
LogDebug(m_FileName, ": [", sectName, "]:", k, "=", v); LogDebug(_filename, ": [", sectName, "]:", k, "=", v);
m_Config[std::string{sectName}].emplace(k, v); _config[std::string{sectName}].emplace(k, v);
} }
else // malformed? else // malformed?
{ {
throw std::runtime_error( throw std::runtime_error(
fmt::format("{} invalid line ({}): '{}'", m_FileName, lineno, line)); fmt::format("{} invalid line ({}): '{}'", _filename, lineno, line));
} }
} }
return true; return true;
} }
void void
ConfigParser::IterAll(std::function<void(std::string_view, const SectionValues_t&)> visit) ConfigParser::iter_all_sections(std::function<void(std::string_view, const SectionValues&)> visit)
{ {
for (const auto& item : m_Config) for (const auto& item : _config)
visit(item.first, item.second); visit(item.first, item.second);
} }
bool bool
ConfigParser::VisitSection( ConfigParser::visit_section(
const char* name, std::function<bool(const SectionValues_t& sect)> visit) const const char* name, std::function<bool(const SectionValues& sect)> visit) const
{ {
// m_Config is effectively: // m_Config is effectively:
// unordered_map< string, unordered_multimap< string, string >> // unordered_map< string, unordered_multimap< string, string >>
// in human terms: a map of of sections // in human terms: a map of of sections
// where a section is a multimap of k:v pairs // where a section is a multimap of k:v pairs
auto itr = m_Config.find(name); auto itr = _config.find(name);
if (itr == m_Config.end()) if (itr == _config.end())
return false; return false;
return visit(itr->second); return visit(itr->second);
} }
void void
ConfigParser::AddOverride(fs::path fpath, std::string section, std::string key, std::string value) ConfigParser::add_override(
fs::path fpath, std::string section, std::string key, std::string value)
{ {
auto& data = m_Overrides[fpath]; auto& data = _overrides[fpath];
data[section].emplace(key, value); data[section].emplace(key, value);
} }
void void
ConfigParser::Save() ConfigParser::save()
{ {
// write overrides // write overrides
for (const auto& [fname, overrides] : m_Overrides) for (const auto& [fname, overrides] : _overrides)
{ {
std::ofstream ofs(fname); std::ofstream ofs(fname);
for (const auto& [section, values] : overrides) for (const auto& [section, values] : overrides)
@ -243,27 +244,27 @@ namespace llarp
} }
} }
} }
m_Overrides.clear(); _overrides.clear();
} }
void void
ConfigParser::SaveNew() const ConfigParser::save_new() const
{ {
if (not m_Overrides.empty()) if (not _overrides.empty())
{ {
throw std::invalid_argument("Override specified when attempting new .ini save"); throw std::invalid_argument("Override specified when attempting new .ini save");
} }
if (m_Config.empty()) if (_config.empty())
{ {
throw std::invalid_argument("New config not loaded when attempting new .ini save"); throw std::invalid_argument("New config not loaded when attempting new .ini save");
} }
if (m_FileName.empty()) if (_filename.empty())
{ {
throw std::invalid_argument("New config cannot be saved with filepath specified"); throw std::invalid_argument("New config cannot be saved with filepath specified");
} }
std::ofstream ofs(m_FileName); std::ofstream ofs(_filename);
for (const auto& [section, values] : m_Config) for (const auto& [section, values] : _config)
{ {
ofs << std::endl << "[" << section << "]" << std::endl; ofs << std::endl << "[" << section << "]" << std::endl;
for (const auto& [key, value] : values) for (const auto& [key, value] : values)

@ -13,68 +13,68 @@ namespace llarp
{ {
struct ConfigParser struct ConfigParser
{ {
using SectionValues_t = std::unordered_multimap<std::string, std::string>; using SectionValues = std::unordered_multimap<std::string, std::string>;
using Config_impl_t = std::unordered_map<std::string, SectionValues_t>; using ConfigMap = std::unordered_map<std::string, SectionValues>;
/// clear parser /// clear parser
void void
Clear(); clear();
/// load config file for bootserv /// load config file for bootserv
/// return true on success /// return true on success
/// return false on error /// return false on error
bool bool
LoadFile(const fs::path& fname); load_file(const fs::path& fname);
/// load new .ini file from string (calls ParseAll() rather than Parse()) /// load new .ini file from string (calls ParseAll() rather than Parse())
/// return true on success /// return true on success
/// return false on error /// return false on error
bool bool
LoadNewFromStr(std::string_view str); load_new_from_str(std::string_view str);
/// load from string /// load from string
/// return true on success /// return true on success
/// return false on error /// return false on error
bool bool
LoadFromStr(std::string_view str); load_from_str(std::string_view str);
/// iterate all sections and thier values /// iterate all sections and thier values
void void
IterAll(std::function<void(std::string_view, const SectionValues_t&)> visit); iter_all_sections(std::function<void(std::string_view, const SectionValues&)> visit);
/// visit a section in config read only by name /// visit a section in config read only by name
/// return false if no section or value propagated from visitor /// return false if no section or value propagated from visitor
bool bool
VisitSection(const char* name, std::function<bool(const SectionValues_t&)> visit) const; visit_section(const char* name, std::function<bool(const SectionValues&)> visit) const;
/// add a config option that is appended in another file /// add a config option that is appended in another file
void void
AddOverride(fs::path file, std::string section, std::string key, std::string value); add_override(fs::path file, std::string section, std::string key, std::string value);
/// save config overrides /// save config overrides
void void
Save(); save();
/// save new .ini config file to path /// save new .ini config file to path
void void
SaveNew() const; save_new() const;
inline void void
Filename(fs::path f) set_filename(const fs::path& f)
{ {
m_FileName = f; _filename = f;
}; }
private: private:
bool bool
ParseAll(); parse_all();
bool bool
Parse(); parse();
std::string m_Data; std::string _data;
Config_impl_t m_Config; ConfigMap _config;
std::unordered_map<fs::path, Config_impl_t, util::FileHash> m_Overrides; std::unordered_map<fs::path, ConfigMap, util::FileHash> _overrides;
fs::path m_FileName; fs::path _filename;
}; };
} // namespace llarp } // namespace llarp

@ -27,7 +27,7 @@ namespace llarp
return true; return true;
} }
const fs::path root = config.router.m_dataDir; const fs::path root = config.router.data_dir;
// utility function to assign a path, using the specified config parameter if present and // utility function to assign a path, using the specified config parameter if present and
// falling back to root / defaultName if not // falling back to root / defaultName if not
@ -46,10 +46,10 @@ namespace llarp
} }
}; };
m_rcPath = deriveFile(our_rc_filename, config.router.m_routerContactFile); m_rcPath = deriveFile(our_rc_filename, config.router.rc_file);
m_idKeyPath = deriveFile(our_identity_filename, config.router.m_identityKeyFile); m_idKeyPath = deriveFile(our_identity_filename, config.router.idkey_file);
m_encKeyPath = deriveFile(our_enc_key_filename, config.router.m_encryptionKeyFile); m_encKeyPath = deriveFile(our_enc_key_filename, config.router.enckey_file);
m_transportKeyPath = deriveFile(our_transport_key_filename, config.router.m_transportKeyFile); m_transportKeyPath = deriveFile(our_transport_key_filename, config.router.transkey_file);
RemoteRC rc; RemoteRC rc;
bool exists = rc.read(m_rcPath); bool exists = rc.read(m_rcPath);
@ -90,7 +90,7 @@ namespace llarp
} }
} }
if (not config.router.m_isRelay) if (not config.router.is_relay)
{ {
// load identity key or create if needed // load identity key or create if needed
auto identityKeygen = [](llarp::SecretKey& key) { auto identityKeygen = [](llarp::SecretKey& key) {

@ -62,7 +62,7 @@ namespace llarp
if (!loop) if (!loop)
{ {
auto jobQueueSize = std::max(event_loop_queue_size, config->router.m_JobQueueSize); auto jobQueueSize = std::max(event_loop_queue_size, config->router.job_que_size);
loop = EventLoop::create(jobQueueSize); loop = EventLoop::create(jobQueueSize);
} }

@ -33,11 +33,6 @@ namespace llarp
return oxenc::to_hex(begin(), end()); return oxenc::to_hex(begin(), end());
} }
PubKey::operator RouterID() const
{
return {as_array()};
}
PubKey& PubKey&
PubKey::operator=(const byte_t* ptr) PubKey::operator=(const byte_t* ptr)
{ {
@ -51,12 +46,6 @@ namespace llarp
return lhs.as_array() == rhs.as_array(); return lhs.as_array() == rhs.as_array();
} }
bool
operator==(const PubKey& lhs, const RouterID& rhs)
{
return lhs.as_array() == rhs.as_array();
}
bool bool
SecretKey::LoadFromFile(const fs::path& fname) SecretKey::LoadFromFile(const fs::path& fname)
{ {

@ -38,8 +38,6 @@ namespace llarp
static PubKey static PubKey
from_string(const std::string& s); from_string(const std::string& s);
operator RouterID() const;
PubKey& PubKey&
operator=(const byte_t* ptr); operator=(const byte_t* ptr);
}; };
@ -47,9 +45,6 @@ namespace llarp
bool bool
operator==(const PubKey& lhs, const PubKey& rhs); operator==(const PubKey& lhs, const PubKey& rhs);
bool
operator==(const PubKey& lhs, const RouterID& rhs);
struct PrivateKey; struct PrivateKey;
/// Stores a sodium "secret key" value, which is actually the seed /// Stores a sodium "secret key" value, which is actually the seed

@ -233,13 +233,13 @@ namespace llarp::dns
bool is_apple_tramp = false; bool is_apple_tramp = false;
// set up forward dns // set up forward dns
for (const auto& dns : conf.m_upstreamDNS) for (const auto& dns : conf.upstream_dns)
{ {
AddUpstreamResolver(dns); AddUpstreamResolver(dns);
is_apple_tramp = is_apple_tramp or ConfigureAppleTrampoline(dns); is_apple_tramp = is_apple_tramp or ConfigureAppleTrampoline(dns);
} }
if (auto maybe_addr = conf.m_QueryBind; maybe_addr and not is_apple_tramp) if (auto maybe_addr = conf.query_bind; maybe_addr and not is_apple_tramp)
{ {
SockAddr addr{*maybe_addr}; SockAddr addr{*maybe_addr};
std::string host{addr.hostString()}; std::string host{addr.hostString()};
@ -356,11 +356,11 @@ namespace llarp::dns
SetOpt("do-tcp:", "no"); SetOpt("do-tcp:", "no");
for (const auto& [k, v] : conf.m_ExtraOpts) for (const auto& [k, v] : conf.extra_opts)
SetOpt(k, v); SetOpt(k, v);
// add host files // add host files
for (const auto& file : conf.m_hostfiles) for (const auto& file : conf.hostfiles)
{ {
const auto str = file.u8string(); const auto str = file.u8string();
if (auto ret = ub_ctx_hosts(m_ctx, str.c_str())) if (auto ret = ub_ctx_hosts(m_ctx, str.c_str()))
@ -447,7 +447,7 @@ namespace llarp::dns
{ {
Down(); Down();
if (replace_upstream) if (replace_upstream)
m_conf.m_upstreamDNS = std::move(*replace_upstream); m_conf.upstream_dns = std::move(*replace_upstream);
Up(m_conf); Up(m_conf);
} }
@ -590,7 +590,7 @@ namespace llarp::dns
Server::Start() Server::Start()
{ {
// set up udp sockets // set up udp sockets
for (const auto& addr : m_Config.m_bind) for (const auto& addr : m_Config.bind_addr)
{ {
if (auto ptr = MakePacketSourceOn(addr, m_Config)) if (auto ptr = MakePacketSourceOn(addr, m_Config))
AddPacketSource(std::move(ptr)); AddPacketSource(std::move(ptr));
@ -622,7 +622,7 @@ namespace llarp::dns
std::shared_ptr<Resolver_Base> std::shared_ptr<Resolver_Base>
Server::MakeDefaultResolver() Server::MakeDefaultResolver()
{ {
if (m_Config.m_upstreamDNS.empty()) if (m_Config.upstream_dns.empty())
{ {
log::info( log::info(
logcat, logcat,

@ -86,6 +86,12 @@ namespace llarp
return remote_signkey; return remote_signkey;
} }
RouterID
router_id() const
{
return remote_signkey.data();
}
uint64_t uint64_t
TxRate() const TxRate() const
{ {

@ -99,7 +99,7 @@ namespace llarp::handlers
{ {
if (not itr->second->LooksDead(Now())) if (not itr->second->LooksDead(Now()))
{ {
return router->send_data_message(itr->second->PubKey(), std::move(payload)); return router->send_data_message(itr->second->router_id(), std::move(payload));
} }
} }
@ -232,7 +232,7 @@ namespace llarp::handlers
auto itr = ip_to_key.find(*ip); auto itr = ip_to_key.find(*ip);
if (itr != ip_to_key.end() && snode_keys.find(itr->second) != snode_keys.end()) if (itr != ip_to_key.end() && snode_keys.find(itr->second) != snode_keys.end())
{ {
RouterID them = itr->second; RouterID them{itr->second.data()};
msg.AddAReply(them.ToString()); msg.AddAReply(them.ToString());
} }
else else
@ -389,7 +389,7 @@ namespace llarp::handlers
// check if it's a service node session we made and queue it via our // check if it's a service node session we made and queue it via our
// snode session that we made otherwise use an inbound session that // snode session that we made otherwise use an inbound session that
// was made by the other service node // was made by the other service node
auto itr = snode_sessions.find(pk); auto itr = snode_sessions.find(RouterID{pk.data()});
if (itr != snode_sessions.end()) if (itr != snode_sessions.end())
{ {
itr->second->send_packet_to_remote(buf.to_string()); itr->second->send_packet_to_remote(buf.to_string());
@ -594,7 +594,7 @@ namespace llarp::handlers
std::unordered_set<AddressVariant_t> remote; std::unordered_set<AddressVariant_t> remote;
for (const auto& [path, pubkey] : paths) for (const auto& [path, pubkey] : paths)
{ {
remote.insert(RouterID{pubkey}); remote.insert(RouterID{pubkey.data()});
} }
return remote; return remote;
} }
@ -691,12 +691,12 @@ namespace llarp::handlers
dns_conf = dnsConfig; dns_conf = dnsConfig;
if (networkConfig.m_endpointType == "null") if (networkConfig.endpoint_type == "null")
{ {
should_init_tun = false; should_init_tun = false;
} }
ip_range = networkConfig.m_ifaddr; ip_range = networkConfig.if_addr;
if (!ip_range.addr.h) if (!ip_range.addr.h)
{ {
const auto maybe = router->net().FindFreeRange(); const auto maybe = router->net().FindFreeRange();
@ -711,7 +711,7 @@ namespace llarp::handlers
highest_addr = ip_range.HighestAddr(); highest_addr = ip_range.HighestAddr();
use_ipv6 = not ip_range.IsV4(); use_ipv6 = not ip_range.IsV4();
if_name = networkConfig.m_ifname; if_name = networkConfig.if_name;
if (if_name.empty()) if (if_name.empty())
{ {
const auto maybe = router->net().FindFreeTun(); const auto maybe = router->net().FindFreeTun();

@ -92,7 +92,7 @@ namespace llarp::handlers
// tunnel. // tunnel.
return to.getIP() != m_OurIP; return to.getIP() != m_OurIP;
} }
else if (auto maybe_addr = m_Config.m_QueryBind) else if (auto maybe_addr = m_Config.query_bind)
{ {
const auto& addr = *maybe_addr; const auto& addr = *maybe_addr;
// omit traffic to and from our dns socket // omit traffic to and from our dns socket
@ -116,7 +116,7 @@ namespace llarp::handlers
explicit TunDNS(TunEndpoint* ep, const llarp::DnsConfig& conf) explicit TunDNS(TunEndpoint* ep, const llarp::DnsConfig& conf)
: dns::Server{ep->router()->loop(), conf, 0} : dns::Server{ep->router()->loop(), conf, 0}
, m_Endpoint{ep} , m_Endpoint{ep}
, m_QueryBind{conf.m_QueryBind} , m_QueryBind{conf.query_bind}
, m_OurIP{ToNet(ep->GetIfAddr())} , m_OurIP{ToNet(ep->GetIfAddr())}
{} {}
@ -144,7 +144,7 @@ namespace llarp::handlers
TunEndpoint::SetupDNS() TunEndpoint::SetupDNS()
{ {
const auto& info = GetVPNInterface()->Info(); const auto& info = GetVPNInterface()->Info();
if (m_DnsConfig.m_raw_dns) if (m_DnsConfig.raw)
{ {
auto dns = std::make_shared<TunDNS>(this, m_DnsConfig); auto dns = std::make_shared<TunDNS>(this, m_DnsConfig);
m_DNS = dns; m_DNS = dns;
@ -166,7 +166,7 @@ namespace llarp::handlers
m_DNS->AddResolver(weak_from_this()); m_DNS->AddResolver(weak_from_this());
m_DNS->Start(); m_DNS->Start();
if (m_DnsConfig.m_raw_dns) if (m_DnsConfig.raw)
{ {
if (auto vpn = router()->vpn_platform()) if (auto vpn = router()->vpn_platform())
{ {
@ -209,17 +209,17 @@ namespace llarp::handlers
obj["ifname"] = m_IfName; obj["ifname"] = m_IfName;
std::vector<std::string> upstreamRes; std::vector<std::string> upstreamRes;
for (const auto& ent : m_DnsConfig.m_upstreamDNS) for (const auto& ent : m_DnsConfig.upstream_dns)
upstreamRes.emplace_back(ent.ToString()); upstreamRes.emplace_back(ent.ToString());
obj["ustreamResolvers"] = upstreamRes; obj["ustreamResolvers"] = upstreamRes;
std::vector<std::string> localRes; std::vector<std::string> localRes;
for (const auto& ent : m_DnsConfig.m_bind) for (const auto& ent : m_DnsConfig.bind_addr)
localRes.emplace_back(ent.ToString()); localRes.emplace_back(ent.ToString());
obj["localResolvers"] = localRes; obj["localResolvers"] = localRes;
// for backwards compat // for backwards compat
if (not m_DnsConfig.m_bind.empty()) if (not m_DnsConfig.bind_addr.empty())
obj["localResolver"] = localRes[0]; obj["localResolver"] = localRes[0];
util::StatusObject ips{}; util::StatusObject ips{};
@ -266,7 +266,7 @@ namespace llarp::handlers
bool bool
TunEndpoint::Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) TunEndpoint::Configure(const NetworkConfig& conf, const DnsConfig& dnsConf)
{ {
if (conf.m_reachable) if (conf.is_reachable)
{ {
_publish_introset = true; _publish_introset = true;
log::info(link_cat, "TunEndpoint setting to be reachable by default"); log::info(link_cat, "TunEndpoint setting to be reachable by default");
@ -277,23 +277,23 @@ namespace llarp::handlers
log::info(link_cat, "TunEndpoint setting to be not reachable by default"); log::info(link_cat, "TunEndpoint setting to be not reachable by default");
} }
if (conf.m_AuthType == service::AuthType::eAuthTypeFile) if (conf.auth_type == service::AuthType::FILE)
{ {
_auth_policy = service::MakeFileAuthPolicy(router(), conf.m_AuthFiles, conf.m_AuthFileType); _auth_policy = service::make_file_auth_policy(router(), conf.auth_files, conf.auth_file_type);
} }
else if (conf.m_AuthType != service::AuthType::eAuthTypeNone) else if (conf.auth_type != service::AuthType::NONE)
{ {
std::string url, method; std::string url, method;
if (conf.m_AuthUrl.has_value() and conf.m_AuthMethod.has_value()) if (conf.auth_url.has_value() and conf.auth_method.has_value())
{ {
url = *conf.m_AuthUrl; url = *conf.auth_url;
method = *conf.m_AuthMethod; method = *conf.auth_method;
} }
auto auth = std::make_shared<rpc::EndpointAuthRPC>( auto auth = std::make_shared<rpc::EndpointAuthRPC>(
url, url,
method, method,
conf.m_AuthWhitelist, conf.auth_whitelist,
conf.m_AuthStaticTokens, conf.auth_static_tokens,
router()->lmq(), router()->lmq(),
shared_from_this()); shared_from_this());
auth->Start(); auth->Start();
@ -301,25 +301,25 @@ namespace llarp::handlers
} }
m_DnsConfig = dnsConf; m_DnsConfig = dnsConf;
m_TrafficPolicy = conf.m_TrafficPolicy; m_TrafficPolicy = conf.traffic_policy;
m_OwnedRanges = conf.m_OwnedRanges; m_OwnedRanges = conf.owned_ranges;
m_BaseV6Address = conf.m_baseV6Address; m_BaseV6Address = conf.base_ipv6_addr;
if (conf.m_PathAlignmentTimeout) if (conf.path_alignment_timeout)
{ {
m_PathAlignmentTimeout = *conf.m_PathAlignmentTimeout; m_PathAlignmentTimeout = *conf.path_alignment_timeout;
} }
else else
m_PathAlignmentTimeout = service::Endpoint::PathAlignmentTimeout(); m_PathAlignmentTimeout = service::Endpoint::PathAlignmentTimeout();
for (const auto& item : conf.m_mapAddrs) for (const auto& item : conf.map_addrs)
{ {
if (not MapAddress(item.second, item.first, false)) if (not MapAddress(item.second, item.first, false))
return false; return false;
} }
m_IfName = conf.m_ifname; m_IfName = conf.if_name;
if (m_IfName.empty()) if (m_IfName.empty())
{ {
const auto maybe = router()->net().FindFreeTun(); const auto maybe = router()->net().FindFreeTun();
@ -328,7 +328,7 @@ namespace llarp::handlers
m_IfName = *maybe; m_IfName = *maybe;
} }
m_OurRange = conf.m_ifaddr; m_OurRange = conf.if_addr;
if (!m_OurRange.addr.h) if (!m_OurRange.addr.h)
{ {
const auto maybe = router()->net().FindFreeRange(); const auto maybe = router()->net().FindFreeRange();
@ -342,7 +342,7 @@ namespace llarp::handlers
m_OurIP = m_OurRange.addr; m_OurIP = m_OurRange.addr;
m_UseV6 = false; m_UseV6 = false;
m_PersistAddrMapFile = conf.m_AddrMapPersistFile; m_PersistAddrMapFile = conf.addr_map_persist_file;
if (m_PersistAddrMapFile) if (m_PersistAddrMapFile)
{ {
const auto& file = *m_PersistAddrMapFile; const auto& file = *m_PersistAddrMapFile;

@ -314,7 +314,9 @@ namespace llarp
// TODO: confirm remote end is using the expected pubkey (RouterID). // TODO: confirm remote end is using the expected pubkey (RouterID).
// TODO: ALPN for "client" vs "relay" (could just be set on endpoint creation) // TODO: ALPN for "client" vs "relay" (could just be set on endpoint creation)
if (auto rv = ep.establish_connection(remote_addr, rc); rv) if (auto rv = ep.establish_connection(
oxen::quic::RemoteAddress{rc.router_id().ToView(), remote_addr}, rc);
rv)
{ {
log::info(quic_cat, "Connection to {} successfully established!", remote_addr); log::info(quic_cat, "Connection to {} successfully established!", remote_addr);
return; return;

@ -71,7 +71,8 @@ namespace llarp
template <typename... Opt> template <typename... Opt>
bool bool
establish_connection(const oxen::quic::Address& remote, const RemoteRC& rc, Opt&&... opts); establish_connection(
const oxen::quic::RemoteAddress& remote, const RemoteRC& rc, Opt&&... opts);
void void
for_each_connection(std::function<void(link::Connection&)> func); for_each_connection(std::function<void(link::Connection&)> func);
@ -364,7 +365,7 @@ namespace llarp
template <typename... Opt> template <typename... Opt>
bool bool
Endpoint::establish_connection( Endpoint::establish_connection(
const oxen::quic::Address& remote, const RemoteRC& rc, Opt&&... opts) const oxen::quic::RemoteAddress& remote, const RemoteRC& rc, Opt&&... opts)
{ {
try try
{ {

@ -121,21 +121,9 @@ namespace llarp
return var::visit([](auto&& ip) { return not ip.n; }, ip); return var::visit([](auto&& ip) { return not ip.n; }, ip);
} }
virtual std::optional<std::string> virtual std::optional<sockaddr*>
GetBestNetIF(int af = AF_INET) const = 0; GetBestNetIF(int af = AF_INET) const = 0;
inline std::optional<SockAddr>
MaybeInferPublicAddr(port_t default_port, int af = AF_INET) const
{
std::optional<SockAddr> maybe_addr;
if (auto maybe_ifname = GetBestNetIF(af))
maybe_addr = GetInterfaceAddr(*maybe_ifname, af);
if (maybe_addr)
maybe_addr->setPort(default_port);
return maybe_addr;
}
virtual std::optional<IPRange> virtual std::optional<IPRange>
FindFreeRange() const = 0; FindFreeRange() const = 0;

@ -50,10 +50,11 @@ namespace llarp::net
return ifname; return ifname;
} }
std::optional<std::string> std::optional<sockaddr*>
GetBestNetIF(int af) const override GetBestNetIF(int af) const override
{ {
std::optional<std::string> found; std::optional<sockaddr*> found;
iter_all([this, &found, af](auto i) { iter_all([this, &found, af](auto i) {
if (found) if (found)
return; return;
@ -61,7 +62,7 @@ namespace llarp::net
{ {
if (not IsBogon(*i->ifa_addr)) if (not IsBogon(*i->ifa_addr))
{ {
found = i->ifa_name; found = i->ifa_addr;
} }
} }
}); });

@ -18,16 +18,16 @@ namespace llarp
void void
SockAddr::init() SockAddr::init()
{ {
llarp::Zero(&m_addr, sizeof(m_addr)); llarp::Zero(&addr6, sizeof(addr6));
m_addr.sin6_family = AF_INET6; addr6.sin6_family = AF_INET6;
llarp::Zero(&m_addr4, sizeof(m_addr4)); llarp::Zero(&addr4, sizeof(addr4));
m_addr4.sin_family = AF_INET; addr4.sin_family = AF_INET;
} }
void void
SockAddr::applyIPv4MapBytes() SockAddr::applyIPv4MapBytes()
{ {
std::memcpy(m_addr.sin6_addr.s6_addr, ipv4_map_prefix.data(), ipv4_map_prefix.size()); std::memcpy(addr6.sin6_addr.s6_addr, ipv4_map_prefix.data(), ipv4_map_prefix.size());
} }
SockAddr::SockAddr() SockAddr::SockAddr()
@ -86,7 +86,7 @@ namespace llarp
SockAddr& SockAddr&
SockAddr::operator=(const SockAddr& other) SockAddr::operator=(const SockAddr& other)
{ {
*this = other.m_addr; *this = other.addr6;
return *this; return *this;
} }
@ -121,10 +121,10 @@ namespace llarp
applyIPv4MapBytes(); applyIPv4MapBytes();
// avoid byte order conversion (this is NBO -> NBO) // avoid byte order conversion (this is NBO -> NBO)
memcpy(m_addr.sin6_addr.s6_addr + 12, &other.sin_addr.s_addr, sizeof(in_addr)); memcpy(addr6.sin6_addr.s6_addr + 12, &other.sin_addr.s_addr, sizeof(in_addr));
m_addr.sin6_port = other.sin_port; addr6.sin6_port = other.sin_port;
m_addr4.sin_addr.s_addr = other.sin_addr.s_addr; addr4.sin_addr.s_addr = other.sin_addr.s_addr;
m_addr4.sin_port = other.sin_port; addr4.sin_port = other.sin_port;
m_empty = false; m_empty = false;
return *this; return *this;
@ -140,7 +140,7 @@ namespace llarp
{ {
init(); init();
memcpy(&m_addr, &other, sizeof(sockaddr_in6)); memcpy(&addr6, &other, sizeof(sockaddr_in6));
if (IPRange::V4MappedRange().Contains(asIPv6())) if (IPRange::V4MappedRange().Contains(asIPv6()))
{ {
setIPv4( setIPv4(
@ -148,7 +148,7 @@ namespace llarp
other.sin6_addr.s6_addr[13], other.sin6_addr.s6_addr[13],
other.sin6_addr.s6_addr[14], other.sin6_addr.s6_addr[14],
other.sin6_addr.s6_addr[15]); other.sin6_addr.s6_addr[15]);
m_addr4.sin_port = m_addr.sin6_port; addr4.sin_port = addr6.sin6_port;
} }
m_empty = false; m_empty = false;
@ -164,11 +164,11 @@ namespace llarp
SockAddr::operator=(const in6_addr& other) SockAddr::operator=(const in6_addr& other)
{ {
init(); init();
memcpy(&m_addr.sin6_addr.s6_addr, &other.s6_addr, sizeof(m_addr.sin6_addr.s6_addr)); memcpy(&addr6.sin6_addr.s6_addr, &other.s6_addr, sizeof(addr6.sin6_addr.s6_addr));
if (IPRange::V4MappedRange().Contains(asIPv6())) if (IPRange::V4MappedRange().Contains(asIPv6()))
{ {
setIPv4(other.s6_addr[12], other.s6_addr[13], other.s6_addr[14], other.s6_addr[15]); setIPv4(other.s6_addr[12], other.s6_addr[13], other.s6_addr[14], other.s6_addr[15]);
m_addr4.sin_port = m_addr.sin6_port; addr4.sin_port = addr6.sin6_port;
} }
m_empty = false; m_empty = false;
@ -177,48 +177,48 @@ namespace llarp
SockAddr::operator const sockaddr*() const SockAddr::operator const sockaddr*() const
{ {
return isIPv4() ? reinterpret_cast<const sockaddr*>(&m_addr4) return isIPv4() ? reinterpret_cast<const sockaddr*>(&addr4)
: reinterpret_cast<const sockaddr*>(&m_addr); : reinterpret_cast<const sockaddr*>(&addr6);
} }
SockAddr::operator const sockaddr_in*() const SockAddr::operator const sockaddr_in*() const
{ {
return &m_addr4; return &addr4;
} }
SockAddr::operator const sockaddr_in6*() const SockAddr::operator const sockaddr_in6*() const
{ {
return &m_addr; return &addr6;
} }
size_t size_t
SockAddr::sockaddr_len() const SockAddr::sockaddr_len() const
{ {
return isIPv6() ? sizeof(m_addr) : sizeof(m_addr4); return isIPv6() ? sizeof(addr6) : sizeof(addr4);
} }
bool bool
SockAddr::operator<(const SockAddr& other) const SockAddr::operator<(const SockAddr& other) const
{ {
return m_addr < other.m_addr; return addr6 < other.addr6;
} }
bool bool
SockAddr::operator==(const SockAddr& other) const SockAddr::operator==(const SockAddr& other) const
{ {
return m_addr == other.m_addr; return addr6 == other.addr6;
} }
huint128_t huint128_t
SockAddr::asIPv6() const SockAddr::asIPv6() const
{ {
return net::In6ToHUInt(m_addr.sin6_addr); return net::In6ToHUInt(addr6.sin6_addr);
} }
huint32_t huint32_t
SockAddr::asIPv4() const SockAddr::asIPv4() const
{ {
const nuint32_t n{m_addr4.sin_addr.s_addr}; const nuint32_t n{addr4.sin_addr.s_addr};
return ToHost(n); return ToHost(n);
} }
@ -241,7 +241,7 @@ namespace llarp
if (splits.size() > 2) if (splits.size() > 2)
{ {
std::string data{str}; std::string data{str};
if (inet_pton(AF_INET6, data.c_str(), m_addr.sin6_addr.s6_addr) == -1) if (inet_pton(AF_INET6, data.c_str(), addr6.sin6_addr.s6_addr) == -1)
throw std::runtime_error{"invalid ip6 address: " + data}; throw std::runtime_error{"invalid ip6 address: " + data};
return; return;
} }
@ -290,11 +290,11 @@ namespace llarp
if (isIPv4()) if (isIPv4())
{ {
// IPv4 mapped addrs // IPv4 mapped addrs
inet_ntop(AF_INET, &m_addr4.sin_addr.s_addr, buf.data(), buf.size()); inet_ntop(AF_INET, &addr4.sin_addr.s_addr, buf.data(), buf.size());
return buf.data(); return buf.data();
} }
inet_ntop(AF_INET6, &m_addr.sin6_addr.s6_addr, buf.data(), buf.size()); inet_ntop(AF_INET6, &addr6.sin6_addr.s6_addr, buf.data(), buf.size());
if (not ipv6_brackets) if (not ipv6_brackets)
return buf.data(); return buf.data();
@ -321,7 +321,7 @@ namespace llarp
nuint32_t nuint32_t
SockAddr::getIPv4() const SockAddr::getIPv4() const
{ {
return {m_addr4.sin_addr.s_addr}; return {addr4.sin_addr.s_addr};
} }
nuint128_t nuint128_t
@ -331,7 +331,7 @@ namespace llarp
// Explicit cast to void* here to avoid non-trivial type copying warnings (technically this // Explicit cast to void* here to avoid non-trivial type copying warnings (technically this
// isn't trivial because of the zeroing default constructor, but it's trivial enough that this // isn't trivial because of the zeroing default constructor, but it's trivial enough that this
// copy is safe). // copy is safe).
std::memcpy(static_cast<void*>(&a), &m_addr.sin6_addr, 16); std::memcpy(static_cast<void*>(&a), &addr6.sin6_addr, 16);
return a; return a;
} }
@ -346,13 +346,13 @@ namespace llarp
void void
SockAddr::setIPv4(nuint32_t ip) SockAddr::setIPv4(nuint32_t ip)
{ {
uint8_t* ip6 = m_addr.sin6_addr.s6_addr; uint8_t* ip6 = addr6.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr)); llarp::Zero(ip6, sizeof(addr6.sin6_addr.s6_addr));
applyIPv4MapBytes(); applyIPv4MapBytes();
std::memcpy(ip6 + 12, &ip, 4); std::memcpy(ip6 + 12, &ip, 4);
m_addr4.sin_addr.s_addr = ip.n; addr4.sin_addr.s_addr = ip.n;
m_empty = false; m_empty = false;
} }
@ -365,8 +365,8 @@ namespace llarp
void void
SockAddr::setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d) SockAddr::setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{ {
uint8_t* ip6 = m_addr.sin6_addr.s6_addr; uint8_t* ip6 = addr6.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr)); llarp::Zero(ip6, sizeof(addr6.sin6_addr.s6_addr));
applyIPv4MapBytes(); applyIPv4MapBytes();
@ -375,7 +375,7 @@ namespace llarp
ip6[14] = c; ip6[14] = c;
ip6[15] = d; ip6[15] = d;
const auto ip = ipaddr_ipv4_bits(a, b, c, d); const auto ip = ipaddr_ipv4_bits(a, b, c, d);
m_addr4.sin_addr.s_addr = htonl(ip.h); addr4.sin_addr.s_addr = htonl(ip.h);
m_empty = false; m_empty = false;
} }
@ -388,23 +388,23 @@ namespace llarp
void void
SockAddr::setIPv6(nuint128_t ip) SockAddr::setIPv6(nuint128_t ip)
{ {
std::memcpy(&m_addr.sin6_addr, &ip, sizeof(m_addr.sin6_addr)); std::memcpy(&addr6.sin6_addr, &ip, sizeof(addr6.sin6_addr));
if (isIPv4()) if (isIPv4())
{ {
setIPv4( setIPv4(
m_addr.sin6_addr.s6_addr[12], addr6.sin6_addr.s6_addr[12],
m_addr.sin6_addr.s6_addr[13], addr6.sin6_addr.s6_addr[13],
m_addr.sin6_addr.s6_addr[14], addr6.sin6_addr.s6_addr[14],
m_addr.sin6_addr.s6_addr[15]); addr6.sin6_addr.s6_addr[15]);
m_addr4.sin_port = m_addr.sin6_port; addr4.sin_port = addr6.sin6_port;
} }
} }
void void
SockAddr::setPort(nuint16_t port) SockAddr::setPort(nuint16_t port)
{ {
m_addr.sin6_port = port.n; addr6.sin6_port = port.n;
m_addr4.sin_port = port.n; addr4.sin_port = port.n;
} }
void void
@ -416,7 +416,7 @@ namespace llarp
net::port_t net::port_t
SockAddr::port() const SockAddr::port() const
{ {
return net::port_t{m_addr.sin6_port}; return net::port_t{addr6.sin6_port};
} }
} // namespace llarp } // namespace llarp

@ -177,10 +177,21 @@ namespace llarp
huint32_t huint32_t
asIPv4() const; asIPv4() const;
const sockaddr_in*
in()
{
return &addr4;
}
const sockaddr_in6*
in6()
{
return &addr6;
}
private: private:
bool m_empty = true; bool m_empty = true;
sockaddr_in6 m_addr; sockaddr_in6 addr6;
sockaddr_in m_addr4; sockaddr_in addr4;
void void
init(); init();

@ -129,7 +129,7 @@ namespace llarp::net
return "lokitun0"; return "lokitun0";
} }
std::optional<std::string> std::optional<sockaddr*>
GetBestNetIF(int) const override GetBestNetIF(int) const override
{ {
// TODO: implement me ? // TODO: implement me ?

@ -363,7 +363,7 @@ namespace llarp
hopsSet.insert(rc); hopsSet.insert(rc);
#ifndef TESTNET #ifndef TESTNET
if (not pathConfig.Acceptable(hopsSet)) if (not pathConfig.check_rcs(hopsSet))
return false; return false;
#endif #endif
return rc.router_id() != endpointRC.router_id(); return rc.router_id() != endpointRC.router_id();

@ -120,7 +120,7 @@ namespace llarp
if (router.is_service_node()) if (router.is_service_node())
return false; return false;
if (const auto& conf = router.config()) if (const auto& conf = router.config())
return conf->network.m_EnableRoutePoker; return conf->network.enable_route_poker;
throw std::runtime_error{"Attempting to use RoutePoker with router with no config set"}; throw std::runtime_error{"Attempting to use RoutePoker with router with no config set"};
} }
@ -214,7 +214,7 @@ namespace llarp
vpn::AbstractRouteManager& route = router.vpn_platform()->RouteManager(); vpn::AbstractRouteManager& route = router.vpn_platform()->RouteManager();
// black hole all routes if enabled // black hole all routes if enabled
if (router.config()->network.m_BlackholeRoutes) if (router.config()->network.blackhole_routes)
route.add_blackhole(); route.add_blackhole();
// explicit route pokes for first hops // explicit route pokes for first hops

@ -377,30 +377,29 @@ namespace llarp
// Do logging config as early as possible to get the configured log level applied // Do logging config as early as possible to get the configured log level applied
// Backwards compat: before 0.9.10 we used `type=file` with `file=|-|stdout` for print mode // Backwards compat: before 0.9.10 we used `type=file` with `file=|-|stdout` for print mode
auto log_type = conf.logging.m_logType; auto log_type = conf.logging.type;
if (log_type == log::Type::File if (log_type == log::Type::File
&& (conf.logging.m_logFile == "stdout" || conf.logging.m_logFile == "-" && (conf.logging.file == "stdout" || conf.logging.file == "-" || conf.logging.file.empty()))
|| conf.logging.m_logFile.empty()))
log_type = log::Type::Print; log_type = log::Type::Print;
if (log::get_level_default() != log::Level::off) if (log::get_level_default() != log::Level::off)
log::reset_level(conf.logging.m_logLevel); log::reset_level(conf.logging.level);
log::clear_sinks(); log::clear_sinks();
log::add_sink(log_type, log_type == log::Type::System ? "lokinet" : conf.logging.m_logFile); log::add_sink(log_type, log_type == log::Type::System ? "lokinet" : conf.logging.file);
// re-add rpc log sink if rpc enabled, else free it // re-add rpc log sink if rpc enabled, else free it
if (_config->api.m_enableRPCServer and llarp::logRingBuffer) if (_config->api.enable_rpc_server and llarp::logRingBuffer)
log::add_sink(llarp::logRingBuffer, llarp::log::DEFAULT_PATTERN_MONO); log::add_sink(llarp::logRingBuffer, llarp::log::DEFAULT_PATTERN_MONO);
else else
llarp::logRingBuffer = nullptr; llarp::logRingBuffer = nullptr;
log::debug(logcat, "Configuring router"); log::debug(logcat, "Configuring router");
_is_service_node = conf.router.m_isRelay; _is_service_node = conf.router.is_relay;
if (_is_service_node) if (_is_service_node)
{ {
rpc_addr = oxenmq::address(conf.lokid.lokidRPCAddr); rpc_addr = oxenmq::address(conf.lokid.rpc_addr);
_rpc_client = std::make_shared<rpc::LokidRpcClient>(_lmq, weak_from_this()); _rpc_client = std::make_shared<rpc::LokidRpcClient>(_lmq, weak_from_this());
} }
@ -408,8 +407,8 @@ namespace llarp
if (not StartRpcServer()) if (not StartRpcServer())
throw std::runtime_error("Failed to start rpc server"); throw std::runtime_error("Failed to start rpc server");
if (conf.router.m_workerThreads > 0) if (conf.router.worker_threads > 0)
_lmq->set_general_threads(conf.router.m_workerThreads); _lmq->set_general_threads(conf.router.worker_threads);
log::debug(logcat, "Starting OMQ server"); log::debug(logcat, "Starting OMQ server");
_lmq->start(); _lmq->start();
@ -560,11 +559,11 @@ namespace llarp
Router::from_config(const Config& conf) Router::from_config(const Config& conf)
{ {
// Set netid before anything else // Set netid before anything else
log::debug(logcat, "Network ID set to {}", conf.router.m_netId); log::debug(logcat, "Network ID set to {}", conf.router.net_id);
if (!conf.router.m_netId.empty() if (!conf.router.net_id.empty()
&& strcmp(conf.router.m_netId.c_str(), llarp::LOKINET_DEFAULT_NETID) != 0) && strcmp(conf.router.net_id.c_str(), llarp::LOKINET_DEFAULT_NETID) != 0)
{ {
const auto& netid = conf.router.m_netId; const auto& netid = conf.router.net_id;
llarp::LogWarn( llarp::LogWarn(
"!!!! you have manually set netid to be '", "!!!! you have manually set netid to be '",
netid, netid,
@ -576,24 +575,24 @@ namespace llarp
} }
// Router config // Router config
_link_manager.max_connected_routers = conf.router.m_maxConnectedRouters; _link_manager.max_connected_routers = conf.router.max_connected_routers;
_link_manager.min_connected_routers = conf.router.m_minConnectedRouters; _link_manager.min_connected_routers = conf.router.min_connected_routers;
encryption_keyfile = _key_manager->m_encKeyPath; encryption_keyfile = _key_manager->m_encKeyPath;
our_rc_file = _key_manager->m_rcPath; our_rc_file = _key_manager->m_rcPath;
transport_keyfile = _key_manager->m_transportKeyPath; transport_keyfile = _key_manager->m_transportKeyPath;
identity_keyfile = _key_manager->m_idKeyPath; identity_keyfile = _key_manager->m_idKeyPath;
if (auto maybe_ip = conf.links.PublicAddress) if (auto maybe_ip = conf.links.public_addr)
_ourAddress = var::visit([](auto&& ip) { return SockAddr{ip}; }, *maybe_ip); _ourAddress = var::visit([](auto&& ip) { return SockAddr{ip}; }, *maybe_ip);
else if (auto maybe_ip = conf.router.PublicIP) else if (auto maybe_ip = conf.router.public_ip)
_ourAddress = var::visit([](auto&& ip) { return SockAddr{ip}; }, *maybe_ip); _ourAddress = var::visit([](auto&& ip) { return SockAddr{ip}; }, *maybe_ip);
if (_ourAddress) if (_ourAddress)
{ {
if (auto maybe_port = conf.links.PublicPort) if (auto maybe_port = conf.links.public_port)
_ourAddress->setPort(*maybe_port); _ourAddress->setPort(*maybe_port);
else if (auto maybe_port = conf.router.PublicPort) else if (auto maybe_port = conf.router.public_port)
_ourAddress->setPort(*maybe_port); _ourAddress->setPort(*maybe_port);
else else
throw std::runtime_error{"public ip provided without public port"}; throw std::runtime_error{"public ip provided without public port"};
@ -602,16 +601,16 @@ namespace llarp
else else
log::debug(logcat, "No explicit public address given; will auto-detect during link setup"); log::debug(logcat, "No explicit public address given; will auto-detect during link setup");
RouterContact::BLOCK_BOGONS = conf.router.m_blockBogons; RouterContact::BLOCK_BOGONS = conf.router.block_bogons;
auto& networkConfig = conf.network; auto& networkConfig = conf.network;
/// build a set of strictConnectPubkeys /// build a set of strictConnectPubkeys
std::unordered_set<RouterID> strictConnectPubkeys; std::unordered_set<RouterID> strictConnectPubkeys;
if (not networkConfig.m_strictConnect.empty()) if (not networkConfig.strict_connect.empty())
{ {
const auto& val = networkConfig.m_strictConnect; const auto& val = networkConfig.strict_connect;
if (is_service_node()) if (is_service_node())
throw std::runtime_error("cannot use strict-connect option as service node"); throw std::runtime_error("cannot use strict-connect option as service node");
if (val.size() < 2) if (val.size() < 2)
@ -628,7 +627,7 @@ namespace llarp
// if our conf had no bootstrap files specified, try the default location of // if our conf had no bootstrap files specified, try the default location of
// <DATA_DIR>/bootstrap.signed. If this isn't present, leave a useful error message // <DATA_DIR>/bootstrap.signed. If this isn't present, leave a useful error message
// TODO: use constant // TODO: use constant
fs::path defaultBootstrapFile = conf.router.m_dataDir / "bootstrap.signed"; fs::path defaultBootstrapFile = conf.router.data_dir / "bootstrap.signed";
if (configRouters.empty() and conf.bootstrap.routers.empty()) if (configRouters.empty() and conf.bootstrap.routers.empty())
{ {
if (fs::exists(defaultBootstrapFile)) if (fs::exists(defaultBootstrapFile))
@ -708,10 +707,10 @@ namespace llarp
InitOutboundLinks(); InitOutboundLinks();
// profiling // profiling
_profile_file = conf.router.m_dataDir / "profiles.dat"; _profile_file = conf.router.data_dir / "profiles.dat";
// Network config // Network config
if (conf.network.m_enableProfiling.value_or(false)) if (conf.network.enable_profiling.value_or(false))
{ {
LogInfo("router profiling enabled"); LogInfo("router profiling enabled");
if (not fs::exists(_profile_file)) if (not fs::exists(_profile_file))
@ -1009,7 +1008,7 @@ namespace llarp
_exit_context.Tick(now); _exit_context.Tick(now);
// save profiles // save profiles
if (router_profiling().ShouldSave(now) and _config->network.m_saveProfiles) if (router_profiling().ShouldSave(now) and _config->network.save_profiles)
{ {
queue_disk_io([&]() { router_profiling().Save(_profile_file); }); queue_disk_io([&]() { router_profiling().Save(_profile_file); });
} }
@ -1048,7 +1047,7 @@ namespace llarp
bool bool
Router::StartRpcServer() Router::StartRpcServer()
{ {
if (_config->api.m_enableRPCServer) if (_config->api.enable_rpc_server)
_rpc_server = std::make_unique<rpc::RPCServer>(_lmq, *this); _rpc_server = std::make_unique<rpc::RPCServer>(_lmq, *this);
return true; return true;

@ -12,32 +12,6 @@
namespace llarp namespace llarp
{ {
// RouterContact::RouterContact(std::string buf)
// {
// try
// {
// oxenc::bt_list_consumer btlc{buf};
// // signature.from_string(btlc.consume_string());
// signed_bt_dict = btlc.consume_string();
// // TODO: parse bt dict
// }
// catch (...)
// {
// log::warning(llarp_cat, "Error: RouterContact failed to populate bt encoded contents!");
// }
// }
// std::string
// RouterContact::bt_encode() const
// {
// oxenc::bt_dict_producer btdp;
// bt_encode(btdp);
// return std::move(btdp).str();
// }
void void
RouterContact::bt_load(oxenc::bt_dict_consumer& data) RouterContact::bt_load(oxenc::bt_dict_consumer& data)
{ {

@ -244,7 +244,7 @@ namespace llarp
void void
clear() override clear() override
{ {
_addr = {}; _addr = oxen::quic::Address{};
_addr6.reset(); _addr6.reset();
_router_id.Zero(); _router_id.Zero();
_timestamp = {}; _timestamp = {};
@ -338,7 +338,7 @@ namespace llarp
void void
clear() override clear() override
{ {
_addr = {}; _addr = oxen::quic::Address{};
_addr6.reset(); _addr6.reset();
_router_id.Zero(); _router_id.Zero();
_timestamp = {}; _timestamp = {};

@ -37,13 +37,13 @@ namespace llarp::rpc
} }
bool bool
EndpointAuthRPC::AsyncAuthPending(service::ConvoTag tag) const EndpointAuthRPC::auth_async_pending(service::ConvoTag tag) const
{ {
return m_PendingAuths.count(tag) > 0; return m_PendingAuths.count(tag) > 0;
} }
void void
EndpointAuthRPC::AuthenticateAsync( EndpointAuthRPC::authenticate_async(
std::shared_ptr<llarp::service::ProtocolMessage> msg, std::shared_ptr<llarp::service::ProtocolMessage> msg,
std::function<void(std::string, bool)> hook) std::function<void(std::string, bool)> hook)
{ {
@ -99,15 +99,15 @@ namespace llarp::rpc
m_AuthMethod, m_AuthMethod,
[self = shared_from_this(), reply = std::move(reply)]( [self = shared_from_this(), reply = std::move(reply)](
bool success, std::vector<std::string> data) { bool success, std::vector<std::string> data) {
service::AuthResult result{service::AuthResultCode::eAuthFailed, "no reason given"}; service::AuthResult result{service::AuthCode::FAILED, "no reason given"};
if (success and not data.empty()) if (success and not data.empty())
{ {
if (const auto maybe = service::ParseAuthResultCode(data[0])) if (const auto maybe = service::parse_auth_code(data[0]))
{ {
result.code = *maybe; result.code = *maybe;
} }
if (result.code == service::AuthResultCode::eAuthAccepted) if (result.code == service::AuthCode::ACCEPTED)
{ {
result.reason = "OK"; result.reason = "OK";
} }

@ -33,12 +33,12 @@ namespace llarp::rpc
Start(); Start();
void void
AuthenticateAsync( authenticate_async(
std::shared_ptr<llarp::service::ProtocolMessage> msg, std::shared_ptr<llarp::service::ProtocolMessage> msg,
std::function<void(std::string, bool)> hook) override; std::function<void(std::string, bool)> hook) override;
bool bool
AsyncAuthPending(service::ConvoTag tag) const override; auth_async_pending(service::ConvoTag tag) const override;
private: private:
const std::string m_AuthURL; const std::string m_AuthURL;

@ -98,7 +98,7 @@ namespace llarp::rpc
: m_LMQ{std::move(lmq)}, m_Router(r), log_subs{*m_LMQ, llarp::logRingBuffer} : m_LMQ{std::move(lmq)}, m_Router(r), log_subs{*m_LMQ, llarp::logRingBuffer}
{ {
// copied logic loop as placeholder // copied logic loop as placeholder
for (const auto& addr : r.config()->api.m_rpcBindAddresses) for (const auto& addr : r.config()->api.rpc_bind_addrs)
{ {
m_LMQ->listen_plain(addr.zmq_address()); m_LMQ->listen_plain(addr.zmq_address());
LogInfo("Bound RPC server to ", addr.full_address()); LogInfo("Bound RPC server to ", addr.full_address());
@ -566,10 +566,10 @@ namespace llarp::rpc
auto parser = ConfigParser(); auto parser = ConfigParser();
if (parser.LoadNewFromStr(config.request.ini)) if (parser.load_new_from_str(config.request.ini))
{ {
parser.Filename(conf_d / (config.request.filename)); parser.set_filename(conf_d / (config.request.filename));
parser.SaveNew(); parser.save_new();
} }
} }
catch (std::exception& e) catch (std::exception& e)

@ -11,14 +11,14 @@
namespace llarp::service namespace llarp::service
{ {
/// maybe get auth result from string /// maybe get auth result from string
std::optional<AuthResultCode> std::optional<AuthCode>
ParseAuthResultCode(std::string data) parse_auth_code(std::string data)
{ {
std::unordered_map<std::string, AuthResultCode> values = { std::unordered_map<std::string, AuthCode> values = {
{"OKAY", AuthResultCode::eAuthAccepted}, {"OKAY", AuthCode::ACCEPTED},
{"REJECT", AuthResultCode::eAuthRejected}, {"REJECT", AuthCode::REJECTED},
{"PAYME", AuthResultCode::eAuthPaymentRequired}, {"PAYME", AuthCode::PAYMENT_REQUIRED},
{"LIMITED", AuthResultCode::eAuthRateLimit}}; {"LIMITED", AuthCode::RATE_LIMIT}};
auto itr = values.find(data); auto itr = values.find(data);
if (itr == values.end()) if (itr == values.end())
return std::nullopt; return std::nullopt;
@ -26,13 +26,13 @@ namespace llarp::service
} }
AuthType AuthType
ParseAuthType(std::string data) parse_auth_type(std::string data)
{ {
std::unordered_map<std::string, AuthType> values = { std::unordered_map<std::string, AuthType> values = {
{"file", AuthType::eAuthTypeFile}, {"file", AuthType::FILE},
{"lmq", AuthType::eAuthTypeLMQ}, {"lmq", AuthType::OMQ},
{"whitelist", AuthType::eAuthTypeWhitelist}, {"whitelist", AuthType::WHITELIST},
{"none", AuthType::eAuthTypeNone}}; {"none", AuthType::NONE}};
const auto itr = values.find(data); const auto itr = values.find(data);
if (itr == values.end()) if (itr == values.end())
throw std::invalid_argument("no such auth type: " + data); throw std::invalid_argument("no such auth type: " + data);
@ -40,19 +40,19 @@ namespace llarp::service
} }
AuthFileType AuthFileType
ParseAuthFileType(std::string data) parse_auth_file_type(std::string data)
{ {
std::unordered_map<std::string, AuthFileType> values = { std::unordered_map<std::string, AuthFileType> values = {
{"plain", AuthFileType::eAuthFilePlain}, {"plain", AuthFileType::PLAIN},
{"plaintext", AuthFileType::eAuthFilePlain}, {"plaintext", AuthFileType::PLAIN},
{"hashed", AuthFileType::eAuthFileHashes}, {"hashed", AuthFileType::HASHES},
{"hashes", AuthFileType::eAuthFileHashes}, {"hashes", AuthFileType::HASHES},
{"hash", AuthFileType::eAuthFileHashes}}; {"hash", AuthFileType::HASHES}};
const auto itr = values.find(data); const auto itr = values.find(data);
if (itr == values.end()) if (itr == values.end())
throw std::invalid_argument("no such auth file type: " + data); throw std::invalid_argument("no such auth file type: " + data);
#ifndef HAVE_CRYPT #ifndef HAVE_CRYPT
if (itr->second == AuthFileType::eAuthFileHashes) if (itr->second == AuthFileType::HASHES)
throw std::invalid_argument("unsupported auth file type: " + data); throw std::invalid_argument("unsupported auth file type: " + data);
#endif #endif
return itr->second; return itr->second;
@ -60,26 +60,26 @@ namespace llarp::service
/// turn an auth result code into an int /// turn an auth result code into an int
uint64_t uint64_t
AuthResultCodeAsInt(AuthResultCode code) auth_code_to_int(AuthCode code)
{ {
return static_cast<std::underlying_type_t<AuthResultCode>>(code); return static_cast<std::underlying_type_t<AuthCode>>(code);
} }
/// may turn an int into an auth result code /// may turn an int into an auth result code
std::optional<AuthResultCode> std::optional<AuthCode>
AuthResultCodeFromInt(uint64_t code) int_to_auth_code(uint64_t code)
{ {
switch (code) switch (code)
{ {
case 0: case 0:
return AuthResultCode::eAuthAccepted; return AuthCode::ACCEPTED;
case 1: case 1:
return AuthResultCode::eAuthRejected; return AuthCode::REJECTED;
case 2: case 2:
return AuthResultCode::eAuthFailed; return AuthCode::FAILED;
case 3: case 3:
return AuthResultCode::eAuthRateLimit; return AuthCode::RATE_LIMIT;
case 4: case 4:
return AuthResultCode::eAuthPaymentRequired; return AuthCode::PAYMENT_REQUIRED;
default: default:
return std::nullopt; return std::nullopt;
} }
@ -96,7 +96,7 @@ namespace llarp::service
/// matching it /// matching it
/// this is expected to be done in the IO thread /// this is expected to be done in the IO thread
AuthResult AuthResult
CheckFiles(const AuthInfo& info) const check_files(const AuthInfo& info) const
{ {
for (const auto& f : m_Files) for (const auto& f : m_Files)
{ {
@ -109,22 +109,22 @@ namespace llarp::service
if (auto part = parts[0]; not parts.empty() and not parts[0].empty()) if (auto part = parts[0]; not parts.empty() and not parts[0].empty())
{ {
// split off whitespaces and check password // split off whitespaces and check password
if (CheckPasswd(std::string{TrimWhitespace(part)}, info.token)) if (check_passwd(std::string{TrimWhitespace(part)}, info.token))
return AuthResult{AuthResultCode::eAuthAccepted, "accepted by whitelist"}; return AuthResult{AuthCode::ACCEPTED, "accepted by whitelist"};
} }
} }
} }
return AuthResult{AuthResultCode::eAuthRejected, "rejected by whitelist"}; return AuthResult{AuthCode::REJECTED, "rejected by whitelist"};
} }
bool bool
CheckPasswd(std::string hash, std::string challenge) const check_passwd(std::string hash, std::string challenge) const
{ {
switch (m_Type) switch (m_Type)
{ {
case AuthFileType::eAuthFilePlain: case AuthFileType::PLAIN:
return hash == challenge; return hash == challenge;
case AuthFileType::eAuthFileHashes: case AuthFileType::HASHES:
#ifdef HAVE_CRYPT #ifdef HAVE_CRYPT
return crypto::check_passwd_hash(std::move(hash), std::move(challenge)); return crypto::check_passwd_hash(std::move(hash), std::move(challenge));
#endif #endif
@ -139,7 +139,7 @@ namespace llarp::service
{} {}
void void
AuthenticateAsync( authenticate_async(
std::shared_ptr<ProtocolMessage> msg, std::function<void(std::string, bool)> hook) override std::shared_ptr<ProtocolMessage> msg, std::function<void(std::string, bool)> hook) override
{ {
auto reply = m_Router->loop()->make_caller( auto reply = m_Router->loop()->make_caller(
@ -148,7 +148,7 @@ namespace llarp::service
util::Lock _lock{self->m_Access}; util::Lock _lock{self->m_Access};
self->m_Pending.erase(tag); self->m_Pending.erase(tag);
} }
hook(result.reason, result.code == AuthResultCode::eAuthAccepted); hook(result.reason, result.code == AuthCode::ACCEPTED);
}); });
{ {
util::Lock _lock{m_Access}; util::Lock _lock{m_Access};
@ -163,19 +163,19 @@ namespace llarp::service
reply]() { reply]() {
try try
{ {
reply(self->CheckFiles(auth)); reply(self->check_files(auth));
} }
catch (std::exception& ex) catch (std::exception& ex)
{ {
reply(AuthResult{AuthResultCode::eAuthFailed, ex.what()}); reply(AuthResult{AuthCode::FAILED, ex.what()});
} }
}); });
} }
else else
reply(AuthResult{AuthResultCode::eAuthRejected, "protocol error"}); reply(AuthResult{AuthCode::REJECTED, "protocol error"});
} }
bool bool
AsyncAuthPending(ConvoTag tag) const override auth_async_pending(ConvoTag tag) const override
{ {
util::Lock _lock{m_Access}; util::Lock _lock{m_Access};
return m_Pending.count(tag); return m_Pending.count(tag);
@ -183,7 +183,7 @@ namespace llarp::service
}; };
std::shared_ptr<IAuthPolicy> std::shared_ptr<IAuthPolicy>
MakeFileAuthPolicy(Router* r, std::set<fs::path> files, AuthFileType filetype) make_file_auth_policy(Router* r, std::set<fs::path> files, AuthFileType filetype)
{ {
return std::make_shared<FileAuthPolicy>(r, std::move(files), filetype); return std::make_shared<FileAuthPolicy>(r, std::move(files), filetype);
} }

@ -15,32 +15,32 @@ namespace llarp
namespace llarp::service namespace llarp::service
{ {
/// authentication status code /// authentication status code
enum class AuthResultCode : uint64_t enum class AuthCode : uint64_t
{ {
/// explicitly accepted /// explicitly accepted
eAuthAccepted = 0, ACCEPTED = 0,
/// explicitly rejected /// explicitly rejected
eAuthRejected = 1, REJECTED = 1,
/// attempt failed /// attempt failed
eAuthFailed = 2, FAILED = 2,
/// attempt rate limited /// attempt rate limited
eAuthRateLimit = 3, RATE_LIMIT = 3,
/// need mo munny /// need mo munny
eAuthPaymentRequired = 4 PAYMENT_REQUIRED = 4
}; };
/// turn an auth result code into an int /// turn an auth result code into an int
uint64_t uint64_t
AuthResultCodeAsInt(AuthResultCode code); auth_code_to_int(AuthCode code);
/// may turn an int into an auth result code /// may turn an int into an auth result code
std::optional<AuthResultCode> std::optional<AuthCode>
AuthResultCodeFromInt(uint64_t code); int_to_auth_code(uint64_t code);
/// auth result object with code and reason /// auth result object with code and reason
struct AuthResult struct AuthResult
{ {
AuthResultCode code; AuthCode code;
std::string reason; std::string reason;
}; };
@ -48,8 +48,8 @@ namespace llarp::service
struct ConvoTag; struct ConvoTag;
/// maybe get auth result from string /// maybe get auth result from string
std::optional<AuthResultCode> std::optional<AuthCode>
ParseAuthResultCode(std::string data); parse_auth_code(std::string data);
struct IAuthPolicy struct IAuthPolicy
{ {
@ -58,12 +58,12 @@ namespace llarp::service
/// asynchronously determine if we accept new convotag from remote service, call hook with /// asynchronously determine if we accept new convotag from remote service, call hook with
/// result later /// result later
virtual void virtual void
AuthenticateAsync( authenticate_async(
std::shared_ptr<ProtocolMessage> msg, std::function<void(std::string, bool)> hook) = 0; std::shared_ptr<ProtocolMessage> msg, std::function<void(std::string, bool)> hook) = 0;
/// return true if we are asynchronously processing authentication on this convotag /// return true if we are asynchronously processing authentication on this convotag
virtual bool virtual bool
AsyncAuthPending(ConvoTag tag) const = 0; auth_async_pending(ConvoTag tag) const = 0;
}; };
/// info needed by clients in order to authenticate to a remote endpoint /// info needed by clients in order to authenticate to a remote endpoint
@ -76,34 +76,34 @@ namespace llarp::service
enum class AuthType enum class AuthType
{ {
/// no authentication /// no authentication
eAuthTypeNone, NONE,
/// manual whitelist /// manual whitelist
eAuthTypeWhitelist, WHITELIST,
/// LMQ server /// LMQ server
eAuthTypeLMQ, OMQ,
/// static file /// static file
eAuthTypeFile, FILE,
}; };
/// how to interpret an file for auth /// how to interpret an file for auth
enum class AuthFileType enum class AuthFileType
{ {
eAuthFilePlain, PLAIN,
eAuthFileHashes, HASHES,
}; };
/// get an auth type from a string /// get an auth type from a string
/// throws std::invalid_argument if arg is invalid /// throws std::invalid_argument if arg is invalid
AuthType AuthType
ParseAuthType(std::string arg); parse_auth_type(std::string arg);
/// get an auth file type from a string /// get an auth file type from a string
/// throws std::invalid_argument if arg is invalid /// throws std::invalid_argument if arg is invalid
AuthFileType AuthFileType
ParseAuthFileType(std::string arg); parse_auth_file_type(std::string arg);
/// make an IAuthPolicy that reads out of a static file /// make an IAuthPolicy that reads out of a static file
std::shared_ptr<IAuthPolicy> std::shared_ptr<IAuthPolicy>
MakeFileAuthPolicy(Router*, std::set<fs::path> files, AuthFileType fileType); make_file_auth_policy(Router*, std::set<fs::path> files, AuthFileType fileType);
} // namespace llarp::service } // namespace llarp::service

@ -186,7 +186,7 @@ namespace llarp::service
if (m_Endpoints.find(endpointName) != m_Endpoints.end()) if (m_Endpoints.find(endpointName) != m_Endpoints.end())
throw std::invalid_argument("service::Context only supports one endpoint now"); throw std::invalid_argument("service::Context only supports one endpoint now");
const auto& endpointType = conf.network.m_endpointType; const auto& endpointType = conf.network.endpoint_type;
// use factory to create endpoint // use factory to create endpoint
const auto itr = endpointConstructors.find(endpointType); const auto itr = endpointConstructors.find(endpointType);
if (itr == endpointConstructors.end()) if (itr == endpointConstructors.end())

@ -50,24 +50,24 @@ namespace llarp::service
bool bool
Endpoint::Configure(const NetworkConfig& conf, [[maybe_unused]] const DnsConfig& dnsConf) Endpoint::Configure(const NetworkConfig& conf, [[maybe_unused]] const DnsConfig& dnsConf)
{ {
if (conf.m_Paths.has_value()) if (conf.paths.has_value())
numDesiredPaths = *conf.m_Paths; numDesiredPaths = *conf.paths;
if (conf.m_Hops.has_value()) if (conf.hops.has_value())
numHops = *conf.m_Hops; numHops = *conf.hops;
conf.m_ExitMap.ForEachEntry( conf.exit_map.ForEachEntry(
[&](const IPRange& range, const service::Address& addr) { MapExitRange(range, addr); }); [&](const IPRange& range, const service::Address& addr) { MapExitRange(range, addr); });
for (auto [exit, auth] : conf.m_ExitAuths) for (auto [exit, auth] : conf.exit_auths)
{ {
SetAuthInfoForEndpoint(exit, auth); SetAuthInfoForEndpoint(exit, auth);
} }
conf.m_LNSExitMap.ForEachEntry([&](const IPRange& range, const std::string& name) { conf.ons_exit_map.ForEachEntry([&](const IPRange& range, const std::string& name) {
std::optional<AuthInfo> auth; std::optional<AuthInfo> auth;
const auto itr = conf.m_LNSExitAuths.find(name); const auto itr = conf.ons_exit_auths.find(name);
if (itr != conf.m_LNSExitAuths.end()) if (itr != conf.ons_exit_auths.end())
auth = itr->second; auth = itr->second;
_startup_ons_mappings[name] = std::make_pair(range, auth); _startup_ons_mappings[name] = std::make_pair(range, auth);
}); });
@ -999,10 +999,10 @@ namespace llarp::service
{ {
if (_auth_policy) if (_auth_policy)
{ {
if (not _auth_policy->AsyncAuthPending(msg->tag)) if (not _auth_policy->auth_async_pending(msg->tag))
{ {
// do 1 authentication attempt and drop everything else // do 1 authentication attempt and drop everything else
_auth_policy->AuthenticateAsync(std::move(msg), std::move(hook)); _auth_policy->authenticate_async(std::move(msg), std::move(hook));
} }
} }
else else

@ -5,12 +5,12 @@ namespace llarp::service
bool bool
EndpointState::Configure(const NetworkConfig& conf) EndpointState::Configure(const NetworkConfig& conf)
{ {
if (conf.m_keyfile.has_value()) if (conf.keyfile.has_value())
key_file = conf.m_keyfile->string(); key_file = conf.keyfile->string();
snode_blacklist = conf.m_snodeBlacklist; snode_blacklist = conf.snode_blacklist;
is_exit_enabled = conf.m_AllowExit; is_exit_enabled = conf.allow_exit;
for (const auto& record : conf.m_SRVRecords) for (const auto& record : conf.srv_records)
{ {
local_introset.SRVs.push_back(record.toTuple()); local_introset.SRVs.push_back(record.toTuple());
} }

Loading…
Cancel
Save