diff --git a/cmake/target_link_libraries_system.cmake b/cmake/target_link_libraries_system.cmake index eca571601..761b7c767 100644 --- a/cmake/target_link_libraries_system.cmake +++ b/cmake/target_link_libraries_system.cmake @@ -4,6 +4,6 @@ function(target_link_libraries_system target) foreach(lib ${libs}) get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES) target_include_directories(${target} SYSTEM PUBLIC ${lib_include_dirs}) - target_link_libraries(${target} PUBLIC ${lib}) + target_link_libraries(${target} ${lib}) endforeach(lib) endfunction() diff --git a/daemon/main.cpp b/daemon/main.cpp index 2fce4f6fb..aaaf3fa2c 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -1,9 +1,9 @@ -#include // for ensure_config +#include // for ensure_config #include #include #include -#include +#include #if !defined(_WIN32) && !defined(__OpenBSD__) #include diff --git a/include/llarp.hpp b/include/llarp.hpp index da5aa4f8d..56d3aa322 100644 --- a/include/llarp.hpp +++ b/include/llarp.hpp @@ -18,12 +18,11 @@ struct llarp_threadpool; namespace llarp { - class Logic; - struct AbstractRouter; struct Config; struct Crypto; struct CryptoManager; - struct MetricsConfig; + class Logic; + struct AbstractRouter; struct RouterContact; namespace metrics @@ -48,8 +47,13 @@ namespace llarp std::unique_ptr< metrics::DefaultManagerGuard > m_metricsManager; std::unique_ptr< metrics::PublisherScheduler > m_metricsPublisher; - int num_nethreads = 1; - bool singleThreaded = false; + int num_nethreads = 1; + bool singleThreaded = false; + bool disableMetrics = false; + bool disableMetricLogs = false; + fs::path jsonMetricsPath; + std::string metricTankHost; + std::map< std::string, std::string > metricTags; std::unique_ptr< Crypto > crypto; std::unique_ptr< CryptoManager > cryptoManager; @@ -107,11 +111,14 @@ namespace llarp bool ReloadConfig(); + void + iter_config(const char *section, const char *key, const char *val); + void progress(); void - setupMetrics(const MetricsConfig &metricsConfig); + setupMetrics(); std::string configfile; std::string pidfile; diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 211ca19bc..de365675c 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -1,6 +1,4 @@ set(LIB_UTIL_SRC - config/config.cpp - config/ini.cpp constants/defaults.cpp constants/link_layer.cpp constants/path.cpp @@ -15,6 +13,7 @@ set(LIB_UTIL_SRC util/encode.cpp util/endian.cpp util/fs.cpp + util/ini.cpp util/json.cpp util/logger.cpp util/android_logger.cpp @@ -53,7 +52,6 @@ set(LIB_UTIL_SRC add_library(${UTIL_LIB} STATIC ${LIB_UTIL_SRC}) target_include_directories(${UTIL_LIB} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include) -target_link_libraries(${UTIL_LIB} PUBLIC ${CRYPTOGRAPHY_LIB}) target_link_libraries_system(${UTIL_LIB} absl::synchronization absl::hash absl::container nlohmann_json::nlohmann_json) # cut back on fluff @@ -127,6 +125,7 @@ set(DNSLIB_SRC set(LIB_SRC ${DNSLIB_SRC} + config.cpp context.cpp crypto/constants.cpp crypto/crypto_libsodium.cpp diff --git a/llarp/config.cpp b/llarp/config.cpp new file mode 100644 index 000000000..ca1ec36ea --- /dev/null +++ b/llarp/config.cpp @@ -0,0 +1,369 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace llarp +{ + template < typename Config, typename Section > + Section + find_section(Config &c, const std::string &name, const Section &fallback) + { + Section ret; + if(c.VisitSection(name.c_str(), + [&ret](const ConfigParser::Section_t &s) -> bool { + for(const auto &item : s) + { + ret.emplace_back(string_view_string(item.first), + string_view_string(item.second)); + } + return true; + })) + return ret; + else + return fallback; + } + + bool + Config::Load(const char *fname) + { + ConfigParser parser; + if(!parser.LoadFile(fname)) + { + return false; + } + router = find_section(parser, "router", section_t{}); + network = find_section(parser, "network", section_t{}); + connect = find_section(parser, "connect", section_t{}); + netdb = find_section(parser, "netdb", section_t{}); + dns = find_section(parser, "dns", section_t{}); + iwp_links = find_section(parser, "bind", section_t{}); + services = find_section(parser, "services", section_t{}); + system = find_section(parser, "system", section_t{}); + metrics = find_section(parser, "metrics", section_t{}); + api = find_section(parser, "api", section_t{}); + lokid = find_section(parser, "lokid", section_t{}); + bootstrap = find_section(parser, "bootstrap", section_t{}); + logging = find_section(parser, "logging", section_t{}); + return true; + } + + void + Config::visit(const Visitor &functor) + { + std::unordered_map< std::string, const llarp::Config::section_t & > + sections = {{"network", network}, + {"connect", connect}, + {"bootstrap", bootstrap}, + {"system", system}, + {"metrics", metrics}, + {"netdb", netdb}, + {"api", api}, + {"services", services}}; + + auto visitor = [&](const char *name, const auto &item) { + functor(name, item.first.c_str(), item.second.c_str()); + }; + + using namespace std::placeholders; + + std::for_each(logging.begin(), logging.end(), + std::bind(visitor, "logging", _1)); + // end of logging section commit settings and go + functor("logging", "", ""); + std::for_each(lokid.begin(), lokid.end(), std::bind(visitor, "lokid", _1)); + std::for_each(router.begin(), router.end(), + std::bind(visitor, "router", _1)); + + std::for_each(dns.begin(), dns.end(), std::bind(visitor, "dns", _1)); + std::for_each(iwp_links.begin(), iwp_links.end(), + std::bind(visitor, "bind", _1)); + + std::for_each(sections.begin(), sections.end(), [&](const auto §ion) { + std::for_each(section.second.begin(), section.second.end(), + std::bind(visitor, section.first.c_str(), _1)); + }); + } + +} // namespace llarp + +/// fname should be a relative path (from CWD) or absolute path to the config +/// file +extern "C" bool +llarp_ensure_config(const char *fname, const char *basedir, bool overwrite, + bool asRouter) +{ + std::error_code ec; + if(fs::exists(fname, ec) && !overwrite) + { + return true; + } + if(ec) + { + llarp::LogError(ec); + return false; + } + + std::string basepath = ""; + if(basedir) + { + basepath = basedir; +#ifndef _WIN32 + basepath += "/"; +#else + basepath += "\\"; +#endif + } + + llarp::LogInfo("Attempting to create config file ", fname); + + // abort if config already exists + if(!asRouter) + { + if(fs::exists(fname, ec) && !overwrite) + { + llarp::LogError(fname, " currently exists, please use -f to overwrite"); + return true; + } + if(ec) + { + llarp::LogError(ec); + return false; + } + } + + // write fname ini + auto optional_f = + llarp::util::OpenFileStream< std::ofstream >(fname, std::ios::binary); + if(!optional_f || !optional_f.value().is_open()) + { + llarp::LogError("failed to open ", fname, " for writing"); + return false; + } + auto &f = optional_f.value(); + llarp_generic_ensure_config(f, basepath); + if(asRouter) + { + llarp_ensure_router_config(f, basepath); + } + else + { + llarp_ensure_client_config(f, basepath); + } + llarp::LogInfo("Generated new config ", fname); + return true; +} + +void +llarp_generic_ensure_config(std::ofstream &f, std::string basepath) +{ + f << "# this configuration was auto generated with 'sane' defaults" + << std::endl; + f << "# change these values as desired" << std::endl; + f << std::endl << std::endl; + f << "[router]" << std::endl; + f << "# number of crypto worker threads " << std::endl; + f << "threads=4" << std::endl; + f << "# path to store signed RC" << std::endl; + f << "contact-file=" << basepath << "self.signed" << std::endl; + f << "# path to store transport private key" << std::endl; + f << "transport-privkey=" << basepath << "transport.private" << std::endl; + f << "# path to store identity signing key" << std::endl; + f << "ident-privkey=" << basepath << "identity.private" << std::endl; + f << "# encryption key for onion routing" << std::endl; + f << "encryption-privkey=" << basepath << "encryption.private" << std::endl; + f << std::endl; + f << "# uncomment following line to set router nickname to 'lokinet'" + << std::endl; + f << "#nickname=lokinet" << std::endl; + f << std::endl << std::endl; + + // logging + f << "[logging]" << std::endl; + f << "level=info" << std::endl; + f << "# uncomment for logging to file" << std::endl; + f << "#type=file" << std::endl; + f << "#file=/path/to/logfile" << std::endl; + f << "# uncomment for syslog logging" << std::endl; + f << "#type=syslog" << std::endl; + + // metrics + f << "[metrics]" << std::endl; + f << "json-metrics-path=" << basepath << "metrics.json" << std::endl; + + f << std::endl << std::endl; + + f << "# admin api (disabled by default)" << std::endl; + f << "[api]" << std::endl; + f << "enabled=false" << std::endl; + f << "#authkey=insertpubkey1here" << std::endl; + f << "#authkey=insertpubkey2here" << std::endl; + f << "#authkey=insertpubkey3here" << std::endl; + f << "bind=127.0.0.1:1190" << std::endl; + f << std::endl << std::endl; + + f << "# system settings for privileges and such" << std::endl; + f << "[system]" << std::endl; + f << "user=" << DEFAULT_LOKINET_USER << std::endl; + f << "group=" << DEFAULT_LOKINET_GROUP << std::endl; + f << "pidfile=" << basepath << "lokinet.pid" << std::endl; + f << std::endl << std::endl; + + f << "# dns provider configuration section" << std::endl; + f << "[dns]" << std::endl; + f << "# resolver" << std::endl; + f << "upstream=" << DEFAULT_RESOLVER_US << std::endl; + +// Make auto-config smarter +// will this break reproducibility rules? +// (probably) +#ifdef __linux__ +#ifdef ANDROID + f << "bind=127.0.0.1:1153" << std::endl; +#else + f << "bind=127.3.2.1:53" << std::endl; +#endif +#else + f << "bind=127.0.0.1:53" << std::endl; +#endif + f << std::endl << std::endl; + + f << "# network database settings block " << std::endl; + f << "[netdb]" << std::endl; + f << "# directory for network database skiplist storage" << std::endl; + f << "dir=" << basepath << "netdb" << std::endl; + f << std::endl << std::endl; + + f << "# bootstrap settings" << std::endl; + f << "[bootstrap]" << std::endl; + f << "# add a bootstrap node's signed identity to the list of nodes we want " + "to bootstrap from" + << std::endl; + f << "# if we don't have any peers we connect to this router" << std::endl; + f << "add-node=" << basepath << "bootstrap.signed" << std::endl; + // we only process one of these... + // f << "# add another bootstrap node" << std::endl; + // f << "#add-node=/path/to/alternative/self.signed" << std::endl; + f << std::endl << std::endl; +} + +void +llarp_ensure_router_config(std::ofstream &f, std::string basepath) +{ + f << "# lokid settings (disabled by default)" << std::endl; + f << "[lokid]" << std::endl; + f << "enabled=false" << std::endl; + f << "jsonrpc=127.0.0.1:22023" << std::endl; + f << "#service-node-seed=/path/to/servicenode/seed" << std::endl; + f << std::endl; + f << "# network settings " << std::endl; + f << "[network]" << std::endl; + f << "profiles=" << basepath << "profiles.dat" << std::endl; + // better to let the routers auto-configure + // f << "ifaddr=auto" << std::endl; + // f << "ifname=auto" << std::endl; + f << "enabled=true" << std::endl; + f << "exit=false" << std::endl; + f << "#exit-blacklist=tcp:25" << std::endl; + f << "#exit-whitelist=tcp:*" << std::endl; + f << "#exit-whitelist=udp:*" << std::endl; + f << std::endl; + f << "# ROUTERS ONLY: publish network interfaces for handling inbound traffic" + << std::endl; + f << "[bind]" << std::endl; + // get ifname + std::string ifname; + if(llarp::GetBestNetIF(ifname, AF_INET)) + f << ifname << "=1090" << std::endl; + else + f << "# could not autodetect network interface" << std::endl + << "#eth0=1090" << std::endl; + + f << std::endl; +} + +bool +llarp_ensure_client_config(std::ofstream &f, std::string basepath) +{ + // write snapp-example.ini + const std::string snappExample_fpath = basepath + "snapp-example.ini"; + { + auto stream = llarp::util::OpenFileStream< std::ofstream >( + snappExample_fpath, std::ios::binary); + if(!stream) + return false; + auto &example_f = stream.value(); + if(example_f.is_open()) + { + // pick ip + // don't revert me + const static std::string ip = "10.33.0.1/16"; + /* + std::string ip = llarp::findFreePrivateRange(); + if(ip == "") + { + llarp::LogError( + "Couldn't easily detect a private range to map lokinet onto"); + return false; + } + */ + example_f << "# this is an example configuration for a snapp" + << std::endl; + example_f << "[example-snapp]" << std::endl; + example_f << "# keyfile is the path to the private key of the snapp, " + "your .loki is tied to this key, DON'T LOSE IT" + << std::endl; + example_f << "keyfile=" << basepath << "example-snap-keyfile.private" + << std::endl; + example_f << "# ifaddr is the ip range to allocate to this snapp" + << std::endl; + example_f << "ifaddr=" << ip << std::endl; + // probably fine to leave this (and not-auto-detect it) I'm not worried + // about any collisions + example_f << "# ifname is the name to try and give to the network " + "interface this snap owns" + << std::endl; + example_f << "ifname=snapp-tun0" << std::endl; + } + else + { + llarp::LogError("failed to write ", snappExample_fpath); + } + } + // now do up fname + f << std::endl << std::endl; + f << "# snapps configuration section" << std::endl; + f << "[services]"; + f << "# uncomment next line to enable a snapp" << std::endl; + f << "#example-snapp=" << snappExample_fpath << std::endl; + f << std::endl << std::endl; + + f << "# network settings " << std::endl; + f << "[network]" << std::endl; + f << "profiles=" << basepath << "profiles.dat" << std::endl; + f << "# uncomment next line to add router with pubkey to list of routers we " + "connect directly to" + << std::endl; + f << "#strict-connect=pubkey" << std::endl; + f << "# uncomment next line to use router with pubkey as an exit node" + << std::endl; + f << "#exit-node=pubkey" << std::endl; + + // better to set them to auto then to hard code them now + // operating environment may change over time and this will help adapt + // f << "ifname=auto" << std::endl; + // f << "ifaddr=auto" << std::endl; + + // should this also be auto? or not declared? + // probably auto in case they want to set up a hidden service + f << "enabled=true" << std::endl; + return true; +} diff --git a/llarp/config.hpp b/llarp/config.hpp new file mode 100644 index 000000000..520733bd9 --- /dev/null +++ b/llarp/config.hpp @@ -0,0 +1,50 @@ +#ifndef LLARP_CONFIG_HPP +#define LLARP_CONFIG_HPP + +#include +#include +#include +#include + +namespace llarp +{ + struct Config + { + using section_t = std::vector< std::pair< std::string, std::string > >; + + section_t router; + section_t network; + section_t netdb; + section_t dns; + section_t iwp_links; + section_t connect; + section_t services; + section_t system; + section_t metrics; + section_t api; + section_t lokid; + section_t bootstrap; + section_t logging; + + bool + Load(const char *fname); + + using Visitor = std::function< void(const char *section, const char *key, + const char *val) >; + + void + visit(const Visitor &visitor); + }; + +} // namespace llarp + +void +llarp_generic_ensure_config(std::ofstream &f, std::string basepath); + +void +llarp_ensure_router_config(std::ofstream &f, std::string basepath); + +bool +llarp_ensure_client_config(std::ofstream &f, std::string basepath); + +#endif diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp deleted file mode 100644 index d7092a4d5..000000000 --- a/llarp/config/config.cpp +++ /dev/null @@ -1,704 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace llarp -{ - bool - RouterConfig::fromSection(string_view key, string_view val) - { - if(key == "netid") - { - if(val.size() <= rc.netID.size()) - { - llarp::LogWarn("!!!! you have manually set netid to be '", val, - "' which does not equal '", Version::LLARP_NET_ID, - "' you will run as a different network, good luck " - "and " - "don't forget: something something MUH traffic " - "shape " - "correlation !!!!"); - NetID::DefaultValue() = - NetID(reinterpret_cast< const byte_t * >(std::string(val).c_str())); - // re set netid in our rc - rc.netID = llarp::NetID(); - netid.assign(val.begin(), val.end()); - } - else - { - llarp::LogError("invalid netid '", val, "', is too long"); - } - } - if(key == "max-connections") - { - std::string sVal(val.begin(), val.end()); - auto ival = atoi(sVal.c_str()); - if(ival > 0) - { - maxConnectedRouters = ival; - LogInfo("max connections set to ", maxConnectedRouters); - } - } - if(key == "min-connections") - { - std::string sVal(val.begin(), val.end()); - auto ival = atoi(sVal.c_str()); - if(ival > 0) - { - minConnectedRouters = ival; - LogInfo("min connections set to ", minConnectedRouters); - } - } - if(key == "nickname") - { - rc.SetNick(val); - // set logger name here - LogContext::Instance().nodeName = rc.Nick(); - } - if(key == "encryption-privkey") - { - encryption_keyfile.assign(val.begin(), val.end()); - } - if(key == "contact-file") - { - our_rc_file.assign(val.begin(), val.end()); - } - if(key == "transport-privkey") - { - transport_keyfile.assign(val.begin(), val.end()); - } - if((key == "identity-privkey" || key == "ident-privkey")) - { - ident_keyfile.assign(val.begin(), val.end()); - } - if(key == "public-address" || key == "public-ip") - { - llarp::LogInfo("public ip ", val, " size ", val.size()); - if(val.size() < 17) - { - // assume IPv4 - llarp::Addr a(val); - llarp::LogInfo("setting public ipv4 ", a); - addrInfo.ip = *a.addr6(); - publicOverride = true; - } - // llarp::Addr a(val); - } - if(key == "public-port") - { - llarp::LogInfo("Setting public port ", val); - int p = atoi(std::string(val).c_str()); - // Not needed to flip upside-down - this is done in llarp::Addr(const - // AddressInfo&) - ip4addr.sin_port = p; - addrInfo.port = p; - publicOverride = true; - } - if(key == "worker-threads") - { - workerThreads = atoi(std::string(val).c_str()); - } - if(key == "net-threads") - { - num_nethreads = atoi(std::string(val).c_str()); - if(num_nethreads <= 0) - num_nethreads = 1; - } - - return true; - } - bool - NetworkConfig::fromSection(string_view key, string_view val) - { - if(key == "profiling") - { - if(IsTrueValue(val)) - { - enableProfiling.emplace(true); - } - else if(IsFalseValue(val)) - { - enableProfiling.emplace(false); - } - } - if(key == "profiles") - { - routerProfilesFile.assign(val.begin(), val.end()); - llarp::LogInfo("setting profiles to ", routerProfilesFile); - } - else if(key == "strict-connect") - { - strictConnect.assign(val.begin(), val.end()); - } - else - { - netConfig.emplace(key, val); - } - return true; - } - - bool - NetdbConfig::fromSection(string_view key, string_view val) - { - if(key == "dir") - { - nodedb_dir.assign(val.begin(), val.end()); - } - - return true; - } - - bool - DnsConfig::fromSection(string_view key, string_view val) - { - if(key == "upstream") - { - llarp::LogInfo("add upstream resolver ", val); - netConfig.emplace("upstream-dns", val); - } - if(key == "bind") - { - llarp::LogInfo("set local dns to ", val); - netConfig.emplace("local-dns", val); - } - return true; - } - - bool - IwpConfig::fromSection(string_view key, string_view val) - { - // try IPv4 first - uint16_t proto = 0; - - std::set< std::string > parsed_opts; - std::string v(val.begin(), val.end()); - std::string::size_type idx; - do - { - idx = v.find_first_of(','); - if(idx != std::string::npos) - { - parsed_opts.insert(v.substr(0, idx)); - v = v.substr(idx + 1); - } - else - { - parsed_opts.insert(v); - } - } while(idx != std::string::npos); - - /// for each option - for(const auto &item : parsed_opts) - { - /// see if it's a number - auto port = std::atoi(item.c_str()); - if(port > 0) - { - /// set port - if(proto == 0) - { - proto = port; - } - } - } - - if(key == "*") - { - m_OutboundPort = proto; - } - else - { - servers.emplace_back(key, AF_INET, proto); - } - return true; - } - - bool - ConnectConfig::fromSection(ABSL_ATTRIBUTE_UNUSED string_view key, - string_view val) - { - routers.emplace_back(val.begin(), val.end()); - return true; - } - - bool - ServicesConfig::fromSection(string_view key, string_view val) - { - services.emplace_back(std::string(key.begin(), key.end()), - std::string(val.begin(), val.end())); - return true; - } - - bool - SystemConfig::fromSection(string_view key, string_view val) - { - if(key == "pidfile") - { - pidfile.assign(val.begin(), val.end()); - } - - return true; - } - - bool - MetricsConfig::fromSection(string_view key, string_view val) - { - if(key == "disable-metrics") - { - disableMetrics = true; - } - else if(key == "disable-metrics-log") - { - disableMetricLogs = true; - } - else if(key == "json-metrics-path") - { - jsonMetricsPath.assign(val.begin(), val.end()); - } - else if(key == "metric-tank-host") - { - metricTankHost.assign(val.begin(), val.end()); - } - else - { - // consume everything else as a metric tag - metricTags[std::string(key)] = std::string(val); - } - - return true; - } - - bool - ApiConfig::fromSection(string_view key, string_view val) - { - if(key == "enabled") - { - enableRPCServer = IsTrueValue(val); - } - if(key == "bind") - { - rpcBindAddr.assign(val.begin(), val.end()); - } - if(key == "authkey") - { - // TODO: add pubkey to whitelist - } - - return true; - } - - bool - LokidConfig::fromSection(string_view key, string_view val) - { - if(key == "service-node-seed") - { - usingSNSeed = true; - ident_keyfile.assign(val.begin(), val.end()); - } - if(key == "enabled") - { - whitelistRouters = IsTrueValue(val); - } - if(key == "jsonrpc" || key == "addr") - { - lokidRPCAddr.assign(val.begin(), val.end()); - } - if(key == "username") - { - lokidRPCUser.assign(val.begin(), val.end()); - } - if(key == "password") - { - lokidRPCPassword.assign(val.begin(), val.end()); - } - - return true; - } - - bool - BootstrapConfig::fromSection(string_view key, string_view val) - { - if(key == "add-node") - { - routers.emplace_back(val.begin(), val.end()); - } - - return true; - } - - bool - LoggingConfig::fromSection(string_view key, string_view val) - { - if(key == "type" && val == "syslog") - { - // TODO(despair): write event log syslog class -#if defined(_WIN32) - LogError("syslog not supported on win32"); -#else - LogInfo("Switching to syslog"); - LogContext::Instance().logStream = std::make_unique< SysLogStream >(); -#endif - } - if(key == "type" && val == "json") - { - m_LogJSON = true; - } - if(key == "file") - { - LogInfo("open log file: ", val); - std::string fname(val.begin(), val.end()); - FILE *const logfile = ::fopen(fname.c_str(), "a"); - if(logfile) - { - m_LogFile = logfile; - LogInfo("will log to file ", val); - } - else if(errno) - { - LogError("could not open log file at '", val, "': ", strerror(errno)); - errno = 0; - } - else - { - LogError("failed to open log file at '", val, - "' for an unknown reason, bailing tf out kbai"); - ::abort(); - } - } - - return true; - } - - template < typename Section, typename Config > - Section - find_section(Config &c, const std::string &name) - { - Section ret; - - auto visitor = [&ret](const ConfigParser::Section_t §ion) -> bool { - for(const auto &sec : section) - { - if(!ret.fromSection(sec.first, sec.second)) - { - return false; - } - } - return true; - }; - - if(c.VisitSection(name.c_str(), visitor)) - return ret; - else - return {}; - } - - bool - Config::Load(const char *fname) - { - ConfigParser parser; - if(!parser.LoadFile(fname)) - { - return false; - } - router = find_section< RouterConfig >(parser, "router"); - network = find_section< NetworkConfig >(parser, "network"); - connect = find_section< ConnectConfig >(parser, "connect"); - netdb = find_section< NetdbConfig >(parser, "netdb"); - dns = find_section< DnsConfig >(parser, "dns"); - iwp_links = find_section< IwpConfig >(parser, "bind"); - services = find_section< ServicesConfig >(parser, "services"); - system = find_section< SystemConfig >(parser, "system"); - metrics = find_section< MetricsConfig >(parser, "metrics"); - api = find_section< ApiConfig >(parser, "api"); - lokid = find_section< LokidConfig >(parser, "lokid"); - bootstrap = find_section< BootstrapConfig >(parser, "bootstrap"); - logging = find_section< LoggingConfig >(parser, "logging"); - return true; - } - -} // namespace llarp - -/// fname should be a relative path (from CWD) or absolute path to the config -/// file -extern "C" bool -llarp_ensure_config(const char *fname, const char *basedir, bool overwrite, - bool asRouter) -{ - std::error_code ec; - if(fs::exists(fname, ec) && !overwrite) - { - return true; - } - if(ec) - { - llarp::LogError(ec); - return false; - } - - std::string basepath = ""; - if(basedir) - { - basepath = basedir; -#ifndef _WIN32 - basepath += "/"; -#else - basepath += "\\"; -#endif - } - - llarp::LogInfo("Attempting to create config file ", fname); - - // abort if config already exists - if(!asRouter) - { - if(fs::exists(fname, ec) && !overwrite) - { - llarp::LogError(fname, " currently exists, please use -f to overwrite"); - return true; - } - if(ec) - { - llarp::LogError(ec); - return false; - } - } - - // write fname ini - auto optional_f = - llarp::util::OpenFileStream< std::ofstream >(fname, std::ios::binary); - if(!optional_f || !optional_f.value().is_open()) - { - llarp::LogError("failed to open ", fname, " for writing"); - return false; - } - auto &f = optional_f.value(); - llarp_generic_ensure_config(f, basepath); - if(asRouter) - { - llarp_ensure_router_config(f, basepath); - } - else - { - llarp_ensure_client_config(f, basepath); - } - llarp::LogInfo("Generated new config ", fname); - return true; -} - -void -llarp_generic_ensure_config(std::ofstream &f, std::string basepath) -{ - f << "# this configuration was auto generated with 'sane' defaults" - << std::endl; - f << "# change these values as desired" << std::endl; - f << std::endl << std::endl; - f << "[router]" << std::endl; - f << "# number of crypto worker threads " << std::endl; - f << "threads=4" << std::endl; - f << "# path to store signed RC" << std::endl; - f << "contact-file=" << basepath << "self.signed" << std::endl; - f << "# path to store transport private key" << std::endl; - f << "transport-privkey=" << basepath << "transport.private" << std::endl; - f << "# path to store identity signing key" << std::endl; - f << "ident-privkey=" << basepath << "identity.private" << std::endl; - f << "# encryption key for onion routing" << std::endl; - f << "encryption-privkey=" << basepath << "encryption.private" << std::endl; - f << std::endl; - f << "# uncomment following line to set router nickname to 'lokinet'" - << std::endl; - f << "#nickname=lokinet" << std::endl; - f << std::endl << std::endl; - - // logging - f << "[logging]" << std::endl; - f << "level=info" << std::endl; - f << "# uncomment for logging to file" << std::endl; - f << "#type=file" << std::endl; - f << "#file=/path/to/logfile" << std::endl; - f << "# uncomment for syslog logging" << std::endl; - f << "#type=syslog" << std::endl; - - // metrics - f << "[metrics]" << std::endl; - f << "json-metrics-path=" << basepath << "metrics.json" << std::endl; - - f << std::endl << std::endl; - - f << "# admin api (disabled by default)" << std::endl; - f << "[api]" << std::endl; - f << "enabled=false" << std::endl; - f << "#authkey=insertpubkey1here" << std::endl; - f << "#authkey=insertpubkey2here" << std::endl; - f << "#authkey=insertpubkey3here" << std::endl; - f << "bind=127.0.0.1:1190" << std::endl; - f << std::endl << std::endl; - - f << "# system settings for privileges and such" << std::endl; - f << "[system]" << std::endl; - f << "user=" << DEFAULT_LOKINET_USER << std::endl; - f << "group=" << DEFAULT_LOKINET_GROUP << std::endl; - f << "pidfile=" << basepath << "lokinet.pid" << std::endl; - f << std::endl << std::endl; - - f << "# dns provider configuration section" << std::endl; - f << "[dns]" << std::endl; - f << "# resolver" << std::endl; - f << "upstream=" << DEFAULT_RESOLVER_US << std::endl; - -// Make auto-config smarter -// will this break reproducibility rules? -// (probably) -#ifdef __linux__ -#ifdef ANDROID - f << "bind=127.0.0.1:1153" << std::endl; -#else - f << "bind=127.3.2.1:53" << std::endl; -#endif -#else - f << "bind=127.0.0.1:53" << std::endl; -#endif - f << std::endl << std::endl; - - f << "# network database settings block " << std::endl; - f << "[netdb]" << std::endl; - f << "# directory for network database skiplist storage" << std::endl; - f << "dir=" << basepath << "netdb" << std::endl; - f << std::endl << std::endl; - - f << "# bootstrap settings" << std::endl; - f << "[bootstrap]" << std::endl; - f << "# add a bootstrap node's signed identity to the list of nodes we want " - "to bootstrap from" - << std::endl; - f << "# if we don't have any peers we connect to this router" << std::endl; - f << "add-node=" << basepath << "bootstrap.signed" << std::endl; - // we only process one of these... - // f << "# add another bootstrap node" << std::endl; - // f << "#add-node=/path/to/alternative/self.signed" << std::endl; - f << std::endl << std::endl; -} - -void -llarp_ensure_router_config(std::ofstream &f, std::string basepath) -{ - f << "# lokid settings (disabled by default)" << std::endl; - f << "[lokid]" << std::endl; - f << "enabled=false" << std::endl; - f << "jsonrpc=127.0.0.1:22023" << std::endl; - f << "#service-node-seed=/path/to/servicenode/seed" << std::endl; - f << std::endl; - f << "# network settings " << std::endl; - f << "[network]" << std::endl; - f << "profiles=" << basepath << "profiles.dat" << std::endl; - // better to let the routers auto-configure - // f << "ifaddr=auto" << std::endl; - // f << "ifname=auto" << std::endl; - f << "enabled=true" << std::endl; - f << "exit=false" << std::endl; - f << "#exit-blacklist=tcp:25" << std::endl; - f << "#exit-whitelist=tcp:*" << std::endl; - f << "#exit-whitelist=udp:*" << std::endl; - f << std::endl; - f << "# ROUTERS ONLY: publish network interfaces for handling inbound traffic" - << std::endl; - f << "[bind]" << std::endl; - // get ifname - std::string ifname; - if(llarp::GetBestNetIF(ifname, AF_INET)) - f << ifname << "=1090" << std::endl; - else - f << "# could not autodetect network interface" << std::endl - << "#eth0=1090" << std::endl; - - f << std::endl; -} - -bool -llarp_ensure_client_config(std::ofstream &f, std::string basepath) -{ - // write snapp-example.ini - const std::string snappExample_fpath = basepath + "snapp-example.ini"; - { - auto stream = llarp::util::OpenFileStream< std::ofstream >( - snappExample_fpath, std::ios::binary); - if(!stream) - return false; - auto &example_f = stream.value(); - if(example_f.is_open()) - { - // pick ip - // don't revert me - const static std::string ip = "10.33.0.1/16"; - /* - std::string ip = llarp::findFreePrivateRange(); - if(ip == "") - { - llarp::LogError( - "Couldn't easily detect a private range to map lokinet onto"); - return false; - } - */ - example_f << "# this is an example configuration for a snapp" - << std::endl; - example_f << "[example-snapp]" << std::endl; - example_f << "# keyfile is the path to the private key of the snapp, " - "your .loki is tied to this key, DON'T LOSE IT" - << std::endl; - example_f << "keyfile=" << basepath << "example-snap-keyfile.private" - << std::endl; - example_f << "# ifaddr is the ip range to allocate to this snapp" - << std::endl; - example_f << "ifaddr=" << ip << std::endl; - // probably fine to leave this (and not-auto-detect it) I'm not worried - // about any collisions - example_f << "# ifname is the name to try and give to the network " - "interface this snap owns" - << std::endl; - example_f << "ifname=snapp-tun0" << std::endl; - } - else - { - llarp::LogError("failed to write ", snappExample_fpath); - } - } - // now do up fname - f << std::endl << std::endl; - f << "# snapps configuration section" << std::endl; - f << "[services]"; - f << "# uncomment next line to enable a snapp" << std::endl; - f << "#example-snapp=" << snappExample_fpath << std::endl; - f << std::endl << std::endl; - - f << "# network settings " << std::endl; - f << "[network]" << std::endl; - f << "profiles=" << basepath << "profiles.dat" << std::endl; - f << "# uncomment next line to add router with pubkey to list of routers we " - "connect directly to" - << std::endl; - f << "#strict-connect=pubkey" << std::endl; - f << "# uncomment next line to use router with pubkey as an exit node" - << std::endl; - f << "#exit-node=pubkey" << std::endl; - - // better to set them to auto then to hard code them now - // operating environment may change over time and this will help adapt - // f << "ifname=auto" << std::endl; - // f << "ifaddr=auto" << std::endl; - - // should this also be auto? or not declared? - // probably auto in case they want to set up a hidden service - f << "enabled=true" << std::endl; - return true; -} diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp deleted file mode 100644 index 3cbe53c75..000000000 --- a/llarp/config/config.hpp +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef LLARP_CONFIG_HPP -#define LLARP_CONFIG_HPP - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace llarp -{ - struct RouterConfig - { - /// always maintain this many connections to other routers - size_t minConnectedRouters = 2; - - /// hard upperbound limit on the number of router to router connections - size_t maxConnectedRouters = 2000; - - std::string netid; - RouterContact rc; - - fs::path encryption_keyfile = "encryption.key"; - - // path to write our self signed rc to - fs::path our_rc_file = "rc.signed"; - - // transient iwp encryption key - fs::path transport_keyfile = "transport.key"; - - // long term identity key - fs::path ident_keyfile = "identity.key"; - - bool publicOverride = false; - struct sockaddr_in ip4addr; - AddressInfo addrInfo; - - int workerThreads; - int num_nethreads; - - bool - fromSection(string_view key, string_view val); - }; - - struct NetworkConfig - { - absl::optional< bool > enableProfiling; - std::string routerProfilesFile = "profiles.dat"; - std::string strictConnect; - std::unordered_multimap< std::string, std::string > netConfig; - - bool - fromSection(string_view key, string_view val); - }; - - struct NetdbConfig - { - std::string nodedb_dir; - - bool - fromSection(string_view key, string_view val); - }; - - struct DnsConfig - { - std::unordered_multimap< std::string, std::string > netConfig; - - bool - fromSection(string_view key, string_view val); - }; - - struct IwpConfig - { - uint16_t m_OutboundPort = 0; - - std::vector< std::tuple< std::string, int, uint16_t > > servers; - - bool - fromSection(string_view key, string_view val); - }; - - struct ConnectConfig - { - std::vector< std::string > routers; - - bool - fromSection(string_view key, string_view val); - }; - - struct ServicesConfig - { - std::vector< std::pair< std::string, std::string > > services; - bool - fromSection(string_view key, string_view val); - }; - - struct SystemConfig - { - std::string pidfile; - - bool - fromSection(string_view key, string_view val); - }; - - struct MetricsConfig - { - bool disableMetrics = false; - bool disableMetricLogs = false; - fs::path jsonMetricsPath; - std::string metricTankHost; - std::map< std::string, std::string > metricTags; - - bool - fromSection(string_view key, string_view val); - }; - - struct ApiConfig - { - bool enableRPCServer = false; - std::string rpcBindAddr; - - bool - fromSection(string_view key, string_view val); - }; - - struct LokidConfig - { - bool usingSNSeed = false; - bool whitelistRouters = false; - fs::path ident_keyfile = "identity.key"; - std::string lokidRPCAddr = "127.0.0.1:22023"; - std::string lokidRPCUser; - std::string lokidRPCPassword; - - bool - fromSection(string_view key, string_view val); - }; - - struct BootstrapConfig - { - std::vector< std::string > routers; - bool - fromSection(string_view key, string_view val); - }; - - struct LoggingConfig - { - bool m_LogJSON = false; - FILE *m_LogFile = stdout; - - bool - fromSection(string_view key, string_view val); - }; - - struct Config - { - RouterConfig router; - NetworkConfig network; - ConnectConfig connect; - NetdbConfig netdb; - DnsConfig dns; - IwpConfig iwp_links; - ServicesConfig services; - SystemConfig system; - MetricsConfig metrics; - ApiConfig api; - LokidConfig lokid; - BootstrapConfig bootstrap; - LoggingConfig logging; - - bool - Load(const char *fname); - }; - -} // namespace llarp - -void -llarp_generic_ensure_config(std::ofstream &f, std::string basepath); - -void -llarp_ensure_router_config(std::ofstream &f, std::string basepath); - -bool -llarp_ensure_client_config(std::ofstream &f, std::string basepath); - -#endif diff --git a/llarp/context.cpp b/llarp/context.cpp index 28c41c677..4200b2a8d 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include #include @@ -52,49 +52,92 @@ namespace llarp llarp::LogError("failed to load config file ", configfile); return false; } + config->visit(util::memFn(&Context::iter_config, this)); - // System config - if(!config->system.pidfile.empty()) + if(!disableMetrics) { - SetPIDFile(config->system.pidfile); + setupMetrics(); + if(!disableMetricLogs) + { + m_metricsManager->instance()->addGlobalPublisher( + std::make_shared< metrics::StreamPublisher >(std::cerr)); + } } + return true; + } - // Router config - if(!singleThreaded && config->router.workerThreads > 0 && !worker) + void + Context::iter_config(const char *section, const char *key, const char *val) + { + if(!strcmp(section, "system")) { - worker.reset( - llarp_init_threadpool(config->router.workerThreads, "llarp-worker")); + if(!strcmp(key, "pidfile")) + { + SetPIDFile(val); + } } - - if(singleThreaded) + if(!strcmp(section, "metrics")) { - num_nethreads = 0; + if(!strcmp(key, "disable-metrics")) + { + disableMetrics = true; + } + else if(!strcmp(key, "disable-metrics-log")) + { + disableMetricLogs = true; + } + else if(!strcmp(key, "json-metrics-path")) + { + jsonMetricsPath = val; + } + else if(!strcmp(key, "metric-tank-host")) + { + metricTankHost = val; + } + else + { + // consume everything else as a metric tag + metricTags[key] = val; + } } - else + if(!strcmp(section, "router")) { - num_nethreads = config->router.num_nethreads; + if(!strcmp(key, "worker-threads") && !singleThreaded) + { + int workers = atoi(val); + if(workers > 0 && worker == nullptr) + { + worker.reset(llarp_init_threadpool(workers, "llarp-worker")); + } + } + else if(!strcmp(key, "net-threads")) + { + num_nethreads = atoi(val); + if(num_nethreads <= 0) + num_nethreads = 1; + if(singleThreaded) + num_nethreads = 0; + } + else if(!strcmp(key, "netid")) + { + metricTags["netid"] = val; + } + else if(!strcmp(key, "nickname")) + { + metricTags["nickname"] = val; + } } - - nodedb_dir = config->netdb.nodedb_dir; - - if(!config->metrics.disableMetrics) + if(!strcmp(section, "netdb")) { - auto &metricsConfig = config->metrics; - auto &tags = metricsConfig.metricTags; - tags["netid"] = config->router.netid; - tags["nickname"] = config->router.rc.Nick(); - setupMetrics(metricsConfig); - if(!config->metrics.disableMetricLogs) + if(!strcmp(key, "dir")) { - m_metricsManager->instance()->addGlobalPublisher( - std::make_shared< metrics::StreamPublisher >(std::cerr)); + nodedb_dir = val; } } - return true; } void - Context::setupMetrics(const MetricsConfig &metricsConfig) + Context::setupMetrics() { if(!m_scheduler) { @@ -110,15 +153,15 @@ namespace llarp *m_scheduler, m_metricsManager->instance()); } - if(!metricsConfig.jsonMetricsPath.native().empty()) + if(!jsonMetricsPath.native().empty()) { m_metricsManager->instance()->addGlobalPublisher( std::make_shared< metrics::JsonPublisher >( std::bind(&metrics::JsonPublisher::directoryPublisher, - std::placeholders::_1, metricsConfig.jsonMetricsPath))); + std::placeholders::_1, jsonMetricsPath))); } - if(!metricsConfig.metricTankHost.empty()) + if(!metricTankHost.empty()) { if(std::getenv("LOKINET_ENABLE_METRIC_TANK")) { @@ -143,11 +186,11 @@ __ ___ ____ _ _ ___ _ _ ____ std::cerr << WARNING << '\n'; std::pair< std::string, std::string > split = - absl::StrSplit(metricsConfig.metricTankHost, ':'); + absl::StrSplit(metricTankHost, ':'); m_metricsManager->instance()->addGlobalPublisher( std::make_shared< metrics::MetricTankPublisher >( - metricsConfig.metricTags, split.first, stoi(split.second))); + metricTags, split.first, stoi(split.second))); } else { diff --git a/llarp/exit/context.cpp b/llarp/exit/context.cpp index f8e995c92..8f798aa40 100644 --- a/llarp/exit/context.cpp +++ b/llarp/exit/context.cpp @@ -70,8 +70,8 @@ namespace llarp } } - exit::Endpoint* - Context::FindEndpointForPath(const PathID_t& path) const + llarp::exit::Endpoint* + Context::FindEndpointForPath(const llarp::PathID_t& path) const { auto itr = m_Exits.begin(); while(itr != m_Exits.end()) @@ -85,7 +85,7 @@ namespace llarp } bool - Context::ObtainNewExit(const PubKey& pk, const PathID_t& path, + Context::ObtainNewExit(const llarp::PubKey& pk, const llarp::PathID_t& path, bool permitInternet) { auto itr = m_Exits.begin(); @@ -106,13 +106,13 @@ namespace llarp auto itr = m_Exits.find(name); if(itr != m_Exits.end()) { - LogError("duplicate exit with name ", name); + llarp::LogError("duplicate exit with name ", name); return false; } } - std::unique_ptr< handlers::ExitEndpoint > endpoint; + std::unique_ptr< llarp::handlers::ExitEndpoint > endpoint; // make new endpoint - endpoint.reset(new handlers::ExitEndpoint(name, m_Router)); + endpoint.reset(new llarp::handlers::ExitEndpoint(name, m_Router)); // configure { auto itr = conf.begin(); @@ -120,7 +120,8 @@ namespace llarp { if(!endpoint->SetOption(itr->first, itr->second)) { - LogWarn("Couldn't set option ", itr->first, " to ", itr->second); + llarp::LogWarn("Couldn't set option ", itr->first, " to ", + itr->second); return false; } ++itr; @@ -129,7 +130,7 @@ namespace llarp // add endpoint if(!endpoint->Start()) { - LogWarn("Couldn't start exit endpoint"); + llarp::LogWarn("Couldn't start exit endpoint"); return false; } m_Exits.emplace(name, std::move(endpoint)); diff --git a/llarp/exit/context.hpp b/llarp/exit/context.hpp index 4dc10cb7d..b977c28f4 100644 --- a/llarp/exit/context.hpp +++ b/llarp/exit/context.hpp @@ -35,11 +35,11 @@ namespace llarp AddExitEndpoint(const std::string &name, const Config_t &config); bool - ObtainNewExit(const PubKey &remote, const PathID_t &path, + ObtainNewExit(const llarp::PubKey &remote, const llarp::PathID_t &path, bool permitInternet); - exit::Endpoint * - FindEndpointForPath(const PathID_t &path) const; + llarp::exit::Endpoint * + FindEndpointForPath(const llarp::PathID_t &path) const; /// calculate (pk, tx, rx) for all exit traffic using TrafficStats = @@ -52,9 +52,9 @@ namespace llarp private: AbstractRouter *m_Router; std::unordered_map< std::string, - std::shared_ptr< handlers::ExitEndpoint > > + std::shared_ptr< llarp::handlers::ExitEndpoint > > m_Exits; - std::list< std::shared_ptr< handlers::ExitEndpoint > > m_Closed; + std::list< std::shared_ptr< llarp::handlers::ExitEndpoint > > m_Closed; }; } // namespace exit } // namespace llarp diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index ad688d940..7dc659156 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -607,7 +607,6 @@ namespace llarp pk, path, !wantInternet, ip, this)); m_Paths[path] = pk; - return HasLocalMappedAddrFor(pk); } diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index 8bde2e224..676eb8988 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -104,7 +104,7 @@ namespace llarp return false; } else if(!GetIFAddr(ifname, m_ourAddr, af)) - m_ourAddr = Addr(ifname); + m_ourAddr = ifname; m_ourAddr.port(port); return llarp_ev_add_udp(m_Loop.get(), &m_udp, m_ourAddr) != -1; } diff --git a/llarp/net/net_addr.cpp b/llarp/net/net_addr.cpp index ac33a7f33..383c73ce8 100644 --- a/llarp/net/net_addr.cpp +++ b/llarp/net/net_addr.cpp @@ -63,14 +63,14 @@ namespace llarp return (const in_addr*)&_addr.sin6_addr.s6_addr[12]; } - Addr::Addr(string_view str) + Addr::Addr(const std::string str) { - this->from_char_array(str); + this->from_char_array(str.c_str()); } - Addr::Addr(string_view str, const uint16_t p_port) + Addr::Addr(const std::string str, const uint16_t p_port) { - this->from_char_array(str); + this->from_char_array(str.c_str()); this->port(p_port); } @@ -81,17 +81,25 @@ namespace llarp } bool - Addr::from_char_array(string_view in) + Addr::from_char_array(const char* in) { - auto str = in.begin(); - auto pPosition = in.find(':'); - if(pPosition != string_view::npos) + char* str = (char*)in; + char* pPosition = strchr(str, ':'); + bool freeStr = false; + if(pPosition) { // parse port - uint16_t port = - std::atoi(std::string(in.begin() + pPosition + 1, in.end()).c_str()); + char buf[6]; + snprintf(buf, 6, "%s", pPosition + 1); + uint16_t port = std::atoi(buf); LogDebug("Setting port ", std::to_string(port)); this->port(port); + // trim str + // can't VLA + str = strdup(in); // copy it + str[pPosition - in] = '\0'; // nul terminate it early + LogDebug("Truncating to ", str); + freeStr = true; } Zero(&_addr, sizeof(sockaddr_in6)); struct addrinfo hint, *res = NULL; @@ -102,30 +110,27 @@ namespace llarp hint.ai_family = PF_UNSPEC; hint.ai_flags = AI_NUMERICHOST; - if(pPosition != string_view::npos) - { - ret = getaddrinfo(std::string(in.begin(), in.begin() + pPosition).c_str(), - NULL, &hint, &res); - } - else - { - ret = getaddrinfo(std::string(in).c_str(), NULL, &hint, &res); - } - + ret = getaddrinfo(str, NULL, &hint, &res); if(ret) { LogError("failed to determine address family: ", str); + if(freeStr) + free(str); return false; } if(res->ai_family == AF_INET6) { LogError("IPv6 address not supported yet", str); + if(freeStr) + free(str); return false; } else if(res->ai_family != AF_INET) { LogError("Address family not supported yet", str); + if(freeStr) + free(str); return false; } @@ -134,8 +139,12 @@ namespace llarp if(inet_aton(str, addr) == 0) { LogError("failed to parse ", str); + if(freeStr) + free(str); return false; } + if(freeStr) + free(str); _addr.sin6_family = res->ai_family; _addr4.sin_family = res->ai_family; @@ -153,6 +162,11 @@ namespace llarp return true; } + Addr::Addr(const char* str) + { + this->from_char_array(str); + } + bool Addr::from_4int(const uint8_t one, const uint8_t two, const uint8_t three, const uint8_t four) diff --git a/llarp/net/net_addr.hpp b/llarp/net/net_addr.hpp index 8ee0691d0..c469ae0d2 100644 --- a/llarp/net/net_addr.hpp +++ b/llarp/net/net_addr.hpp @@ -23,12 +23,6 @@ namespace llarp Addr(const Addr& other); - Addr(string_view str); - - Addr(string_view str, const uint16_t p_port); - - Addr(string_view addr_str, string_view port_str); - void port(uint16_t port); @@ -44,8 +38,16 @@ namespace llarp const in_addr* addr4() const; + Addr(const std::string str); + + Addr(const std::string str, const uint16_t p_port); + + Addr(string_view addr_str, string_view port_str); + bool - from_char_array(string_view str); + from_char_array(const char* str); + + Addr(const char* str); bool from_4int(const uint8_t one, const uint8_t two, const uint8_t three, diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index a4a48db55..981e201b0 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include #include @@ -464,8 +464,7 @@ namespace llarp bool Router::Configure(Config *conf) { - fromConfig(conf); - + conf->visit(util::memFn(&Router::router_iter_config, this)); if(!InitOutboundLinks()) return false; if(!Ready()) @@ -767,142 +766,260 @@ namespace llarp } void - Router::fromConfig(Config *conf) + Router::router_iter_config(const char *section, const char *key, + const char *val) { - // IWP config - m_OutboundPort = conf->iwp_links.m_OutboundPort; + llarp::LogDebug(section, " ", key, "=", val); - for(const auto &serverConfig : conf->iwp_links.servers) + int af; + uint16_t proto = 0; + std::set< std::string > opts; + if(StrEq(val, "eth")) + { +#ifdef AF_LINK + af = AF_LINK; +#endif +#ifdef AF_PACKET + af = AF_PACKET; +#endif + proto = LLARP_ETH_PROTO; + } + else if(StrEq(section, "bind")) { - auto server = llarp::utp::NewServerFromRouter(this); - if(!server->EnsureKeys(transport_keyfile.string().c_str())) + // try IPv4 first + af = AF_INET; + std::set< std::string > parsed_opts; + std::string v = val; + std::string::size_type idx; + do { - llarp::LogError("failed to ensure keyfile ", transport_keyfile); - return; - } + idx = v.find_first_of(','); + if(idx != std::string::npos) + { + parsed_opts.insert(v.substr(0, idx)); + v = v.substr(idx + 1); + } + else + parsed_opts.insert(v); + } while(idx != std::string::npos); - const auto &key = std::get< 0 >(serverConfig); - int af = std::get< 1 >(serverConfig); - uint16_t port = std::get< 2 >(serverConfig); - if(server->Configure(netloop(), key, af, port)) + /// for each option + for(const auto &item : parsed_opts) { - AddLink(std::move(server), true); - return; + /// see if it's a number + auto port = std::atoi(item.c_str()); + if(port > 0) + { + /// set port + if(proto == 0) + proto = port; + } /// otherwise add to opts + else + opts.insert(item); } - LogError("failed to bind inbound link on ", key, " port ", port); } - // set network config - netConfig = conf->network.netConfig; - - // Network config - if(conf->network.enableProfiling.has_value()) + if(StrEq(section, "bind")) { - if(conf->network.enableProfiling.value()) + if(StrEq(key, "*")) { - routerProfiling().Enable(); - LogInfo("router profiling explicitly enabled"); + m_OutboundPort = proto; } else { - routerProfiling().Disable(); - LogInfo("router profiling explicitly disabled"); + auto server = llarp::utp::NewServerFromRouter(this); + if(!server->EnsureKeys(transport_keyfile.string().c_str())) + { + llarp::LogError("failed to ensure keyfile ", transport_keyfile); + return; + } + if(server->Configure(netloop(), key, af, proto)) + { + AddLink(std::move(server), true); + return; + } + LogError("failed to bind inbound link on ", key, " port ", proto); } } - - if(!conf->network.routerProfilesFile.empty()) + else if(StrEq(section, "network")) { - routerProfilesFile = conf->network.routerProfilesFile; - routerProfiling().Load(routerProfilesFile.c_str()); - llarp::LogInfo("setting profiles to ", routerProfilesFile); - } - - if(!conf->network.strictConnect.empty()) - { - const auto &val = conf->network.strictConnect; - if(IsServiceNode()) + if(StrEq(key, "profiling")) { - llarp::LogError("cannot use strict-connect option as service node"); - return; + if(IsTrueValue(val)) + { + routerProfiling().Enable(); + LogInfo("router profiling explicitly enabled"); + } + else if(IsFalseValue(val)) + { + routerProfiling().Disable(); + LogInfo("router profiling explicitly disabled"); + } } - llarp::RouterID snode; - llarp::PubKey pk; - if(pk.FromString(val)) + if(StrEq(key, "profiles")) { - if(strictConnectPubkeys.emplace(pk).second) - llarp::LogInfo("added ", pk, " to strict connect list"); - else - llarp::LogWarn("duplicate key for strict connect: ", pk); + routerProfilesFile = val; + routerProfiling().Load(val); + llarp::LogInfo("setting profiles to ", routerProfilesFile); } - else if(snode.FromString(val)) + else if(StrEq(key, "strict-connect")) { - if(strictConnectPubkeys.insert(snode).second) + if(IsServiceNode()) + { + llarp::LogError("cannot use strict-connect option as service node"); + return; + } + llarp::RouterID snode; + llarp::PubKey pk; + if(pk.FromString(val)) { - llarp::LogInfo("added ", snode, " to strict connect list"); - netConfig.emplace("strict-connect", val); + if(strictConnectPubkeys.emplace(pk).second) + llarp::LogInfo("added ", pk, " to strict connect list"); + else + llarp::LogWarn("duplicate key for strict connect: ", pk); + } + else if(snode.FromString(val)) + { + if(strictConnectPubkeys.insert(snode).second) + { + llarp::LogInfo("added ", snode, " to strict connect list"); + netConfig.emplace(key, val); + } + else + llarp::LogWarn("duplicate key for strict connect: ", snode); } else - llarp::LogWarn("duplicate key for strict connect: ", snode); + llarp::LogError("invalid key for strict-connect: ", val); } else - llarp::LogError("invalid key for strict-connect: ", val); + { + netConfig.emplace(key, val); + } } - - - // API config - enableRPCServer = conf->api.enableRPCServer; - rpcBindAddr = conf->api.rpcBindAddr; - - // Services config - for(const auto &service : conf->services.services) + else if(StrEq(section, "api")) + { + if(StrEq(key, "enabled")) + { + enableRPCServer = IsTrueValue(val); + } + if(StrEq(key, "bind")) + { + rpcBindAddr = val; + } + if(StrEq(key, "authkey")) + { + // TODO: add pubkey to whitelist + } + } + else if(StrEq(section, "services")) { - if(LoadHiddenServiceConfig(service.second)) + if(LoadHiddenServiceConfig(val)) { - llarp::LogInfo("loaded hidden service config for ", service.first); + llarp::LogInfo("loaded hidden service config for ", key); } else { - llarp::LogWarn("failed to load hidden service config for ", - service.first); + llarp::LogWarn("failed to load hidden service config for ", key); } } - - // Logging config - - auto logfile = conf->logging.m_LogFile; - - if(conf->logging.m_LogJSON) + else if(StrEq(section, "logging")) { - LogContext::Instance().logStream = std::make_unique< JSONLogStream >( - diskworker(), logfile, 100, logfile != stdout); + if(strlen(key) == 0 && strlen(val) == 0) + { + if(m_LogJSON) + { + LogContext::Instance().logStream = std::make_unique< JSONLogStream >( + diskworker(), m_LogFile, 100, m_LogFile != stdout); + } + else if(m_LogFile != stdout) + { + LogContext::Instance().logStream = std::make_unique< FileLogStream >( + diskworker(), m_LogFile, 100, true); + } + } + if(StrEq(key, "type") && StrEq(val, "syslog")) + { + // TODO(despair): write event log syslog class +#if defined(_WIN32) + LogError("syslog not supported on win32"); +#else + LogInfo("Switching to syslog"); + LogContext::Instance().logStream = std::make_unique< SysLogStream >(); +#endif + } + if(StrEq(key, "type") && StrEq(val, "json")) + { + m_LogJSON = true; + } + if(StrEq(key, "file")) + { + LogInfo("open log file: ", val); + FILE *const logfile = ::fopen(val, "a"); + if(logfile) + { + m_LogFile = logfile; + LogInfo("will log to file ", val); + } + else if(errno) + { + LogError("could not open log file at '", val, "': ", strerror(errno)); + errno = 0; + } + else + { + LogError("failed to open log file at '", val, + "' for an unknown reason, bailing tf out kbai"); + ::abort(); + } + } } - else if(logfile != stdout) + else if(StrEq(section, "lokid")) { - LogContext::Instance().logStream = - std::make_unique< FileLogStream >(diskworker(), logfile, 100, true); + if(StrEq(key, "service-node-seed")) + { + usingSNSeed = true; + ident_keyfile = val; + } + if(StrEq(key, "enabled")) + { + whitelistRouters = IsTrueValue(val); + } + if(StrEq(key, "jsonrpc") || StrEq(key, "addr")) + { + lokidRPCAddr = val; + } + if(StrEq(key, "username")) + { + lokidRPCUser = val; + } + if(StrEq(key, "password")) + { + lokidRPCPassword = val; + } } - - // Lokid Config - usingSNSeed = conf->lokid.usingSNSeed; - ident_keyfile = conf->lokid.ident_keyfile; - whitelistRouters = conf->lokid.whitelistRouters; - lokidRPCAddr = conf->lokid.lokidRPCAddr; - lokidRPCUser = conf->lokid.lokidRPCUser; - lokidRPCPassword = conf->lokid.lokidRPCPassword; - - netConfig.insert(conf->dns.netConfig.begin(), conf->dns.netConfig.end()); - - std::vector< std::string > configRouters = conf->connect.routers; - configRouters.insert(configRouters.end(), conf->bootstrap.routers.begin(), - conf->bootstrap.routers.end()); - for(const auto &router : configRouters) + else if(StrEq(section, "dns")) + { + if(StrEq(key, "upstream")) + { + llarp::LogInfo("add upstream resolver ", val); + netConfig.emplace("upstream-dns", val); + } + if(StrEq(key, "bind")) + { + llarp::LogInfo("set local dns to ", val); + netConfig.emplace("local-dns", val); + } + } + else if(StrEq(section, "connect") + || (StrEq(section, "bootstrap") && StrEq(key, "add-node"))) { // llarp::LogDebug("connect section has ", key, "=", val); RouterContact rc; - if(!rc.Read(router.c_str())) + if(!rc.Read(val)) { - llarp::LogWarn("failed to decode bootstrap RC, file='", router, + llarp::LogWarn("failed to decode bootstrap RC, file='", val, "' rc=", rc); + ; return; } if(rc.Verify(Now())) @@ -922,25 +1039,98 @@ namespace llarp } else { - llarp::LogError("malformed rc file='", router, "' rc=", rc); + llarp::LogError("malformed rc file='", val, "' rc=", rc); } } } - - // Router config - _rc = conf->router.rc; - maxConnectedRouters = conf->router.maxConnectedRouters; - minConnectedRouters = conf->router.minConnectedRouters; - encryption_keyfile = conf->router.encryption_keyfile; - our_rc_file = conf->router.our_rc_file; - transport_keyfile = conf->router.transport_keyfile; - addrInfo = conf->router.addrInfo; - publicOverride = conf->router.publicOverride; - ip4addr = conf->router.ip4addr; - - if(!usingSNSeed) + else if(StrEq(section, "router")) { - ident_keyfile = conf->router.ident_keyfile; + if(StrEq(key, "netid")) + { + if(strlen(val) <= _rc.netID.size()) + { + llarp::LogWarn("!!!! you have manually set netid to be '", val, + "' which does not equal '", Version::LLARP_NET_ID, + "' you will run as a different network, good luck " + "and " + "don't forget: something something MUH traffic " + "shape " + "correlation !!!!"); + llarp::NetID::DefaultValue() = + llarp::NetID(reinterpret_cast< const byte_t * >(strdup(val))); + // re set netid in our rc + _rc.netID = llarp::NetID(); + } + else + llarp::LogError("invalid netid '", val, "', is too long"); + } + if(StrEq(key, "max-connections")) + { + auto ival = atoi(val); + if(ival > 0) + { + maxConnectedRouters = ival; + LogInfo("max connections set to ", maxConnectedRouters); + } + } + if(StrEq(key, "min-connections")) + { + auto ival = atoi(val); + if(ival > 0) + { + minConnectedRouters = ival; + LogInfo("min connections set to ", minConnectedRouters); + } + } + if(StrEq(key, "nickname")) + { + _rc.SetNick(val); + // set logger name here + LogContext::Instance().nodeName = rc().Nick(); + } + if(StrEq(key, "encryption-privkey")) + { + encryption_keyfile = val; + } + if(StrEq(key, "contact-file")) + { + our_rc_file = val; + } + if(StrEq(key, "transport-privkey")) + { + transport_keyfile = val; + } + if((StrEq(key, "identity-privkey") || StrEq(key, "ident-privkey")) + && !usingSNSeed) + { + ident_keyfile = val; + } + if(StrEq(key, "public-address") || StrEq(key, "public-ip")) + { + llarp::LogInfo("public ip ", val, " size ", strlen(val)); + if(strlen(val) < 17) + { + // assume IPv4 + // inet_pton(AF_INET, val, &ip4addr.sin_addr); + // struct sockaddr dest; + // sockaddr *dest = (sockaddr *)&ip4addr; + llarp::Addr a(val); + llarp::LogInfo("setting public ipv4 ", a); + addrInfo.ip = *a.addr6(); + publicOverride = true; + } + // llarp::Addr a(val); + } + if(StrEq(key, "public-port")) + { + llarp::LogInfo("Setting public port ", val); + int p = atoi(val); + // Not needed to flip upside-down - this is done in llarp::Addr(const + // AddressInfo&) + ip4addr.sin_port = p; + addrInfo.port = p; + publicOverride = true; + } } } @@ -1776,10 +1966,58 @@ namespace llarp return _exitContext.AddExitEndpoint("default-connectivity", netConfig); } + /// validate a new configuration against an already made and running + /// router + struct RouterConfigValidator + { + void + ValidateEntry(const char *section, const char *key, const char *val) + { + if(valid) + { + if(!OnEntry(section, key, val)) + { + LogError("invalid entry in section [", section, "]: '", key, "'='", + val, "'"); + valid = false; + } + } + } + + const Router *router; + Config *config; + bool valid; + RouterConfigValidator(const Router *r, Config *conf) + : router(r), config(conf), valid(true) + { + } + + /// checks the (section, key, value) config tuple + /// return false if that entry conflicts + /// with existing configuration in router + bool + OnEntry(const char *, const char *, const char *) const + { + // TODO: implement me + return true; + } + + /// do validation + /// return true if this config is valid + /// return false if this config is not valid + bool + Validate() + { + config->visit(util::memFn(&RouterConfigValidator::ValidateEntry, this)); + return valid; + } + }; + bool - Router::ValidateConfig(ABSL_ATTRIBUTE_UNUSED Config *conf) const + Router::ValidateConfig(Config *conf) const { - return true; + RouterConfigValidator validator(this, conf); + return validator.Validate(); } bool @@ -1857,7 +2095,7 @@ namespace llarp } bool - Router::LoadHiddenServiceConfig(string_view fname) + Router::LoadHiddenServiceConfig(const char *fname) { LogDebug("opening hidden service config ", fname); service::Config conf; diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index cebf57d7a..57381576d 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -260,15 +260,16 @@ namespace llarp ShouldCreateDefaultHiddenService(); const std::string DefaultRPCBindAddr = "127.0.0.1:1190"; - bool enableRPCServer = false; + bool enableRPCServer = true; std::unique_ptr< rpc::Server > rpcServer; std::string rpcBindAddr = DefaultRPCBindAddr; /// lokid caller + const std::string DefaultLokidRPCAddr = "127.0.0.1:22023"; std::unique_ptr< rpc::Caller > rpcCaller; - std::string lokidRPCAddr = "127.0.0.1:22023"; - std::string lokidRPCUser; - std::string lokidRPCPassword; + std::string lokidRPCAddr = DefaultLokidRPCAddr; + std::string lokidRPCUser = ""; + std::string lokidRPCPassword = ""; using LinkSet = std::set< LinkLayer_ptr, ComparePtr< LinkLayer_ptr > >; @@ -304,6 +305,11 @@ namespace llarp // set to max value right now std::unordered_map< RouterID, llarp_time_t, PubKey::Hash > lokinetRouters; + // set to true if we are configured to run with json logging + bool m_LogJSON = false; + // the file we are logging to + FILE *m_LogFile = stdout; + Router(struct llarp_threadpool *tp, llarp_ev_loop_ptr __netloop, std::shared_ptr< Logic > logic); @@ -338,7 +344,7 @@ namespace llarp Close(); bool - LoadHiddenServiceConfig(string_view fname); + LoadHiddenServiceConfig(const char *fname); bool AddHiddenService(const service::Config::section_t &config); @@ -566,7 +572,7 @@ namespace llarp } void - fromConfig(Config *conf); + router_iter_config(const char *section, const char *key, const char *val); }; } // namespace llarp diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index 973ec7a92..8321f756c 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -223,7 +223,7 @@ namespace llarp } void - RouterContact::SetNick(string_view nick) + RouterContact::SetNick(const std::string &nick) { nickname.Zero(); std::copy(nick.begin(), diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index fb31d6db4..4226ab02e 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -162,7 +162,7 @@ namespace llarp IsPublicRouter() const; void - SetNick(string_view nick); + SetNick(const std::string &nick); bool Verify(llarp_time_t now, bool allowExpired = true) const; diff --git a/llarp/service/config.cpp b/llarp/service/config.cpp index a33dcfd95..84e3a6585 100644 --- a/llarp/service/config.cpp +++ b/llarp/service/config.cpp @@ -1,16 +1,16 @@ #include -#include +#include namespace llarp { namespace service { bool - Config::Load(string_view fname) + Config::Load(const std::string& fname) { ConfigParser parser; - if(!parser.LoadFile(fname)) + if(!parser.LoadFile(fname.c_str())) return false; parser.IterAll([&](const ConfigParser::String_t& name, const ConfigParser::Section_t& section) { diff --git a/llarp/service/config.hpp b/llarp/service/config.hpp index ec0401bc8..1f8d9cbe2 100644 --- a/llarp/service/config.hpp +++ b/llarp/service/config.hpp @@ -1,8 +1,5 @@ #ifndef LLARP_SERVICE_CONFIG_HPP #define LLARP_SERVICE_CONFIG_HPP - -#include - #include #include @@ -19,7 +16,7 @@ namespace llarp std::list< section_t > services; bool - Load(string_view fname); + Load(const std::string& fname); }; } // namespace service } // namespace llarp diff --git a/llarp/config/ini.cpp b/llarp/util/ini.cpp similarity index 94% rename from llarp/config/ini.cpp rename to llarp/util/ini.cpp index 70f8df1ae..0f7c4bb69 100644 --- a/llarp/config/ini.cpp +++ b/llarp/util/ini.cpp @@ -1,9 +1,8 @@ -#include -#include - +#include #include #include #include +#include #ifdef LoadString #undef LoadString @@ -12,11 +11,10 @@ namespace llarp { bool - ConfigParser::LoadFile(string_view fname) + ConfigParser::LoadFile(const char* fname) { - std::string name{fname}; { - std::ifstream f(name, std::ios::in | std::ios::binary); + std::ifstream f(fname, std::ios::in | std::ios::binary); if(!f.is_open()) return false; f.seekg(0, std::ios::end); @@ -26,12 +24,12 @@ namespace llarp return false; f.read(m_Data.data(), m_Data.size()); } - m_FileName = name; + m_FileName = fname; return Parse(); } bool - ConfigParser::LoadString(string_view str) + ConfigParser::LoadString(const std::string& str) { m_Data.resize(str.size()); std::copy(str.begin(), str.end(), m_Data.begin()); diff --git a/llarp/config/ini.hpp b/llarp/util/ini.hpp similarity index 94% rename from llarp/config/ini.hpp rename to llarp/util/ini.hpp index 1610dcea6..4bd2a627b 100644 --- a/llarp/config/ini.hpp +++ b/llarp/util/ini.hpp @@ -1,11 +1,9 @@ #ifndef LOKINET_BOOTSERV_CONFIG_HPP #define LOKINET_BOOTSERV_CONFIG_HPP - +#include #include - #include #include -#include #include namespace llarp @@ -25,13 +23,13 @@ namespace llarp /// return true on success /// return false on error bool - LoadFile(string_view fname); + LoadFile(const char* fname); /// load from string /// return true on success /// return false on error bool - LoadString(string_view str); + LoadString(const std::string& str); /// iterate all sections and thier values void diff --git a/llarp/util/str.cpp b/llarp/util/str.cpp index 6469f8003..ed911975b 100644 --- a/llarp/util/str.cpp +++ b/llarp/util/str.cpp @@ -3,57 +3,25 @@ #include #include #include -#include namespace llarp { bool - CaselessCmp::operator()(string_view lhs, string_view rhs) const + IsFalseValue(const char* str) { - if(lhs.size() < rhs.size()) - { - return true; - } - else if(lhs.size() > rhs.size()) - { - return false; - } - else - { - for(size_t i = 0; i < lhs.size(); ++i) - { - auto l = std::tolower(lhs[i]); - auto r = std::tolower(rhs[i]); - - if(l < r) - { - return true; - } - else if(l > r) - { - return false; - } - } - return false; - } - } - - bool - IsFalseValue(string_view str) - { - static const std::set< string_view, CaselessCmp > vals{"no", "false", "0", - "off"}; - - return vals.count(str) > 0; + std::string value = str; + std::transform(value.begin(), value.end(), value.begin(), + [](char ch) -> char { return std::tolower(ch); }); + return value == "no" || value == "false" || value == "0" || value == "off"; } bool - IsTrueValue(string_view str) + IsTrueValue(const char* str) { - static const std::set< string_view, CaselessCmp > vals{"yes", "true", "1", - "on"}; - - return vals.count(str) > 0; + std::string value = str; + std::transform(value.begin(), value.end(), value.begin(), + [](char ch) -> char { return std::tolower(ch); }); + return value == "yes" || value == "true" || value == "1" || value == "on"; } bool diff --git a/llarp/util/str.hpp b/llarp/util/str.hpp index 7468a4d5e..505de5292 100644 --- a/llarp/util/str.hpp +++ b/llarp/util/str.hpp @@ -1,24 +1,16 @@ #ifndef LLARP_STR_HPP #define LLARP_STR_HPP -#include - namespace llarp { bool StrEq(const char *s1, const char *s2); bool - IsFalseValue(string_view str); - - struct CaselessCmp - { - bool - operator()(string_view lhs, string_view rhs) const; - }; + IsFalseValue(const char *str); bool - IsTrueValue(string_view str); + IsTrueValue(const char *str); } // namespace llarp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 54b5a4dea..fad7fd87d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,7 +1,6 @@ set(TEST_EXE testAll) list(APPEND TEST_SRC - config/test_llarp_config_ini.cpp crypto/test_llarp_crypto_types.cpp crypto/test_llarp_crypto.cpp dht/test_llarp_dht_bucket.cpp @@ -37,6 +36,7 @@ list(APPEND TEST_SRC util/test_llarp_util_bencode.cpp util/test_llarp_util_bits.cpp util/test_llarp_util_encode.cpp + util/test_llarp_util_ini.cpp util/test_llarp_util_metrics_core.cpp util/test_llarp_util_metrics_types.cpp util/test_llarp_util_memfn.cpp @@ -48,7 +48,6 @@ list(APPEND TEST_SRC util/test_llarp_util_timerqueue.cpp util/test_llarp_util_traits.cpp util/test_llarp_utils_scheduler.cpp - util/test_llarp_utils_str.cpp ) add_executable(${TEST_EXE} @@ -73,4 +72,4 @@ endif(NOT WIN32) if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") target_link_directories(${TEST_EXE} PRIVATE /usr/local/lib) -endif() +endif() \ No newline at end of file diff --git a/test/exit/test_llarp_exit_context.cpp b/test/exit/test_llarp_exit_context.cpp index 6a0d4b699..db5e504da 100644 --- a/test/exit/test_llarp_exit_context.cpp +++ b/test/exit/test_llarp_exit_context.cpp @@ -1,18 +1,15 @@ #include #include -#include #include struct ExitTest : public ::testing::Test { - ExitTest() : r(nullptr, nullptr, nullptr), context(&r) + ExitTest() : r(nullptr, nullptr, nullptr) { } - llarp::Router r; - llarp::exit::Context context; }; TEST_F(ExitTest, AddMultipleIP) @@ -26,10 +23,9 @@ TEST_F(ExitTest, AddMultipleIP) conf.emplace("exit", "true"); conf.emplace("type", "null"); conf.emplace("ifaddr", "10.0.0.1/24"); - - ASSERT_TRUE(context.AddExitEndpoint("test-exit", conf)); - ASSERT_TRUE(context.ObtainNewExit(pk, firstPath, true)); - ASSERT_TRUE(context.ObtainNewExit(pk, secondPath, true)); - ASSERT_TRUE(context.FindEndpointForPath(firstPath)->LocalIP() - == context.FindEndpointForPath(secondPath)->LocalIP()); + ASSERT_TRUE(r.exitContext().AddExitEndpoint("test-exit", conf)); + ASSERT_TRUE(r.exitContext().ObtainNewExit(pk, firstPath, true)); + ASSERT_TRUE(r.exitContext().ObtainNewExit(pk, secondPath, true)); + ASSERT_TRUE(r.exitContext().FindEndpointForPath(firstPath)->LocalIP() + == r.exitContext().FindEndpointForPath(secondPath)->LocalIP()); } diff --git a/test/config/test_llarp_config_ini.cpp b/test/util/test_llarp_util_ini.cpp similarity index 98% rename from test/config/test_llarp_config_ini.cpp rename to test/util/test_llarp_util_ini.cpp index 64081ff67..b3fa9947b 100644 --- a/test/config/test_llarp_config_ini.cpp +++ b/test/util/test_llarp_util_ini.cpp @@ -1,6 +1,6 @@ #include -#include +#include struct TestINIParser : public ::testing::Test { diff --git a/test/util/test_llarp_utils_str.cpp b/test/util/test_llarp_utils_str.cpp deleted file mode 100644 index 7836c3132..000000000 --- a/test/util/test_llarp_utils_str.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include - -#include -#include - -using namespace llarp; -using namespace ::testing; - -struct CmpTestData -{ - bool lt; - std::string lhs; - std::string rhs; -}; - -class CaselessCmpTest : public ::testing::TestWithParam< CmpTestData > -{ -}; - -TEST_P(CaselessCmpTest, test) -{ - CaselessCmp cmp; - auto d = GetParam(); - ASSERT_EQ(d.lt, cmp(d.lhs, d.rhs)); -} - -std::vector< CmpTestData > CMPTESTDATA{ - {true, "", "1"}, {false, "1", ""}, {true, "abc", "abcd"}, - {true, "abc", "abd"}, {false, "11", "1"}, {false, "a", "A"}, - {false, "abc", "aBc"}, {false, "ABC", "abc"}}; - -INSTANTIATE_TEST_SUITE_P(TestStr, CaselessCmpTest, ValuesIn(CMPTESTDATA)); - -using TestData = std::pair< bool, std::string >; - -class TestIsFalseValue : public ::testing::TestWithParam< TestData > -{ -}; - -TEST_P(TestIsFalseValue, test) -{ - ASSERT_EQ(GetParam().first, IsFalseValue(GetParam().second)); -} - -std::vector< TestData > FALSE_DATA{ - {true, "false"}, {true, "FaLsE"}, {true, "no"}, {true, "nO"}, - {true, "No"}, {true, "NO"}, {true, "NO"}, {true, "0"}, - {true, "off"}, {true, "oFF"}, {false, "false y"}, {false, "true"}, - {false, "tRue"}, {false, "on"}}; - -INSTANTIATE_TEST_SUITE_P(TestStr, TestIsFalseValue, ValuesIn(FALSE_DATA)); - -class TestIsTrueValue : public ::testing::TestWithParam< TestData > -{ -}; - -TEST_P(TestIsTrueValue, test) -{ - ASSERT_EQ(GetParam().first, IsTrueValue(GetParam().second)); -} - -std::vector< TestData > TRUE_DATA{ - {true, "true"}, {true, "TruE"}, {true, "yes"}, {true, "yeS"}, - {true, "yES"}, {true, "YES"}, {true, "1"}, {false, "0"}, - {true, "on"}, {true, "oN"}, {false, "false y"}, {false, "truth"}, - {false, "false"}, {false, "off"}}; - -INSTANTIATE_TEST_SUITE_P(TestStr, TestIsTrueValue, ValuesIn(TRUE_DATA));