compiles, but does not link

This commit is contained in:
Thomas Winget 2023-08-28 16:50:06 -04:00
parent 450121734a
commit 99be31b72f
10 changed files with 137 additions and 155 deletions

View File

@ -236,7 +236,6 @@ add_library(lokinet-context
context.cpp
link/link_manager.cpp
router/outbound_message_handler.cpp
router/outbound_session_maker.cpp
router/rc_lookup_handler.cpp
router/rc_gossiper.cpp
router/router.cpp
@ -515,7 +514,7 @@ target_link_libraries(lokinet-util PUBLIC
target_link_libraries(lokinet-plainquic PUBLIC
ngtcp2_crypto
libquic
quic
uvw
)

View File

@ -13,6 +13,33 @@ struct llarp_buffer_t;
namespace llarp
{
//TODO: do we still want this?
enum class SessionResult
{
Establish,
Timeout,
RouterNotFound,
InvalidRouter,
NoLink,
EstablishFail
};
constexpr std::string_view
ToString(SessionResult sr)
{
return sr == llarp::SessionResult::Establish ? "success"sv
: sr == llarp::SessionResult::Timeout ? "timeout"sv
: sr == llarp::SessionResult::NoLink ? "no link"sv
: sr == llarp::SessionResult::InvalidRouter ? "invalid router"sv
: sr == llarp::SessionResult::RouterNotFound ? "not found"sv
: sr == llarp::SessionResult::EstablishFail ? "establish failed"sv
: "???"sv;
}
template <>
constexpr inline bool IsToStringFormattable<SessionResult> = true;
struct RouterContact;
struct ILinkSession;
struct IOutboundSessionMaker;
@ -25,9 +52,6 @@ namespace llarp
{
virtual ~ILinkManager() = default;
virtual link::Endpoint*
GetCompatibleLink(const RouterContact& rc) const = 0;
virtual IOutboundSessionMaker*
GetSessionMaker() const = 0;
@ -39,7 +63,7 @@ namespace llarp
uint16_t priority = 0) = 0;
virtual bool
HaveConnection(const RouterID& remote) const = 0;
HaveConnection(const RouterID& remote, bool client_only = false) const = 0;
/// return true if we have a connection to the remote and it is not a relay,
/// else return false
@ -52,19 +76,6 @@ namespace llarp
virtual void
PersistSessionUntil(const RouterID& remote, llarp_time_t until) = 0;
virtual void
ForEachPeer(
std::function<void(const ILinkSession*, bool)> visit, bool randomize = false) const = 0;
virtual void
ForEachPeer(std::function<void(ILinkSession*)> visit) = 0;
virtual void
ForEachInboundLink(std::function<void(LinkLayer_ptr)> visit) const = 0;
virtual void
ForEachOutboundLink(std::function<void(LinkLayer_ptr)> visit) const = 0;
/// close all connections to this peer
/// remove all link layer commits
virtual void
@ -87,6 +98,19 @@ namespace llarp
virtual util::StatusObject
ExtractStatus() const = 0;
// Do an RC lookup for the given RouterID; the result will trigger
// Connect(RouterContact) on success (or if we already have it), and will
// trigger connection failure callback on lookup failure.
virtual void
Connect(RouterID router) = 0;
// Establish a connection to the remote `rc`.
//
// Connection established/failed callbacks should be invoked when either happens,
// but this function should do nothing if already connected.
virtual void
Connect(RouterContact rc) = 0;
};
} // namespace llarp

View File

@ -1,6 +1,7 @@
#include "link_manager.hpp"
#include <llarp/router/i_outbound_session_maker.hpp>
#include <llarp/router/i_rc_lookup_handler.hpp>
#include <llarp/nodedb.hpp>
#include <llarp/crypto/crypto.hpp>
#include <algorithm>
@ -8,13 +9,13 @@
namespace llarp
{
llarp::link::Endpoint*
LinkManager::GetCompatibleLink(const RouterContact& rc) const
link::Endpoint*
LinkManager::GetCompatibleLink(const RouterContact& rc)
{
if (stopping)
return nullptr;
for (const auto& ep : endpoints)
for (auto& ep : endpoints)
{
//TODO: need some notion of "is this link compatible with that address".
// iwp just checks that the link dialect ("iwp") matches the address info dialect,
@ -37,8 +38,7 @@ namespace llarp
if (stopping)
return false;
auto link = GetLinkWithSessionTo(remote);
if (link == nullptr)
if (not HaveConnection(remote))
{
if (completed)
{
@ -47,24 +47,32 @@ namespace llarp
return false;
}
return link->SendTo(remote, buf, completed, priority);
//TODO: send the message
//TODO: if we keep bool return type, change this accordingly
return false;
}
bool
LinkManager::HaveClientConnection(const RouterID& remote) const
LinkManager::HaveConnection(const RouterID& remote, bool client_only) const
{
for (const auto& ep : endpoints)
{
if (auto itr = ep.connections.find(remote); itr != ep.connections.end())
{
if (itr->second.remote_is_relay)
return false;
return true;
if (not (itr->second.remote_is_relay and client_only))
return true;
return false;
}
}
return false;
}
bool
LinkManager::HaveClientConnection(const RouterID& remote) const
{
return HaveConnection(remote, true);
}
void
LinkManager::DeregisterPeer(RouterID remote)
{
@ -73,7 +81,9 @@ namespace llarp
{
if (auto itr = ep.connections.find(remote); itr != ep.connections.end())
{
/*
itr->second.conn->close(); //TODO: libquic needs some function for this
*/
}
}
@ -81,7 +91,7 @@ namespace llarp
}
void
AddLink(oxen::quic::Address bind, bool inbound = false)
LinkManager::AddLink(const oxen::quic::opt::local_addr& bind, bool inbound)
{
//TODO: libquic callbacks: new_conn_alpn_notify, new_conn_pubkey_ok, new_conn_established/ready
auto ep = quic->endpoint(bind);
@ -129,57 +139,6 @@ namespace llarp
}
}
void
LinkManager::ForEachPeer(
std::function<void(const ILinkSession*, bool)> visit, bool randomize) const
{
if (stopping)
return;
for (const auto& link : outboundLinks)
{
link->ForEachSession([visit](const ILinkSession* peer) { visit(peer, true); }, randomize);
}
for (const auto& link : inboundLinks)
{
link->ForEachSession([visit](const ILinkSession* peer) { visit(peer, false); }, randomize);
}
}
void
LinkManager::ForEachPeer(std::function<void(ILinkSession*)> visit)
{
if (stopping)
return;
for (const auto& link : outboundLinks)
{
link->ForEachSession([visit](ILinkSession* peer) { visit(peer); });
}
for (const auto& link : inboundLinks)
{
link->ForEachSession([visit](ILinkSession* peer) { visit(peer); });
}
}
void
LinkManager::ForEachInboundLink(std::function<void(LinkLayer_ptr)> visit) const
{
for (const auto& link : inboundLinks)
{
visit(link);
}
}
void
LinkManager::ForEachOutboundLink(std::function<void(LinkLayer_ptr)> visit) const
{
for (const auto& link : outboundLinks)
{
visit(link);
}
}
size_t
LinkManager::NumberOfConnectedRouters(bool clients_only) const
{
@ -202,18 +161,18 @@ namespace llarp
return NumberOfConnectedRouters(true);
}
//TODO: libquic
bool
LinkManager::GetRandomConnectedRouter(RouterContact& router) const
{
std::unordered_map<RouterID, RouterContact> connectedRouters;
ForEachPeer(
[&connectedRouters](const ILinkSession* peer, bool unused) {
(void)unused;
connectedRouters[peer->GetPubKey()] = peer->GetRemoteRC();
},
false);
for (const auto& ep : endpoints)
{
for (const auto& [router_id, conn] : ep.connections)
{
connectedRouters.emplace(router_id, conn.remote_rc);
}
}
const auto sz = connectedRouters.size();
if (sz)
@ -302,10 +261,10 @@ namespace llarp
// based on which one is compatible with the link we chose. For now, just use
// the first one.
auto& selected = rc.addrs[0];
llarp::quic::opt::remote_addr remote{selected.IPString(), selected.port};
oxen::quic::opt::remote_addr remote{selected.IPString(), selected.port};
//TODO: confirm remote end is using the expected pubkey (RouterID).
//TODO: ALPN for "client" vs "relay" (could just be set on endpoint creation)
auto conn_interface = ep->connect(remote, dgram_cb, stream_cb, tls_creds);
auto conn_interface = ep->endpoint->connect(remote, dgram_cb, stream_cb, tls_creds);
std::shared_ptr<oxen::quic::Stream> stream = conn_interface->get_new_stream();
@ -324,6 +283,7 @@ namespace llarp
LinkManager::ConnectToRandomRouters(int numDesired)
{
std::set<RouterID> exclude;
auto remainingDesired = numDesired;
do
{
auto filter = [exclude](const auto& rc) -> bool { return exclude.count(rc.pubkey) == 0; };
@ -345,19 +305,6 @@ namespace llarp
} while (remainingDesired > 0);
}
bool
LinkManager::HaveConnection(const RouterID& remote)
{
for (const auto& ep : endpoints)
{
if (ep.connections.contains(remote))
{
return true;
}
}
return false;
}
void
LinkManager::HandleIncomingDataMessage(oxen::quic::dgram_interface& dgi, bstring dgram)
{

View File

@ -23,9 +23,6 @@ namespace llarp
~LinkManager() override = default;
link::Endpoint*
GetCompatibleLink(const RouterContact& rc) const override;
IOutboundSessionMaker*
GetSessionMaker() const override;
@ -37,7 +34,7 @@ namespace llarp
uint16_t priority) override;
bool
HaveConnection(const RouterID& remote) const override;
HaveConnection(const RouterID& remote, bool client_only = false) const override;
bool
HaveClientConnection(const RouterID& remote) const override;
@ -46,7 +43,7 @@ namespace llarp
DeregisterPeer(RouterID remote) override;
void
AddLink(oxen::quic::Address bind, bool inbound = false);
AddLink(const oxen::quic::opt::local_addr& bind, bool inbound = false);
void
Stop() override;
@ -54,23 +51,6 @@ namespace llarp
void
PersistSessionUntil(const RouterID& remote, llarp_time_t until) override;
//TODO: change for libquic Connections
void
ForEachPeer(std::function<void(const ILinkSession*, bool)> visit, bool randomize = false)
const override;
//TODO: change for libquic Connections
void
ForEachPeer(std::function<void(ILinkSession*)> visit) override;
//TODO: change for libquic Endpoints
void
ForEachInboundLink(std::function<void(LinkLayer_ptr)> visit) const override;
//TODO: change for libquic Endpoints
void
ForEachOutboundLink(std::function<void(LinkLayer_ptr)> visit) const override;
size_t
NumberOfConnectedRouters(bool clients_only = false) const override;
@ -92,16 +72,9 @@ namespace llarp
void
Init(I_RCLookupHandler* rcLookup);
// Do an RC lookup for the given RouterID; the result will trigger
// Connect(RouterContact) on success (or if we already have it), and will
// trigger connection failure callback on lookup failure.
void
Connect(RouterID router);
// Establish a connection to the remote `rc`.
//
// Connection established/failed callbacks should be invoked when either happens,
// but this function should do nothing if already connected.
void
Connect(RouterContact rc);
@ -121,6 +94,9 @@ namespace llarp
private:
link::Endpoint*
GetCompatibleLink(const RouterContact& rc);
std::atomic<bool> stopping;
mutable util::Mutex _mutex; // protects m_PersistingSessions

View File

@ -183,7 +183,7 @@ namespace llarp
{
char tmp[INET6_ADDRSTRLEN] = {0};
inet_ntop(AF_INET6, (void*)&ip, tmp, sizeof(tmp));
return std::string{sizeof(tmp), tmp};
return std::string{tmp};
}
void

View File

@ -168,11 +168,11 @@ namespace llarp
_router->loop()->call([f = std::move(callback), status] { f(status); });
}
//TODO: still necessary/desired?
void
OutboundMessageHandler::QueueSessionCreation(const RouterID& remote)
{
auto fn = util::memFn(&OutboundMessageHandler::OnSessionResult, this);
_router->linkManager().GetSessionMaker()->CreateSessionTo(remote, fn);
_router->linkManager().Connect(remote);
}
bool

View File

@ -100,6 +100,9 @@ namespace llarp
std::vector<RouterID> gossipTo;
/*
* TODO: gossip RC via libquic
*
// select peers to gossip to
m_LinkManager->ForEachPeer(
[&](const ILinkSession* peerSession, bool) {
@ -140,6 +143,10 @@ namespace llarp
// send message
peerSession->SendMessageBuffer(std::move(msg), nullptr, gossip.Priority());
});
*
*
*/
return true;
}

View File

@ -337,6 +337,9 @@ namespace llarp
return;
// explore via every connected peer
/*
* TODO: DHT explore via libquic
*
_linkManager->ForEachPeer([&](ILinkSession* s) {
if (!s->IsEstablished())
return;
@ -347,6 +350,9 @@ namespace llarp
_dht->impl->ExploreNetworkVia(dht::Key_t{rc.pubkey});
}
});
*
*
*/
}
void

View File

@ -91,7 +91,6 @@ namespace llarp
paths.PumpUpstream();
_hiddenServiceContext.Pump();
_outboundMessageHandler.Pump();
_linkManager.PumpLinks();
llarp::LogTrace("Router::PumpLL() end");
}
@ -224,24 +223,30 @@ namespace llarp
return inbound_link_msg_parser.ProcessFrom(session, buf);
}
//TODO: investigate changes needed for libquic integration
void
Router::Freeze()
{
if (IsServiceNode())
return;
/*
*TODO: investigate changes needed for libquic integration
*
linkManager().ForEachPeer([](auto peer) {
if (peer)
peer->Close();
});
*
*/
}
//TODO: investigate changes needed for libquic integration
void
Router::Thaw()
{
if (IsServiceNode())
return;
/*
*TODO: investigate changes needed for libquic integration
*
// get pubkeys we are connected to
std::unordered_set<RouterID> peerPubkeys;
linkManager().ForEachPeer([&peerPubkeys](auto peer) {
@ -261,6 +266,8 @@ namespace llarp
return true;
});
LogInfo("We are ready to go bruh... probably");
*
*/
}
void
@ -316,14 +323,14 @@ namespace llarp
void
Router::ForEachPeer(std::function<void(const ILinkSession*, bool)> visit, bool randomize) const
{
_linkManager.ForEachPeer(visit, randomize);
//_linkManager.ForEachPeer(visit, randomize);
}
//TODO: if still needed/useful, replace this in line with libquic impl
void
Router::ForEachPeer(std::function<void(ILinkSession*)> visit)
{
_linkManager.ForEachPeer(visit);
//_linkManager.ForEachPeer(visit);
}
void
@ -338,7 +345,7 @@ namespace llarp
if (remote.Verify(Now()))
{
LogDebug("verified signature");
_linkManager->Connect(remote);
_linkManager.Connect(remote);
}
else
LogError(rcfile, " contains invalid RC");
@ -625,12 +632,14 @@ namespace llarp
{
//TODO: libquic change
// propagate RC by renegotiating sessions
/*
ForEachPeer([](ILinkSession* s) {
if (s->RenegotiateSession())
LogInfo("renegotiated session");
else
LogWarn("failed to renegotiate session");
});
*/
}
if (IsServiceNode())
return SaveRC();
@ -1032,6 +1041,9 @@ namespace llarp
// find all deregistered relays
std::unordered_set<PubKey> closePeers;
/*
* TODO: change for libquic
*
_linkManager.ForEachPeer([&](auto session) {
if (whitelistRouters and not gotWhitelist)
return;
@ -1043,6 +1055,9 @@ namespace llarp
closePeers.emplace(pk);
}
});
*
*
*/
// mark peers as de-registered
for (auto& peer : closePeers)
@ -1134,7 +1149,9 @@ namespace llarp
}
}
//TODO: libquic change
/*
*TODO: libquic change
*
// get connected peers
std::set<dht::Key_t> peersWeHave;
_linkManager.ForEachPeer([&peersWeHave](ILinkSession* s) {
@ -1147,6 +1164,8 @@ namespace llarp
[&peersWeHave](const dht::Key_t& k) -> bool { return peersWeHave.count(k) == 0; });
// expire paths
paths.ExpirePaths(now);
*
*/
// update tick timestamp
_lastTick = llarp::time_now_ms();
}
@ -1184,7 +1203,6 @@ namespace llarp
// TODO: make sure this is a public router (on whitelist)?
m_peerDb->modifyPeerStats(id, [&](PeerStats& stats) { stats.numConnectionTimeouts++; });
}
_outboundSessionMaker.OnConnectTimeout(session);
}
void
@ -1209,7 +1227,6 @@ namespace llarp
m_peerDb->modifyPeerStats(id, [&](PeerStats& stats) { stats.numConnectionSuccesses++; });
}
NotifyRouterEvent<tooling::LinkSessionEstablishedEvent>(pubkey(), id, inbound);
return _outboundSessionMaker.OnSessionEstablished(session);
}
bool
@ -1391,7 +1408,7 @@ namespace llarp
LogDebug("Establishing session to ", router, " for SN testing");
// try to make a session to this random router
// this will do a dht lookup if needed
_linkManager->Connect(router);
_linkManager.Connect(router);
/*
* TODO: container of pending snode test routers to be queried on
@ -1533,7 +1550,6 @@ namespace llarp
paths.PumpUpstream();
llarp::sys::service_manager->stopping();
log::debug(logcat, "final links pump");
_linkManager.PumpLinks();
_loop->call_later(200ms, [this] { AfterStopIssued(); });
}
@ -1590,7 +1606,7 @@ namespace llarp
return false;
}
_linkManager->Connect(rc);
_linkManager.Connect(rc);
return true;
}
@ -1616,14 +1632,16 @@ namespace llarp
return ep and ep->HasExit();
}
//TODO: change to use new LinkManager foreach semantics, or make function for this
// on LinkManager itself
std::optional<std::variant<nuint32_t, nuint128_t>>
Router::OurPublicIP() const
{
if (_ourAddress)
return _ourAddress->getIP();
std::optional<std::variant<nuint32_t, nuint128_t>> found;
/*
*TODO: change to use new LinkManager foreach semantics, or make function for this
* on LinkManager itself
*
_linkManager.ForEachInboundLink([&found](const auto& link) {
if (found)
return;
@ -1631,11 +1649,14 @@ namespace llarp
if (link->GetOurAddressInfo(ai))
found = ai.IP();
});
*
*
*/
return found;
}
void
AddAddressToRC(AddressInfo& ai)
Router::AddAddressToRC(AddressInfo& ai)
{
// override ip and port as needed
if (_ourAddress)
@ -1702,10 +1723,11 @@ namespace llarp
throw std::runtime_error{"no public ip provided for inbound socket"};
}
_linkManager.AddLink(bind_addr.ToString(), true);
AddressInfo ai;
ai.fromSockAddr(bind_addr);
_linkManager.AddLink({ai.IPString(), ai.port}, true);
ai.pubkey = llarp::seckey_topublic(_identity);
ai.dialect = "quicinet"; // FIXME: constant, also better name?
ai.rank = 2; // FIXME: hardcoded from the beginning...keep?
@ -1722,7 +1744,9 @@ namespace llarp
for (auto& bind_addr : addrs)
{
_linkManager.AddLink(bind_addr.ToString(), false);
AddressInfo ai;
ai.fromSockAddr(bind_addr);
_linkManager.AddLink({ai.IPString(), ai.port}, false);
}
}

View File

@ -19,7 +19,6 @@
#include <llarp/profiling.hpp>
#include <llarp/router_contact.hpp>
#include "outbound_message_handler.hpp"
#include "outbound_session_maker.hpp"
#include "rc_gossiper.hpp"
#include "rc_lookup_handler.hpp"
#include "route_poker.hpp"