From 5c6c6bcfeef0ec9a89a971beedc493814e0a1795 Mon Sep 17 00:00:00 2001 From: dr7ana Date: Fri, 3 Nov 2023 15:11:35 -0700 Subject: [PATCH] config addr change - the one addr to rule them all, and its name was oxen::quic::Address - no more vectors of inbound/outbound junk --- llarp/config/config.cpp | 213 +++++++++++++++++++++++++--------------- llarp/config/config.hpp | 7 +- llarp/crypto/types.cpp | 11 --- llarp/crypto/types.hpp | 5 - llarp/exit/endpoint.hpp | 6 ++ llarp/handlers/exit.cpp | 8 +- llarp/net/net.hpp | 14 +-- llarp/net/posix.cpp | 7 +- llarp/net/win32.cpp | 2 +- 9 files changed, 155 insertions(+), 118 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index a586ee680..745e0c6de 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -909,9 +909,6 @@ namespace llarp const auto* net_ptr = params.Net_ptr(); - static constexpr Default DefaultInboundPort{uint16_t{1090}}; - static constexpr Default DefaultOutboundPort{uint16_t{0}}; - conf.define_option( "bind", "public-ip", @@ -936,48 +933,95 @@ namespace llarp }, [this](uint16_t arg) { public_port = net::port_t::from_host(arg); }); - auto parse_addr_for_link = [net_ptr]( - const std::string& arg, net::port_t default_port, bool inbound) { - std::optional addr = std::nullopt; + // DISCUSS: does this need to be an optional? + auto parse_addr_for_link = [net_ptr](const std::string& arg) { + std::optional maybe = std::nullopt; + std::string_view arg_v; + // explicitly provided value if (not arg.empty()) { - if (arg[0] == ':') - { - // port only case - default_port = net::port_t::from_string(arg.substr(1)); - if (!inbound) - addr = net_ptr->WildcardWithPort(default_port); - } - else - { - addr = SockAddr{arg}; - if (net_ptr->IsLoopbackAddress(addr->getIP())) - throw std::invalid_argument{fmt::format("{} is a loopback address", arg)}; - } + arg_v = std::string_view{arg}; } - if (not addr) + + if (arg_v[0] == ':') { - // infer public address - if (auto maybe_ifname = net_ptr->GetBestNetIF()) - addr = net_ptr->GetInterfaceAddr(*maybe_ifname); + uint16_t res = std::atoi(arg_v.substr(1).data()); + + maybe = oxen::quic::Address{""s, res ? res : DEFAULT_LISTEN_PORT}; } + else if (auto pos = arg_v.find(':'); pos != arg_v.npos) + { + auto h = arg_v.substr(0, pos); + uint16_t p = std::atoi(arg_v.substr(pos + 1).data()); + + maybe = oxen::quic::Address{std::string{h}, p}; - if (addr) + // TODO: unfuck llarp/net + // if (net_ptr->IsLoopbackAddress(addr->port())) + // throw std::invalid_argument{fmt::format("{} is a loopback address", arg)}; + } + if (not maybe) { - // set port if not explicitly provided - if (addr->getPort() == 0) - addr->setPort(default_port); + // infer public address + if (auto maybe_ifname = net_ptr->GetBestNetIF()) + maybe = oxen::quic::Address{*maybe_ifname}; } - return addr; + + if (maybe->port() == 0) + maybe = oxen::quic::Address{maybe->host(), DEFAULT_LISTEN_PORT}; + + return maybe; }; + conf.define_option( + "bind", + "listen", + Required, + Comment{ + "********** NEW API OPTION (see note) **********", + "", + "IP and/or port for lokinet to bind to for inbound/outbound connections.", + "", + "If IP is omitted then lokinet will search for a local network interface with a", + "public IP address and use that IP (and will exit with an error if no such IP is found", + "on the system). If port is omitted then lokinet defaults to 1090.", + "", + "Note: only one address will be accepted. If this option is not specified, it will " + "default", + "to the inbound or outbound value. Conversely, specifying this option will supercede " + "the", + "deprecated inbound/outbound opts.", + "", + "Examples:", + " listen=15.5.29.5:443", + " listen=10.0.2.2", + " listen=:1234", + "", + "Using a private range IP address (like the second example entry) will require using", + "the public-ip= and public-port= to specify the public IP address at which this", + "router can be reached.", + }, + [this, parse_addr_for_link](const std::string& arg) { + if (auto a = parse_addr_for_link(arg); a and a->is_addressable()) + addr = a; + else + addr = oxen::quic::Address{""s, DEFAULT_LISTEN_PORT}; + + using_new_api = true; + }); + conf.define_option( "bind", "inbound", RelayOnly, MultiValue, Comment{ + "********** DEPRECATED **********", + "Note: the new API dictates the lokinet bind address through the 'listen' config", + "parameter. Only ONE address will be read (no more lists of inbounds). Any address", + "passed to `listen` will supersede the", + "", "IP and/or port to listen on for incoming connections.", "", "If IP is omitted then lokinet will search for a local network interface with a", @@ -994,9 +1038,13 @@ namespace llarp "router can be reached.", }, [this, parse_addr_for_link](const std::string& arg) { - auto default_port = net::port_t::from_host(DefaultInboundPort.val); - if (auto addr = parse_addr_for_link(arg, default_port, /*inbound=*/true)) - inbound_listen_addrs.emplace_back(std::move(*addr)); + if (using_new_api) + throw std::runtime_error{"USE THE NEW API -- SPECIFY LOCAL ADDRESS UNDER [LISTEN]"}; + + if (auto a = parse_addr_for_link(arg); a and a->is_addressable()) + addr = a; + else + addr = oxen::quic::Address{""s, DEFAULT_LISTEN_PORT}; }); conf.define_option( @@ -1004,6 +1052,8 @@ namespace llarp "outbound", MultiValue, params.is_relay ? Comment{ + "********** THIS PARAMETER IS DEPRECATED -- USE 'LISTEN' INSTEAD **********", + "", "IP and/or port to use for outbound socket connections to other lokinet routers.", "", "If no outbound bind IP is configured, or the 0.0.0.0 wildcard IP is given, then", @@ -1021,6 +1071,8 @@ namespace llarp "The second example binds on the default incoming IP using port 9000; the third", "example binds on the given IP address using a random high port.", } : Comment{ + "********** DEPRECATED **********", + "", "IP and/or port to use for outbound socket connections to lokinet routers.", "", "If no outbound bind IP is configured then lokinet will use a wildcard IP address", @@ -1035,57 +1087,60 @@ namespace llarp "The second example binds on the wildcard address using port 9000; the third example", "binds on the given IP address using a random high port.", }, - [this, net_ptr, parse_addr_for_link](const std::string& arg) { - auto default_port = net::port_t::from_host(DefaultOutboundPort.val); - auto addr = parse_addr_for_link(arg, default_port, /*inbound=*/false); - if (not addr) - addr = net_ptr->WildcardWithPort(default_port); - outbound_links.emplace_back(std::move(*addr)); - }); + [this, parse_addr_for_link](const std::string& arg) { + if (using_new_api) + throw std::runtime_error{"USE THE NEW API -- SPECIFY LOCAL ADDRESS UNDER [LISTEN]"}; - conf.add_undeclared_handler( - "bind", [this, net_ptr](std::string_view, std::string_view key, std::string_view val) { - LogWarn( - "using the [bind] section with *=/IP=/INTERFACE= is deprecated; use the inbound= " - "and/or outbound= settings instead"); - std::optional addr; - // special case: wildcard for outbound - if (key == "*") - { - addr = net_ptr->Wildcard(); - // set port, zero is acceptable here. - if (auto port = std::stoi(std::string{val}); - port < std::numeric_limits::max()) - { - addr->setPort(port); - } - else - throw std::invalid_argument{fmt::format("invalid port value: '{}'", val)}; - outbound_links.emplace_back(std::move(*addr)); - return; - } - // try as interface name first - addr = net_ptr->GetInterfaceAddr(key, AF_INET); - if (addr and net_ptr->IsLoopbackAddress(addr->getIP())) - throw std::invalid_argument{fmt::format("{} is a loopback interface", key)}; - // try as ip address next, throws if unable to parse - if (not addr) - { - addr = SockAddr{key, huint16_t{0}}; - if (net_ptr->IsLoopbackAddress(addr->getIP())) - throw std::invalid_argument{fmt::format("{} is a loopback address", key)}; - } - // parse port and set if acceptable non zero value - if (auto port = std::stoi(std::string{val}); - port and port < std::numeric_limits::max()) - { - addr->setPort(port); - } + if (auto a = parse_addr_for_link(arg); a and a->is_addressable()) + addr = a; else - throw std::invalid_argument{fmt::format("invalid port value: '{}'", val)}; - - inbound_listen_addrs.emplace_back(std::move(*addr)); + addr = oxen::quic::Address{""s, DEFAULT_LISTEN_PORT}; }); + + // DISCUSS: drop this shit? + // conf.add_undeclared_handler( + // "bind", [this, net_ptr](std::string_view, std::string_view key, std::string_view val) { + // LogWarn( + // "using the [bind] section with *=/IP=/INTERFACE= is deprecated; use the inbound= " + // "and/or outbound= settings instead"); + // std::optional addr; + // // special case: wildcard for outbound + // if (key == "*") + // { + // addr = net_ptr->Wildcard(); + // // set port, zero is acceptable here. + // if (auto port = std::stoi(std::string{val}); + // port < std::numeric_limits::max()) + // { + // addr->setPort(port); + // } + // else + // throw std::invalid_argument{fmt::format("invalid port value: '{}'", val)}; + // outbound_links.emplace_back(std::move(*addr)); + // return; + // } + // // try as interface name first + // addr = net_ptr->GetInterfaceAddr(key, AF_INET); + // if (addr and net_ptr->IsLoopbackAddress(addr->getIP())) + // throw std::invalid_argument{fmt::format("{} is a loopback interface", key)}; + // // try as ip address next, throws if unable to parse + // if (not addr) + // { + // addr = SockAddr{key, huint16_t{0}}; + // if (net_ptr->IsLoopbackAddress(addr->getIP())) + // throw std::invalid_argument{fmt::format("{} is a loopback address", key)}; + // } + // // parse port and set if acceptable non zero value + // if (auto port = std::stoi(std::string{val}); + // port and port < std::numeric_limits::max()) + // { + // addr->setPort(port); + // } + // else + // throw std::invalid_argument{fmt::format("invalid port value: '{}'", val)}; + + // inbound_listen_addrs.emplace_back(std::move(*addr)); + // }); } void diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index ecee74bbf..624b22cb5 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -34,6 +34,8 @@ namespace llarp 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 /// parameters that need to be passed around. @@ -170,8 +172,9 @@ namespace llarp { std::optional public_addr; std::optional public_port; - std::vector outbound_links; - std::vector inbound_listen_addrs; + + std::optional addr; + bool using_new_api = false; void define_config_options(ConfigDefinition& conf, const ConfigGenParameters& params); diff --git a/llarp/crypto/types.cpp b/llarp/crypto/types.cpp index 092698e81..547c7e97a 100644 --- a/llarp/crypto/types.cpp +++ b/llarp/crypto/types.cpp @@ -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) { diff --git a/llarp/crypto/types.hpp b/llarp/crypto/types.hpp index 6e723fae5..39b7ad379 100644 --- a/llarp/crypto/types.hpp +++ b/llarp/crypto/types.hpp @@ -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 diff --git a/llarp/exit/endpoint.hpp b/llarp/exit/endpoint.hpp index 7405ce1f9..0e40a8dc5 100644 --- a/llarp/exit/endpoint.hpp +++ b/llarp/exit/endpoint.hpp @@ -86,6 +86,12 @@ namespace llarp return remote_signkey; } + RouterID + router_id() const + { + return remote_signkey.data(); + } + uint64_t TxRate() const { diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index 76c5415e9..3f710796f 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -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 remote; for (const auto& [path, pubkey] : paths) { - remote.insert(RouterID{pubkey}); + remote.insert(RouterID{pubkey.data()}); } return remote; } diff --git a/llarp/net/net.hpp b/llarp/net/net.hpp index 0c4b50700..c821c2879 100644 --- a/llarp/net/net.hpp +++ b/llarp/net/net.hpp @@ -121,21 +121,9 @@ namespace llarp return var::visit([](auto&& ip) { return not ip.n; }, ip); } - virtual std::optional + virtual std::optional GetBestNetIF(int af = AF_INET) const = 0; - inline std::optional - MaybeInferPublicAddr(port_t default_port, int af = AF_INET) const - { - std::optional 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 FindFreeRange() const = 0; diff --git a/llarp/net/posix.cpp b/llarp/net/posix.cpp index 5bf8c85f1..d48fbb39e 100644 --- a/llarp/net/posix.cpp +++ b/llarp/net/posix.cpp @@ -50,10 +50,11 @@ namespace llarp::net return ifname; } - std::optional + std::optional GetBestNetIF(int af) const override { - std::optional found; + std::optional 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; } } }); diff --git a/llarp/net/win32.cpp b/llarp/net/win32.cpp index b48798885..88b011b20 100644 --- a/llarp/net/win32.cpp +++ b/llarp/net/win32.cpp @@ -129,7 +129,7 @@ namespace llarp::net return "lokitun0"; } - std::optional + std::optional GetBestNetIF(int) const override { // TODO: implement me ?