initial lokinet router testing:

* report via rpc to oxen core connection stats on success and failure
* connect to random service node by pubkey every 5 seconds for testing
pull/1659/head
Jeff Becker 3 years ago
parent 5b858c6314
commit b830eeb535
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -13,6 +13,8 @@
#include <llarp/crypto/crypto.hpp>
#include <utility>
#include <llarp/rpc/lokid_rpc_client.hpp>
namespace llarp
{
struct PendingSession
@ -35,7 +37,7 @@ namespace llarp
// TODO: do we want to keep it
const auto router = RouterID(session->GetPubKey());
const bool isOutbound = not session->IsInbound();
const std::string remoteType = session->GetRemoteRC().IsPublicRouter() ? "router" : "client";
LogInfo("session with ", remoteType, " [", router, "] established");
@ -44,9 +46,18 @@ namespace llarp
FinalizeRequest(router, SessionResult::InvalidRouter);
return false;
}
auto func = std::bind(&OutboundSessionMaker::VerifyRC, this, session->GetRemoteRC());
work(func);
if (isOutbound)
{
// add a callback for this router if it's outbound to inform core if applicable
if (auto rpc = _router->RpcClient())
{
util::Lock l{_mutex};
pendingCallbacks[router].emplace_back([rpc](const auto& router, const auto result) {
rpc->RecordConnection(router, result == SessionResult::Establish);
});
}
}
work([this, rc = session->GetRemoteRC()] { VerifyRC(rc); });
return true;
}
@ -54,13 +65,16 @@ namespace llarp
void
OutboundSessionMaker::OnConnectTimeout(ILinkSession* session)
{
// TODO: retry/num attempts
LogWarn(
"Session establish attempt to ",
RouterID(session->GetPubKey()),
" timed out.",
session->GetRemoteEndpoint());
FinalizeRequest(session->GetPubKey(), SessionResult::Timeout);
const auto router = RouterID(session->GetPubKey());
LogWarn("Session establish attempt to ", router, " timed out.", session->GetRemoteEndpoint());
// inform core if needed
if (auto rpc = _router->RpcClient())
{
rpc->RecordConnection(router, false);
}
FinalizeRequest(router, SessionResult::Timeout);
}
void

@ -1181,6 +1181,25 @@ namespace llarp
#if defined(WITH_SYSTEMD)
::sd_notify(0, "READY=1");
#endif
if (whitelistRouters)
{
// do service node testing if we are in service node whitelist mode
_loop->call_every(5s, weak_from_this(), [this] {
// dont run tests if we are not running or we are stopping
if (not _running)
return;
// get a random router to test by pubkey
RouterID router{};
if (not _rcLookupHandler.GetRandomWhitelistRouter(router))
{
LogError("could not get random whitelisted router for testing");
return;
}
// try to make a session to this random router
// this will do a dht lookup if needed
_outboundSessionMaker.CreateSessionTo(router, nullptr);
});
}
LogContext::Instance().DropToRuntimeLevel();
return _running;
}

@ -104,6 +104,7 @@ namespace llarp
{
nlohmann::json request, fields;
fields["pubkey_ed25519"] = true;
fields["service_node_pubkey"] = true;
request["fields"] = fields;
request["active_only"] = true;
if (not topblock.empty())
@ -179,7 +180,7 @@ namespace llarp
}
}
}
std::unordered_map<RouterID, PubKey> keymap;
std::vector<RouterID> nodeList;
{
const auto itr = j.find("service_node_states");
@ -190,9 +191,16 @@ namespace llarp
const auto ed_itr = j_itr->find("pubkey_ed25519");
if (ed_itr == j_itr->end() or not ed_itr->is_string())
continue;
const auto svc_itr = j_itr->find("service_node_pubkey");
if (svc_itr == j_itr->end() or not svc_itr->is_string())
continue;
RouterID rid;
if (rid.FromHex(ed_itr->get<std::string>()))
PubKey pk;
if (rid.FromHex(ed_itr->get<std::string>()) and pk.FromHex(svc_itr->get<std::string>()))
{
nodeList.emplace_back(std::move(rid));
keymap[rid] = pk;
}
}
}
}
@ -203,8 +211,33 @@ namespace llarp
return;
}
// inform router about the new list
m_Router->loop()->call([r = m_Router, nodeList = std::move(nodeList)]() mutable {
r->SetRouterWhitelist(std::move(nodeList));
m_Router->loop()->call(
[this, nodeList = std::move(nodeList), keymap = std::move(keymap)]() mutable {
m_KeyMap = std::move(keymap);
m_Router->SetRouterWhitelist(std::move(nodeList));
});
}
void
LokidRpcClient::RecordConnection(RouterID router, bool success)
{
m_Router->loop()->call([router, success, this]() {
if (auto itr = m_KeyMap.find(router); itr != m_KeyMap.end())
{
const nlohmann::json request = {
{"passed", success}, {"pubkey", itr->second.ToHex()}, {"type", "lokinet"}};
Request(
"admin.report_peer_status",
[self = shared_from_this()](bool success, std::vector<std::string>) {
if (not success)
{
LogError("Failed to report connection status to oxend");
return;
}
LogDebug("reported connection status to core");
},
request.dump());
}
});
}

@ -42,6 +42,10 @@ namespace llarp
dht::Key_t namehash,
std::function<void(std::optional<service::EncryptedName>)> resultHandler);
/// record that if connected to a router successfully
void
RecordConnection(RouterID router, bool success);
private:
/// called when we have connected to lokid via lokimq
void
@ -85,6 +89,8 @@ namespace llarp
AbstractRouter* const m_Router;
std::atomic<bool> m_UpdatingList;
std::unordered_map<RouterID, PubKey> m_KeyMap;
uint64_t m_BlockHeight;
};

Loading…
Cancel
Save