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
6 months ago
dr7ana 5a628007e1 A soothing re-nomenclatura 6 months ago

@ -14,28 +14,42 @@ option(WITH_WINDOWS_32 "build 32 bit windows" OFF)
# to .r[o]data section one after the other!
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)
link_libatomic()
endif()
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)")
set(WINTUN_SOURCE wintun-${WINTUN_VERSION}.zip)
set(WINTUN_HASH SHA256=07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51
CACHE STRING "wintun source hash")
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)")
set(WINDIVERT_SOURCE WinDivert-${WINDIVERT_VERSION}.zip)
set(WINDIVERT_HASH SHA512=92eb2ef98ced175d44de1cdb7c52f2ebc534b6a997926baeb83bfe94cba9287b438f796aff11f6163918bcdbc25bcd4e3383715f139f690d207ce219f846a345
CACHE STRING "windivert source hash")
set(WINTUN_URL ${WINTUN_MIRROR}/${WINTUN_SOURCE}
CACHE STRING "wintun download url")
set(WINDIVERT_URL ${WINDIVERT_MIRROR}/${WINDIVERT_SOURCE}
CACHE STRING "windivert download url")
expand_urls(WINTUN_URL ${WINTUN_SOURCE} ${WINTUN_MIRROR})
expand_urls(WINDIVERT_URL ${WINDIVERT_SOURCE} ${WINDIVERT_MIRROR})
message(STATUS "Downloading wintun from ${WINTUN_URL}")
file(DOWNLOAD ${WINTUN_URL} ${CMAKE_BINARY_DIR}/wintun.zip EXPECTED_HASH ${WINTUN_HASH})

@ -450,7 +450,7 @@ namespace
{
try
{
llarp::ensureConfig(basedir, *configFile, options.overwrite, opts.isSNode);
llarp::ensure_config(basedir, *configFile, options.overwrite, opts.isSNode);
}
catch (std::exception& ex)
{
@ -479,7 +479,7 @@ namespace
{
try
{
llarp::ensureConfig(
llarp::ensure_config(
llarp::GetDefaultDataDir(),
llarp::GetDefaultConfigPath(),
options.overwrite,
@ -562,7 +562,7 @@ namespace
{
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");
exit_code.set_value(1);
@ -570,7 +570,7 @@ namespace
}
// 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->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);
fs::path config_path = config_dir / "lokinet.ini";
if (!fs::exists(config_path))
llarp::ensureConfig(config_dir, config_path, /*overwrite=*/false, /*asRouter=*/false);
config->Load(config_path);
llarp::ensure_config(config_dir, config_path, /*overwrite=*/false, /*asRouter=*/false);
config->load(config_path);
// 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.
auto& range = config->network.m_ifaddr;
auto& range = config->network.if_addr;
if (!range.addr.h)
{
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->upstream_dns[0] = '\0';
for (auto& upstream : config->dns.m_upstreamDNS)
for (auto& upstream : config->dns.upstream_dns)
{
if (upstream.isIPv4())
{

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

File diff suppressed because it is too large Load Diff

@ -31,8 +31,10 @@
namespace llarp
{
using SectionValues_t = llarp::ConfigParser::SectionValues_t;
using Config_impl_t = llarp::ConfigParser::Config_impl_t;
using SectionValues = llarp::ConfigParser::SectionValues;
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
/// 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(ConfigGenParameters&&) = delete;
bool isRelay = false;
fs::path defaultDataDir;
bool is_relay = false;
fs::path default_data_dir;
/// get network platform (virtual for unit test mocks)
virtual const llarp::net::Platform*
@ -55,33 +57,33 @@ namespace llarp
struct RouterConfig
{
size_t m_minConnectedRouters = 0;
size_t m_maxConnectedRouters = 0;
size_t min_connected_routers = 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 m_numNetThreads = -1;
int worker_threads = -1;
int net_threads = -1;
size_t m_JobQueueSize = 0;
size_t job_que_size = 0;
std::string m_routerContactFile;
std::string m_encryptionKeyFile;
std::string m_identityKeyFile;
std::string m_transportKeyFile;
std::string rc_file;
std::string enckey_file;
std::string idkey_file;
std::string transkey_file;
bool m_isRelay = false;
bool is_relay = false;
/// deprecated
std::optional<net::ipaddr_t> PublicIP;
std::optional<net::ipaddr_t> public_ip;
/// deprecated
std::optional<net::port_t> PublicPort;
std::optional<net::port_t> public_port;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
/// config for path hop selection
@ -90,91 +92,92 @@ namespace llarp
/// 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
///
int m_UniqueHopsNetmaskSize;
int unique_hop_netmask;
/// 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
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
bool
Acceptable(const std::set<RemoteRC>& hops) const;
check_rcs(const std::set<RemoteRC>& hops) const;
};
struct NetworkConfig
{
std::optional<bool> m_enableProfiling;
bool m_saveProfiles;
std::set<RouterID> m_strictConnect;
std::string m_ifname;
IPRange m_ifaddr;
std::optional<bool> enable_profiling;
bool save_profiles;
std::set<RouterID> strict_connect;
std::string if_name;
IPRange if_addr;
std::optional<fs::path> m_keyfile;
std::string m_endpointType;
bool m_reachable = false;
std::optional<int> m_Hops;
std::optional<int> m_Paths;
bool m_AllowExit = false;
std::set<RouterID> m_snodeBlacklist;
net::IPRangeMap<service::Address> m_ExitMap;
net::IPRangeMap<std::string> m_LNSExitMap;
std::optional<fs::path> keyfile;
std::string endpoint_type;
bool is_reachable = false;
std::optional<int> hops;
std::optional<int> paths;
bool allow_exit = false;
std::set<RouterID> snode_blacklist;
net::IPRangeMap<service::Address> exit_map;
net::IPRangeMap<std::string> ons_exit_map;
std::unordered_map<service::Address, service::AuthInfo> m_ExitAuths;
std::unordered_map<std::string, service::AuthInfo> m_LNSExitAuths;
std::unordered_map<service::Address, service::AuthInfo> exit_auths;
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::AuthFileType m_AuthFileType = service::AuthFileType::eAuthFileHashes;
std::optional<std::string> m_AuthUrl;
std::optional<std::string> m_AuthMethod;
std::unordered_set<service::Address> m_AuthWhitelist;
std::unordered_set<std::string> m_AuthStaticTokens;
std::set<fs::path> m_AuthFiles;
service::AuthType auth_type = service::AuthType::NONE;
service::AuthFileType auth_file_type = service::AuthFileType::HASHES;
std::optional<std::string> auth_url;
std::optional<std::string> auth_method;
std::unordered_set<service::Address> auth_whitelist;
std::unordered_set<std::string> auth_static_tokens;
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::optional<net::TrafficPolicy> m_TrafficPolicy;
std::set<IPRange> owned_ranges;
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 m_BlackholeRoutes;
bool enable_route_poker;
bool blackhole_routes;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
struct DnsConfig
{
bool m_raw_dns;
std::vector<SockAddr> m_bind;
std::vector<SockAddr> m_upstreamDNS;
std::vector<fs::path> m_hostfiles;
std::optional<SockAddr> m_QueryBind;
bool raw;
std::vector<SockAddr> bind_addr;
std::vector<SockAddr> upstream_dns;
std::vector<fs::path> hostfiles;
std::optional<SockAddr> query_bind;
std::unordered_multimap<std::string, std::string> m_ExtraOpts;
std::unordered_multimap<std::string, std::string> extra_opts;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
struct LinksConfig
{
std::optional<net::ipaddr_t> PublicAddress;
std::optional<net::port_t> PublicPort;
std::vector<SockAddr> OutboundLinks;
std::vector<SockAddr> InboundListenAddrs;
std::optional<net::ipaddr_t> public_addr;
std::optional<net::port_t> public_port;
std::optional<oxen::quic::Address> addr;
bool using_new_api = false;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
struct ConnectConfig
@ -182,26 +185,26 @@ namespace llarp
std::vector<fs::path> routers;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
// TODO: remove oxenmq from this header
struct ApiConfig
{
bool m_enableRPCServer = false;
std::vector<oxenmq::address> m_rpcBindAddresses;
bool enable_rpc_server = false;
std::vector<oxenmq::address> rpc_bind_addrs;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
struct LokidConfig
{
fs::path ident_keyfile;
oxenmq::address lokidRPCAddr;
fs::path id_keyfile;
oxenmq::address rpc_addr;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
struct BootstrapConfig
@ -209,18 +212,19 @@ namespace llarp
std::vector<fs::path> files;
BootstrapList routers;
bool seednode;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
struct LoggingConfig
{
log::Type m_logType = log::Type::Print;
log::Level m_logLevel = log::Level::off;
std::string m_logFile;
log::Type type = log::Type::Print;
log::Level level = log::Level::off;
std::string file;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params);
};
struct Config
@ -231,7 +235,7 @@ namespace llarp
/// create generation params (virtual for unit test mock)
virtual std::unique_ptr<ConfigGenParameters>
MakeGenParams() const;
make_gen_params() const;
RouterConfig router;
NetworkConfig network;
@ -246,41 +250,41 @@ namespace llarp
// Initialize config definition
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
/// tolerate old values that are no longer accepted)
///
/// @param conf is the config to modify
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
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
bool
LoadString(std::string_view ini, bool isRelay = false);
load_string(std::string_view ini, bool isRelay = false);
std::string
generateBaseClientConfig();
generate_client_config_base();
std::string
generateBaseRouterConfig();
generate_router_config_base();
void
Save();
save();
void
Override(std::string section, std::string key, std::string value);
override(std::string section, std::string key, std::string value);
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
static std::shared_ptr<Config>
EmbeddedConfig();
make_embedded_config();
private:
/// 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
/// @return true on success, false otherwise
bool
LoadDefault(bool isRelay);
load_default_config(bool isRelay);
bool
LoadConfigData(
load_config_data(
std::string_view ini, std::optional<fs::path> fname = std::nullopt, bool isRelay = false);
void
LoadOverrides(ConfigDefinition& conf) const;
load_overrides(ConfigDefinition& conf) const;
std::vector<std::array<std::string, 3>> m_Additional;
ConfigParser m_Parser;
const fs::path m_DataDir;
std::vector<std::array<std::string, 3>> additional;
ConfigParser parser;
const fs::path data_dir;
};
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

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

@ -22,42 +22,45 @@ namespace llarp
{
namespace config
{
// Base class for the following option flag types
struct option_flag
{};
struct Required_t : option_flag
{};
struct Hidden_t : option_flag
{};
struct MultiValue_t : option_flag
{};
struct RelayOnly_t : option_flag
{};
struct ClientOnly_t : option_flag
{};
struct Deprecated_t : option_flag
{};
namespace flag
{
// Base class for the following option flag types
struct opt
{};
struct REQUIRED : opt
{};
struct HIDDEN : opt
{};
struct MULTIVALUE : opt
{};
struct RELAYONLY : opt
{};
struct CLIENTONLY : opt
{};
struct DEPRECATED : opt
{};
} // namespace flag
/// 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
/// 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.
/// (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
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
/// 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
/// 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
/// 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.
inline constexpr Deprecated_t Deprecated{};
inline constexpr flag::DEPRECATED Deprecated{};
/// Wrapper to specify a default value to an OptionDefinition
template <typename T>
@ -82,7 +85,7 @@ namespace llarp
/// particular, a reference to a local variable may be problematic.
template <typename T>
auto
AssignmentAcceptor(T& ref)
assignment_acceptor(T& ref)
{
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>>;
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_invocable_v<remove_cvref_t<Option>, T>;
} // namespace config
@ -121,12 +124,12 @@ namespace llarp
OptionDefinitionBase(std::string section_, std::string name_, const T&...)
: section(std::move(section_))
, name(std::move(name_))
, required{(std::is_same_v<T, config::Required_t> || ...)}
, multiValued{(std::is_same_v<T, config::MultiValue_t> || ...)}
, deprecated{(std::is_same_v<T, config::Deprecated_t> || ...)}
, hidden{deprecated || (std::is_same_v<T, config::Hidden_t> || ...)}
, relayOnly{(std::is_same_v<T, config::RelayOnly_t> || ...)}
, clientOnly{(std::is_same_v<T, config::ClientOnly_t> || ...)}
, required{(std::is_same_v<T, config::flag::REQUIRED> || ...)}
, multi_valued{(std::is_same_v<T, config::flag::MULTIVALUE> || ...)}
, deprecated{(std::is_same_v<T, config::flag::DEPRECATED> || ...)}
, hidden{deprecated || (std::is_same_v<T, config::flag::HIDDEN> || ...)}
, relay_only{(std::is_same_v<T, config::flag::RELAYONLY> || ...)}
, clientOnly{(std::is_same_v<T, config::flag::CLIENTONLY> || ...)}
{}
virtual ~OptionDefinitionBase() = default;
@ -135,39 +138,39 @@ namespace llarp
///
/// @return the option's default value represented as a string
virtual std::vector<std::string>
defaultValuesAsString() = 0;
default_values_as_string() = 0;
/// Subclasses should parse and store the provided input
///
/// @param input is the string input to interpret
virtual void
parseValue(const std::string& input) = 0;
parse_value(const std::string& input) = 0;
/// Subclasses should provide the number of values found.
///
/// @return number of values found
virtual size_t
getNumberFound() const = 0;
get_number_found() const = 0;
/// Subclasess should write their parsed values as strings.
///
/// @return the option's value(s) as strings
virtual std::vector<std::string>
valuesAsString() = 0;
values_as_string() = 0;
/// Subclassess should call their acceptor, if present. See OptionDefinition for more details.
///
/// @throws if the acceptor throws or the option is required but missing
virtual void
tryAccept() const = 0;
try_accept() const = 0;
std::string section;
std::string name;
bool required = false;
bool multiValued = false;
bool multi_valued = false;
bool deprecated = false;
bool hidden = false;
bool relayOnly = false;
bool relay_only = false;
bool clientOnly = false;
// Temporarily holds comments given during construction until the option is actually added to
// the owning ConfigDefinition.
@ -188,7 +191,7 @@ namespace llarp
///
/// @param defaultValue_ is used in the following situations:
/// 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
///
/// @param opts - 0 or more of config::Required, config::Hidden, config::Default{...}, etc.
@ -204,40 +207,40 @@ namespace llarp
constexpr bool has_default =
((config::is_default_array<Options> || config::is_default<Options>) || ...);
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 =
(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(
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");
(extractDefault(std::forward<Options>(opts)), ...);
(extractAcceptor(std::forward<Options>(opts)), ...);
(extractComments(std::forward<Options>(opts)), ...);
(extract_default(std::forward<Options>(opts)), ...);
(extract_acceptor(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
/// multi-valued options with multi-value default); ignores anything else.
template <typename U>
void
extractDefault(U&& defaultValue_)
extract_default(U&& defaultValue_)
{
if constexpr (config::is_default_array<U>)
{
if (!multiValued)
if (!multi_valued)
throw std::logic_error{"Array config defaults require multiValue mode"};
defaultValues.clear();
defaultValues.reserve(defaultValue_.size());
default_values.clear();
default_values.reserve(defaultValue_.size());
for (const auto& def : defaultValue_)
defaultValues.push_back(def.val);
default_values.push_back(def.val);
}
else if constexpr (config::is_default<U>)
{
static_assert(
std::is_convertible_v<decltype(std::forward<U>(defaultValue_).val), T>,
"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.
template <typename U>
void
extractAcceptor(U&& acceptor_)
extract_acceptor(U&& acceptor_)
{
if constexpr (std::is_invocable_v<U, T>)
acceptor = std::forward<U>(acceptor_);
@ -254,7 +257,7 @@ namespace llarp
/// Extracts option Comments and forwards them addOptionComments.
template <typename U>
void
extractComments(U&& comment)
extract_comments(U&& comment)
{
if constexpr (std::is_same_v<config::remove_cvref_t<U>, config::Comment>)
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.
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 defaultValues.front();
return default_values.front();
}
return parsedValues.front();
return parsed_values.front();
}
/// Returns the number of values found.
///
/// @return number of values found
size_t
getNumberFound() const override
get_number_found() const override
{
return parsedValues.size();
return parsed_values.size();
}
std::vector<std::string>
defaultValuesAsString() override
default_values_as_string() override
{
if (defaultValues.empty())
if (default_values.empty())
return {};
if constexpr (std::is_same_v<fs::path, T>)
return {{defaultValues.front().u8string()}};
return {{default_values.front().u8string()}};
else
{
std::vector<std::string> def_strs;
def_strs.reserve(defaultValues.size());
for (const auto& v : defaultValues)
def_strs.reserve(default_values.size());
for (const auto& v : default_values)
{
if constexpr (std::is_same_v<bool, T>)
def_strs.push_back(fmt::format("{}", (bool)v));
@ -308,18 +311,18 @@ namespace llarp
}
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)};
}
parsedValues.emplace_back(fromString(input));
parsed_values.emplace_back(from_string(input));
}
T
fromString(const std::string& input)
from_string(const std::string& input)
{
if constexpr (std::is_same_v<T, std::string>)
{
@ -337,13 +340,13 @@ namespace llarp
}
std::vector<std::string>
valuesAsString() override
values_as_string() override
{
if (parsedValues.empty())
if (parsed_values.empty())
return {};
std::vector<std::string> result;
result.reserve(parsedValues.size());
for (const auto& v : parsedValues)
result.reserve(parsed_values.size());
for (const auto& v : parsed_values)
{
if constexpr (std::is_same_v<bool, T>)
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
/// 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.
///
/// @throws if required and no value present or if the acceptor throws
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(
"cannot call tryAccept() on [{}]:{} when required but no value available",
"cannot call try_accept() on [{}]:{} when required but no value available",
section,
name)};
}
if (acceptor)
{
if (multiValued)
if (multi_valued)
{
// add default value in multi value mode
if (parsedValues.empty() and not defaultValues.empty())
for (const auto& v : defaultValues)
if (parsed_values.empty() and not default_values.empty())
for (const auto& v : default_values)
acceptor(v);
for (auto value : parsedValues)
for (auto value : parsed_values)
{
acceptor(value);
}
}
else
{
auto maybe = getValue();
auto maybe = get_value();
if (maybe)
acceptor(*maybe);
}
}
}
std::vector<T> defaultValues;
std::vector<T> parsedValues;
std::vector<T> default_values;
std::vector<T> parsed_values;
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)
template <>
bool
OptionDefinition<bool>::fromString(const std::string& input);
OptionDefinition<bool>::from_string(const std::string& input);
using UndeclaredValueHandler =
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
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
using SectionMap = std::unordered_map<std::string, DefinitionMap>;
@ -443,15 +444,15 @@ namespace llarp
/// @return `*this` for chaining calls
/// @throws std::invalid_argument if the option already exists
ConfigDefinition&
defineOption(OptionDefinition_ptr def);
define_option(std::unique_ptr<OptionDefinitionBase> def);
/// Convenience function which calls defineOption with a OptionDefinition of the specified
/// type and with parameters passed through to OptionDefinition's constructor.
template <typename T, typename... Params>
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
@ -459,7 +460,7 @@ namespace llarp
/// called).
///
/// 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.
///
/// @param section is the section this value resides in
@ -467,7 +468,7 @@ namespace llarp
/// @return `*this` for chaining calls
/// @throws if the option doesn't exist or the provided string isn't parseable
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
/// be returned. If no value and no default is provided, an empty optional will be returned.
@ -482,9 +483,9 @@ namespace llarp
// provided
template <typename 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());
if (not derived)
@ -505,19 +506,19 @@ namespace llarp
/// @param handler
/// @throws if there is already a handler for this section
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.
///
/// @param section is the section which we want to remove the handler for
void
removeUndeclaredHandler(const std::string& section);
remove_undeclared_handler(const std::string& section);
/// Validate that all required fields are present.
///
/// @throws std::invalid_argument if configuration constraints are not met
void
validateRequiredFields();
validate_required_fields();
/// 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,
@ -525,14 +526,14 @@ namespace llarp
///
/// @throws if any option's acceptor throws
void
acceptAllOptions();
accept_all_options();
/// validates and accept all parsed options
inline void
process()
{
validateRequiredFields();
acceptAllOptions();
validate_required_fields();
accept_all_options();
}
/// Add comments for a given section. Comments are replayed in-order during config file
@ -542,7 +543,7 @@ namespace llarp
/// @param section
/// @param comment
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
/// [section]:name pair.
@ -551,7 +552,7 @@ namespace llarp
/// @param name
/// @param comment
void
addOptionComments(
add_option_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
@ -566,38 +567,39 @@ namespace llarp
/// addConfigValue()) or only definitions
/// @return a string containing the config in INI format
std::string
generateINIConfig(bool useValues = false);
generate_ini_config(bool useValues = false);
private:
// If true skip client-only options; if false skip relay-only options.
bool relay;
OptionDefinition_ptr&
lookupDefinitionOrThrow(std::string_view section, std::string_view name);
const OptionDefinition_ptr&
lookupDefinitionOrThrow(std::string_view section, std::string_view name) const;
std::unique_ptr<OptionDefinitionBase>&
lookup_definition_or_throw(std::string_view section, std::string_view name);
const std::unique_ptr<OptionDefinitionBase>&
lookup_definition_or_throw(std::string_view section, std::string_view name) const;
using SectionVisitor = std::function<void(const std::string&, const DefinitionMap&)>;
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
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.
std::vector<std::string> m_sectionOrdering;
std::unordered_map<std::string, std::vector<std::string>> m_definitionOrdering;
std::vector<std::string> section_ordering;
std::unordered_map<std::string, std::vector<std::string>> definition_ordering;
// comments for config file generation
using CommentList = std::vector<std::string>;
using CommentsMap = std::unordered_map<std::string, CommentList>;
CommentsMap m_sectionComments;
std::unordered_map<std::string, CommentsMap> m_definitionComments;
CommentsMap section_comments;
std::unordered_map<std::string, CommentsMap> definition_comments;
};
} // namespace llarp

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

@ -13,68 +13,68 @@ namespace llarp
{
struct ConfigParser
{
using SectionValues_t = std::unordered_multimap<std::string, std::string>;
using Config_impl_t = std::unordered_map<std::string, SectionValues_t>;
using SectionValues = std::unordered_multimap<std::string, std::string>;
using ConfigMap = std::unordered_map<std::string, SectionValues>;
/// clear parser
void
Clear();
clear();
/// load config file for bootserv
/// return true on success
/// return false on error
bool
LoadFile(const fs::path& fname);
load_file(const fs::path& fname);
/// load new .ini file from string (calls ParseAll() rather than Parse())
/// return true on success
/// return false on error
bool
LoadNewFromStr(std::string_view str);
load_new_from_str(std::string_view str);
/// load from string
/// return true on success
/// return false on error
bool
LoadFromStr(std::string_view str);
load_from_str(std::string_view str);
/// iterate all sections and thier values
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
/// return false if no section or value propagated from visitor
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
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
void
Save();
save();
/// save new .ini config file to path
void
SaveNew() const;
save_new() const;
inline void
Filename(fs::path f)
void
set_filename(const fs::path& f)
{
m_FileName = f;
};
_filename = f;
}
private:
bool
ParseAll();
parse_all();
bool
Parse();
parse();
std::string m_Data;
Config_impl_t m_Config;
std::unordered_map<fs::path, Config_impl_t, util::FileHash> m_Overrides;
fs::path m_FileName;
std::string _data;
ConfigMap _config;
std::unordered_map<fs::path, ConfigMap, util::FileHash> _overrides;
fs::path _filename;
};
} // namespace llarp

@ -27,7 +27,7 @@ namespace llarp
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
// falling back to root / defaultName if not
@ -46,10 +46,10 @@ namespace llarp
}
};
m_rcPath = deriveFile(our_rc_filename, config.router.m_routerContactFile);
m_idKeyPath = deriveFile(our_identity_filename, config.router.m_identityKeyFile);
m_encKeyPath = deriveFile(our_enc_key_filename, config.router.m_encryptionKeyFile);
m_transportKeyPath = deriveFile(our_transport_key_filename, config.router.m_transportKeyFile);
m_rcPath = deriveFile(our_rc_filename, config.router.rc_file);
m_idKeyPath = deriveFile(our_identity_filename, config.router.idkey_file);
m_encKeyPath = deriveFile(our_enc_key_filename, config.router.enckey_file);
m_transportKeyPath = deriveFile(our_transport_key_filename, config.router.transkey_file);
RemoteRC rc;
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
auto identityKeygen = [](llarp::SecretKey& key) {

@ -62,7 +62,7 @@ namespace llarp
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);
}

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

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

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

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

@ -99,7 +99,7 @@ namespace llarp::handlers
{
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);
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());
}
else
@ -389,7 +389,7 @@ namespace llarp::handlers
// 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
// 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())
{
itr->second->send_packet_to_remote(buf.to_string());
@ -594,7 +594,7 @@ namespace llarp::handlers
std::unordered_set<AddressVariant_t> remote;
for (const auto& [path, pubkey] : paths)
{
remote.insert(RouterID{pubkey});
remote.insert(RouterID{pubkey.data()});
}
return remote;
}
@ -691,12 +691,12 @@ namespace llarp::handlers
dns_conf = dnsConfig;
if (networkConfig.m_endpointType == "null")
if (networkConfig.endpoint_type == "null")
{
should_init_tun = false;
}
ip_range = networkConfig.m_ifaddr;
ip_range = networkConfig.if_addr;
if (!ip_range.addr.h)
{
const auto maybe = router->net().FindFreeRange();
@ -711,7 +711,7 @@ namespace llarp::handlers
highest_addr = ip_range.HighestAddr();
use_ipv6 = not ip_range.IsV4();
if_name = networkConfig.m_ifname;
if_name = networkConfig.if_name;
if (if_name.empty())
{
const auto maybe = router->net().FindFreeTun();

@ -92,7 +92,7 @@ namespace llarp::handlers
// tunnel.
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;
// omit traffic to and from our dns socket
@ -116,7 +116,7 @@ namespace llarp::handlers
explicit TunDNS(TunEndpoint* ep, const llarp::DnsConfig& conf)
: dns::Server{ep->router()->loop(), conf, 0}
, m_Endpoint{ep}
, m_QueryBind{conf.m_QueryBind}
, m_QueryBind{conf.query_bind}
, m_OurIP{ToNet(ep->GetIfAddr())}
{}
@ -144,7 +144,7 @@ namespace llarp::handlers
TunEndpoint::SetupDNS()
{
const auto& info = GetVPNInterface()->Info();
if (m_DnsConfig.m_raw_dns)
if (m_DnsConfig.raw)
{
auto dns = std::make_shared<TunDNS>(this, m_DnsConfig);
m_DNS = dns;
@ -166,7 +166,7 @@ namespace llarp::handlers
m_DNS->AddResolver(weak_from_this());
m_DNS->Start();
if (m_DnsConfig.m_raw_dns)
if (m_DnsConfig.raw)
{
if (auto vpn = router()->vpn_platform())
{
@ -209,17 +209,17 @@ namespace llarp::handlers
obj["ifname"] = m_IfName;
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());
obj["ustreamResolvers"] = upstreamRes;
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());
obj["localResolvers"] = localRes;
// for backwards compat
if (not m_DnsConfig.m_bind.empty())
if (not m_DnsConfig.bind_addr.empty())
obj["localResolver"] = localRes[0];
util::StatusObject ips{};
@ -266,7 +266,7 @@ namespace llarp::handlers
bool
TunEndpoint::Configure(const NetworkConfig& conf, const DnsConfig& dnsConf)
{
if (conf.m_reachable)
if (conf.is_reachable)
{
_publish_introset = true;
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");
}
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;
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;
method = *conf.m_AuthMethod;
url = *conf.auth_url;
method = *conf.auth_method;
}
auto auth = std::make_shared<rpc::EndpointAuthRPC>(
url,
method,
conf.m_AuthWhitelist,
conf.m_AuthStaticTokens,
conf.auth_whitelist,
conf.auth_static_tokens,
router()->lmq(),
shared_from_this());
auth->Start();
@ -301,25 +301,25 @@ namespace llarp::handlers
}
m_DnsConfig = dnsConf;
m_TrafficPolicy = conf.m_TrafficPolicy;
m_OwnedRanges = conf.m_OwnedRanges;
m_TrafficPolicy = conf.traffic_policy;
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
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))
return false;
}
m_IfName = conf.m_ifname;
m_IfName = conf.if_name;
if (m_IfName.empty())
{
const auto maybe = router()->net().FindFreeTun();
@ -328,7 +328,7 @@ namespace llarp::handlers
m_IfName = *maybe;
}
m_OurRange = conf.m_ifaddr;
m_OurRange = conf.if_addr;
if (!m_OurRange.addr.h)
{
const auto maybe = router()->net().FindFreeRange();
@ -342,7 +342,7 @@ namespace llarp::handlers
m_OurIP = m_OurRange.addr;
m_UseV6 = false;
m_PersistAddrMapFile = conf.m_AddrMapPersistFile;
m_PersistAddrMapFile = conf.addr_map_persist_file;
if (m_PersistAddrMapFile)
{
const auto& file = *m_PersistAddrMapFile;

@ -314,7 +314,9 @@ namespace llarp
// TODO: confirm remote end is using the expected pubkey (RouterID).
// 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);
return;

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

@ -121,21 +121,9 @@ namespace llarp
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;
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>
FindFreeRange() const = 0;

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

@ -18,16 +18,16 @@ namespace llarp
void
SockAddr::init()
{
llarp::Zero(&m_addr, sizeof(m_addr));
m_addr.sin6_family = AF_INET6;
llarp::Zero(&m_addr4, sizeof(m_addr4));
m_addr4.sin_family = AF_INET;
llarp::Zero(&addr6, sizeof(addr6));
addr6.sin6_family = AF_INET6;
llarp::Zero(&addr4, sizeof(addr4));
addr4.sin_family = AF_INET;
}
void
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()
@ -86,7 +86,7 @@ namespace llarp
SockAddr&
SockAddr::operator=(const SockAddr& other)
{
*this = other.m_addr;
*this = other.addr6;
return *this;
}
@ -121,10 +121,10 @@ namespace llarp
applyIPv4MapBytes();
// avoid byte order conversion (this is NBO -> NBO)
memcpy(m_addr.sin6_addr.s6_addr + 12, &other.sin_addr.s_addr, sizeof(in_addr));
m_addr.sin6_port = other.sin_port;
m_addr4.sin_addr.s_addr = other.sin_addr.s_addr;
m_addr4.sin_port = other.sin_port;
memcpy(addr6.sin6_addr.s6_addr + 12, &other.sin_addr.s_addr, sizeof(in_addr));
addr6.sin6_port = other.sin_port;
addr4.sin_addr.s_addr = other.sin_addr.s_addr;
addr4.sin_port = other.sin_port;
m_empty = false;
return *this;
@ -140,7 +140,7 @@ namespace llarp
{
init();
memcpy(&m_addr, &other, sizeof(sockaddr_in6));
memcpy(&addr6, &other, sizeof(sockaddr_in6));
if (IPRange::V4MappedRange().Contains(asIPv6()))
{
setIPv4(
@ -148,7 +148,7 @@ namespace llarp
other.sin6_addr.s6_addr[13],
other.sin6_addr.s6_addr[14],
other.sin6_addr.s6_addr[15]);
m_addr4.sin_port = m_addr.sin6_port;
addr4.sin_port = addr6.sin6_port;
}
m_empty = false;
@ -164,11 +164,11 @@ namespace llarp
SockAddr::operator=(const in6_addr& other)
{
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()))
{
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;
@ -177,48 +177,48 @@ namespace llarp
SockAddr::operator const sockaddr*() const
{
return isIPv4() ? reinterpret_cast<const sockaddr*>(&m_addr4)
: reinterpret_cast<const sockaddr*>(&m_addr);
return isIPv4() ? reinterpret_cast<const sockaddr*>(&addr4)
: reinterpret_cast<const sockaddr*>(&addr6);
}
SockAddr::operator const sockaddr_in*() const
{
return &m_addr4;
return &addr4;
}
SockAddr::operator const sockaddr_in6*() const
{
return &m_addr;
return &addr6;
}
size_t
SockAddr::sockaddr_len() const
{
return isIPv6() ? sizeof(m_addr) : sizeof(m_addr4);
return isIPv6() ? sizeof(addr6) : sizeof(addr4);
}
bool
SockAddr::operator<(const SockAddr& other) const
{
return m_addr < other.m_addr;
return addr6 < other.addr6;
}
bool
SockAddr::operator==(const SockAddr& other) const
{
return m_addr == other.m_addr;
return addr6 == other.addr6;
}
huint128_t
SockAddr::asIPv6() const
{
return net::In6ToHUInt(m_addr.sin6_addr);
return net::In6ToHUInt(addr6.sin6_addr);
}
huint32_t
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);
}
@ -241,7 +241,7 @@ namespace llarp
if (splits.size() > 2)
{
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};
return;
}
@ -290,11 +290,11 @@ namespace llarp
if (isIPv4())
{
// 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();
}
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)
return buf.data();
@ -321,7 +321,7 @@ namespace llarp
nuint32_t
SockAddr::getIPv4() const
{
return {m_addr4.sin_addr.s_addr};
return {addr4.sin_addr.s_addr};
}
nuint128_t
@ -331,7 +331,7 @@ namespace llarp
// 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
// 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;
}
@ -346,13 +346,13 @@ namespace llarp
void
SockAddr::setIPv4(nuint32_t ip)
{
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr));
uint8_t* ip6 = addr6.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(addr6.sin6_addr.s6_addr));
applyIPv4MapBytes();
std::memcpy(ip6 + 12, &ip, 4);
m_addr4.sin_addr.s_addr = ip.n;
addr4.sin_addr.s_addr = ip.n;
m_empty = false;
}
@ -365,8 +365,8 @@ namespace llarp
void
SockAddr::setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr));
uint8_t* ip6 = addr6.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(addr6.sin6_addr.s6_addr));
applyIPv4MapBytes();
@ -375,7 +375,7 @@ namespace llarp
ip6[14] = c;
ip6[15] = 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;
}
@ -388,23 +388,23 @@ namespace llarp
void
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())
{
setIPv4(
m_addr.sin6_addr.s6_addr[12],
m_addr.sin6_addr.s6_addr[13],
m_addr.sin6_addr.s6_addr[14],
m_addr.sin6_addr.s6_addr[15]);
m_addr4.sin_port = m_addr.sin6_port;
addr6.sin6_addr.s6_addr[12],
addr6.sin6_addr.s6_addr[13],
addr6.sin6_addr.s6_addr[14],
addr6.sin6_addr.s6_addr[15]);
addr4.sin_port = addr6.sin6_port;
}
}
void
SockAddr::setPort(nuint16_t port)
{
m_addr.sin6_port = port.n;
m_addr4.sin_port = port.n;
addr6.sin6_port = port.n;
addr4.sin_port = port.n;
}
void
@ -416,7 +416,7 @@ namespace llarp
net::port_t
SockAddr::port() const
{
return net::port_t{m_addr.sin6_port};
return net::port_t{addr6.sin6_port};
}
} // namespace llarp

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

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

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

@ -120,7 +120,7 @@ namespace llarp
if (router.is_service_node())
return false;
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"};
}
@ -214,7 +214,7 @@ namespace llarp
vpn::AbstractRouteManager& route = router.vpn_platform()->RouteManager();
// black hole all routes if enabled
if (router.config()->network.m_BlackholeRoutes)
if (router.config()->network.blackhole_routes)
route.add_blackhole();
// 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
// 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
&& (conf.logging.m_logFile == "stdout" || conf.logging.m_logFile == "-"
|| conf.logging.m_logFile.empty()))
&& (conf.logging.file == "stdout" || conf.logging.file == "-" || conf.logging.file.empty()))
log_type = log::Type::Print;
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::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
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);
else
llarp::logRingBuffer = nullptr;
log::debug(logcat, "Configuring router");
_is_service_node = conf.router.m_isRelay;
_is_service_node = conf.router.is_relay;
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());
}
@ -408,8 +407,8 @@ namespace llarp
if (not StartRpcServer())
throw std::runtime_error("Failed to start rpc server");
if (conf.router.m_workerThreads > 0)
_lmq->set_general_threads(conf.router.m_workerThreads);
if (conf.router.worker_threads > 0)
_lmq->set_general_threads(conf.router.worker_threads);
log::debug(logcat, "Starting OMQ server");
_lmq->start();
@ -560,11 +559,11 @@ namespace llarp
Router::from_config(const Config& conf)
{
// Set netid before anything else
log::debug(logcat, "Network ID set to {}", conf.router.m_netId);
if (!conf.router.m_netId.empty()
&& strcmp(conf.router.m_netId.c_str(), llarp::LOKINET_DEFAULT_NETID) != 0)
log::debug(logcat, "Network ID set to {}", conf.router.net_id);
if (!conf.router.net_id.empty()
&& 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(
"!!!! you have manually set netid to be '",
netid,
@ -576,24 +575,24 @@ namespace llarp
}
// Router config
_link_manager.max_connected_routers = conf.router.m_maxConnectedRouters;
_link_manager.min_connected_routers = conf.router.m_minConnectedRouters;
_link_manager.max_connected_routers = conf.router.max_connected_routers;
_link_manager.min_connected_routers = conf.router.min_connected_routers;
encryption_keyfile = _key_manager->m_encKeyPath;
our_rc_file = _key_manager->m_rcPath;
transport_keyfile = _key_manager->m_transportKeyPath;
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);
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);
if (_ourAddress)
{
if (auto maybe_port = conf.links.PublicPort)
if (auto maybe_port = conf.links.public_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);
else
throw std::runtime_error{"public ip provided without public port"};
@ -602,16 +601,16 @@ namespace llarp
else
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;
/// build a set of 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())
throw std::runtime_error("cannot use strict-connect option as service node");
if (val.size() < 2)
@ -628,7 +627,7 @@ namespace llarp
// 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
// 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 (fs::exists(defaultBootstrapFile))
@ -708,10 +707,10 @@ namespace llarp
InitOutboundLinks();
// profiling
_profile_file = conf.router.m_dataDir / "profiles.dat";
_profile_file = conf.router.data_dir / "profiles.dat";
// Network config
if (conf.network.m_enableProfiling.value_or(false))
if (conf.network.enable_profiling.value_or(false))
{
LogInfo("router profiling enabled");
if (not fs::exists(_profile_file))
@ -1009,7 +1008,7 @@ namespace llarp
_exit_context.Tick(now);
// 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); });
}
@ -1048,7 +1047,7 @@ namespace llarp
bool
Router::StartRpcServer()
{
if (_config->api.m_enableRPCServer)
if (_config->api.enable_rpc_server)
_rpc_server = std::make_unique<rpc::RPCServer>(_lmq, *this);
return true;

@ -12,32 +12,6 @@
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
RouterContact::bt_load(oxenc::bt_dict_consumer& data)
{

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

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

@ -33,12 +33,12 @@ namespace llarp::rpc
Start();
void
AuthenticateAsync(
authenticate_async(
std::shared_ptr<llarp::service::ProtocolMessage> msg,
std::function<void(std::string, bool)> hook) override;
bool
AsyncAuthPending(service::ConvoTag tag) const override;
auth_async_pending(service::ConvoTag tag) const override;
private:
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}
{
// 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());
LogInfo("Bound RPC server to ", addr.full_address());
@ -566,10 +566,10 @@ namespace llarp::rpc
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.SaveNew();
parser.set_filename(conf_d / (config.request.filename));
parser.save_new();
}
}
catch (std::exception& e)

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

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

@ -186,7 +186,7 @@ namespace llarp::service
if (m_Endpoints.find(endpointName) != m_Endpoints.end())
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
const auto itr = endpointConstructors.find(endpointType);
if (itr == endpointConstructors.end())

@ -50,24 +50,24 @@ namespace llarp::service
bool
Endpoint::Configure(const NetworkConfig& conf, [[maybe_unused]] const DnsConfig& dnsConf)
{
if (conf.m_Paths.has_value())
numDesiredPaths = *conf.m_Paths;
if (conf.paths.has_value())
numDesiredPaths = *conf.paths;
if (conf.m_Hops.has_value())
numHops = *conf.m_Hops;
if (conf.hops.has_value())
numHops = *conf.hops;
conf.m_ExitMap.ForEachEntry(
conf.exit_map.ForEachEntry(
[&](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);
}
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;
const auto itr = conf.m_LNSExitAuths.find(name);
if (itr != conf.m_LNSExitAuths.end())
const auto itr = conf.ons_exit_auths.find(name);
if (itr != conf.ons_exit_auths.end())
auth = itr->second;
_startup_ons_mappings[name] = std::make_pair(range, auth);
});
@ -999,10 +999,10 @@ namespace llarp::service
{
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
_auth_policy->AuthenticateAsync(std::move(msg), std::move(hook));
_auth_policy->authenticate_async(std::move(msg), std::move(hook));
}
}
else

@ -5,12 +5,12 @@ namespace llarp::service
bool
EndpointState::Configure(const NetworkConfig& conf)
{
if (conf.m_keyfile.has_value())
key_file = conf.m_keyfile->string();
snode_blacklist = conf.m_snodeBlacklist;
is_exit_enabled = conf.m_AllowExit;
if (conf.keyfile.has_value())
key_file = conf.keyfile->string();
snode_blacklist = conf.snode_blacklist;
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());
}

Loading…
Cancel
Save