Local router mode

- Up and running locally, no connections yet
- Next: flip testnet and do the gosh dang thing
pull/2227/head
dr7ana 5 months ago
parent ed6bd28a35
commit cef2ff7782

2
.gitignore vendored

@ -43,7 +43,7 @@ testnet_tmp
vsproject/
.vs
daemon.ini
*.ini
.gradle/

@ -77,6 +77,7 @@ namespace llarp
else
{
RemoteRC rc;
if (not rc.read(fpath))
{
throw std::runtime_error{

@ -19,14 +19,7 @@
namespace llarp
{
// constants for config file default values
constexpr int DefaultMinConnectionsForRouter = 6;
constexpr int DefaultMaxConnectionsForRouter = 60;
constexpr int DefaultMinConnectionsForClient = 4;
constexpr int DefaultMaxConnectionsForClient = 6;
constexpr int DefaultPublicPort = 1090;
constexpr int DEFAULT_PUBLIC_PORT = 1090;
using namespace config;
namespace
@ -72,38 +65,44 @@ namespace llarp
net_id = std::move(arg);
});
int minConnections =
(params.is_relay ? DefaultMinConnectionsForRouter : DefaultMinConnectionsForClient);
conf.define_option<int>(
"router",
"min-connections",
Default{minConnections},
"relay-connections",
Default{CLIENT_ROUTER_CONNECTIONS},
ClientOnly,
Comment{
"Minimum number of routers lokinet will attempt to maintain connections to.",
"Minimum number of routers lokinet client will attempt to maintain connections to.",
},
[=](int arg) {
if (arg < minConnections)
if (arg < CLIENT_ROUTER_CONNECTIONS)
throw std::invalid_argument{
fmt::format("min-connections must be >= {}", minConnections)};
fmt::format("Client relay connections must be >= {}", CLIENT_ROUTER_CONNECTIONS)};
min_connected_routers = arg;
client_router_connections = arg;
});
conf.define_option<int>(
"router",
"min-connections",
Deprecated,
Comment{
"Minimum number of routers lokinet will attempt to maintain connections to.",
},
[=](int) {
log::warning(
logcat, "Router min-connections is deprecated; use relay-connections for clients");
});
int maxConnections =
(params.is_relay ? DefaultMaxConnectionsForRouter : DefaultMaxConnectionsForClient);
conf.define_option<int>(
"router",
"max-connections",
Default{maxConnections},
Deprecated,
Comment{
"Maximum number (hard limit) of routers lokinet will be connected to at any time.",
},
[=](int arg) {
if (arg < maxConnections)
throw std::invalid_argument{
fmt::format("max-connections must be >= {}", maxConnections)};
max_connected_routers = arg;
[=](int) {
log::warning(
logcat, "Router max-connections is deprecated; use relay-connections for clients");
});
conf.define_option<std::string>("router", "nickname", Deprecated);
@ -159,7 +158,7 @@ namespace llarp
"router",
"public-port",
RelayOnly,
Default{DefaultPublicPort},
Default{DEFAULT_PUBLIC_PORT},
Comment{
"When specifying public-ip=, this specifies the public UDP port at which this lokinet",
"router is reachable. Required when public-ip is used.",
@ -1162,7 +1161,7 @@ namespace llarp
conf.define_option<bool>(
"lokid",
"disable-testing",
Default{true},
Default{false},
Hidden,
RelayOnly,
Comment{

@ -35,6 +35,7 @@ namespace llarp
using ConfigMap = llarp::ConfigParser::ConfigMap;
inline static constexpr uint16_t DEFAULT_LISTEN_PORT{1090};
constexpr int CLIENT_ROUTER_CONNECTIONS = 4;
// 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
@ -57,8 +58,7 @@ namespace llarp
struct RouterConfig
{
size_t min_connected_routers = 0;
size_t max_connected_routers = 0;
int client_router_connections{CLIENT_ROUTER_CONNECTIONS};
std::string net_id;

@ -10,20 +10,20 @@
namespace llarp
{
KeyManager::KeyManager() : m_initialized(false), m_needBackup(false)
KeyManager::KeyManager() : is_initialized(false), backup_keys(false)
{}
bool
KeyManager::initialize(const llarp::Config& config, bool genIfAbsent, bool isSNode)
KeyManager::initialize(const llarp::Config& config, bool gen_if_absent, bool is_snode)
{
if (m_initialized)
if (is_initialized)
return false;
if (not isSNode)
if (not is_snode)
{
crypto::identity_keygen(identityKey);
crypto::encryption_keygen(encryptionKey);
crypto::encryption_keygen(transportKey);
crypto::identity_keygen(identity_key);
crypto::encryption_keygen(encryption_key);
crypto::encryption_keygen(transport_key);
return true;
}
@ -46,80 +46,87 @@ namespace llarp
}
};
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);
rc_path = deriveFile(our_rc_filename, config.router.rc_file);
idkey_path = deriveFile(our_identity_filename, config.router.idkey_file);
enckey_path = deriveFile(our_enc_key_filename, config.router.enckey_file);
transkey_path = deriveFile(our_transport_key_filename, config.router.transkey_file);
RemoteRC rc;
bool exists = rc.read(m_rcPath);
if (not exists and not genIfAbsent)
{
LogError("Could not read RouterContact at path ", m_rcPath);
return false;
}
// we need to back up keys if our self.signed doesn't appear to have a
// valid signature
m_needBackup = (isSNode and not rc.verify());
// if our RC file can't be verified, assume it is out of date (e.g. uses
// older encryption) and needs to be regenerated. before doing so, backup
// files that will be overwritten
if (exists and m_needBackup)
if (auto exists = rc.read(rc_path); not exists)
{
if (!genIfAbsent)
if (not gen_if_absent)
{
LogError("Our RouterContact ", m_rcPath, " is invalid or out of date");
log::error(logcat, "Could not read RC at path {}", rc_path);
return false;
}
else
}
else
{
if (backup_keys = (is_snode and not rc.verify()); backup_keys)
{
LogWarn(
"Our RouterContact ",
m_rcPath,
" seems out of date, backing up and regenerating private keys");
auto err = "RC (path:{}) is invalid or out of date"_format(rc_path);
if (!backupKeyFilesByMoving())
if (not gen_if_absent)
{
LogError(
"Could not mv some key files, please ensure key files"
" are backed up if needed and remove");
log::error(logcat, err);
return false;
}
}
}
if (not config.router.is_relay)
{
// load identity key or create if needed
auto identityKeygen = [](llarp::SecretKey& key) {
// TODO: handle generating from service node seed
llarp::crypto::identity_keygen(key);
};
if (not loadOrCreateKey(m_idKeyPath, identityKey, identityKeygen))
return false;
log::warning(logcat, "{}; backing up and regenerating private keys...", err);
if (not copy_backup_keyfiles())
{
log::error(logcat, "Failed to copy-backup key files");
return false;
}
}
}
// load encryption key
auto encryptionKeygen = [](llarp::SecretKey& key) { llarp::crypto::encryption_keygen(key); };
if (not loadOrCreateKey(m_encKeyPath, encryptionKey, encryptionKeygen))
auto enckey_gen = [](llarp::SecretKey& key) { llarp::crypto::encryption_keygen(key); };
if (not keygen(enckey_path, encryption_key, enckey_gen))
{
log::critical(
logcat, "KeyManager::keygen failed to generate encryption key line:{}", __LINE__);
return false;
}
// TODO: transport key (currently done in LinkLayer)
auto transportKeygen = [](llarp::SecretKey& key) {
auto transkey_gen = [](llarp::SecretKey& key) {
key.Zero();
crypto::encryption_keygen(key);
};
if (not loadOrCreateKey(m_transportKeyPath, transportKey, transportKeygen))
if (not keygen(transkey_path, transport_key, transkey_gen))
{
log::critical(
logcat, "KeyManager::keygen failed to generate transport key line:{}", __LINE__);
return false;
}
m_initialized = true;
if (not config.router.is_relay)
{
// load identity key or create if needed
auto idkey_gen = [](llarp::SecretKey& key) {
// TODO: handle generating from service node seed
llarp::crypto::identity_keygen(key);
};
if (not keygen(idkey_path, identity_key, idkey_gen))
{
log::critical(
logcat, "KeyManager::keygen failed to generate identity key line:{}", __LINE__);
return false;
}
}
is_initialized = true;
return true;
}
bool
KeyManager::backupFileByMoving(const fs::path& filepath)
KeyManager::copy_backup_keyfile(const fs::path& filepath)
{
auto findFreeBackupFilename = [](const fs::path& filepath) {
for (int i = 0; i < 9; i++)
@ -136,6 +143,7 @@ namespace llarp
std::error_code ec;
bool exists = fs::exists(filepath, ec);
if (ec)
{
LogError("Could not determine status of file ", filepath, ": ", ec.message());
@ -168,13 +176,13 @@ namespace llarp
}
bool
KeyManager::backupKeyFilesByMoving() const
KeyManager::copy_backup_keyfiles() const
{
std::vector<fs::path> files = {m_rcPath, m_idKeyPath, m_encKeyPath, m_transportKeyPath};
std::vector<fs::path> files = {rc_path, idkey_path, enckey_path, transkey_path};
for (auto& filepath : files)
{
if (not backupFileByMoving(filepath))
if (not copy_backup_keyfile(filepath))
return false;
}
@ -182,7 +190,7 @@ namespace llarp
}
bool
KeyManager::loadOrCreateKey(
KeyManager::keygen(
fs::path path, llarp::SecretKey& key, std::function<void(llarp::SecretKey& key)> keygen)
{
if (not fs::exists(path))

@ -29,7 +29,7 @@ namespace llarp
/// @param filepath is the name of the original file to backup.
/// @return true if the file could be moved or didn't exist, false otherwise
static bool
backupFileByMoving(const fs::path& filepath);
copy_backup_keyfile(const fs::path& filepath);
/// Constructor
KeyManager();
@ -52,37 +52,37 @@ namespace llarp
/// @param rc (out) will be modified to contian the RouterContact
/// @return true on success, false otherwise
bool
getRouterContact(llarp::RouterContact& rc) const;
gen_rc(llarp::RouterContact& rc) const;
/// Return whether or not we need to backup keys as we load them
bool
needBackup() const
needs_backup() const
{
return m_needBackup;
return backup_keys;
}
llarp::SecretKey identityKey;
llarp::SecretKey encryptionKey;
llarp::SecretKey transportKey;
llarp::SecretKey identity_key;
llarp::SecretKey encryption_key;
llarp::SecretKey transport_key;
fs::path m_rcPath;
fs::path m_idKeyPath;
fs::path m_encKeyPath;
fs::path m_transportKeyPath;
fs::path rc_path;
fs::path idkey_path;
fs::path enckey_path;
fs::path transkey_path;
private:
std::atomic_bool m_initialized;
std::atomic_bool m_needBackup;
std::atomic_bool is_initialized;
std::atomic_bool backup_keys;
/// Backup each key file (by copying, e.g. foo -> foo.bak)
bool
backupKeyFilesByMoving() const;
copy_backup_keyfiles() const;
/// Load the key at a given filepath or create it
///
/// @param keygen is a function that will generate the key if needed
static bool
loadOrCreateKey(
keygen(
fs::path filepath,
llarp::SecretKey& key,
std::function<void(llarp::SecretKey& key)> keygen);

@ -13,19 +13,19 @@ namespace llarp::exit
Context::Tick(llarp_time_t now)
{
{
auto itr = m_Exits.begin();
while (itr != m_Exits.end())
auto itr = _exits.begin();
while (itr != _exits.end())
{
itr->second->Tick(now);
++itr;
}
}
{
auto itr = m_Closed.begin();
while (itr != m_Closed.end())
auto itr = _closed.begin();
while (itr != _closed.end())
{
if ((*itr)->ShouldRemove())
itr = m_Closed.erase(itr);
itr = _closed.erase(itr);
else
++itr;
}
@ -33,14 +33,14 @@ namespace llarp::exit
}
void
Context::Stop()
Context::stop()
{
auto itr = m_Exits.begin();
while (itr != m_Exits.end())
auto itr = _exits.begin();
while (itr != _exits.end())
{
itr->second->Stop();
m_Closed.emplace_back(std::move(itr->second));
itr = m_Exits.erase(itr);
_closed.emplace_back(std::move(itr->second));
itr = _exits.erase(itr);
}
}
@ -48,8 +48,8 @@ namespace llarp::exit
Context::ExtractStatus() const
{
util::StatusObject obj{};
auto itr = m_Exits.begin();
while (itr != m_Exits.end())
auto itr = _exits.begin();
while (itr != _exits.end())
{
obj[itr->first] = itr->second->ExtractStatus();
++itr;
@ -58,10 +58,10 @@ namespace llarp::exit
}
void
Context::CalculateExitTraffic(TrafficStats& stats)
Context::calculate_exit_traffic(TrafficStats& stats)
{
auto itr = m_Exits.begin();
while (itr != m_Exits.end())
auto itr = _exits.begin();
while (itr != _exits.end())
{
itr->second->CalculateTrafficStats(stats);
++itr;
@ -69,10 +69,10 @@ namespace llarp::exit
}
exit::Endpoint*
Context::FindEndpointForPath(const PathID_t& path) const
Context::find_endpoint_for_path(const PathID_t& path) const
{
auto itr = m_Exits.begin();
while (itr != m_Exits.end())
auto itr = _exits.begin();
while (itr != _exits.end())
{
auto ep = itr->second->FindEndpointByPath(path);
if (ep)
@ -83,10 +83,10 @@ namespace llarp::exit
}
bool
Context::ObtainNewExit(const PubKey& pk, const PathID_t& path, bool permitInternet)
Context::obtain_new_exit(const PubKey& pk, const PathID_t& path, bool permitInternet)
{
auto itr = m_Exits.begin();
while (itr != m_Exits.end())
auto itr = _exits.begin();
while (itr != _exits.end())
{
if (itr->second->AllocateNewExit(pk, path, permitInternet))
return true;
@ -96,9 +96,9 @@ namespace llarp::exit
}
std::shared_ptr<handlers::ExitEndpoint>
Context::GetExitEndpoint(std::string name) const
Context::get_exit_endpoint(std::string name) const
{
if (auto itr = m_Exits.find(name); itr != m_Exits.end())
if (auto itr = _exits.find(name); itr != _exits.end())
{
return itr->second;
}
@ -106,10 +106,10 @@ namespace llarp::exit
}
void
Context::AddExitEndpoint(
Context::add_exit_endpoint(
const std::string& name, const NetworkConfig& networkConfig, const DnsConfig& dnsConfig)
{
if (m_Exits.find(name) != m_Exits.end())
if (_exits.find(name) != _exits.end())
throw std::invalid_argument{fmt::format("An exit with name {} already exists", name)};
auto endpoint = std::make_unique<handlers::ExitEndpoint>(name, router);
@ -119,7 +119,7 @@ namespace llarp::exit
if (!endpoint->Start())
throw std::runtime_error{fmt::format("Failed to start endpoint {}", name)};
m_Exits.emplace(name, std::move(endpoint));
_exits.emplace(name, std::move(endpoint));
}
} // namespace llarp::exit

@ -18,37 +18,37 @@ namespace llarp::exit
Tick(llarp_time_t now);
void
ClearAllEndpoints();
clear_all_endpoints();
util::StatusObject
ExtractStatus() const;
/// send close to all exit sessions and remove all sessions
void
Stop();
stop();
void
AddExitEndpoint(
add_exit_endpoint(
const std::string& name, const NetworkConfig& networkConfig, const DnsConfig& dnsConfig);
bool
ObtainNewExit(const PubKey& remote, const PathID_t& path, bool permitInternet);
obtain_new_exit(const PubKey& remote, const PathID_t& path, bool permitInternet);
exit::Endpoint*
FindEndpointForPath(const PathID_t& path) const;
find_endpoint_for_path(const PathID_t& path) const;
/// calculate (pk, tx, rx) for all exit traffic
using TrafficStats = std::unordered_map<PubKey, std::pair<uint64_t, uint64_t>>;
void
CalculateExitTraffic(TrafficStats& stats);
calculate_exit_traffic(TrafficStats& stats);
std::shared_ptr<handlers::ExitEndpoint>
GetExitEndpoint(std::string name) const;
get_exit_endpoint(std::string name) const;
private:
Router* router;
std::unordered_map<std::string, std::shared_ptr<handlers::ExitEndpoint>> m_Exits;
std::list<std::shared_ptr<handlers::ExitEndpoint>> m_Closed;
std::unordered_map<std::string, std::shared_ptr<handlers::ExitEndpoint>> _exits;
std::list<std::shared_ptr<handlers::ExitEndpoint>> _closed;
};
} // namespace llarp::exit

@ -5,82 +5,38 @@
namespace llarp
{
Contacts::Contacts(const dht::Key_t& k, Router& r) : _local_key{k}, _router{r}
Contacts::Contacts(Router& r) : _router{r}, _local_key{r.pubkey()}
{
timer_keepalive = std::make_shared<int>(0);
_router.loop()->call_every(1s, timer_keepalive, [this]() { on_clean_contacts(); });
_rc_nodes = std::make_unique<dht::Bucket<dht::RCNode>>(_local_key, llarp::randint);
_introset_nodes = std::make_unique<dht::Bucket<dht::ISNode>>(_local_key, llarp::randint);
}
std::optional<service::EncryptedIntroSet>
Contacts::get_introset_by_location(const dht::Key_t& key) const
{
return _router.loop()->call_get([this, key]() -> std::optional<service::EncryptedIntroSet> {
auto& introsets = _introset_nodes->nodes;
std::optional<service::EncryptedIntroSet> enc = std::nullopt;
if (auto itr = introsets.find(key); itr != introsets.end())
return itr->second.introset;
auto& introsets = _introset_nodes->nodes;
return std::nullopt;
});
}
void
Contacts::on_clean_contacts()
{
const auto now = llarp::time_now_ms();
if (_rc_nodes)
{
auto& nodes = _rc_nodes->nodes;
auto itr = nodes.begin();
while (itr != nodes.end())
{
if (itr->second.rc.is_expired(now))
itr = nodes.erase(itr);
else
++itr;
}
}
if (auto itr = introsets.find(key); itr != introsets.end())
enc = itr->second.introset;
if (_introset_nodes)
{
auto& svcs = _introset_nodes->nodes;
auto itr = svcs.begin();
while (itr != svcs.end())
{
if (itr->second.introset.IsExpired(now))
itr = svcs.erase(itr);
else
++itr;
}
}
return enc;
}
util::StatusObject
Contacts::ExtractStatus() const
{
util::StatusObject obj{
{"nodes", _rc_nodes->ExtractStatus()},
{"services", _introset_nodes->ExtractStatus()},
{"local_key", _local_key.ToHex()}};
{"services", _introset_nodes->ExtractStatus()}, {"local_key", _local_key.ToHex()}};
return obj;
}
void
Contacts::put_rc_node_async(const dht::RCNode& val)
{
_router.loop()->call([this, val]() { _rc_nodes->PutNode(val); });
}
void
Contacts::delete_rc_node_async(const dht::Key_t& val)
Contacts::put_intro(service::EncryptedIntroSet enc)
{
_router.loop()->call([this, val]() { _rc_nodes->DelNode(val); });
_introset_nodes->PutNode(std::move(enc));
}
} // namespace llarp

@ -15,28 +15,14 @@ namespace llarp
private:
// TODO: why was this a shared ptr in the original implementation? revisit this
std::shared_ptr<int> timer_keepalive;
const dht::Key_t& _local_key;
Router& _router;
std::atomic<bool> transit_allowed{false};
const dht::Key_t _local_key;
// holds router contacts
std::unique_ptr<dht::Bucket<dht::RCNode>> _rc_nodes;
// holds introsets for remote services
std::unique_ptr<dht::Bucket<dht::ISNode>> _introset_nodes;
public:
Contacts(const dht::Key_t& local, Router& r);
/// Sets the value of transit_allowed to the value of `b`. Returns false if the
/// value was already b, true otherwise
bool
set_transit_allowed(bool b)
{
return not transit_allowed.exchange(b) == b;
}
void
on_clean_contacts();
Contacts(Router& r);
std::optional<service::EncryptedIntroSet>
get_introset_by_location(const dht::Key_t& key) const;
@ -46,16 +32,7 @@ namespace llarp
ExtractStatus() const;
void
put_rc_node_async(const dht::RCNode& val);
void
delete_rc_node_async(const dht::Key_t& val);
dht::Bucket<dht::RCNode>*
rc_nodes() const
{
return _rc_nodes.get();
}
put_intro(service::EncryptedIntroSet enc);
dht::Bucket<dht::ISNode>*
services() const

@ -183,9 +183,11 @@ namespace llarp
- connection close callback
- stream constructor callback
- will return a BTRequestStream on the first call to get_new_stream<BTRequestStream>
- bt stream construction contains a stream close callback that shuts down the connection
if the btstream closes unexpectedly
*/
auto ep = quic->endpoint(
_router.local_addr(),
_router.listen_addr(),
[this](oxen::quic::connection_interface& ci) { return on_conn_open(ci); },
[this](oxen::quic::connection_interface& ci, uint64_t ec) {
return on_conn_closed(ci, ec);
@ -198,7 +200,14 @@ namespace llarp
std::optional<int64_t> id) -> std::shared_ptr<oxen::quic::Stream> {
if (id && id == 0)
{
auto s = std::make_shared<oxen::quic::BTRequestStream>(c, e);
auto s = std::make_shared<oxen::quic::BTRequestStream>(
c, e, [](oxen::quic::Stream& s, uint64_t error_code) {
log::warning(
logcat,
"BTRequestStream closed unexpectedly (ec:{}); closing connection...",
error_code);
s.conn.close_connection(error_code);
});
register_commands(s);
return s;
}
@ -216,6 +225,13 @@ namespace llarp
, ep{startup_endpoint(), *this}
{}
std::unique_ptr<LinkManager>
LinkManager::make(Router& r)
{
std::unique_ptr<LinkManager> p{new LinkManager(r)};
return p;
}
bool
LinkManager::send_control_message(
const RouterID& remote,
@ -496,6 +512,7 @@ namespace llarp
{
is_stopping = false;
node_db = _router.node_db();
client_router_connections = _router.required_num_client_conns();
}
void
@ -898,7 +915,7 @@ namespace llarp
"Received PublishIntroMessage in which we are peer index {}.. storing introset",
relay_order);
_router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)});
_router.contacts().put_intro(std::move(enc));
respond(serialize_response({{messages::STATUS_KEY, ""}}));
}
else
@ -936,7 +953,7 @@ namespace llarp
{
log::info(link_cat, "Received PublishIntroMessage for {} (TXID: {}); we are candidate {}");
_router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)});
_router.contacts().put_intro(std::move(enc));
respond(serialize_response({{messages::STATUS_KEY, ""}}));
}
else
@ -1064,7 +1081,7 @@ namespace llarp
}
else
{
if (auto maybe_intro = _router.contacts()->get_introset_by_location(addr))
if (auto maybe_intro = _router.contacts().get_introset_by_location(addr))
respond(serialize_response({{"INTROSET", maybe_intro->bt_encode()}}));
else
{
@ -1102,7 +1119,7 @@ namespace llarp
if (m)
{
service::EncryptedIntroSet enc{payload};
_router.contacts()->services()->PutNode(std::move(enc));
_router.contacts().put_intro(std::move(enc));
}
else
{
@ -1114,7 +1131,7 @@ namespace llarp
void
LinkManager::handle_path_build(oxen::quic::message m, const RouterID& from)
{
if (!_router.path_context().AllowingTransit())
if (!_router.path_context().is_transit_allowed())
{
log::warning(link_cat, "got path build request when not permitting transit");
m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::NO_TRANSIT}}), true);
@ -1200,7 +1217,7 @@ namespace llarp
hop->info.upstream.from_string(upstream);
if (_router.path_context().HasTransitHop(hop->info))
if (_router.path_context().has_transit_hop(hop->info))
{
log::warning(link_cat, "Invalid PathID; PathIDs must be unique");
m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_PATHID}}), true);
@ -1237,7 +1254,7 @@ namespace llarp
{
hop->terminal_hop = true;
// we are terminal hop and everything is okay
_router.path_context().PutTransitHop(hop);
_router.path_context().put_transit_hop(hop);
m.respond(messages::OK_RESPONSE, false);
return;
}
@ -1270,7 +1287,7 @@ namespace llarp
link_cat,
"Upstream returned successful path build response; giving hop info to Router, "
"then relaying response");
_router.path_context().PutTransitHop(hop);
_router.path_context().put_transit_hop(hop);
}
if (m.timed_out)
log::info(link_cat, "Upstream timed out on path build; relaying timeout");
@ -1380,7 +1397,7 @@ namespace llarp
auto success =
(crypto::verify(pubkey, to_usv(dict_data), sig)
and _router.exitContext().ObtainNewExit(PubKey{pubkey.data()}, rx_id, flag != 0));
and _router.exitContext().obtain_new_exit(PubKey{pubkey.data()}, rx_id, flag != 0));
m.respond(
ObtainExitMessage::sign_and_serialize_response(_router.identity(), tx_id), not success);
@ -1417,7 +1434,7 @@ namespace llarp
throw;
}
auto path_ptr = _router.path_context().GetPath(PathID_t{to_usv(tx_id).data()});
auto path_ptr = _router.path_context().get_path(PathID_t{to_usv(tx_id).data()});
if (crypto::verify(_router.pubkey(), to_usv(dict_data), sig))
path_ptr->enable_exit_traffic();
@ -1449,7 +1466,8 @@ namespace llarp
auto transit_hop =
_router.path_context().GetTransitHop(_router.pubkey(), PathID_t{to_usv(tx_id).data()});
if (auto exit_ep = _router.exitContext().FindEndpointForPath(PathID_t{to_usv(path_id).data()}))
if (auto exit_ep =
_router.exitContext().find_endpoint_for_path(PathID_t{to_usv(path_id).data()}))
{
if (crypto::verify(exit_ep->PubKey().data(), to_usv(dict_data), sig))
{
@ -1495,7 +1513,7 @@ namespace llarp
return;
}
auto path_ptr = _router.path_context().GetPath(PathID_t{to_usv(tx_id).data()});
auto path_ptr = _router.path_context().get_path(PathID_t{to_usv(tx_id).data()});
if (crypto::verify(_router.pubkey(), to_usv(dict_data), sig))
{
@ -1536,7 +1554,7 @@ namespace llarp
const auto rx_id = transit_hop->info.rxID;
if (auto exit_ep = router().exitContext().FindEndpointForPath(rx_id))
if (auto exit_ep = router().exitContext().find_endpoint_for_path(rx_id))
{
if (crypto::verify(exit_ep->PubKey().data(), to_usv(dict_data), sig))
{
@ -1580,7 +1598,7 @@ namespace llarp
return;
}
auto path_ptr = _router.path_context().GetPath(PathID_t{to_usv(tx_id).data()});
auto path_ptr = _router.path_context().get_path(PathID_t{to_usv(tx_id).data()});
if (path_ptr->SupportsAnyRoles(path::ePathRoleExit | path::ePathRoleSVC)
and crypto::verify(_router.pubkey(), to_usv(dict_data), sig))

@ -30,6 +30,8 @@ namespace llarp
using conn_open_hook = oxen::quic::connection_established_callback;
using conn_closed_hook = oxen::quic::connection_closed_callback;
using stream_open_hook = oxen::quic::stream_open_callback;
using stream_closed_hook = oxen::quic::stream_close_callback;
namespace link
{
@ -141,7 +143,8 @@ namespace llarp
struct LinkManager
{
public:
explicit LinkManager(Router& r);
static std::unique_ptr<LinkManager>
make(Router& r);
bool
send_control_message(
@ -160,6 +163,8 @@ namespace llarp
}
private:
explicit LinkManager(Router& r);
bool
send_control_message_impl(
const RouterID& remote,
@ -310,11 +315,8 @@ namespace llarp
void
connect_to_random(int num_conns);
// TODO: tune these (maybe even remove max?) now that we're switching to quic
/// always maintain this many connections to other routers
size_t min_connected_routers = 4;
/// hard upperbound limit on the number of router to router connections
size_t max_connected_routers = 6;
/// always maintain this many client connections to other routers
int client_router_connections = 4;
private:
// DHT messages

@ -766,8 +766,7 @@ namespace llarp
router_greenlist.clear();
router_greenlist.insert(greenlist.begin(), greenlist.end());
log::info(
logcat, "lokinet service node list now has ", known_rids.size(), " active router RIDs");
log::info(logcat, "lokinet service node list now has {} active router RIDs", known_rids.size());
}
std::optional<RouterID>
@ -843,7 +842,7 @@ namespace llarp
const auto& rid = rc.router_id();
auto [itr, b] = known_rcs.emplace(std::move(rc));
auto [itr, b] = known_rcs.insert(std::move(rc));
rc_lookup.emplace(rid, *itr);
known_rids.insert(rid);
@ -930,7 +929,7 @@ namespace llarp
known_rcs.erase(rc);
rc_lookup.erase(rid);
auto [itr, b] = known_rcs.emplace(std::move(rc));
auto [itr, b] = known_rcs.insert(std::move(rc));
rc_lookup.emplace(rid, *itr);
known_rids.insert(rid);
@ -939,9 +938,9 @@ namespace llarp
}
size_t
NodeDB::num_loaded() const
NodeDB::num_rcs() const
{
return _router.loop()->call_get([this]() { return known_rcs.size(); });
return known_rcs.size();
}
bool

@ -178,7 +178,7 @@ namespace llarp
fs::path
get_path_by_pubkey(RouterID pk) const;
std::unique_ptr<BootstrapList> _bootstraps;
std::unique_ptr<BootstrapList> _bootstraps{};
public:
explicit NodeDB(
@ -299,10 +299,28 @@ namespace llarp
return _pinned_edges;
}
std::unique_ptr<BootstrapList>&
size_t
num_bootstraps() const
{
return _bootstraps ? _bootstraps->size() : 0;
}
bool
has_bootstraps() const
{
return _bootstraps ? _bootstraps->empty() : false;
}
const BootstrapList&
bootstrap_list() const
{
return *_bootstraps;
}
BootstrapList&
bootstrap_list()
{
return _bootstraps;
return *_bootstraps;
}
void
@ -354,7 +372,7 @@ namespace llarp
/// the number of RCs that are loaded from disk
size_t
num_loaded() const;
num_rcs() const;
/// do periodic tasks like flush to disk and expiration
void

@ -13,19 +13,19 @@ namespace llarp::path
{}
void
PathContext::AllowTransit()
PathContext::allow_transit()
{
m_AllowTransit = true;
}
bool
PathContext::AllowingTransit() const
PathContext::is_transit_allowed() const
{
return m_AllowTransit;
}
bool
PathContext::CheckPathLimitHitByIP(const IpAddress& ip)
PathContext::check_path_limit_hit_by_ip(const IpAddress& ip)
{
#ifdef TESTNET
return false;
@ -39,21 +39,6 @@ namespace llarp::path
#endif
}
bool
PathContext::CheckPathLimitHitByIP(const std::string& ip)
{
#ifdef TESTNET
return false;
#else
IpAddress remote{ip};
// null out the port -- we don't care about it for path limiting purposes
remote.setPort(0);
// try inserting remote address by ip into decaying hash set
// if it cannot insert it has hit a limit
return not path_limits.Insert(remote);
#endif
}
const EventLoop_ptr&
PathContext::loop()
{
@ -102,7 +87,7 @@ namespace llarp::path
}
bool
PathContext::HasTransitHop(const TransitHopInfo& info)
PathContext::has_transit_hop(const TransitHopInfo& info)
{
TransitHopID downstream{info.downstream, info.rxID};
if (transit_hops.count(downstream))
@ -125,7 +110,7 @@ namespace llarp::path
}
Path_ptr
PathContext::GetPath(const PathID_t& path_id)
PathContext::get_path(const PathID_t& path_id)
{
if (auto itr = own_paths.find(path_id); itr != own_paths.end())
return itr->second;
@ -186,7 +171,7 @@ namespace llarp::path
}
void
PathContext::PutTransitHop(std::shared_ptr<TransitHop> hop)
PathContext::put_transit_hop(std::shared_ptr<TransitHop> hop)
{
TransitHopID downstream{hop->info.downstream, hop->info.rxID};
TransitHopID upstream{hop->info.upstream, hop->info.txID};

@ -62,28 +62,25 @@ namespace llarp::path
ExpirePaths(llarp_time_t now);
void
AllowTransit();
allow_transit();
void
RejectTransit();
reject_transit();
bool
CheckPathLimitHitByIP(const IpAddress& ip);
check_path_limit_hit_by_ip(const IpAddress& ip);
bool
CheckPathLimitHitByIP(const std::string& ip);
is_transit_allowed() const;
bool
AllowingTransit() const;
bool
HasTransitHop(const TransitHopInfo& info);
has_transit_hop(const TransitHopInfo& info);
void
PutTransitHop(std::shared_ptr<TransitHop> hop);
put_transit_hop(std::shared_ptr<TransitHop> hop);
Path_ptr
GetPath(const PathID_t& path_id);
get_path(const PathID_t& path_id);
bool
TransitHopPreviousIsRouter(const PathID_t& path, const RouterID& r);

@ -224,7 +224,7 @@ namespace llarp
const auto& rid = rc.router_id();
#ifndef TESTNET
if (router->IsBootstrapNode(rid))
if (router->is_bootstrap_node(rid))
return;
#endif
if (exclude.count(rid))

@ -45,7 +45,7 @@ namespace llarp
, _disk_thread{_lmq->add_tagged_thread("disk")}
, _rpc_server{nullptr}
, _randomStartDelay{platform::is_simulation ? std::chrono::milliseconds{(llarp::randint() % 1250) + 2000} : 0s}
, _link_manager{*this}
// , _link_manager{*this}
, _hidden_service_context{this}
{
_key_manager = std::make_shared<KeyManager>();
@ -59,9 +59,7 @@ namespace llarp
}
Router::~Router()
{
_contacts.reset();
}
{}
// TODO: investigate changes needed for libquic integration
// still needed at all?
@ -86,11 +84,10 @@ namespace llarp
return util::StatusObject{
{"running", true},
{"numNodesKnown", _node_db->num_loaded()},
{"contacts", _contacts->ExtractStatus()},
{"numNodesKnown", _node_db->num_rcs()},
{"services", _hidden_service_context.ExtractStatus()},
{"exit", _exit_context.ExtractStatus()},
{"links", _link_manager.extract_status()}};
{"links", _link_manager->extract_status()}};
}
// TODO: investigate changes needed for libquic integration
@ -102,7 +99,7 @@ namespace llarp
auto services = _hidden_service_context.ExtractStatus();
auto link_types = _link_manager.extract_status();
auto link_types = _link_manager->extract_status();
uint64_t tx_rate = 0;
uint64_t rx_rate = 0;
@ -175,7 +172,7 @@ namespace llarp
{"uptime", to_json(Uptime())},
{"numPathsBuilt", pathsCount},
{"numPeersConnected", peers},
{"numRoutersKnown", _node_db->num_loaded()},
{"numRoutersKnown", _node_db->num_rcs()},
{"ratio", ratio},
{"txRate", tx_rate},
{"rxRate", rx_rate},
@ -227,14 +224,14 @@ namespace llarp
loop()->call([this, &peer_pubkeys]() {
for (auto& pk : peer_pubkeys)
_link_manager.close_connection(pk);
_link_manager->close_connection(pk);
});
}
void
Router::persist_connection_until(const RouterID& remote, llarp_time_t until)
{
_link_manager.set_conn_persist(remote, until);
_link_manager->set_conn_persist(remote, until);
}
std::optional<RouterID>
@ -262,19 +259,19 @@ namespace llarp
void
Router::connect_to(const RouterID& rid)
{
_link_manager.connect_to(rid);
_link_manager->connect_to(rid);
}
void
Router::connect_to(const RemoteRC& rc)
{
_link_manager.connect_to(rc);
_link_manager->connect_to(rc);
}
bool
Router::send_data_message(const RouterID& remote, std::string payload)
{
return _link_manager.send_data_message(remote, std::move(payload));
return _link_manager->send_data_message(remote, std::move(payload));
}
bool
@ -284,20 +281,20 @@ namespace llarp
std::string body,
std::function<void(oxen::quic::message m)> func)
{
return _link_manager.send_control_message(
return _link_manager->send_control_message(
remote, std::move(ep), std::move(body), std::move(func));
}
void
Router::for_each_connection(std::function<void(link::Connection&)> func)
{
return _link_manager.for_each_connection(func);
return _link_manager->for_each_connection(func);
}
bool
Router::EnsureIdentity()
{
_encryption = _key_manager->encryptionKey;
_encryption = _key_manager->encryption_key;
if (is_service_node())
{
@ -340,13 +337,19 @@ namespace llarp
}
else
{
_identity = _key_manager->identityKey;
_identity = _key_manager->identity_key;
}
if (_identity.IsZero())
{
log::critical(logcat, "FUCK @ line:{}", __LINE__);
return false;
}
if (_encryption.IsZero())
{
log::critical(logcat, "FUCK @ line:{}", __LINE__);
return false;
}
return true;
}
@ -435,7 +438,7 @@ namespace llarp
Router::insufficient_peers() const
{
constexpr int KnownPeerWarningThreshold = 5;
return node_db()->num_loaded() < KnownPeerWarningThreshold;
return node_db()->num_rcs() < KnownPeerWarningThreshold;
}
std::optional<std::string>
@ -509,21 +512,22 @@ namespace llarp
}
size_t
Router::NumberOfConnectedRouters() const
Router::num_router_connections() const
{
return _link_manager.get_num_connected();
return _link_manager->get_num_connected();
}
size_t
Router::NumberOfConnectedClients() const
Router::num_client_connections() const
{
return _link_manager.get_num_connected_clients();
return _link_manager->get_num_connected_clients();
}
void
Router::save_rc()
{
_node_db->put_rc(router_contact.view());
log::info(logcat, "Saving RC file to {}", our_rc_file);
queue_disk_io([&]() { router_contact.write(our_rc_file); });
}
@ -552,13 +556,14 @@ namespace llarp
}
// Router config
_link_manager.max_connected_routers = conf.router.max_connected_routers;
_link_manager.min_connected_routers = conf.router.min_connected_routers;
client_router_connections = conf.router.client_router_connections;
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;
encryption_keyfile = _key_manager->enckey_path;
our_rc_file = _key_manager->rc_path;
transport_keyfile = _key_manager->transkey_path;
identity_keyfile = _key_manager->idkey_path;
std::optional<SockAddr> _ourAddress;
if (auto maybe_ip = conf.links.public_addr)
_ourAddress = var::visit([](auto&& ip) { return SockAddr{ip}; }, *maybe_ip);
@ -574,11 +579,22 @@ namespace llarp
else
throw std::runtime_error{"public ip provided without public port"};
log::debug(logcat, "Using {} for our public address", *_ourAddress);
_public_address = oxen::quic::Address{static_cast<const sockaddr*>(*_ourAddress)};
log::critical(logcat, "PUBLIC ADDR: {}", *_public_address);
}
else
log::debug(logcat, "No explicit public address given; will auto-detect during link setup");
{
log::debug(logcat, "No explicit public address given; inferring now...");
_local_addr = conf.links.addr;
if (auto maybe_addr = net().GetBestNetIF())
{
_public_address = oxen::quic::Address{static_cast<const sockaddr*>(*maybe_addr)};
log::critical(logcat, "PUBLIC ADDR: {}", *_public_address);
}
}
_listen_addr = conf.links.addr;
RouterContact::BLOCK_BOGONS = conf.router.block_bogons;
@ -618,6 +634,26 @@ namespace llarp
auto _bootstrap_rc_list = std::make_unique<BootstrapList>();
auto clear_bad_rcs = [&]() mutable {
// in case someone has an old bootstrap file and is trying to use a bootstrap
// that no longer exists
for (auto it = _bootstrap_rc_list->begin(); it != _bootstrap_rc_list->end();)
{
if (it->is_obsolete_bootstrap())
log::warning(logcat, "ignoring obsolete bootstrap RC: {}", it->router_id());
else if (not it->verify())
log::warning(logcat, "ignoring invalid bootstrap RC: {}", it->router_id());
else
{
++it;
continue;
}
// we are in one of the above error cases that we warned about:
it = _bootstrap_rc_list->erase(it);
}
};
for (const auto& router : configRouters)
{
log::debug(logcat, "Loading bootstrap router list from {}", defaultBootstrapFile);
@ -629,11 +665,18 @@ namespace llarp
_bootstrap_rc_list->emplace(rc);
}
clear_bad_rcs();
if (_bootstrap_rc_list->empty() and not conf.bootstrap.seednode)
{
auto fallbacks = llarp::load_bootstrap_fallbacks();
if (_bootstrap_rc_list->empty() and not conf.bootstrap.seednode)
if (auto itr = fallbacks.find(RouterContact::ACTIVE_NETID); itr != fallbacks.end())
{
_bootstrap_rc_list->merge(itr->second);
}
if (_bootstrap_rc_list->empty())
{
// empty after trying fallback, if set
log::error(
@ -644,35 +687,15 @@ namespace llarp
throw std::runtime_error("No bootstrap nodes available.");
}
}
// in case someone has an old bootstrap file and is trying to use a bootstrap
// that no longer exists
for (auto it = _bootstrap_rc_list->begin(); it != _bootstrap_rc_list->end();)
{
if (it->is_obsolete_bootstrap())
log::warning(logcat, "ignoring obsolete bootstrap RC: {}", it->router_id());
else if (not it->verify())
log::warning(logcat, "ignoring invalid bootstrap RC: {}", it->router_id());
else
{
++it;
continue;
}
// we are in one of the above error cases that we warned about:
it = _bootstrap_rc_list->erase(it);
log::info(
logcat, "Loaded {} default fallback bootstrap routers!", _bootstrap_rc_list->size());
clear_bad_rcs();
node_db()->set_bootstrap_routers(std::move(_bootstrap_rc_list));
}
node_db()->set_bootstrap_routers(std::move(_bootstrap_rc_list));
if (conf.bootstrap.seednode)
LogInfo("we are a seed node");
else
LogInfo("Loaded ", _bootstrap_rc_list->size(), " bootstrap routers");
// Init components after relevant config settings loaded
_link_manager.init();
log::critical(logcat, "We are a bootstrap seed node!");
// TODO: RC refactor here
if (_is_service_node)
@ -713,14 +736,18 @@ namespace llarp
}
bool
Router::IsBootstrapNode(const RouterID r) const
Router::is_bootstrap_node(const RouterID r) const
{
const auto& b = _node_db->bootstrap_list();
return std::count_if(
b->begin(),
b->end(),
[r](const RemoteRC& rc) -> bool { return rc.router_id() == r; })
> 0;
if (_node_db->has_bootstraps())
{
const auto& b = _node_db->bootstrap_list();
return std::count_if(
b.begin(),
b.end(),
[r](const RemoteRC& rc) -> bool { return rc.router_id() == r; })
> 0;
}
return false;
}
bool
@ -737,16 +764,16 @@ namespace llarp
log::info(
logcat,
"{} RCs loaded with {} bootstrap peers and {} router connections!",
node_db()->num_loaded(),
_node_db->bootstrap_list()->size(),
NumberOfConnectedRouters());
_node_db->num_rcs(),
_node_db->num_bootstraps(),
num_router_connections());
if (is_service_node())
{
log::info(
logcat,
"Local service node has {} client connections since last RC update ({} to expiry)",
NumberOfConnectedClients(),
num_client_connections(),
router_contact.age(now),
router_contact.time_to_expiry(now));
}
@ -766,9 +793,9 @@ namespace llarp
fmt::format_to(
out,
" snode | known/svc/clients: {}/{}/{}",
node_db()->num_loaded(),
NumberOfConnectedRouters(),
NumberOfConnectedClients());
node_db()->num_rcs(),
num_router_connections(),
num_client_connections());
fmt::format_to(
out,
" | {} active paths | block {} ",
@ -784,10 +811,7 @@ namespace llarp
else
{
fmt::format_to(
out,
" client | known/connected: {}/{}",
node_db()->num_loaded(),
NumberOfConnectedRouters());
out, " client | known/connected: {}/{}", node_db()->num_rcs(), num_router_connections());
if (auto ep = hidden_service_context().GetDefault())
{
@ -850,7 +874,7 @@ namespace llarp
auto view = router_contact.view();
_link_manager.gossip_rc(
_link_manager->gossip_rc(
pubkey(), std::string{reinterpret_cast<const char*>(view.data()), view.size()});
last_rc_gossip = now_timepoint;
@ -891,14 +915,14 @@ namespace llarp
// remove RCs for nodes that are no longer allowed by network policy
node_db()->RemoveIf([&](const RemoteRC& rc) -> bool {
// don't purge bootstrap nodes from nodedb
if (IsBootstrapNode(rc.router_id()))
if (is_bootstrap_node(rc.router_id()))
{
log::trace(logcat, "Not removing {}: is bootstrap node", rc.router_id());
return false;
}
// if for some reason we stored an RC that isn't a valid router
// purge this entry
if (not rc.is_public_router())
if (not rc.is_public_addressable())
{
log::debug(logcat, "Removing {}: not a valid router", rc.router_id());
return true;
@ -956,11 +980,11 @@ namespace llarp
}
*/
_link_manager.check_persisting_conns(now);
_link_manager->check_persisting_conns(now);
size_t connected = NumberOfConnectedRouters();
size_t connected = num_router_connections();
size_t connectToNum = _link_manager.min_connected_routers;
size_t connectToNum = _link_manager->client_router_connections;
const auto& pinned_edges = _node_db->pinned_edges();
const auto pinned_count = pinned_edges.size();
@ -989,7 +1013,7 @@ namespace llarp
log::error(
logcat,
"We appear to be an active service node, but have only {} known peers.",
node_db()->num_loaded());
node_db()->num_rcs());
_next_decomm_warning = now + DecommissionWarnInterval;
}
}
@ -1000,7 +1024,7 @@ namespace llarp
{
size_t dlt = connectToNum - connected;
LogDebug("connecting to ", dlt, " random routers to keep alive");
_link_manager.connect_to_random(dlt);
_link_manager->connect_to_random(dlt);
}
_hidden_service_context.Tick(now);
@ -1023,7 +1047,7 @@ namespace llarp
bool
Router::GetRandomConnectedRouter(RemoteRC& result) const
{
return _link_manager.get_random_connected(result);
return _link_manager->get_random_connected(result);
}
const std::set<RouterID>&
@ -1054,16 +1078,22 @@ namespace llarp
bool
Router::Run()
{
log::critical(logcat, "{} called", __PRETTY_FUNCTION__);
if (is_running || is_stopping)
return false;
// TODO: look at _ourAddress
router_contact = LocalRC::make(
identity(), _is_service_node and _public_address ? *_public_address : _listen_addr);
router_contact = LocalRC::make(identity(), local_addr());
_link_manager = LinkManager::make(*this);
if (is_service_node() and not router_contact.is_public_router())
// Init components after relevant config settings loaded
_link_manager->init();
if (is_service_node())
{
if (not router_contact.is_public_router())
if (not router_contact.is_public_addressable())
{
log::error(logcat, "Router is configured as relay but has no reachable addresses!");
return false;
@ -1101,16 +1131,19 @@ namespace llarp
log::info(logcat, "Loading NodeDB from disk...");
_node_db->load_from_disk();
_contacts = std::make_shared<Contacts>(llarp::dht::Key_t(pubkey()), *this);
log::info(logcat, "Creating Introset Contacts...");
_contacts = std::make_unique<Contacts>(*this);
for (const auto& rc : *_node_db->bootstrap_list())
if (_node_db->has_bootstraps())
{
node_db()->put_rc(rc);
_contacts->rc_nodes()->PutNode(rc);
log::info(logcat, "Added bootstrap node (rid: {})", rc.router_id());
}
for (const auto& rc : _node_db->bootstrap_list())
{
node_db()->put_rc(rc);
log::info(logcat, "Added bootstrap node (rid: {})", rc.router_id());
}
log::info(logcat, "Router populated NodeDB with {} routers", _node_db->num_loaded());
log::info(logcat, "Router populated NodeDB with {} routers", _node_db->num_rcs());
}
_loop->call_every(ROUTER_TICK_INTERVAL, weak_from_this(), [this] { Tick(); });
@ -1155,7 +1188,7 @@ namespace llarp
// try to make a session to this random router
// this will do a dht lookup if needed
_link_manager.test_reachability(
_link_manager->test_reachability(
router,
[this, rid = router, previous = fails](oxen::quic::connection_interface& conn) {
log::info(
@ -1224,7 +1257,7 @@ namespace llarp
void
Router::StopLinks()
{
_link_manager.stop();
_link_manager->stop();
}
void
@ -1241,7 +1274,7 @@ namespace llarp
LogWarn("stopping router hard");
llarp::sys::service_manager->stopping();
hidden_service_context().StopAll();
_exit_context.Stop();
_exit_context.stop();
StopLinks();
Close();
}
@ -1261,27 +1294,27 @@ namespace llarp
}
is_stopping.store(true);
if (auto level = log::get_level_default();
level > log::Level::info and level != log::Level::off)
log::reset_level(log::Level::info);
log::info(logcat, "stopping");
log::info(logcat, "stopping service manager...");
llarp::sys::service_manager->stopping();
log::debug(logcat, "stopping hidden service context");
log::debug(logcat, "stopping hidden service context...");
hidden_service_context().StopAll();
llarp::sys::service_manager->stopping();
log::debug(logcat, "stopping exit context");
_exit_context.Stop();
llarp::sys::service_manager->stopping();
log::debug(logcat, "final upstream pump");
llarp::sys::service_manager->stopping();
log::debug(logcat, "final links pump");
log::debug(logcat, "stopping exit context...");
_exit_context.stop();
_loop->call_later(200ms, [this] { AfterStopIssued(); });
}
bool
Router::HasSessionTo(const RouterID& remote) const
{
return _link_manager.have_connection_to(remote);
return _link_manager->have_connection_to(remote);
}
std::string
@ -1300,19 +1333,20 @@ namespace llarp
Router::ConnectToRandomRouters(int _want)
{
const size_t want = _want;
auto connected = NumberOfConnectedRouters();
auto connected = num_router_connections();
if (connected >= want)
return;
_link_manager.connect_to_random(want);
_link_manager->connect_to_random(want);
}
bool
Router::init_service_node()
{
LogInfo("accepting transit traffic");
paths.AllowTransit();
_contacts->set_transit_allowed(true);
_exit_context.AddExitEndpoint("default", _config->network, _config->dns);
log::info(logcat, "Router accepting transit traffic...");
paths.allow_transit();
_exit_context.add_exit_endpoint("default", _config->network, _config->dns);
return true;
}
@ -1338,9 +1372,9 @@ namespace llarp
}
oxen::quic::Address
Router::local_addr() const
Router::listen_addr() const
{
return _local_addr;
return _listen_addr;
}
void

@ -91,8 +91,8 @@ namespace llarp
consensus::reachability_testing router_testing;
std::optional<SockAddr> _ourAddress;
oxen::quic::Address _local_addr;
std::optional<oxen::quic::Address> _public_address; // public addr for relays
oxen::quic::Address _listen_addr;
EventLoop_ptr _loop;
std::shared_ptr<vpn::Platform> _vpn;
@ -122,7 +122,9 @@ namespace llarp
oxenmq::address rpc_addr;
Profiling _router_profiling;
fs::path _profile_file;
LinkManager _link_manager{*this};
std::unique_ptr<LinkManager> _link_manager;
int client_router_connections;
// should we be sending padded messages every interval?
bool send_padding = false;
@ -155,6 +157,12 @@ namespace llarp
std::chrono::system_clock::time_point next_bootstrap_attempt{last_rc_gossip};
public:
int
required_num_client_conns() const
{
return client_router_connections;
}
RouterID
local_rid() const
{
@ -176,10 +184,16 @@ namespace llarp
void
connect_to(const RemoteRC& rc);
Contacts*
const Contacts&
contacts() const
{
return _contacts.get();
return *_contacts;
}
Contacts&
contacts()
{
return *_contacts;
}
std::shared_ptr<Config>
@ -212,10 +226,16 @@ namespace llarp
LinkManager&
link_manager()
{
return _link_manager;
return *_link_manager;
}
const LinkManager&
link_manager() const
{
return *_link_manager;
}
inline int
int
outbound_udp_socket() const
{
return _outbound_udp_socket;
@ -282,7 +302,7 @@ namespace llarp
}
oxen::quic::Address
local_addr() const;
listen_addr() const;
util::StatusObject
ExtractStatus() const;
@ -473,7 +493,7 @@ namespace llarp
std::string body,
std::function<void(oxen::quic::message m)> func = nullptr);
bool IsBootstrapNode(RouterID) const;
bool is_bootstrap_node(RouterID) const;
/// call internal router ticker
void
@ -490,11 +510,11 @@ namespace llarp
/// count the number of unique service nodes connected via pubkey
size_t
NumberOfConnectedRouters() const;
num_router_connections() const;
/// count the number of unique clients connected by pubkey
size_t
NumberOfConnectedClients() const;
num_client_connections() const;
bool
GetRandomConnectedRouter(RemoteRC& result) const;

@ -102,7 +102,7 @@ namespace llarp
{
util::StatusObject obj{
{"lastUpdated", _timestamp.time_since_epoch().count()},
{"publicRouter", is_public_router()},
{"publicRouter", is_public_addressable()},
{"identity", _router_id.ToString()},
{"address", _addr.to_string()}};
@ -221,10 +221,11 @@ namespace llarp
}
bool
RouterContact::is_public_router() const
RouterContact::is_public_addressable() const
{
if (_router_version.empty())
return false;
return _addr.is_addressable();
}

@ -176,7 +176,7 @@ namespace llarp
decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf);
bool
is_public_router() const;
is_public_addressable() const;
/// does this RC expire soon? default delta is 1 minute
bool

@ -22,7 +22,8 @@ namespace llarp
{
_router_id = llarp::seckey_to_pubkey(_secret_key);
_addr = std::move(local);
_addr6.emplace(&_addr.in6());
if (_addr.is_ipv6())
_addr6.emplace(&_addr.in6());
resign();
}
@ -123,8 +124,6 @@ namespace llarp
static_assert(llarp::LOKINET_VERSION.size() == 3);
btdp.append(
"v", std::string_view{reinterpret_cast<const char*>(llarp::LOKINET_VERSION.data()), 3});
bt_sign(btdp);
}
void

@ -89,7 +89,7 @@ namespace llarp
}
catch (const std::exception& e)
{
log::error(logcat, "Failed to read or validate RC from {}: {}", fname, e.what());
log::warning(logcat, "Failed to read or validate RC from {}: {}", fname, e.what());
return false;
}

@ -76,7 +76,7 @@ namespace llarp::rpc
{
if (r.is_service_node())
{
return r.exitContext().GetExitEndpoint(name);
return r.exitContext().get_exit_endpoint(name);
}
return r.hidden_service_context().GetEndpointByName(name);
@ -329,7 +329,7 @@ namespace llarp::rpc
}
m_Router.loop()->call([&]() {
auto endpoint = m_Router.exitContext().GetExitEndpoint("default");
auto endpoint = m_Router.exitContext().get_exit_endpoint("default");
if (endpoint == nullptr)
{

@ -516,7 +516,7 @@ namespace llarp::service
const auto& keyfile = _state->key_file;
if (!keyfile.empty())
{
_identity.EnsureKeys(keyfile, router()->key_manager()->needBackup());
_identity.EnsureKeys(keyfile, router()->key_manager()->needs_backup());
}
else
{
@ -1310,7 +1310,7 @@ namespace llarp::service
// TODO: if all requests fail, call callback with failure?
for (const auto& path : paths)
{
path->find_intro(location, false, 0, [this, hook, got_it](std::string resp) mutable {
path->find_intro(location, false, 0, [hook, got_it, this](std::string resp) mutable {
// asking many, use only first successful
if (*got_it)
return;
@ -1335,7 +1335,7 @@ namespace llarp::service
}
service::EncryptedIntroSet enc{introset};
router()->contacts()->services()->PutNode(std::move(enc));
router()->contacts().put_intro(std::move(enc));
// TODO: finish this
/*

@ -97,7 +97,7 @@ namespace llarp::service
if (exists and needBackup)
{
KeyManager::backupFileByMoving(fname);
KeyManager::copy_backup_keyfile(fname);
exists = false;
}

Loading…
Cancel
Save