mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-02 03:40:12 +00:00
Compilation fixes
- almost all errors have been commented out for refactor or already refactored - committing this prior to sorting out the cmake structure - upcoming include-what-you-use application
This commit is contained in:
parent
88fd0852db
commit
66ec886480
@ -206,7 +206,6 @@ add_library(lokinet-service-deprecated-kitchensink
|
||||
endpoint_base.cpp
|
||||
exit/context.cpp
|
||||
exit/endpoint.cpp
|
||||
exit/exit_messages.cpp
|
||||
exit/policy.cpp
|
||||
exit/session.cpp
|
||||
handlers/exit.cpp
|
||||
@ -228,24 +227,10 @@ add_library(lokinet-service-deprecated-kitchensink
|
||||
service/name.cpp
|
||||
service/outbound_context.cpp
|
||||
service/protocol.cpp
|
||||
service/sendcontext.cpp
|
||||
service/session.cpp
|
||||
service/tag.cpp
|
||||
)
|
||||
|
||||
|
||||
# interal tooling for pybind
|
||||
add_library(lokinet-tooling INTERFACE)
|
||||
if(WITH_HIVE)
|
||||
add_library(lokinet-hive-tooling
|
||||
STATIC
|
||||
tooling/router_hive.cpp
|
||||
tooling/hive_router.cpp
|
||||
tooling/hive_context.cpp
|
||||
)
|
||||
target_link_libraries(lokinet-tooling INTERFACE lokinet-hive-tooling)
|
||||
endif()
|
||||
|
||||
# interface library for setting commone includes, linkage and flags.
|
||||
add_library(lokinet-base INTERFACE)
|
||||
target_include_directories(lokinet-base
|
||||
@ -264,7 +249,8 @@ add_library(lokinet-amalgum INTERFACE)
|
||||
|
||||
# helper function to link a library to lokinet-base, enable lto, add to lokinet-amalgum and then link to other libs
|
||||
function(lokinet_link_lib libname)
|
||||
message(DEBUG "created target: ${libname}")
|
||||
# Absolutely fuck this line, it doesn't "create" the target, as the target already exists
|
||||
# message(DEBUG "created target: ${libname}")
|
||||
enable_lto(${libname})
|
||||
target_link_libraries(${libname} PUBLIC lokinet-base ${ARGN})
|
||||
target_link_libraries(lokinet-amalgum INTERFACE ${libname})
|
||||
@ -275,11 +261,7 @@ lokinet_link_lib(lokinet-util lokinet-libntrup)
|
||||
lokinet_link_lib(lokinet-cryptography lokinet-libcrypt lokinet-util)
|
||||
lokinet_link_lib(lokinet-peerstats lokinet-context)
|
||||
lokinet_link_lib(lokinet-consensus lokinet-context)
|
||||
lokinet_link_lib(lokinet-layer-link lokinet-peerstats)
|
||||
|
||||
if(TARGET lokinet-hive-tooling)
|
||||
lokinet_link_lib(lokinet-hive-tooling lokinet-context)
|
||||
endif()
|
||||
lokinet_link_lib(lokinet-layer-link lokinet-cryptography lokinet-peerstats)
|
||||
|
||||
if(TARGET lokinet-dns-systemd)
|
||||
lokinet_link_lib(lokinet-dns-systemd
|
||||
|
@ -1,22 +1,21 @@
|
||||
#include <llarp.hpp>
|
||||
#include "constants/version.hpp"
|
||||
#include "constants/evloop.hpp"
|
||||
|
||||
#include "config/config.hpp"
|
||||
#include "crypto/crypto.hpp"
|
||||
#include "ev/ev.hpp"
|
||||
#include <memory>
|
||||
#include "nodedb.hpp"
|
||||
#include "router/router.hpp"
|
||||
#include "service/context.hpp"
|
||||
#include "util/logging.hpp"
|
||||
|
||||
#include <llarp.hpp>
|
||||
#include <llarp/constants/version.hpp>
|
||||
#include <llarp/constants/evloop.hpp>
|
||||
#include <llarp/config/config.hpp>
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/ev/ev.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/service/context.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
#include <llarp/util/service_manager.hpp>
|
||||
|
||||
#include <CLI/App.hpp>
|
||||
#include <CLI/Formatter.hpp>
|
||||
#include <CLI/Config.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <csignal>
|
||||
#include <stdexcept>
|
||||
|
||||
@ -89,7 +88,9 @@ namespace llarp
|
||||
Context::makeNodeDB()
|
||||
{
|
||||
return std::make_shared<NodeDB>(
|
||||
nodedb_dirname, [r = router.get()](auto call) { r->queue_disk_io(std::move(call)); });
|
||||
nodedb_dirname,
|
||||
[r = router.get()](auto call) { r->queue_disk_io(std::move(call)); },
|
||||
router.get());
|
||||
}
|
||||
|
||||
std::shared_ptr<Router>
|
||||
|
@ -1,22 +1,15 @@
|
||||
#include "context.hpp"
|
||||
|
||||
#include "explorenetworkjob.hpp"
|
||||
#include "localrouterlookup.hpp"
|
||||
#include "localserviceaddresslookup.hpp"
|
||||
#include "localtaglookup.hpp"
|
||||
#include <llarp/dht/messages/findrouter.hpp>
|
||||
#include <llarp/dht/messages/gotintro.hpp>
|
||||
#include <llarp/dht/messages/gotrouter.hpp>
|
||||
#include <llarp/dht/messages/pubintro.hpp>
|
||||
#include "node.hpp"
|
||||
#include "publishservicejob.hpp"
|
||||
#include "recursiverouterlookup.hpp"
|
||||
#include "serviceaddresslookup.hpp"
|
||||
#include "taglookup.hpp"
|
||||
#include <llarp/messages/dht_immediate.hpp>
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/routing/path_dht_message.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/profiling.hpp>
|
||||
#include <llarp/router/rc_lookup_handler.hpp>
|
||||
|
@ -1,42 +1,41 @@
|
||||
#include "context.hpp"
|
||||
#include "dht.h"
|
||||
#include <llarp/router_contact.hpp>
|
||||
|
||||
llarp_dht_context::llarp_dht_context(llarp::Router* router)
|
||||
{
|
||||
parent = router;
|
||||
impl = llarp::dht::make_handler();
|
||||
}
|
||||
// llarp_dht_context::llarp_dht_context(llarp::Router* router)
|
||||
// {
|
||||
// parent = router;
|
||||
// impl = llarp::dht::make_handler();
|
||||
// }
|
||||
|
||||
struct llarp_dht_context*
|
||||
llarp_dht_context_new(llarp::Router* router)
|
||||
{
|
||||
return new llarp_dht_context(router);
|
||||
}
|
||||
// struct llarp_dht_context*
|
||||
// llarp_dht_context_new(llarp::Router* router)
|
||||
// {
|
||||
// return new llarp_dht_context(router);
|
||||
// }
|
||||
|
||||
void
|
||||
llarp_dht_context_free(struct llarp_dht_context* ctx)
|
||||
{
|
||||
delete ctx;
|
||||
}
|
||||
// void
|
||||
// llarp_dht_context_free(struct llarp_dht_context* ctx)
|
||||
// {
|
||||
// delete ctx;
|
||||
// }
|
||||
|
||||
void
|
||||
__llarp_dht_remove_peer(struct llarp_dht_context* ctx, const byte_t* id)
|
||||
{
|
||||
ctx->impl->Nodes()->DelNode(llarp::dht::Key_t(id));
|
||||
}
|
||||
// void
|
||||
// __llarp_dht_remove_peer(struct llarp_dht_context* ctx, const byte_t* id)
|
||||
// {
|
||||
// ctx->impl->Nodes()->DelNode(llarp::dht::Key_t(id));
|
||||
// }
|
||||
|
||||
void
|
||||
llarp_dht_allow_transit(llarp_dht_context* ctx)
|
||||
{
|
||||
ctx->impl->AllowTransit() = true;
|
||||
}
|
||||
// void
|
||||
// llarp_dht_allow_transit(llarp_dht_context* ctx)
|
||||
// {
|
||||
// ctx->impl->AllowTransit() = true;
|
||||
// }
|
||||
|
||||
void
|
||||
llarp_dht_context_start(struct llarp_dht_context* ctx, const byte_t* key)
|
||||
{
|
||||
ctx->impl->Init(llarp::dht::Key_t(key), ctx->parent);
|
||||
}
|
||||
// void
|
||||
// llarp_dht_context_start(struct llarp_dht_context* ctx, const byte_t* key)
|
||||
// {
|
||||
// ctx->impl->Init(llarp::dht::Key_t(key), ctx->parent);
|
||||
// }
|
||||
|
||||
void
|
||||
llarp_dht_lookup_router(struct llarp_dht_context* ctx, struct llarp_router_lookup_job* job)
|
||||
|
@ -1,38 +0,0 @@
|
||||
#include "explorenetworkjob.hpp"
|
||||
|
||||
#include <llarp/router/router.hpp>
|
||||
|
||||
#include <llarp/nodedb.hpp>
|
||||
|
||||
#include <llarp/tooling/dht_event.hpp>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
void
|
||||
ExploreNetworkJob::Start(const TXOwner& peer)
|
||||
{
|
||||
auto msg = new FindRouterMessage(peer.txid);
|
||||
auto router = parent->GetRouter();
|
||||
if (router)
|
||||
{
|
||||
router->notify_router_event<tooling::FindRouterSentEvent>(router->pubkey(), *msg);
|
||||
}
|
||||
parent->DHTSendTo(peer.node.as_array(), msg);
|
||||
}
|
||||
|
||||
void
|
||||
ExploreNetworkJob::SendReply()
|
||||
{
|
||||
llarp::LogDebug("got ", valuesFound.size(), " routers from exploration");
|
||||
|
||||
auto router = parent->GetRouter();
|
||||
for (const auto& pk : valuesFound)
|
||||
{
|
||||
// lookup router
|
||||
if (router and router->node_db()->Has(pk))
|
||||
continue;
|
||||
parent->LookupRouter(
|
||||
pk, [router, pk](const auto& res) { router->HandleDHTLookupForExplore(pk, res); });
|
||||
}
|
||||
}
|
||||
} // namespace llarp::dht
|
@ -1,30 +0,0 @@
|
||||
#ifndef LLARP_DHT_EXPLORENETWORKJOB
|
||||
#define LLARP_DHT_EXPLORENETWORKJOB
|
||||
|
||||
#include "tx.hpp"
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
struct ExploreNetworkJob : public TX<RouterID, RouterID>
|
||||
{
|
||||
ExploreNetworkJob(const RouterID& peer, AbstractDHTMessageHandler* ctx)
|
||||
: TX<RouterID, RouterID>(TXOwner{}, peer, ctx)
|
||||
{}
|
||||
|
||||
bool
|
||||
Validate(const RouterID&) const override
|
||||
{
|
||||
// TODO: check with lokid
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Start(const TXOwner& peer) override;
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
} // namespace llarp::dht
|
||||
|
||||
#endif
|
@ -1,61 +0,0 @@
|
||||
#include "localrouterlookup.hpp"
|
||||
|
||||
#include "context.hpp"
|
||||
#include <llarp/dht/messages/gotrouter.hpp>
|
||||
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/routing/path_dht_message.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
LocalRouterLookup::LocalRouterLookup(
|
||||
const PathID_t& path, uint64_t txid, const RouterID& _target, AbstractDHTMessageHandler* ctx)
|
||||
: RecursiveRouterLookup(TXOwner{ctx->OurKey(), txid}, _target, ctx, nullptr), localPath(path)
|
||||
{}
|
||||
|
||||
void
|
||||
LocalRouterLookup::SendReply()
|
||||
{
|
||||
auto path =
|
||||
parent->GetRouter()->path_context().GetByUpstream(parent->OurKey().as_array(), localPath);
|
||||
if (!path)
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"did not send reply for relayed dht request, no such local path "
|
||||
"for pathid=",
|
||||
localPath);
|
||||
return;
|
||||
}
|
||||
if (valuesFound.size())
|
||||
{
|
||||
RouterContact found;
|
||||
for (const auto& rc : valuesFound)
|
||||
{
|
||||
if (rc.OtherIsNewer(found))
|
||||
found = rc;
|
||||
}
|
||||
valuesFound.clear();
|
||||
if (not found.pubkey.IsZero())
|
||||
{
|
||||
valuesFound.resize(1);
|
||||
valuesFound[0] = found;
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogWarn("We found a null RC for dht request, dropping it");
|
||||
}
|
||||
}
|
||||
routing::PathDHTMessage msg;
|
||||
msg.dht_msgs.emplace_back(
|
||||
new GotRouterMessage(parent->OurKey(), whoasked.txid, valuesFound, true));
|
||||
if (!path->SendRoutingMessage(msg, parent->GetRouter()))
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"failed to send routing message when informing result of dht "
|
||||
"request, pathid=",
|
||||
localPath);
|
||||
}
|
||||
}
|
||||
} // namespace llarp::dht
|
@ -1,27 +0,0 @@
|
||||
#ifndef LLARP_DHT_LOCALROUTERLOOKUP
|
||||
#define LLARP_DHT_LOCALROUTERLOOKUP
|
||||
|
||||
#include "recursiverouterlookup.hpp"
|
||||
|
||||
#include <llarp/path/path_types.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
struct LocalRouterLookup : public RecursiveRouterLookup
|
||||
{
|
||||
PathID_t localPath;
|
||||
|
||||
LocalRouterLookup(
|
||||
const PathID_t& path,
|
||||
uint64_t txid,
|
||||
const RouterID& target,
|
||||
AbstractDHTMessageHandler* ctx);
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
} // namespace llarp::dht
|
||||
|
||||
#endif
|
@ -1,58 +0,0 @@
|
||||
#include "localserviceaddresslookup.hpp"
|
||||
|
||||
#include "context.hpp"
|
||||
#include <llarp/dht/messages/gotintro.hpp>
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/routing/path_dht_message.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
LocalServiceAddressLookup::LocalServiceAddressLookup(
|
||||
const PathID_t& pathid,
|
||||
uint64_t txid,
|
||||
uint64_t relayOrder,
|
||||
const Key_t& addr,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
[[maybe_unused]] const Key_t& askpeer)
|
||||
: ServiceAddressLookup(TXOwner{ctx->OurKey(), txid}, addr, ctx, relayOrder, nullptr)
|
||||
, localPath(pathid)
|
||||
{}
|
||||
|
||||
void
|
||||
LocalServiceAddressLookup::SendReply()
|
||||
{
|
||||
auto path =
|
||||
parent->GetRouter()->path_context().GetByUpstream(parent->OurKey().as_array(), localPath);
|
||||
if (!path)
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"did not send reply for relayed dht request, no such local path "
|
||||
"for pathid=",
|
||||
localPath);
|
||||
return;
|
||||
}
|
||||
// pick newest if we have more than 1 result
|
||||
if (valuesFound.size())
|
||||
{
|
||||
service::EncryptedIntroSet found;
|
||||
for (const auto& introset : valuesFound)
|
||||
{
|
||||
if (found.OtherIsNewer(introset))
|
||||
found = introset;
|
||||
}
|
||||
valuesFound.clear();
|
||||
valuesFound.emplace_back(found);
|
||||
}
|
||||
routing::PathDHTMessage msg;
|
||||
msg.dht_msgs.emplace_back(new GotIntroMessage(valuesFound, whoasked.txid));
|
||||
if (!path->SendRoutingMessage(msg, parent->GetRouter()))
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"failed to send routing message when informing result of dht "
|
||||
"request, pathid=",
|
||||
localPath);
|
||||
}
|
||||
}
|
||||
} // namespace llarp::dht
|
@ -1,28 +0,0 @@
|
||||
#ifndef LLARP_DHT_LOCALSERVICEADDRESSLOOKUP
|
||||
#define LLARP_DHT_LOCALSERVICEADDRESSLOOKUP
|
||||
|
||||
#include "serviceaddresslookup.hpp"
|
||||
|
||||
#include <llarp/path/path_types.hpp>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
struct LocalServiceAddressLookup : public ServiceAddressLookup
|
||||
{
|
||||
PathID_t localPath;
|
||||
|
||||
LocalServiceAddressLookup(
|
||||
const PathID_t& pathid,
|
||||
uint64_t txid,
|
||||
uint64_t relayOrder,
|
||||
const Key_t& addr,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
[[maybe_unused]] const Key_t& askpeer);
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
|
||||
} // namespace llarp::dht
|
||||
|
||||
#endif
|
@ -1,42 +0,0 @@
|
||||
#include "localtaglookup.hpp"
|
||||
|
||||
#include "context.hpp"
|
||||
#include <llarp/dht/messages/gotintro.hpp>
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/routing/path_dht_message.hpp>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
LocalTagLookup::LocalTagLookup(
|
||||
const PathID_t& path,
|
||||
uint64_t txid,
|
||||
const service::Tag& _target,
|
||||
AbstractDHTMessageHandler* ctx)
|
||||
: TagLookup(TXOwner{ctx->OurKey(), txid}, _target, ctx, 0), localPath(path)
|
||||
{}
|
||||
|
||||
void
|
||||
LocalTagLookup::SendReply()
|
||||
{
|
||||
auto path =
|
||||
parent->GetRouter()->path_context().GetByUpstream(parent->OurKey().as_array(), localPath);
|
||||
if (!path)
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"did not send reply for relayed dht request, no such local path "
|
||||
"for pathid=",
|
||||
localPath);
|
||||
return;
|
||||
}
|
||||
routing::PathDHTMessage msg;
|
||||
msg.dht_msgs.emplace_back(new GotIntroMessage(valuesFound, whoasked.txid));
|
||||
if (!path->SendRoutingMessage(msg, parent->GetRouter()))
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"failed to send routing message when informing result of dht "
|
||||
"request, pathid=",
|
||||
localPath);
|
||||
}
|
||||
}
|
||||
} // namespace llarp::dht
|
@ -1,23 +0,0 @@
|
||||
#ifndef LLARP_DHT_LOOKUPTAGLOOKUP
|
||||
#define LLARP_DHT_LOOKUPTAGLOOKUP
|
||||
|
||||
#include "taglookup.hpp"
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
struct LocalTagLookup : public TagLookup
|
||||
{
|
||||
PathID_t localPath;
|
||||
|
||||
LocalTagLookup(
|
||||
const PathID_t& path,
|
||||
uint64_t txid,
|
||||
const service::Tag& target,
|
||||
AbstractDHTMessageHandler* ctx);
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
} // namespace llarp::dht
|
||||
|
||||
#endif
|
@ -1,138 +0,0 @@
|
||||
#include "context.hpp"
|
||||
#include "oxenc/bt_serialize.h"
|
||||
|
||||
#include <memory>
|
||||
#include <llarp/util/bencode.hpp>
|
||||
#include <llarp/dht/messages/findintro.hpp>
|
||||
#include <llarp/dht/messages/findrouter.hpp>
|
||||
#include <llarp/dht/messages/gotintro.hpp>
|
||||
#include <llarp/dht/messages/gotrouter.hpp>
|
||||
#include <llarp/dht/messages/pubintro.hpp>
|
||||
#include <llarp/dht/messages/findname.hpp>
|
||||
#include <llarp/dht/messages/gotname.hpp>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
struct MessageDecoder
|
||||
{
|
||||
const Key_t& From;
|
||||
std::unique_ptr<AbstractDHTMessage> msg;
|
||||
bool firstKey = true;
|
||||
bool relayed = false;
|
||||
|
||||
MessageDecoder(const Key_t& from, bool wasRelayed) : From(from), relayed(wasRelayed)
|
||||
{}
|
||||
|
||||
bool
|
||||
operator()(llarp_buffer_t* buffer, llarp_buffer_t* key)
|
||||
{
|
||||
llarp_buffer_t strbuf;
|
||||
// check for empty dict
|
||||
if (!key)
|
||||
return !firstKey;
|
||||
// first key
|
||||
if (firstKey)
|
||||
{
|
||||
if (!(key->startswith("A")))
|
||||
return false;
|
||||
if (!bencode_read_string(buffer, &strbuf))
|
||||
return false;
|
||||
// bad msg size?
|
||||
if (strbuf.sz != 1)
|
||||
return false;
|
||||
llarp::LogDebug("Handle DHT message ", *strbuf.base, " relayed=", relayed);
|
||||
switch (*strbuf.base)
|
||||
{
|
||||
case 'N':
|
||||
msg = std::make_unique<FindNameMessage>(From, Key_t{}, 0);
|
||||
break;
|
||||
case 'M':
|
||||
msg = std::make_unique<GotNameMessage>(From, 0, service::EncryptedName{});
|
||||
break;
|
||||
case 'F':
|
||||
msg = std::make_unique<FindIntroMessage>(From, relayed, 0);
|
||||
break;
|
||||
case 'R':
|
||||
if (relayed)
|
||||
msg = std::make_unique<RelayedFindRouterMessage>(From);
|
||||
else
|
||||
msg = std::make_unique<FindRouterMessage>(From);
|
||||
break;
|
||||
case 'S':
|
||||
msg = std::make_unique<GotRouterMessage>(From, relayed);
|
||||
break;
|
||||
case 'I':
|
||||
msg = std::make_unique<PublishIntroMessage>(From, relayed);
|
||||
break;
|
||||
case 'G':
|
||||
if (relayed)
|
||||
{
|
||||
msg = std::make_unique<RelayedGotIntroMessage>();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = std::make_unique<GotIntroMessage>(From);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llarp::LogWarn("unknown dht message type: ", (char)*strbuf.base);
|
||||
// bad msg type
|
||||
return false;
|
||||
}
|
||||
firstKey = false;
|
||||
return msg != nullptr;
|
||||
}
|
||||
|
||||
return msg->decode_key(*key, buffer);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<AbstractDHTMessage>
|
||||
DecodeMessage(const Key_t& from, llarp_buffer_t* buf, bool relayed)
|
||||
{
|
||||
MessageDecoder dec(from, relayed);
|
||||
if (!bencode_read_dict(dec, buf))
|
||||
return nullptr;
|
||||
|
||||
return std::move(dec.msg);
|
||||
}
|
||||
|
||||
struct ListDecoder
|
||||
{
|
||||
ListDecoder(
|
||||
bool hasRelayed, const Key_t& from, std::vector<std::unique_ptr<AbstractDHTMessage>>& list)
|
||||
: relayed(hasRelayed), From(from), l(list)
|
||||
{}
|
||||
|
||||
bool relayed;
|
||||
const Key_t& From;
|
||||
std::vector<std::unique_ptr<AbstractDHTMessage>>& l;
|
||||
|
||||
bool
|
||||
operator()(llarp_buffer_t* buffer, bool has)
|
||||
{
|
||||
if (!has)
|
||||
return true;
|
||||
auto msg = DecodeMessage(From, buffer, relayed);
|
||||
if (msg)
|
||||
{
|
||||
l.emplace_back(std::move(msg));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
DecodeMessageList(
|
||||
Key_t from,
|
||||
llarp_buffer_t* buf,
|
||||
std::vector<std::unique_ptr<AbstractDHTMessage>>& list,
|
||||
bool relayed)
|
||||
{
|
||||
ListDecoder dec(relayed, from, list);
|
||||
return bencode_read_list(dec, buf);
|
||||
}
|
||||
} // namespace llarp::dht
|
@ -1,81 +0,0 @@
|
||||
#include "publishservicejob.hpp"
|
||||
|
||||
#include "context.hpp"
|
||||
#include <llarp/dht/messages/pubintro.hpp>
|
||||
#include <llarp/dht/messages/gotintro.hpp>
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/routing/path_dht_message.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
|
||||
#include <utility>
|
||||
namespace llarp::dht
|
||||
{
|
||||
PublishServiceJob::PublishServiceJob(
|
||||
const TXOwner& asker,
|
||||
const service::EncryptedIntroSet& introset_,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
uint64_t relayOrder_)
|
||||
: TX<TXOwner, service::EncryptedIntroSet>(asker, asker, ctx)
|
||||
, relayOrder(relayOrder_)
|
||||
, introset(introset_)
|
||||
{}
|
||||
|
||||
bool
|
||||
PublishServiceJob::Validate(const service::EncryptedIntroSet& value) const
|
||||
{
|
||||
if (value.derivedSigningKey != introset.derivedSigningKey)
|
||||
{
|
||||
llarp::LogWarn("publish introset acknowledgement acked a different service");
|
||||
return false;
|
||||
}
|
||||
const llarp_time_t now = llarp::time_now_ms();
|
||||
return value.verify(now);
|
||||
}
|
||||
|
||||
void
|
||||
PublishServiceJob::Start(const TXOwner& peer)
|
||||
{
|
||||
parent->DHTSendTo(
|
||||
peer.node.as_array(), new PublishIntroMessage(introset, peer.txid, false, relayOrder));
|
||||
}
|
||||
|
||||
void
|
||||
PublishServiceJob::SendReply()
|
||||
{
|
||||
parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage({introset}, whoasked.txid));
|
||||
}
|
||||
|
||||
LocalPublishServiceJob::LocalPublishServiceJob(
|
||||
const TXOwner& peer,
|
||||
const PathID_t& fromID,
|
||||
uint64_t _txid,
|
||||
const service::EncryptedIntroSet& introset,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
uint64_t relayOrder)
|
||||
: PublishServiceJob(peer, introset, ctx, relayOrder), localPath(fromID), txid(_txid)
|
||||
{}
|
||||
|
||||
void
|
||||
LocalPublishServiceJob::SendReply()
|
||||
{
|
||||
auto path =
|
||||
parent->GetRouter()->path_context().GetByUpstream(parent->OurKey().as_array(), localPath);
|
||||
if (!path)
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"did not send reply for relayed dht request, no such local path "
|
||||
"for pathid=",
|
||||
localPath);
|
||||
return;
|
||||
}
|
||||
routing::PathDHTMessage msg;
|
||||
msg.dht_msgs.emplace_back(new GotIntroMessage({introset}, txid));
|
||||
if (!path->SendRoutingMessage(msg, parent->GetRouter()))
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"failed to send routing message when informing result of dht "
|
||||
"request, pathid=",
|
||||
localPath);
|
||||
}
|
||||
}
|
||||
} // namespace llarp::dht
|
@ -1,51 +0,0 @@
|
||||
#ifndef LLARP_DHT_PUBLISHSERVICEJOB
|
||||
#define LLARP_DHT_PUBLISHSERVICEJOB
|
||||
|
||||
#include "tx.hpp"
|
||||
#include "txowner.hpp"
|
||||
#include <llarp/service/address.hpp>
|
||||
#include <llarp/service/intro_set.hpp>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace llarp::dht
|
||||
{
|
||||
struct PublishServiceJob : public TX<TXOwner, service::EncryptedIntroSet>
|
||||
{
|
||||
uint64_t relayOrder;
|
||||
service::EncryptedIntroSet introset;
|
||||
|
||||
PublishServiceJob(
|
||||
const TXOwner& asker,
|
||||
const service::EncryptedIntroSet& introset,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
uint64_t relayOrder);
|
||||
|
||||
bool
|
||||
Validate(const service::EncryptedIntroSet& introset) const override;
|
||||
|
||||
void
|
||||
Start(const TXOwner& peer) override;
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
|
||||
struct LocalPublishServiceJob : public PublishServiceJob
|
||||
{
|
||||
PathID_t localPath;
|
||||
uint64_t txid;
|
||||
LocalPublishServiceJob(
|
||||
const TXOwner& peer,
|
||||
const PathID_t& fromID,
|
||||
uint64_t txid,
|
||||
const service::EncryptedIntroSet& introset,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
uint64_t relayOrder);
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
} // namespace llarp::dht
|
||||
|
||||
#endif
|
@ -1,71 +0,0 @@
|
||||
#include "recursiverouterlookup.hpp"
|
||||
|
||||
#include "context.hpp"
|
||||
#include <llarp/dht/messages/findrouter.hpp>
|
||||
#include <llarp/dht/messages/gotrouter.hpp>
|
||||
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/router/rc_lookup_handler.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dht
|
||||
{
|
||||
RecursiveRouterLookup::RecursiveRouterLookup(
|
||||
const TXOwner& _whoasked,
|
||||
const RouterID& _target,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
RouterLookupHandler result)
|
||||
: TX<RouterID, RouterContact>(_whoasked, _target, ctx), resultHandler(std::move(result))
|
||||
|
||||
{
|
||||
peersAsked.insert(ctx->OurKey());
|
||||
}
|
||||
|
||||
bool
|
||||
RecursiveRouterLookup::Validate(const RouterContact& rc) const
|
||||
{
|
||||
if (!rc.Verify(parent->Now()))
|
||||
{
|
||||
llarp::LogWarn("rc from lookup result is invalid");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RecursiveRouterLookup::Start(const TXOwner& peer)
|
||||
{
|
||||
parent->DHTSendTo(peer.node.as_array(), new FindRouterMessage(peer.txid, target));
|
||||
}
|
||||
|
||||
void
|
||||
RecursiveRouterLookup::SendReply()
|
||||
{
|
||||
if (valuesFound.size())
|
||||
{
|
||||
RouterContact found;
|
||||
for (const auto& rc : valuesFound)
|
||||
{
|
||||
if (found.OtherIsNewer(rc) && parent->GetRouter()->rc_lookup_handler().check_rc(rc))
|
||||
found = rc;
|
||||
}
|
||||
valuesFound.clear();
|
||||
valuesFound.emplace_back(found);
|
||||
}
|
||||
if (resultHandler)
|
||||
{
|
||||
resultHandler(valuesFound);
|
||||
}
|
||||
if (whoasked.node != parent->OurKey())
|
||||
{
|
||||
parent->DHTSendTo(
|
||||
whoasked.node.as_array(),
|
||||
new GotRouterMessage({}, whoasked.txid, valuesFound, false),
|
||||
false);
|
||||
}
|
||||
}
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
@ -1,34 +0,0 @@
|
||||
#ifndef LLARP_DHT_RECURSIVEROUTERLOOKUP
|
||||
#define LLARP_DHT_RECURSIVEROUTERLOOKUP
|
||||
|
||||
#include "tx.hpp"
|
||||
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dht
|
||||
{
|
||||
struct RecursiveRouterLookup : public TX<RouterID, RouterContact>
|
||||
{
|
||||
RouterLookupHandler resultHandler;
|
||||
RecursiveRouterLookup(
|
||||
const TXOwner& whoasked,
|
||||
const RouterID& target,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
RouterLookupHandler result);
|
||||
|
||||
bool
|
||||
Validate(const RouterContact& rc) const override;
|
||||
|
||||
void
|
||||
Start(const TXOwner& peer) override;
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
@ -1,70 +0,0 @@
|
||||
#include "serviceaddresslookup.hpp"
|
||||
|
||||
#include <llarp/dht/messages/findintro.hpp>
|
||||
#include <llarp/dht/messages/gotintro.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dht
|
||||
{
|
||||
ServiceAddressLookup::ServiceAddressLookup(
|
||||
const TXOwner& asker,
|
||||
const Key_t& addr,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
uint32_t order,
|
||||
service::EncryptedIntroSetLookupHandler handler)
|
||||
: TX<TXOwner, service::EncryptedIntroSet>(asker, asker, ctx)
|
||||
, location(addr)
|
||||
, handleResult(std::move(handler))
|
||||
, relayOrder(order)
|
||||
{
|
||||
peersAsked.insert(ctx->OurKey());
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceAddressLookup::Validate(const service::EncryptedIntroSet& value) const
|
||||
{
|
||||
if (!value.verify(parent->Now()))
|
||||
{
|
||||
llarp::LogWarn("Got invalid introset from service lookup");
|
||||
return false;
|
||||
}
|
||||
if (value.derivedSigningKey != location)
|
||||
{
|
||||
llarp::LogWarn("got introset with wrong target from service lookup");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceAddressLookup::Start(const TXOwner& peer)
|
||||
{
|
||||
parent->DHTSendTo(
|
||||
peer.node.as_array(), new FindIntroMessage(peer.txid, location, relayOrder));
|
||||
}
|
||||
|
||||
void
|
||||
ServiceAddressLookup::SendReply()
|
||||
{
|
||||
// get newest introset
|
||||
if (valuesFound.size())
|
||||
{
|
||||
llarp::service::EncryptedIntroSet found;
|
||||
for (const auto& introset : valuesFound)
|
||||
{
|
||||
if (found.OtherIsNewer(introset))
|
||||
found = introset;
|
||||
}
|
||||
valuesFound.clear();
|
||||
valuesFound.emplace_back(found);
|
||||
}
|
||||
if (handleResult)
|
||||
{
|
||||
handleResult(valuesFound);
|
||||
}
|
||||
parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage(valuesFound, whoasked.txid));
|
||||
}
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
@ -1,41 +0,0 @@
|
||||
#ifndef LLARP_DHT_SERVICEADDRESSLOOKUP
|
||||
#define LLARP_DHT_SERVICEADDRESSLOOKUP
|
||||
|
||||
#include "key.hpp"
|
||||
#include "tx.hpp"
|
||||
#include <llarp/service/address.hpp>
|
||||
#include <llarp/service/intro_set.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dht
|
||||
{
|
||||
struct TXOwner;
|
||||
|
||||
struct ServiceAddressLookup : public TX<TXOwner, service::EncryptedIntroSet>
|
||||
{
|
||||
Key_t location;
|
||||
service::EncryptedIntroSetLookupHandler handleResult;
|
||||
uint32_t relayOrder;
|
||||
|
||||
ServiceAddressLookup(
|
||||
const TXOwner& asker,
|
||||
const Key_t& addr,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
uint32_t relayOrder,
|
||||
service::EncryptedIntroSetLookupHandler handler);
|
||||
|
||||
bool
|
||||
Validate(const service::EncryptedIntroSet& value) const override;
|
||||
|
||||
void
|
||||
Start(const TXOwner& peer) override;
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
} // namespace dht
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
#include "taglookup.hpp"
|
||||
|
||||
#include "context.hpp"
|
||||
#include <llarp/dht/messages/gotintro.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dht
|
||||
{
|
||||
bool
|
||||
TagLookup::Validate(const service::EncryptedIntroSet& introset) const
|
||||
{
|
||||
if (!introset.verify(parent->Now()))
|
||||
{
|
||||
llarp::LogWarn("got invalid introset from tag lookup");
|
||||
return false;
|
||||
}
|
||||
if (not introset.topic)
|
||||
return false;
|
||||
if (*introset.topic != target)
|
||||
{
|
||||
llarp::LogWarn("got introset with mismatched topic in tag lookup");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TagLookup::Start(const TXOwner& peer)
|
||||
{
|
||||
parent->DHTSendTo(peer.node.as_array(), new FindIntroMessage(target, peer.txid));
|
||||
}
|
||||
|
||||
void
|
||||
TagLookup::SendReply()
|
||||
{
|
||||
parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage({}, whoasked.txid));
|
||||
}
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
@ -1,35 +0,0 @@
|
||||
#ifndef LLARP_DHT_TAGLOOKUP
|
||||
#define LLARP_DHT_TAGLOOKUP
|
||||
|
||||
#include "tx.hpp"
|
||||
#include <llarp/service/intro_set.hpp>
|
||||
#include <llarp/service/tag.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace dht
|
||||
{
|
||||
struct TagLookup : public TX<service::Tag, service::EncryptedIntroSet>
|
||||
{
|
||||
uint64_t recursionDepth;
|
||||
TagLookup(
|
||||
const TXOwner& asker,
|
||||
const service::Tag& tag,
|
||||
AbstractDHTMessageHandler* ctx,
|
||||
uint64_t recursion)
|
||||
: TX<service::Tag, service::EncryptedIntroSet>(asker, tag, ctx), recursionDepth(recursion)
|
||||
{}
|
||||
|
||||
bool
|
||||
Validate(const service::EncryptedIntroSet& introset) const override;
|
||||
|
||||
void
|
||||
Start(const TXOwner& peer) override;
|
||||
|
||||
void
|
||||
SendReply() override;
|
||||
};
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
110
llarp/dht/tx.hpp
110
llarp/dht/tx.hpp
@ -3,77 +3,77 @@
|
||||
|
||||
#include "key.hpp"
|
||||
#include "txowner.hpp"
|
||||
|
||||
#include <llarp/util/logging.hpp>
|
||||
#include <llarp/util/status.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace llarp::dht
|
||||
namespace llarp
|
||||
{
|
||||
struct AbstractDHTMessageHandler;
|
||||
struct Router;
|
||||
|
||||
template <typename K, typename V>
|
||||
struct TX
|
||||
namespace dht
|
||||
{
|
||||
K target;
|
||||
AbstractDHTMessageHandler* parent;
|
||||
std::set<Key_t> peersAsked;
|
||||
std::vector<V> valuesFound;
|
||||
TXOwner whoasked;
|
||||
|
||||
TX(const TXOwner& asker, const K& k, AbstractDHTMessageHandler* p)
|
||||
: target(k), parent(p), whoasked(asker)
|
||||
{}
|
||||
|
||||
virtual ~TX() = default;
|
||||
|
||||
void
|
||||
OnFound(const Key_t& askedPeer, const V& value);
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const
|
||||
template <typename K, typename V>
|
||||
struct TX
|
||||
{
|
||||
util::StatusObject obj{
|
||||
{"whoasked", whoasked.ExtractStatus()}, {"target", target.ExtractStatus()}};
|
||||
std::vector<util::StatusObject> foundObjs;
|
||||
std::transform(
|
||||
valuesFound.begin(),
|
||||
valuesFound.end(),
|
||||
std::back_inserter(foundObjs),
|
||||
[](const auto& item) -> util::StatusObject { return item.ExtractStatus(); });
|
||||
K target;
|
||||
Router* router;
|
||||
std::set<Key_t> peersAsked;
|
||||
std::vector<V> valuesFound;
|
||||
TXOwner whoasked;
|
||||
|
||||
obj["found"] = foundObjs;
|
||||
std::vector<std::string> asked;
|
||||
std::transform(
|
||||
peersAsked.begin(),
|
||||
peersAsked.end(),
|
||||
std::back_inserter(asked),
|
||||
[](const auto& item) -> std::string { return item.ToString(); });
|
||||
obj["asked"] = asked;
|
||||
return obj;
|
||||
}
|
||||
TX(const TXOwner& asker, const K& k, Router* r) : target(k), router{r}, whoasked(asker)
|
||||
{}
|
||||
|
||||
virtual bool
|
||||
Validate(const V& value) const = 0;
|
||||
virtual ~TX() = default;
|
||||
|
||||
virtual void
|
||||
Start(const TXOwner& peer) = 0;
|
||||
void
|
||||
OnFound(const Key_t& askedPeer, const V& value);
|
||||
|
||||
virtual void
|
||||
SendReply() = 0;
|
||||
};
|
||||
util::StatusObject
|
||||
ExtractStatus() const
|
||||
{
|
||||
util::StatusObject obj{
|
||||
{"whoasked", whoasked.ExtractStatus()}, {"target", target.ExtractStatus()}};
|
||||
std::vector<util::StatusObject> foundObjs;
|
||||
std::transform(
|
||||
valuesFound.begin(),
|
||||
valuesFound.end(),
|
||||
std::back_inserter(foundObjs),
|
||||
[](const auto& item) -> util::StatusObject { return item.ExtractStatus(); });
|
||||
|
||||
template <typename K, typename V>
|
||||
inline void
|
||||
TX<K, V>::OnFound(const Key_t& askedPeer, const V& value)
|
||||
{
|
||||
peersAsked.insert(askedPeer);
|
||||
if (Validate(value))
|
||||
obj["found"] = foundObjs;
|
||||
std::vector<std::string> asked;
|
||||
std::transform(
|
||||
peersAsked.begin(),
|
||||
peersAsked.end(),
|
||||
std::back_inserter(asked),
|
||||
[](const auto& item) -> std::string { return item.ToString(); });
|
||||
obj["asked"] = asked;
|
||||
return obj;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
Validate(const V& value) const = 0;
|
||||
|
||||
virtual void
|
||||
Start(const TXOwner& peer) = 0;
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
inline void
|
||||
TX<K, V>::OnFound(const Key_t& askedPeer, const V& value)
|
||||
{
|
||||
valuesFound.push_back(value);
|
||||
peersAsked.insert(askedPeer);
|
||||
if (Validate(value))
|
||||
{
|
||||
valuesFound.push_back(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace llarp::dht
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
@ -9,208 +9,204 @@
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace llarp
|
||||
namespace llarp::dht
|
||||
{
|
||||
namespace dht
|
||||
template <typename K, typename V>
|
||||
struct TXHolder
|
||||
{
|
||||
template <typename K, typename V>
|
||||
struct TXHolder
|
||||
{
|
||||
using TXPtr = std::unique_ptr<TX<K, V>>;
|
||||
// tx who are waiting for a reply for each key
|
||||
std::unordered_multimap<K, TXOwner> waiting;
|
||||
// tx timesouts by key
|
||||
std::unordered_map<K, llarp_time_t> timeouts;
|
||||
// maps remote peer with tx to handle reply from them
|
||||
std::unordered_map<TXOwner, TXPtr> tx;
|
||||
using TXPtr = std::unique_ptr<TX<K, V>>;
|
||||
// tx who are waiting for a reply for each key
|
||||
std::unordered_multimap<K, TXOwner> waiting;
|
||||
// tx timesouts by key
|
||||
std::unordered_map<K, llarp_time_t> timeouts;
|
||||
// maps remote peer with tx to handle reply from them
|
||||
std::unordered_map<TXOwner, TXPtr> tx;
|
||||
|
||||
const TX<K, V>*
|
||||
GetPendingLookupFrom(const TXOwner& owner) const;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const
|
||||
{
|
||||
util::StatusObject obj{};
|
||||
std::vector<util::StatusObject> txObjs, timeoutsObjs, waitingObjs;
|
||||
std::transform(
|
||||
tx.begin(),
|
||||
tx.end(),
|
||||
std::back_inserter(txObjs),
|
||||
[](const auto& item) -> util::StatusObject {
|
||||
return util::StatusObject{
|
||||
{"owner", item.first.ExtractStatus()}, {"tx", item.second->ExtractStatus()}};
|
||||
});
|
||||
obj["tx"] = txObjs;
|
||||
std::transform(
|
||||
timeouts.begin(),
|
||||
timeouts.end(),
|
||||
std::back_inserter(timeoutsObjs),
|
||||
[](const auto& item) -> util::StatusObject {
|
||||
return util::StatusObject{
|
||||
{"time", to_json(item.second)}, {"target", item.first.ExtractStatus()}};
|
||||
});
|
||||
obj["timeouts"] = timeoutsObjs;
|
||||
std::transform(
|
||||
waiting.begin(),
|
||||
waiting.end(),
|
||||
std::back_inserter(waitingObjs),
|
||||
[](const auto& item) -> util::StatusObject {
|
||||
return util::StatusObject{
|
||||
{"target", item.first.ExtractStatus()},
|
||||
{"whoasked", item.second.ExtractStatus()}};
|
||||
});
|
||||
obj["waiting"] = waitingObjs;
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool
|
||||
HasLookupFor(const K& target) const
|
||||
{
|
||||
return timeouts.find(target) != timeouts.end();
|
||||
}
|
||||
|
||||
bool
|
||||
HasPendingLookupFrom(const TXOwner& owner) const
|
||||
{
|
||||
return GetPendingLookupFrom(owner) != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
NewTX(
|
||||
const TXOwner& askpeer,
|
||||
const TXOwner& whoasked,
|
||||
const K& k,
|
||||
TX<K, V>* t,
|
||||
llarp_time_t requestTimeoutMS = 15s);
|
||||
|
||||
/// mark tx as not fond
|
||||
void
|
||||
NotFound(const TXOwner& from, const std::unique_ptr<Key_t>& next);
|
||||
|
||||
void
|
||||
Found(const TXOwner& from, const K& k, const std::vector<V>& values)
|
||||
{
|
||||
Inform(from, k, values, true);
|
||||
}
|
||||
|
||||
/// inform all watches for key of values found
|
||||
void
|
||||
Inform(
|
||||
TXOwner from,
|
||||
K key,
|
||||
std::vector<V> values,
|
||||
bool sendreply = false,
|
||||
bool removeTimeouts = true);
|
||||
|
||||
void
|
||||
Expire(llarp_time_t now);
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
const TX<K, V>*
|
||||
TXHolder<K, V>::GetPendingLookupFrom(const TXOwner& owner) const
|
||||
{
|
||||
auto itr = tx.find(owner);
|
||||
if (itr == tx.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
GetPendingLookupFrom(const TXOwner& owner) const;
|
||||
|
||||
return itr->second.get();
|
||||
util::StatusObject
|
||||
ExtractStatus() const
|
||||
{
|
||||
util::StatusObject obj{};
|
||||
std::vector<util::StatusObject> txObjs, timeoutsObjs, waitingObjs;
|
||||
std::transform(
|
||||
tx.begin(),
|
||||
tx.end(),
|
||||
std::back_inserter(txObjs),
|
||||
[](const auto& item) -> util::StatusObject {
|
||||
return util::StatusObject{
|
||||
{"owner", item.first.ExtractStatus()}, {"tx", item.second->ExtractStatus()}};
|
||||
});
|
||||
obj["tx"] = txObjs;
|
||||
std::transform(
|
||||
timeouts.begin(),
|
||||
timeouts.end(),
|
||||
std::back_inserter(timeoutsObjs),
|
||||
[](const auto& item) -> util::StatusObject {
|
||||
return util::StatusObject{
|
||||
{"time", to_json(item.second)}, {"target", item.first.ExtractStatus()}};
|
||||
});
|
||||
obj["timeouts"] = timeoutsObjs;
|
||||
std::transform(
|
||||
waiting.begin(),
|
||||
waiting.end(),
|
||||
std::back_inserter(waitingObjs),
|
||||
[](const auto& item) -> util::StatusObject {
|
||||
return util::StatusObject{
|
||||
{"target", item.first.ExtractStatus()}, {"whoasked", item.second.ExtractStatus()}};
|
||||
});
|
||||
obj["waiting"] = waitingObjs;
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool
|
||||
HasLookupFor(const K& target) const
|
||||
{
|
||||
return timeouts.find(target) != timeouts.end();
|
||||
}
|
||||
|
||||
bool
|
||||
HasPendingLookupFrom(const TXOwner& owner) const
|
||||
{
|
||||
return GetPendingLookupFrom(owner) != nullptr;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
TXHolder<K, V>::NewTX(
|
||||
NewTX(
|
||||
const TXOwner& askpeer,
|
||||
const TXOwner& whoasked,
|
||||
const K& k,
|
||||
TX<K, V>* t,
|
||||
llarp_time_t requestTimeoutMS)
|
||||
{
|
||||
(void)whoasked;
|
||||
tx.emplace(askpeer, std::unique_ptr<TX<K, V>>(t));
|
||||
auto count = waiting.count(k);
|
||||
waiting.emplace(k, askpeer);
|
||||
llarp_time_t requestTimeoutMS = 15s);
|
||||
|
||||
auto itr = timeouts.find(k);
|
||||
if (itr == timeouts.end())
|
||||
{
|
||||
timeouts.emplace(k, time_now_ms() + requestTimeoutMS);
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
t->Start(askpeer);
|
||||
}
|
||||
/// mark tx as not fond
|
||||
void
|
||||
NotFound(const TXOwner& from, const std::unique_ptr<Key_t>& next);
|
||||
|
||||
void
|
||||
Found(const TXOwner& from, const K& k, const std::vector<V>& values)
|
||||
{
|
||||
Inform(from, k, values, true);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
/// inform all watches for key of values found
|
||||
void
|
||||
TXHolder<K, V>::NotFound(const TXOwner& from, const std::unique_ptr<Key_t>&)
|
||||
Inform(
|
||||
TXOwner from,
|
||||
K key,
|
||||
std::vector<V> values,
|
||||
bool sendreply = false,
|
||||
bool removeTimeouts = true);
|
||||
|
||||
void
|
||||
Expire(llarp_time_t now);
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
const TX<K, V>*
|
||||
TXHolder<K, V>::GetPendingLookupFrom(const TXOwner& owner) const
|
||||
{
|
||||
auto itr = tx.find(owner);
|
||||
if (itr == tx.end())
|
||||
{
|
||||
auto txitr = tx.find(from);
|
||||
if (txitr == tx.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Inform(from, txitr->second->target, {}, true, true);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
TXHolder<K, V>::Inform(
|
||||
TXOwner from, K key, std::vector<V> values, bool sendreply, bool removeTimeouts)
|
||||
return itr->second.get();
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
TXHolder<K, V>::NewTX(
|
||||
const TXOwner& askpeer,
|
||||
const TXOwner& whoasked,
|
||||
const K& k,
|
||||
TX<K, V>* t,
|
||||
llarp_time_t requestTimeoutMS)
|
||||
{
|
||||
(void)whoasked;
|
||||
tx.emplace(askpeer, std::unique_ptr<TX<K, V>>(t));
|
||||
auto count = waiting.count(k);
|
||||
waiting.emplace(k, askpeer);
|
||||
|
||||
auto itr = timeouts.find(k);
|
||||
if (itr == timeouts.end())
|
||||
{
|
||||
auto range = waiting.equal_range(key);
|
||||
auto itr = range.first;
|
||||
while (itr != range.second)
|
||||
timeouts.emplace(k, time_now_ms() + requestTimeoutMS);
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
t->Start(askpeer);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
TXHolder<K, V>::NotFound(const TXOwner& from, const std::unique_ptr<Key_t>&)
|
||||
{
|
||||
auto txitr = tx.find(from);
|
||||
if (txitr == tx.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Inform(from, txitr->second->target, {}, true, true);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
TXHolder<K, V>::Inform(
|
||||
TXOwner from, K key, std::vector<V> values, bool sendreply, bool removeTimeouts)
|
||||
{
|
||||
auto range = waiting.equal_range(key);
|
||||
auto itr = range.first;
|
||||
while (itr != range.second)
|
||||
{
|
||||
auto txitr = tx.find(itr->second);
|
||||
if (txitr != tx.end())
|
||||
{
|
||||
auto txitr = tx.find(itr->second);
|
||||
if (txitr != tx.end())
|
||||
for (const auto& value : values)
|
||||
{
|
||||
for (const auto& value : values)
|
||||
{
|
||||
txitr->second->OnFound(from.node, value);
|
||||
}
|
||||
if (sendreply)
|
||||
{
|
||||
txitr->second->SendReply();
|
||||
tx.erase(txitr);
|
||||
}
|
||||
txitr->second->OnFound(from.node, value);
|
||||
}
|
||||
if (sendreply)
|
||||
{
|
||||
txitr->second->SendReply();
|
||||
tx.erase(txitr);
|
||||
}
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
|
||||
if (sendreply)
|
||||
{
|
||||
waiting.erase(key);
|
||||
}
|
||||
|
||||
if (removeTimeouts)
|
||||
{
|
||||
timeouts.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
TXHolder<K, V>::Expire(llarp_time_t now)
|
||||
{
|
||||
auto itr = timeouts.begin();
|
||||
while (itr != timeouts.end())
|
||||
{
|
||||
if (now >= itr->second)
|
||||
{
|
||||
Inform(TXOwner{}, itr->first, {}, true, false);
|
||||
itr = timeouts.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
|
||||
if (sendreply)
|
||||
{
|
||||
waiting.erase(key);
|
||||
}
|
||||
|
||||
if (removeTimeouts)
|
||||
{
|
||||
timeouts.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
TXHolder<K, V>::Expire(llarp_time_t now)
|
||||
{
|
||||
auto itr = timeouts.begin();
|
||||
while (itr != timeouts.end())
|
||||
{
|
||||
if (now >= itr->second)
|
||||
{
|
||||
Inform(TXOwner{}, itr->first, {}, true, false);
|
||||
itr = timeouts.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
||||
}
|
||||
} // namespace llarp::dht
|
||||
|
||||
#endif
|
||||
|
@ -4,49 +4,46 @@
|
||||
#include <llarp/util/status.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace llarp
|
||||
namespace llarp::dht
|
||||
{
|
||||
namespace dht
|
||||
struct TXOwner
|
||||
{
|
||||
struct TXOwner
|
||||
Key_t node;
|
||||
uint64_t txid = 0;
|
||||
|
||||
TXOwner() = default;
|
||||
TXOwner(const TXOwner&) = default;
|
||||
TXOwner(TXOwner&&) = default;
|
||||
|
||||
TXOwner&
|
||||
operator=(const TXOwner&) = default;
|
||||
|
||||
TXOwner(const Key_t& k, uint64_t id) : node(k), txid(id)
|
||||
{}
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const
|
||||
{
|
||||
Key_t node;
|
||||
uint64_t txid = 0;
|
||||
util::StatusObject obj{
|
||||
{"txid", txid},
|
||||
{"node", node.ToHex()},
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
|
||||
TXOwner() = default;
|
||||
TXOwner(const TXOwner&) = default;
|
||||
TXOwner(TXOwner&&) = default;
|
||||
bool
|
||||
operator==(const TXOwner& other) const
|
||||
{
|
||||
return std::tie(txid, node) == std::tie(other.txid, other.node);
|
||||
}
|
||||
|
||||
TXOwner&
|
||||
operator=(const TXOwner&) = default;
|
||||
|
||||
TXOwner(const Key_t& k, uint64_t id) : node(k), txid(id)
|
||||
{}
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const
|
||||
{
|
||||
util::StatusObject obj{
|
||||
{"txid", txid},
|
||||
{"node", node.ToHex()},
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const TXOwner& other) const
|
||||
{
|
||||
return std::tie(txid, node) == std::tie(other.txid, other.node);
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const TXOwner& other) const
|
||||
{
|
||||
return std::tie(txid, node) < std::tie(other.txid, other.node);
|
||||
}
|
||||
};
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
||||
bool
|
||||
operator<(const TXOwner& other) const
|
||||
{
|
||||
return std::tie(txid, node) < std::tie(other.txid, other.node);
|
||||
}
|
||||
};
|
||||
} // namespace llarp::dht
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "llarp/ev/ev.hpp"
|
||||
#include "llarp/dns/srv_data.hpp"
|
||||
|
||||
#include <llarp/link/tunnel.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -19,11 +21,6 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace quic
|
||||
{
|
||||
class TunnelManager;
|
||||
}
|
||||
|
||||
namespace dns
|
||||
{
|
||||
class Server;
|
||||
@ -111,7 +108,7 @@ namespace llarp
|
||||
virtual AddressVariant_t
|
||||
LocalAddress() const = 0;
|
||||
|
||||
virtual quic::TunnelManager*
|
||||
virtual link::TunnelManager*
|
||||
GetQUICTunnel() = 0;
|
||||
|
||||
virtual std::optional<AddressVariant_t>
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <llarp/handlers/exit.hpp>
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/quic/tunnel.hpp>
|
||||
|
||||
namespace llarp::exit
|
||||
{
|
||||
@ -14,38 +13,38 @@ namespace llarp::exit
|
||||
huint128_t ip,
|
||||
llarp::handlers::ExitEndpoint* parent)
|
||||
: createdAt{parent->Now()}
|
||||
, m_Parent{parent}
|
||||
, m_remoteSignKey{remoteIdent}
|
||||
, m_CurrentPath{beginPath}
|
||||
, m_IP{ip}
|
||||
, m_RewriteSource{rewriteIP}
|
||||
, parent{parent}
|
||||
, remote_signkey{remoteIdent}
|
||||
, current_path{beginPath}
|
||||
, IP{ip}
|
||||
, rewrite_source{rewriteIP}
|
||||
{
|
||||
m_LastActive = parent->Now();
|
||||
last_active = parent->Now();
|
||||
}
|
||||
|
||||
Endpoint::~Endpoint()
|
||||
{
|
||||
if (m_CurrentPath)
|
||||
m_Parent->DelEndpointInfo(m_CurrentPath->RXID());
|
||||
if (current_path)
|
||||
parent->DelEndpointInfo(current_path->RXID());
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::Close()
|
||||
{
|
||||
m_Parent->RemoveExit(this);
|
||||
parent->RemoveExit(this);
|
||||
}
|
||||
|
||||
util::StatusObject
|
||||
Endpoint::ExtractStatus() const
|
||||
{
|
||||
auto now = m_Parent->Now();
|
||||
auto now = parent->Now();
|
||||
util::StatusObject obj{
|
||||
{"identity", m_remoteSignKey.ToString()},
|
||||
{"ip", m_IP.ToString()},
|
||||
{"txRate", m_TxRate},
|
||||
{"rxRate", m_RxRate},
|
||||
{"identity", remote_signkey.ToString()},
|
||||
{"ip", IP.ToString()},
|
||||
{"txRate", tx_rate},
|
||||
{"rxRate", rx_rate},
|
||||
{"createdAt", to_json(createdAt)},
|
||||
{"exiting", !m_RewriteSource},
|
||||
{"exiting", !rewrite_source},
|
||||
{"looksDead", LooksDead(now)},
|
||||
{"expiresSoon", ExpiresSoon(now)},
|
||||
{"expired", IsExpired(now)}};
|
||||
@ -55,10 +54,10 @@ namespace llarp::exit
|
||||
bool
|
||||
Endpoint::UpdateLocalPath(const llarp::PathID_t& nextPath)
|
||||
{
|
||||
if (!m_Parent->UpdateEndpointPath(m_remoteSignKey, nextPath))
|
||||
if (!parent->UpdateEndpointPath(remote_signkey, nextPath))
|
||||
return false;
|
||||
const RouterID us{m_Parent->GetRouter()->pubkey()};
|
||||
m_CurrentPath = m_Parent->GetRouter()->path_context().GetByUpstream(us, nextPath);
|
||||
const RouterID us{parent->GetRouter()->pubkey()};
|
||||
current_path = parent->GetRouter()->path_context().GetByUpstream(us, nextPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -66,8 +65,8 @@ namespace llarp::exit
|
||||
Endpoint::Tick(llarp_time_t now)
|
||||
{
|
||||
(void)now;
|
||||
m_RxRate = 0;
|
||||
m_TxRate = 0;
|
||||
rx_rate = 0;
|
||||
tx_rate = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -85,8 +84,8 @@ namespace llarp::exit
|
||||
bool
|
||||
Endpoint::ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const
|
||||
{
|
||||
if (m_CurrentPath)
|
||||
return m_CurrentPath->ExpiresSoon(now, dlt);
|
||||
if (current_path)
|
||||
return current_path->ExpiresSoon(now, dlt);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -100,138 +99,145 @@ namespace llarp::exit
|
||||
return true;
|
||||
auto lastPing = path->LastRemoteActivityAt();
|
||||
if (lastPing == 0s || (now > lastPing && now - lastPing > timeout))
|
||||
return now > m_LastActive && now - m_LastActive > timeout;
|
||||
return now > last_active && now - last_active > timeout;
|
||||
else if (lastPing > 0s) // NOLINT
|
||||
return now > lastPing && now - lastPing > timeout;
|
||||
return lastPing > 0s;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::QueueOutboundTraffic(
|
||||
PathID_t path, std::vector<byte_t> buf, uint64_t counter, service::ProtocolType t)
|
||||
{
|
||||
const service::ConvoTag tag{path.as_array()};
|
||||
if (t == service::ProtocolType::QUIC)
|
||||
/* bool
|
||||
Endpoint::QueueOutboundTraffic(
|
||||
PathID_t path, std::vector<byte_t> buf, uint64_t counter, service::ProtocolType t)
|
||||
{
|
||||
auto quic = m_Parent->GetQUICTunnel();
|
||||
if (not quic)
|
||||
const service::ConvoTag tag{path.as_array()};
|
||||
|
||||
// current_path->send_path_control_message(std::string method, std::string body,
|
||||
std::function<void (oxen::quic::message)> func)
|
||||
|
||||
if (t == service::ProtocolType::QUIC)
|
||||
{
|
||||
auto quic = parent->GetQUICTunnel();
|
||||
if (not quic)
|
||||
return false;
|
||||
tx_rate += buf.size();
|
||||
quic->receive_packet(tag, std::move(buf));
|
||||
last_active = parent->Now();
|
||||
return true;
|
||||
}
|
||||
// queue overflow
|
||||
if (m_UpstreamQueue.size() > MaxUpstreamQueueSize)
|
||||
return false;
|
||||
m_TxRate += buf.size();
|
||||
quic->receive_packet(tag, std::move(buf));
|
||||
m_LastActive = m_Parent->Now();
|
||||
return true;
|
||||
}
|
||||
// queue overflow
|
||||
if (m_UpstreamQueue.size() > MaxUpstreamQueueSize)
|
||||
return false;
|
||||
|
||||
llarp::net::IPPacket pkt{std::move(buf)};
|
||||
if (pkt.empty())
|
||||
return false;
|
||||
|
||||
if (pkt.IsV6() && m_Parent->SupportsV6())
|
||||
{
|
||||
huint128_t dst;
|
||||
if (m_RewriteSource)
|
||||
dst = m_Parent->GetIfAddr();
|
||||
else
|
||||
dst = pkt.dstv6();
|
||||
pkt.UpdateIPv6Address(m_IP, dst);
|
||||
}
|
||||
else if (pkt.IsV4() && !m_Parent->SupportsV6())
|
||||
{
|
||||
huint32_t dst;
|
||||
if (m_RewriteSource)
|
||||
dst = net::TruncateV6(m_Parent->GetIfAddr());
|
||||
else
|
||||
dst = pkt.dstv4();
|
||||
pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(m_IP)), xhtonl(dst));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_TxRate += pkt.size();
|
||||
m_UpstreamQueue.emplace(std::move(pkt), counter);
|
||||
m_LastActive = m_Parent->Now();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::QueueInboundTraffic(std::vector<byte_t> buf, service::ProtocolType type)
|
||||
{
|
||||
if (type != service::ProtocolType::QUIC)
|
||||
{
|
||||
llarp::net::IPPacket pkt{std::move(buf)};
|
||||
if (pkt.empty())
|
||||
return false;
|
||||
|
||||
huint128_t src;
|
||||
if (m_RewriteSource)
|
||||
src = m_Parent->GetIfAddr();
|
||||
if (pkt.IsV6() && parent->SupportsV6())
|
||||
{
|
||||
huint128_t dst;
|
||||
if (rewrite_source)
|
||||
dst = parent->GetIfAddr();
|
||||
else
|
||||
dst = pkt.dstv6();
|
||||
pkt.UpdateIPv6Address(IP, dst);
|
||||
}
|
||||
else if (pkt.IsV4() && !parent->SupportsV6())
|
||||
{
|
||||
huint32_t dst;
|
||||
if (rewrite_source)
|
||||
dst = net::TruncateV6(parent->GetIfAddr());
|
||||
else
|
||||
dst = pkt.dstv4();
|
||||
pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(IP)), xhtonl(dst));
|
||||
}
|
||||
else
|
||||
src = pkt.srcv6();
|
||||
if (pkt.IsV6())
|
||||
pkt.UpdateIPv6Address(src, m_IP);
|
||||
else
|
||||
pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(src)), xhtonl(net::TruncateV6(m_IP)));
|
||||
{
|
||||
return false;
|
||||
}
|
||||
tx_rate += pkt.size();
|
||||
m_UpstreamQueue.emplace(std::move(pkt), counter);
|
||||
last_active = parent->Now();
|
||||
return true;
|
||||
} */
|
||||
|
||||
buf = pkt.steal();
|
||||
}
|
||||
bool
|
||||
Endpoint::QueueInboundTraffic(std::vector<byte_t>, service::ProtocolType)
|
||||
{
|
||||
// TODO: this will go away with removing flush
|
||||
|
||||
const uint8_t queue_idx = buf.size() / llarp::routing::EXIT_PAD_SIZE;
|
||||
if (m_DownstreamQueues.find(queue_idx) == m_DownstreamQueues.end())
|
||||
m_DownstreamQueues.emplace(queue_idx, InboundTrafficQueue_t{});
|
||||
auto& queue = m_DownstreamQueues.at(queue_idx);
|
||||
if (queue.size() == 0)
|
||||
{
|
||||
queue.emplace_back();
|
||||
queue.back().protocol = type;
|
||||
return queue.back().PutBuffer(std::move(buf), m_Counter++);
|
||||
}
|
||||
auto& msg = queue.back();
|
||||
if (msg.Size() + buf.size() > llarp::routing::EXIT_PAD_SIZE)
|
||||
{
|
||||
queue.emplace_back();
|
||||
queue.back().protocol = type;
|
||||
return queue.back().PutBuffer(std::move(buf), m_Counter++);
|
||||
}
|
||||
msg.protocol = type;
|
||||
return msg.PutBuffer(std::move(buf), m_Counter++);
|
||||
// if (type != service::ProtocolType::QUIC)
|
||||
// {
|
||||
// llarp::net::IPPacket pkt{std::move(buf)};
|
||||
// if (pkt.empty())
|
||||
// return false;
|
||||
|
||||
// huint128_t src;
|
||||
// if (m_RewriteSource)
|
||||
// src = m_Parent->GetIfAddr();
|
||||
// else
|
||||
// src = pkt.srcv6();
|
||||
// if (pkt.IsV6())
|
||||
// pkt.UpdateIPv6Address(src, m_IP);
|
||||
// else
|
||||
// pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(src)), xhtonl(net::TruncateV6(m_IP)));
|
||||
|
||||
// buf = pkt.steal();
|
||||
// }
|
||||
|
||||
// const uint8_t queue_idx = buf.size() / llarp::routing::EXIT_PAD_SIZE;
|
||||
// if (m_DownstreamQueues.find(queue_idx) == m_DownstreamQueues.end())
|
||||
// m_DownstreamQueues.emplace(queue_idx, InboundTrafficQueue_t{});
|
||||
// auto& queue = m_DownstreamQueues.at(queue_idx);
|
||||
// if (queue.size() == 0)
|
||||
// {
|
||||
// queue.emplace_back();
|
||||
// queue.back().protocol = type;
|
||||
// return queue.back().PutBuffer(std::move(buf), m_Counter++);
|
||||
// }
|
||||
// auto& msg = queue.back();
|
||||
// if (msg.Size() + buf.size() > llarp::routing::EXIT_PAD_SIZE)
|
||||
// {
|
||||
// queue.emplace_back();
|
||||
// queue.back().protocol = type;
|
||||
// return queue.back().PutBuffer(std::move(buf), m_Counter++);
|
||||
// }
|
||||
// msg.protocol = type;
|
||||
// return msg.PutBuffer(std::move(buf), m_Counter++);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::Flush()
|
||||
{
|
||||
// flush upstream queue
|
||||
while (m_UpstreamQueue.size())
|
||||
{
|
||||
m_Parent->QueueOutboundTraffic(const_cast<net::IPPacket&>(m_UpstreamQueue.top().pkt).steal());
|
||||
m_UpstreamQueue.pop();
|
||||
}
|
||||
// while (m_UpstreamQueue.size())
|
||||
// {
|
||||
// parent->QueueOutboundTraffic(const_cast<net::IPPacket&>(m_UpstreamQueue.top().pkt).steal());
|
||||
// m_UpstreamQueue.pop();
|
||||
// }
|
||||
// flush downstream queue
|
||||
auto path = GetCurrentPath();
|
||||
bool sent = path != nullptr;
|
||||
if (path)
|
||||
{
|
||||
for (auto& item : m_DownstreamQueues)
|
||||
{
|
||||
auto& queue = item.second;
|
||||
while (queue.size())
|
||||
{
|
||||
auto& msg = queue.front();
|
||||
msg.sequence_number = path->NextSeqNo();
|
||||
if (path->SendRoutingMessage(msg, m_Parent->GetRouter()))
|
||||
{
|
||||
m_RxRate += msg.Size();
|
||||
sent = true;
|
||||
}
|
||||
queue.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& item : m_DownstreamQueues)
|
||||
item.second.clear();
|
||||
// if (path)
|
||||
// {
|
||||
// for (auto& item : m_DownstreamQueues)
|
||||
// {
|
||||
// auto& queue = item.second;
|
||||
// while (queue.size())
|
||||
// {
|
||||
// auto& msg = queue.front();
|
||||
// msg.sequence_number = path->NextSeqNo();
|
||||
// if (path->SendRoutingMessage(msg, m_Parent->GetRouter()))
|
||||
// {
|
||||
// m_RxRate += msg.Size();
|
||||
// sent = true;
|
||||
// }
|
||||
// queue.pop_front();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// for (auto& item : m_DownstreamQueues)
|
||||
// item.second.clear();
|
||||
return sent;
|
||||
}
|
||||
} // namespace llarp::exit
|
||||
|
@ -65,9 +65,9 @@ namespace llarp
|
||||
|
||||
/// queue outbound traffic
|
||||
/// does ip rewrite here
|
||||
bool
|
||||
QueueOutboundTraffic(
|
||||
PathID_t txid, std::vector<byte_t> data, uint64_t counter, service::ProtocolType t);
|
||||
// bool
|
||||
// QueueOutboundTraffic(
|
||||
// PathID_t txid, std::vector<byte_t> data, uint64_t counter, service::ProtocolType t);
|
||||
|
||||
/// update local path id and cascade information to parent
|
||||
/// return true if success
|
||||
@ -77,66 +77,43 @@ namespace llarp
|
||||
llarp::path::HopHandler_ptr
|
||||
GetCurrentPath() const
|
||||
{
|
||||
return m_CurrentPath;
|
||||
return current_path;
|
||||
}
|
||||
|
||||
const llarp::PubKey&
|
||||
PubKey() const
|
||||
{
|
||||
return m_remoteSignKey;
|
||||
return remote_signkey;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
TxRate() const
|
||||
{
|
||||
return m_TxRate;
|
||||
return tx_rate;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RxRate() const
|
||||
{
|
||||
return m_RxRate;
|
||||
return rx_rate;
|
||||
}
|
||||
|
||||
huint128_t
|
||||
LocalIP() const
|
||||
{
|
||||
return m_IP;
|
||||
return IP;
|
||||
}
|
||||
|
||||
const llarp_time_t createdAt;
|
||||
|
||||
private:
|
||||
llarp::handlers::ExitEndpoint* m_Parent;
|
||||
llarp::PubKey m_remoteSignKey;
|
||||
llarp::path::HopHandler_ptr m_CurrentPath;
|
||||
llarp::huint128_t m_IP;
|
||||
uint64_t m_TxRate, m_RxRate;
|
||||
llarp_time_t m_LastActive;
|
||||
bool m_RewriteSource;
|
||||
using InboundTrafficQueue_t = std::deque<llarp::routing::TransferTrafficMessage>;
|
||||
using TieredQueue = std::map<uint8_t, InboundTrafficQueue_t>;
|
||||
// maps number of fragments the message will fit in to the queue for it
|
||||
TieredQueue m_DownstreamQueues;
|
||||
|
||||
struct UpstreamBuffer
|
||||
{
|
||||
UpstreamBuffer(llarp::net::IPPacket p, uint64_t c) : pkt{std::move(p)}, counter(c)
|
||||
{}
|
||||
|
||||
llarp::net::IPPacket pkt;
|
||||
uint64_t counter;
|
||||
|
||||
bool
|
||||
operator<(const UpstreamBuffer& other) const
|
||||
{
|
||||
return counter < other.counter;
|
||||
}
|
||||
};
|
||||
|
||||
using UpstreamQueue_t = std::priority_queue<UpstreamBuffer>;
|
||||
UpstreamQueue_t m_UpstreamQueue;
|
||||
uint64_t m_Counter;
|
||||
llarp::handlers::ExitEndpoint* parent;
|
||||
llarp::PubKey remote_signkey;
|
||||
llarp::path::HopHandler_ptr current_path;
|
||||
llarp::huint128_t IP;
|
||||
uint64_t tx_rate, rx_rate;
|
||||
llarp_time_t last_active;
|
||||
bool rewrite_source;
|
||||
};
|
||||
} // namespace exit
|
||||
} // namespace llarp
|
||||
|
@ -1,364 +0,0 @@
|
||||
#include "exit_messages.hpp"
|
||||
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/routing/handler.hpp>
|
||||
|
||||
namespace llarp::routing
|
||||
{
|
||||
bool
|
||||
ObtainExitMessage::Sign(const llarp::SecretKey& sk)
|
||||
{
|
||||
pubkey = seckey_topublic(sk);
|
||||
sig.Zero();
|
||||
|
||||
auto bte = bt_encode();
|
||||
return CryptoManager::instance()->sign(
|
||||
sig, sk, reinterpret_cast<uint8_t*>(bte.data()), bte.size());
|
||||
}
|
||||
|
||||
bool
|
||||
ObtainExitMessage::Verify() const
|
||||
{
|
||||
ObtainExitMessage copy;
|
||||
copy = *this;
|
||||
copy.sig.Zero();
|
||||
|
||||
auto bte = copy.bt_encode();
|
||||
return CryptoManager::instance()->verify(
|
||||
pubkey, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), sig);
|
||||
}
|
||||
|
||||
std::string
|
||||
ObtainExitMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("E", flag);
|
||||
btdp.append("I", pubkey.ToView());
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
btdp.append("Z", sig.ToView());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(route_cat, "Error: ObtainExitMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
ObtainExitMessage::decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictInt("E", flag, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("I", pubkey, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("S", sequence_number, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("T", tx_id, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Z", sig, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
ObtainExitMessage::handle_message(AbstractRoutingMessageHandler* h, Router* r) const
|
||||
{
|
||||
return h->HandleObtainExitMessage(*this, r);
|
||||
}
|
||||
|
||||
std::string
|
||||
GrantExitMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
btdp.append("Y", nonce.ToView());
|
||||
btdp.append("Z", sig.ToView());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(route_cat, "Error: GrantExitMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
GrantExitMessage::decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictInt("S", sequence_number, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("T", tx_id, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Y", nonce, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Z", sig, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
GrantExitMessage::Verify(const llarp::PubKey& pk) const
|
||||
{
|
||||
GrantExitMessage copy;
|
||||
copy = *this;
|
||||
copy.sig.Zero();
|
||||
|
||||
auto bte = copy.bt_encode();
|
||||
return CryptoManager::instance()->verify(
|
||||
pk, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), sig);
|
||||
}
|
||||
|
||||
bool
|
||||
GrantExitMessage::Sign(const llarp::SecretKey& sk)
|
||||
{
|
||||
sig.Zero();
|
||||
nonce.Randomize();
|
||||
|
||||
auto bte = bt_encode();
|
||||
return CryptoManager::instance()->sign(
|
||||
sig, sk, reinterpret_cast<uint8_t*>(bte.data()), bte.size());
|
||||
}
|
||||
|
||||
bool
|
||||
GrantExitMessage::handle_message(AbstractRoutingMessageHandler* h, Router* r) const
|
||||
{
|
||||
return h->HandleGrantExitMessage(*this, r);
|
||||
}
|
||||
|
||||
std::string
|
||||
RejectExitMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("B", backoff_time);
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
btdp.append("Y", nonce.ToView());
|
||||
btdp.append("Z", sig.ToView());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(route_cat, "Error: RejectExitMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
RejectExitMessage::decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictInt("B", backoff_time, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("S", sequence_number, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("T", tx_id, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Y", nonce, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Z", sig, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
RejectExitMessage::Sign(const llarp::SecretKey& sk)
|
||||
{
|
||||
sig.Zero();
|
||||
nonce.Randomize();
|
||||
|
||||
auto bte = bt_encode();
|
||||
return CryptoManager::instance()->sign(
|
||||
sig, sk, reinterpret_cast<uint8_t*>(bte.data()), bte.size());
|
||||
}
|
||||
|
||||
bool
|
||||
RejectExitMessage::Verify(const llarp::PubKey& pk) const
|
||||
{
|
||||
RejectExitMessage copy;
|
||||
copy = *this;
|
||||
copy.sig.Zero();
|
||||
|
||||
auto bte = copy.bt_encode();
|
||||
return CryptoManager::instance()->verify(
|
||||
pk, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), sig);
|
||||
}
|
||||
|
||||
bool
|
||||
RejectExitMessage::handle_message(AbstractRoutingMessageHandler* h, Router* r) const
|
||||
{
|
||||
return h->HandleRejectExitMessage(*this, r);
|
||||
}
|
||||
|
||||
std::string
|
||||
UpdateExitMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("P", path_id.ToView());
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
btdp.append("Z", sig.ToView());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(route_cat, "Error: UpdateExitMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
UpdateExitMessage::decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictInt("S", sequence_number, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("T", tx_id, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("P", path_id, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Z", sig, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
UpdateExitMessage::Verify(const llarp::PubKey& pk) const
|
||||
{
|
||||
UpdateExitMessage copy;
|
||||
copy = *this;
|
||||
copy.sig.Zero();
|
||||
|
||||
auto bte = copy.bt_encode();
|
||||
return CryptoManager::instance()->verify(
|
||||
pk, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), sig);
|
||||
}
|
||||
|
||||
bool
|
||||
UpdateExitMessage::Sign(const llarp::SecretKey& sk)
|
||||
{
|
||||
nonce.Randomize();
|
||||
|
||||
auto bte = bt_encode();
|
||||
return CryptoManager::instance()->sign(
|
||||
sig, sk, reinterpret_cast<uint8_t*>(bte.data()), bte.size());
|
||||
}
|
||||
|
||||
bool
|
||||
UpdateExitMessage::handle_message(AbstractRoutingMessageHandler* h, Router* r) const
|
||||
{
|
||||
return h->HandleUpdateExitMessage(*this, r);
|
||||
}
|
||||
|
||||
std::string
|
||||
UpdateExitVerifyMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(route_cat, "Error: UpdateExitVerifyMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
UpdateExitVerifyMessage::decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictInt("S", sequence_number, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("T", tx_id, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
UpdateExitVerifyMessage::handle_message(AbstractRoutingMessageHandler* h, Router* r) const
|
||||
{
|
||||
return h->HandleUpdateExitVerifyMessage(*this, r);
|
||||
}
|
||||
|
||||
std::string
|
||||
CloseExitMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("Y", nonce.ToView());
|
||||
btdp.append("Z", sig.ToView());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(route_cat, "Error: CloseExitMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
CloseExitMessage::decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictInt("S", sequence_number, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Y", nonce, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Z", sig, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
CloseExitMessage::Verify(const llarp::PubKey& pk) const
|
||||
{
|
||||
CloseExitMessage copy;
|
||||
copy = *this;
|
||||
copy.sig.Zero();
|
||||
|
||||
auto bte = copy.bt_encode();
|
||||
return CryptoManager::instance()->verify(
|
||||
pk, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), sig);
|
||||
}
|
||||
|
||||
bool
|
||||
CloseExitMessage::Sign(const llarp::SecretKey& sk)
|
||||
{
|
||||
sig.Zero();
|
||||
nonce.Randomize();
|
||||
|
||||
auto bte = bt_encode();
|
||||
return CryptoManager::instance()->sign(
|
||||
sig, sk, reinterpret_cast<uint8_t*>(bte.data()), bte.size());
|
||||
}
|
||||
|
||||
bool
|
||||
CloseExitMessage::handle_message(AbstractRoutingMessageHandler* h, Router* r) const
|
||||
{
|
||||
return h->HandleCloseExitMessage(*this, r);
|
||||
}
|
||||
} // namespace llarp::routing
|
@ -1,195 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/crypto/types.hpp>
|
||||
#include "policy.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace llarp::routing
|
||||
{
|
||||
struct ObtainExitMessage final : public AbstractRoutingMessage
|
||||
{
|
||||
uint64_t flag{0}; // 0 for snode, 1 for internet access
|
||||
llarp::PubKey pubkey;
|
||||
uint64_t tx_id{0};
|
||||
llarp::Signature sig;
|
||||
|
||||
ObtainExitMessage() : AbstractRoutingMessage()
|
||||
{}
|
||||
|
||||
~ObtainExitMessage() override = default;
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
flag = 0;
|
||||
pubkey.Zero();
|
||||
tx_id = 0;
|
||||
sig.Zero();
|
||||
}
|
||||
|
||||
/// populates I and signs
|
||||
bool
|
||||
Sign(const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify() const;
|
||||
|
||||
std::string
|
||||
bt_encode() const override;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
|
||||
|
||||
bool
|
||||
handle_message(AbstractRoutingMessageHandler* h, Router* r) const override;
|
||||
};
|
||||
|
||||
struct GrantExitMessage final : public AbstractRoutingMessage
|
||||
{
|
||||
uint64_t tx_id;
|
||||
llarp::AlignedBuffer<16> nonce;
|
||||
llarp::Signature sig;
|
||||
|
||||
std::string
|
||||
bt_encode() const override;
|
||||
|
||||
bool
|
||||
Sign(const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify(const llarp::PubKey& pk) const;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
|
||||
|
||||
bool
|
||||
handle_message(AbstractRoutingMessageHandler* h, Router* r) const override;
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
tx_id = 0;
|
||||
nonce.Zero();
|
||||
sig.Zero();
|
||||
}
|
||||
};
|
||||
|
||||
struct RejectExitMessage final : public AbstractRoutingMessage
|
||||
{
|
||||
uint64_t backoff_time;
|
||||
uint64_t tx_id;
|
||||
llarp::AlignedBuffer<16> nonce;
|
||||
llarp::Signature sig;
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
backoff_time = 0;
|
||||
tx_id = 0;
|
||||
nonce.Zero();
|
||||
sig.Zero();
|
||||
}
|
||||
|
||||
bool
|
||||
Sign(const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify(const llarp::PubKey& pk) const;
|
||||
|
||||
std::string
|
||||
bt_encode() const override;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
|
||||
|
||||
bool
|
||||
handle_message(AbstractRoutingMessageHandler* h, Router* r) const override;
|
||||
};
|
||||
|
||||
struct UpdateExitVerifyMessage final : public AbstractRoutingMessage
|
||||
{
|
||||
uint64_t tx_id;
|
||||
llarp::AlignedBuffer<16> nonce;
|
||||
llarp::Signature sig;
|
||||
|
||||
~UpdateExitVerifyMessage() override = default;
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
tx_id = 0;
|
||||
nonce.Zero();
|
||||
sig.Zero();
|
||||
}
|
||||
|
||||
std::string
|
||||
bt_encode() const override;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
|
||||
|
||||
bool
|
||||
handle_message(AbstractRoutingMessageHandler* h, Router* r) const override;
|
||||
};
|
||||
|
||||
struct UpdateExitMessage final : public AbstractRoutingMessage
|
||||
{
|
||||
llarp::PathID_t path_id;
|
||||
uint64_t tx_id;
|
||||
llarp::AlignedBuffer<16> nonce;
|
||||
llarp::Signature sig;
|
||||
|
||||
bool
|
||||
Sign(const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify(const llarp::PubKey& pk) const;
|
||||
|
||||
std::string
|
||||
bt_encode() const override;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
|
||||
|
||||
bool
|
||||
handle_message(AbstractRoutingMessageHandler* h, Router* r) const override;
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
path_id.Zero();
|
||||
tx_id = 0;
|
||||
nonce.Zero();
|
||||
sig.Zero();
|
||||
}
|
||||
};
|
||||
|
||||
struct CloseExitMessage final : public AbstractRoutingMessage
|
||||
{
|
||||
llarp::AlignedBuffer<16> nonce;
|
||||
llarp::Signature sig;
|
||||
|
||||
std::string
|
||||
bt_encode() const override;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
|
||||
|
||||
bool
|
||||
handle_message(AbstractRoutingMessageHandler* h, Router* r) const override;
|
||||
|
||||
bool
|
||||
Sign(const llarp::SecretKey& sk);
|
||||
|
||||
bool
|
||||
Verify(const llarp::PubKey& pk) const;
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
nonce.Zero();
|
||||
sig.Zero();
|
||||
}
|
||||
};
|
||||
} // namespace llarp::routing
|
@ -4,7 +4,6 @@
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/path/path.hpp>
|
||||
#include <llarp/quic/tunnel.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/util/meta/memfn.hpp>
|
||||
#include <utility>
|
||||
@ -99,6 +98,7 @@ namespace llarp::exit
|
||||
// p->SetExitTrafficHandler(util::memFn(&BaseSession::HandleTraffic, this));
|
||||
// p->AddObtainExitHandler(util::memFn(&BaseSession::HandleGotExit, this));
|
||||
|
||||
// TODO: add callback here
|
||||
if (p->obtain_exit(
|
||||
exit_key, std::is_same_v<decltype(p), ExitSession> ? 1 : 0, p->TXID().bt_encode()))
|
||||
log::info(link_cat, "Asking {} for exit", exit_router);
|
||||
@ -171,9 +171,12 @@ namespace llarp::exit
|
||||
if (p->SupportsAnyRoles(path::ePathRoleExit))
|
||||
{
|
||||
LogInfo(p->name(), " closing exit path");
|
||||
routing::CloseExitMessage msg;
|
||||
if (!(msg.Sign(exit_key) && p->SendExitClose(msg, router)))
|
||||
LogWarn(p->name(), " failed to send exit close message");
|
||||
// TODO: add callback here
|
||||
|
||||
if (p->close_exit(exit_key, p->TXID().bt_encode()))
|
||||
log::info(link_cat, "");
|
||||
else
|
||||
log::warning(link_cat, "{} failed to send exit close message", p->name());
|
||||
}
|
||||
};
|
||||
ForEachPath(sendExitClose);
|
||||
@ -183,31 +186,28 @@ namespace llarp::exit
|
||||
|
||||
bool
|
||||
BaseSession::HandleTraffic(
|
||||
llarp::path::Path_ptr path,
|
||||
const llarp_buffer_t& buf,
|
||||
uint64_t counter,
|
||||
service::ProtocolType t)
|
||||
llarp::path::Path_ptr, const llarp_buffer_t&, uint64_t, service::ProtocolType)
|
||||
{
|
||||
const service::ConvoTag tag{path->RXID().as_array()};
|
||||
// const service::ConvoTag tag{path->RXID().as_array()};
|
||||
|
||||
if (t == service::ProtocolType::QUIC)
|
||||
{
|
||||
auto quic = m_Parent->GetQUICTunnel();
|
||||
if (not quic)
|
||||
return false;
|
||||
quic->receive_packet(tag, buf);
|
||||
return true;
|
||||
}
|
||||
// if (t == service::ProtocolType::QUIC)
|
||||
// {
|
||||
// auto quic = m_Parent->GetQUICTunnel();
|
||||
// if (not quic)
|
||||
// return false;
|
||||
// quic->receive_packet(tag, buf);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (packet_write_func)
|
||||
{
|
||||
llarp::net::IPPacket pkt{buf.view_all()};
|
||||
if (pkt.empty())
|
||||
return false;
|
||||
_last_use = router->now();
|
||||
m_Downstream.emplace(counter, pkt);
|
||||
return true;
|
||||
}
|
||||
// if (packet_write_func)
|
||||
// {
|
||||
// llarp::net::IPPacket pkt{buf.view_all()};
|
||||
// if (pkt.empty())
|
||||
// return false;
|
||||
// _last_use = router->now();
|
||||
// m_Downstream.emplace(counter, pkt);
|
||||
// return true;
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -220,29 +220,31 @@ namespace llarp::exit
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::QueueUpstreamTraffic(
|
||||
llarp::net::IPPacket pkt, const size_t N, service::ProtocolType t)
|
||||
BaseSession::QueueUpstreamTraffic(llarp::net::IPPacket, const size_t, service::ProtocolType)
|
||||
{
|
||||
auto& queue = m_Upstream[pkt.size() / N];
|
||||
// auto& queue = m_Upstream[pkt.size() / N];
|
||||
// queue overflow
|
||||
if (queue.size() >= MaxUpstreamQueueLength)
|
||||
return false;
|
||||
if (queue.size() == 0)
|
||||
{
|
||||
queue.emplace_back();
|
||||
queue.back().protocol = t;
|
||||
return queue.back().PutBuffer(llarp_buffer_t{pkt}, _counter++);
|
||||
}
|
||||
auto& back = queue.back();
|
||||
// pack to nearest N
|
||||
if (back.Size() + pkt.size() > N)
|
||||
{
|
||||
queue.emplace_back();
|
||||
queue.back().protocol = t;
|
||||
return queue.back().PutBuffer(llarp_buffer_t{pkt}, _counter++);
|
||||
}
|
||||
back.protocol = t;
|
||||
return back.PutBuffer(llarp_buffer_t{pkt}, _counter++);
|
||||
// if (queue.size() >= MaxUpstreamQueueLength)
|
||||
// return false;
|
||||
// if (queue.size() == 0)
|
||||
// {
|
||||
// queue.emplace_back();
|
||||
// queue.back().protocol = t;
|
||||
// return queue.back().PutBuffer(llarp_buffer_t{pkt}, _counter++);
|
||||
// }
|
||||
|
||||
// auto& back = queue.back();
|
||||
// // pack to nearest N
|
||||
// if (back.Size() + pkt.size() > N)
|
||||
// {
|
||||
// queue.emplace_back();
|
||||
// queue.back().protocol = t;
|
||||
// return queue.back().PutBuffer(llarp_buffer_t{pkt}, _counter++);
|
||||
// }
|
||||
// back.protocol = t;
|
||||
// return back.PutBuffer(llarp_buffer_t{pkt}, _counter++);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -277,25 +279,25 @@ namespace llarp::exit
|
||||
auto path = PickEstablishedPath(llarp::path::ePathRoleExit);
|
||||
if (path)
|
||||
{
|
||||
for (auto& [i, queue] : m_Upstream)
|
||||
{
|
||||
while (queue.size())
|
||||
{
|
||||
auto& msg = queue.front();
|
||||
msg.sequence_number = path->NextSeqNo();
|
||||
path->SendRoutingMessage(msg, router);
|
||||
queue.pop_front();
|
||||
}
|
||||
}
|
||||
// for (auto& [i, queue] : m_Upstream)
|
||||
// {
|
||||
// while (queue.size())
|
||||
// {
|
||||
// auto& msg = queue.front();
|
||||
// msg.sequence_number = path->NextSeqNo();
|
||||
// path->SendRoutingMessage(msg, router);
|
||||
// queue.pop_front();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Upstream.size())
|
||||
llarp::LogWarn("no path for exit session");
|
||||
// discard upstream
|
||||
for (auto& [i, queue] : m_Upstream)
|
||||
queue.clear();
|
||||
m_Upstream.clear();
|
||||
// if (m_Upstream.size())
|
||||
// llarp::LogWarn("no path for exit session");
|
||||
// // discard upstream
|
||||
// for (auto& [i, queue] : m_Upstream)
|
||||
// queue.clear();
|
||||
// m_Upstream.clear();
|
||||
|
||||
if (numHops == 1)
|
||||
{
|
||||
@ -338,12 +340,12 @@ namespace llarp::exit
|
||||
void
|
||||
BaseSession::FlushDownstream()
|
||||
{
|
||||
while (m_Downstream.size())
|
||||
{
|
||||
if (packet_write_func)
|
||||
packet_write_func(const_cast<net::IPPacket&>(m_Downstream.top().second).steal());
|
||||
m_Downstream.pop();
|
||||
}
|
||||
// while (m_Downstream.size())
|
||||
// {
|
||||
// if (packet_write_func)
|
||||
// packet_write_func(const_cast<net::IPPacket&>(m_Downstream.top().second).steal());
|
||||
// m_Downstream.pop();
|
||||
// }
|
||||
}
|
||||
|
||||
SNodeSession::SNodeSession(
|
||||
@ -377,23 +379,26 @@ namespace llarp::exit
|
||||
void
|
||||
ExitSession::send_packet_to_remote(std::string buf)
|
||||
{
|
||||
net::IPPacket pkt{buf};
|
||||
if (pkt.empty())
|
||||
if (buf.empty())
|
||||
return;
|
||||
pkt.ZeroAddresses();
|
||||
|
||||
// QueueUpstreamTraffic(std::move(pkt), llarp::routing::EXIT_PAD_SIZE, t);
|
||||
if (auto path = PickEstablishedPath(llarp::path::ePathRoleExit))
|
||||
{}
|
||||
else
|
||||
{}
|
||||
}
|
||||
|
||||
void
|
||||
SNodeSession::send_packet_to_remote(std::string buf)
|
||||
{
|
||||
net::IPPacket pkt{buf};
|
||||
if (pkt.empty())
|
||||
if (buf.empty())
|
||||
return;
|
||||
|
||||
pkt.ZeroSourceAddress();
|
||||
|
||||
// QueueUpstreamTraffic(std::move(pkt), llarp::routing::EXIT_PAD_SIZE, t);
|
||||
if (auto path = PickEstablishedPath(llarp::path::ePathRoleExit))
|
||||
{
|
||||
//
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
} // namespace llarp::exit
|
||||
|
@ -12,7 +12,7 @@ namespace llarp
|
||||
{
|
||||
class EndpointBase;
|
||||
|
||||
namespace quic
|
||||
namespace link
|
||||
{
|
||||
class TunnelManager;
|
||||
}
|
||||
@ -163,12 +163,12 @@ namespace llarp
|
||||
}
|
||||
};
|
||||
|
||||
uint64_t _counter;
|
||||
[[maybe_unused]] uint64_t _counter;
|
||||
llarp_time_t _last_use;
|
||||
|
||||
std::vector<SessionReadyFunc> m_PendingCallbacks;
|
||||
const bool m_BundleRC;
|
||||
EndpointBase* const m_Parent;
|
||||
[[maybe_unused]] const bool m_BundleRC;
|
||||
[[maybe_unused]] EndpointBase* const m_Parent;
|
||||
|
||||
void
|
||||
CallPendingCallbacks(bool success);
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <llarp/util/str.hpp>
|
||||
#include <llarp/util/bits.hpp>
|
||||
|
||||
#include <llarp/quic/tunnel.hpp>
|
||||
#include <llarp/router/rc_lookup_handler.hpp>
|
||||
|
||||
#include <cassert>
|
||||
@ -18,10 +17,9 @@ namespace llarp::handlers
|
||||
ExitEndpoint::ExitEndpoint(std::string name, Router* r)
|
||||
: router(r)
|
||||
, name(std::move(name))
|
||||
, tunnel_manager{std::make_shared<quic::TunnelManager>(*this)}
|
||||
, tunnel_manager{std::make_shared<link::TunnelManager>(*this)}
|
||||
{
|
||||
should_init_tun = true;
|
||||
tunnel_manager = std::make_shared<quic::TunnelManager>(*this);
|
||||
}
|
||||
|
||||
ExitEndpoint::~ExitEndpoint() = default;
|
||||
@ -749,12 +747,12 @@ namespace llarp::handlers
|
||||
if_name = *maybe;
|
||||
}
|
||||
LogInfo(Name(), " set ifname to ", if_name);
|
||||
if (auto* quic = GetQUICTunnel())
|
||||
{
|
||||
quic->listen([ifaddr = net::TruncateV6(if_addr)](std::string_view, uint16_t port) {
|
||||
return llarp::SockAddr{ifaddr, huint16_t{port}};
|
||||
});
|
||||
}
|
||||
// if (auto* quic = GetQUICTunnel())
|
||||
// {
|
||||
// quic->listen([ifaddr = net::TruncateV6(if_addr)](std::string_view, uint16_t port) {
|
||||
// return llarp::SockAddr{ifaddr, huint16_t{port}};
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
huint128_t
|
||||
@ -783,7 +781,7 @@ namespace llarp::handlers
|
||||
return ip;
|
||||
}
|
||||
|
||||
quic::TunnelManager*
|
||||
link::TunnelManager*
|
||||
ExitEndpoint::GetQUICTunnel()
|
||||
{
|
||||
return tunnel_manager.get();
|
||||
|
@ -162,7 +162,7 @@ namespace llarp
|
||||
void
|
||||
Flush();
|
||||
|
||||
quic::TunnelManager*
|
||||
link::TunnelManager*
|
||||
GetQUICTunnel() override;
|
||||
|
||||
huint128_t
|
||||
@ -226,7 +226,7 @@ namespace llarp
|
||||
SockAddr resolver_addr;
|
||||
std::vector<SockAddr> upstream_resolvers;
|
||||
|
||||
std::shared_ptr<quic::TunnelManager> tunnel_manager;
|
||||
std::shared_ptr<link::TunnelManager> tunnel_manager;
|
||||
|
||||
using PacketQueue_t = std::
|
||||
priority_queue<net::IPPacket, std::vector<net::IPPacket>, net::IPPacket::CompareOrder>;
|
||||
|
@ -50,11 +50,9 @@ namespace llarp::handlers
|
||||
m_PacketRouter->HandleIPPacketFrom(std::move(*from), std::move(pkt));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogWarn("did not handle packet, no endpoint with convotag T=", tag);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogWarn("did not handle packet, no endpoint with convotag T=", tag);
|
||||
return false;
|
||||
}
|
||||
if (t != service::ProtocolType::QUIC)
|
||||
return false;
|
||||
@ -70,7 +68,8 @@ namespace llarp::handlers
|
||||
LogWarn("invalid incoming quic packet, dropping");
|
||||
return false;
|
||||
}
|
||||
quic->receive_packet(tag, buf);
|
||||
// TODO:
|
||||
// quic->receive_packet(tag, buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <llarp/service/protocol_type.hpp>
|
||||
#include <llarp/util/meta/memfn.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/quic/tunnel.hpp>
|
||||
#include <llarp/rpc/endpoint_rpc.hpp>
|
||||
#include <llarp/util/str.hpp>
|
||||
#include <llarp/util/logging/buffer.hpp>
|
||||
@ -391,8 +390,11 @@ namespace llarp::handlers
|
||||
if (not data.empty())
|
||||
{
|
||||
std::string_view bdata{data.data(), data.size()};
|
||||
|
||||
LogDebug(Name(), " parsing address map data: ", bdata);
|
||||
|
||||
const auto parsed = oxenc::bt_deserialize<oxenc::bt_dict>(bdata);
|
||||
|
||||
for (const auto& [key, value] : parsed)
|
||||
{
|
||||
huint128_t ip{};
|
||||
@ -454,12 +456,13 @@ namespace llarp::handlers
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* quic = GetQUICTunnel())
|
||||
{
|
||||
quic->listen([this](std::string_view, uint16_t port) {
|
||||
return llarp::SockAddr{net::TruncateV6(GetIfAddr()), huint16_t{port}};
|
||||
});
|
||||
}
|
||||
// if (auto* quic = GetQUICTunnel())
|
||||
// {
|
||||
// TODO:
|
||||
// quic->listen([this](std::string_view, uint16_t port) {
|
||||
// return llarp::SockAddr{net::TruncateV6(GetIfAddr()), huint16_t{port}};
|
||||
// });
|
||||
// }
|
||||
return Endpoint::Configure(conf, dnsConf);
|
||||
}
|
||||
|
||||
@ -469,19 +472,6 @@ namespace llarp::handlers
|
||||
return m_IPToAddr.find(ip) != m_IPToAddr.end();
|
||||
}
|
||||
|
||||
void
|
||||
TunEndpoint::Pump(llarp_time_t now)
|
||||
{
|
||||
// flush network to user
|
||||
while (not m_NetworkToUserPktQueue.empty())
|
||||
{
|
||||
m_NetIf->WritePacket(m_NetworkToUserPktQueue.top().pkt);
|
||||
m_NetworkToUserPktQueue.pop();
|
||||
}
|
||||
|
||||
service::Endpoint::Pump(now);
|
||||
}
|
||||
|
||||
static bool
|
||||
is_random_snode(const dns::Message& msg)
|
||||
{
|
||||
@ -1367,7 +1357,9 @@ namespace llarp::handlers
|
||||
return false;
|
||||
}
|
||||
LogInfo("tag active T=", tag);
|
||||
quic->receive_packet(tag, buf);
|
||||
|
||||
// TODO:
|
||||
// quic->receive_packet(tag, buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1473,7 +1465,10 @@ namespace llarp::handlers
|
||||
{
|
||||
pkt.UpdateIPv6Address(src, dst);
|
||||
}
|
||||
m_NetworkToUserPktQueue.push(std::move(write));
|
||||
|
||||
// TODO: send this along but without a fucking huint182_t
|
||||
// m_NetworkToUserPktQueue.push(std::move(write));
|
||||
|
||||
// wake up so we ensure that all packets are written to user
|
||||
router()->TriggerPump();
|
||||
return true;
|
||||
|
@ -5,7 +5,7 @@ namespace llarp::link
|
||||
Connection::Connection(
|
||||
std::shared_ptr<oxen::quic::connection_interface>& c,
|
||||
std::shared_ptr<oxen::quic::BTRequestStream>& s,
|
||||
RouterContact& rc)
|
||||
const RouterContact& rc)
|
||||
: conn{c}, control_stream{s}, remote_rc{std::move(rc)}
|
||||
{}
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace llarp::link
|
||||
Connection(
|
||||
std::shared_ptr<oxen::quic::connection_interface>& c,
|
||||
std::shared_ptr<oxen::quic::BTRequestStream>& s,
|
||||
RouterContact& rc);
|
||||
const RouterContact& rc);
|
||||
};
|
||||
} // namespace llarp::link
|
||||
|
||||
|
@ -675,7 +675,8 @@ namespace llarp
|
||||
{
|
||||
m.respond(
|
||||
serialize_response(
|
||||
{{"STATUS", FindRouterMessage::RETRY_ITER}, {"TARGET", target_addr.data()}}),
|
||||
{{"STATUS", FindRouterMessage::RETRY_ITER},
|
||||
{"TARGET", reinterpret_cast<const char*>(target_addr.data())}}),
|
||||
true);
|
||||
}
|
||||
}
|
||||
@ -1656,4 +1657,22 @@ namespace llarp
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_convo_intro(oxen::quic::message m)
|
||||
{
|
||||
if (m.timed_out)
|
||||
{
|
||||
log::info(link_cat, "Path control message timed out!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace llarp
|
||||
|
@ -1,18 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/endpoint_base.hpp>
|
||||
#include <llarp/net/sock_addr.hpp>
|
||||
#include <llarp/service/convotag.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <queue>
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <uvw/tcp.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
class EndpointBase;
|
||||
}
|
||||
|
||||
namespace llarp::link
|
||||
{
|
||||
struct Endpoint;
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace tunnel
|
||||
{
|
||||
// The server sends back a 0x00 to signal that the remote TCP connection was established and
|
||||
@ -176,7 +187,7 @@ namespace llarp::link
|
||||
// Server instance; this listens on pseudo-port 0 (if it listens). This is automatically
|
||||
// instantiated the first time `listen()` is called; if not instantiated we simply drop any
|
||||
// inbound client-to-server quic packets.
|
||||
std::unique_ptr<Server> server_;
|
||||
// std::unique_ptr<Server> server_;
|
||||
|
||||
void
|
||||
make_server();
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include <lokinet.h>
|
||||
#include <llarp.hpp>
|
||||
#include <llarp/config/config.hpp>
|
||||
#include <llarp/crypto/crypto_libsodium.hpp>
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/service/context.hpp>
|
||||
#include <llarp/quic/tunnel.hpp>
|
||||
#include <llarp/link/tunnel.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
|
||||
#include <llarp/util/logging.hpp>
|
||||
@ -305,7 +305,7 @@ struct lokinet_context
|
||||
[[nodiscard]] auto
|
||||
endpoint(std::string name = "default") const
|
||||
{
|
||||
return impl->router->hiddenServiceContext().GetEndpointByName(name);
|
||||
return impl->router->hidden_service_context().GetEndpointByName(name);
|
||||
}
|
||||
|
||||
std::unordered_map<int, bool> streams;
|
||||
@ -490,7 +490,7 @@ extern "C"
|
||||
return -3;
|
||||
auto lock = ctx->acquire();
|
||||
// add a temp cryptography implementation here so rc.Verify works
|
||||
llarp::CryptoManager instance{new llarp::sodium::CryptoLibSodium{}};
|
||||
llarp::CryptoManager instance{new llarp::Crypto{}};
|
||||
if (data[0] == 'l')
|
||||
{
|
||||
if (not ctx->config->bootstrap.routers.BDecode(&buf))
|
||||
@ -577,7 +577,7 @@ extern "C"
|
||||
return -3;
|
||||
if (not ctx->impl->LooksAlive())
|
||||
return -2;
|
||||
return ctx->endpoint()->IsReady() ? 0 : -1;
|
||||
return ctx->endpoint()->is_ready() ? 0 : -1;
|
||||
}
|
||||
|
||||
int EXPORT
|
||||
@ -593,12 +593,12 @@ extern "C"
|
||||
ms = 10;
|
||||
iterations = 1;
|
||||
}
|
||||
while (not ep->IsReady() and iterations > 0)
|
||||
while (not ep->is_ready() and iterations > 0)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{ms / 10});
|
||||
iterations--;
|
||||
}
|
||||
return ep->IsReady() ? 0 : -1;
|
||||
return ep->is_ready() ? 0 : -1;
|
||||
}
|
||||
|
||||
void EXPORT
|
||||
@ -945,7 +945,7 @@ extern "C"
|
||||
else
|
||||
return EHOSTUNREACH;
|
||||
}
|
||||
if (auto maybe = llarp::service::ParseAddress(std::string{remote->remote_host}))
|
||||
if (auto maybe = llarp::service::parse_address(std::string{remote->remote_host}))
|
||||
{
|
||||
llarp::net::IPPacket pkt = llarp::net::IPPacket::UDP(
|
||||
llarp::nuint32_t{0},
|
||||
@ -957,10 +957,10 @@ extern "C"
|
||||
if (pkt.empty())
|
||||
return EINVAL;
|
||||
std::promise<int> ret;
|
||||
ctx->impl->router->loop()->call([addr = *maybe, pkt = std::move(pkt), ep, &ret]() {
|
||||
ctx->impl->router->loop()->call([addr = *maybe, pkt = pkt.to_string(), ep, &ret]() {
|
||||
if (auto tag = ep->GetBestConvoTagFor(addr))
|
||||
{
|
||||
if (ep->SendToOrQueue(*tag, pkt.ConstBuffer(), llarp::service::ProtocolType::TrafficV4))
|
||||
if (ep->send_to(*tag, pkt))
|
||||
{
|
||||
ret.set_value(0);
|
||||
return;
|
||||
@ -997,7 +997,7 @@ extern "C"
|
||||
else
|
||||
return EHOSTUNREACH;
|
||||
}
|
||||
if (auto maybe = llarp::service::ParseAddress(std::string{remote->remote_host}))
|
||||
if (auto maybe = llarp::service::parse_address(std::string{remote->remote_host}))
|
||||
{
|
||||
{
|
||||
// check for pre existing flow
|
||||
@ -1012,14 +1012,19 @@ extern "C"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::promise<bool> gotten;
|
||||
ctx->impl->router->loop()->call([addr = *maybe, ep, &gotten]() {
|
||||
ep->MarkAddressOutbound(addr);
|
||||
auto res = ep->EnsurePathTo(
|
||||
addr, [&gotten](auto result) { gotten.set_value(result.has_value()); }, 5s);
|
||||
if (not res)
|
||||
|
||||
ctx->impl->router->loop()->call([maybe_addr = *maybe, ep, &gotten]() {
|
||||
if (auto* addr = std::get_if<llarp::service::Address>(&maybe_addr))
|
||||
{
|
||||
gotten.set_value(false);
|
||||
ep->MarkAddressOutbound(*addr);
|
||||
auto res = ep->EnsurePathTo(
|
||||
*addr, [&gotten](auto result) { gotten.set_value(result.has_value()); }, 5s);
|
||||
if (not res)
|
||||
{
|
||||
gotten.set_value(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (gotten.get_future().get())
|
||||
|
@ -18,8 +18,8 @@ namespace llarp
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("E", is_exploratory);
|
||||
btdp.append("I", is_iterative);
|
||||
btdp.append("E", is_exploratory ? 1 : 0);
|
||||
btdp.append("I", is_iterative ? 1 : 0);
|
||||
btdp.append("K", rid.ToView());
|
||||
}
|
||||
catch (...)
|
||||
@ -37,8 +37,8 @@ namespace llarp
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("E", is_exploratory);
|
||||
btdp.append("I", is_iterative);
|
||||
btdp.append("E", is_exploratory ? 1 : 0);
|
||||
btdp.append("I", is_iterative ? 1 : 0);
|
||||
btdp.append("K", std::move(rid));
|
||||
}
|
||||
catch (...)
|
||||
|
@ -1,127 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "link_message.hpp"
|
||||
#include <llarp/routing/handler.hpp>
|
||||
#include <llarp/routing/message.hpp>
|
||||
#include <llarp/util/bencode.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct LinkDiscardMessage final : public AbstractLinkMessage
|
||||
{
|
||||
LinkDiscardMessage() : AbstractLinkMessage()
|
||||
{}
|
||||
|
||||
std::string
|
||||
bt_encode() const override
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("a", "x");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(link_cat, "Error: RelayDownstreamMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
version = 0;
|
||||
}
|
||||
|
||||
const char*
|
||||
name() const override
|
||||
{
|
||||
return "Discard";
|
||||
}
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override
|
||||
{
|
||||
if (key.startswith("a"))
|
||||
{
|
||||
llarp_buffer_t strbuf;
|
||||
if (!bencode_read_string(buf, &strbuf))
|
||||
return false;
|
||||
if (strbuf.sz != 1)
|
||||
return false;
|
||||
return *strbuf.cur == 'x';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
handle_message(Router* /*router*/) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
namespace routing
|
||||
{
|
||||
struct DataDiscardMessage final : public AbstractRoutingMessage
|
||||
{
|
||||
PathID_t path_id;
|
||||
|
||||
DataDiscardMessage() = default;
|
||||
|
||||
DataDiscardMessage(const PathID_t& dst, uint64_t s) : path_id(dst)
|
||||
{
|
||||
sequence_number = s;
|
||||
version = llarp::constants::proto_version;
|
||||
}
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
version = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
handle_message(AbstractRoutingMessageHandler* h, Router* r) const override
|
||||
{
|
||||
return h->HandleDataDiscardMessage(*this, r);
|
||||
}
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf) override
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictEntry("P", path_id, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("S", sequence_number, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("V", version, read, k, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
std::string
|
||||
bt_encode() const override
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "D");
|
||||
btdp.append("P", path_id.ToView());
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("V", version);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(route_cat, "Error: DataDiscardMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
};
|
||||
} // namespace routing
|
||||
|
||||
} // namespace llarp
|
@ -1,493 +0,0 @@
|
||||
#include "relay_commit.hpp"
|
||||
#include "relay_status.hpp"
|
||||
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/path/transit_hop.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/router/outbound_message_handler.hpp>
|
||||
#include <llarp/routing/path_confirm_message.hpp>
|
||||
#include <llarp/util/bencode.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
#include <llarp/util/meta/memfn.hpp>
|
||||
#include <llarp/tooling/path_event.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
bool
|
||||
LR_CommitMessage::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
||||
{
|
||||
if (key.startswith("c"))
|
||||
{
|
||||
/// so we dont put it into the shitty queue
|
||||
pathid.Fill('c');
|
||||
return BEncodeReadArray(frames, buf);
|
||||
}
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeVerifyVersion("v", version, llarp::constants::proto_version, read, key, buf))
|
||||
return false;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
void
|
||||
LR_CommitMessage::clear()
|
||||
{
|
||||
std::for_each(frames.begin(), frames.end(), [](auto& f) { f.Clear(); });
|
||||
version = 0;
|
||||
}
|
||||
|
||||
std::string
|
||||
LR_CommitMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("a", "c");
|
||||
{
|
||||
auto sublist = btdp.append_list("c");
|
||||
|
||||
for (auto& f : frames)
|
||||
sublist.append({reinterpret_cast<const char*>(f.data()), f.size()});
|
||||
}
|
||||
|
||||
btdp.append("v", llarp::constants::proto_version);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(link_cat, "Error: LR_CommitMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitMessage::handle_message(Router* router) const
|
||||
{
|
||||
if (frames.size() != path::MAX_LEN)
|
||||
{
|
||||
llarp::LogError("LRCM invalid number of records, ", frames.size(), "!=", path::MAX_LEN);
|
||||
return false;
|
||||
}
|
||||
if (!router->path_context().AllowingTransit())
|
||||
{
|
||||
llarp::LogError("got LRCM when not permitting transit");
|
||||
return false;
|
||||
}
|
||||
return AsyncDecrypt(&router->path_context());
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if (!bencode_start_dict(buf))
|
||||
return false;
|
||||
|
||||
if (!BEncodeWriteDictEntry("c", commkey, buf))
|
||||
return false;
|
||||
if (!BEncodeWriteDictEntry("i", nextHop, buf))
|
||||
return false;
|
||||
if (lifetime > 10s && lifetime < path::DEFAULT_LIFETIME)
|
||||
{
|
||||
if (!BEncodeWriteDictInt("i", lifetime.count(), buf))
|
||||
return false;
|
||||
}
|
||||
if (!BEncodeWriteDictEntry("n", tunnelNonce, buf))
|
||||
return false;
|
||||
if (!BEncodeWriteDictEntry("r", rxid, buf))
|
||||
return false;
|
||||
if (!BEncodeWriteDictEntry("t", txid, buf))
|
||||
return false;
|
||||
if (nextRC)
|
||||
{
|
||||
if (!BEncodeWriteDictEntry("u", *nextRC, buf))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not bencode_write_uint64_entry(buf, "v", 1, llarp::constants::proto_version))
|
||||
return false;
|
||||
if (work and not BEncodeWriteDictEntry("w", *work, buf))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::OnKey(llarp_buffer_t* buffer, llarp_buffer_t* key)
|
||||
{
|
||||
if (!key)
|
||||
return true;
|
||||
|
||||
bool read = false;
|
||||
|
||||
if (!BEncodeMaybeReadDictEntry("c", commkey, read, *key, buffer))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("i", nextHop, read, *key, buffer))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("l", lifetime, read, *key, buffer))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("n", tunnelNonce, read, *key, buffer))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("r", rxid, read, *key, buffer))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("t", txid, read, *key, buffer))
|
||||
return false;
|
||||
if (key->startswith("u"))
|
||||
{
|
||||
nextRC = std::make_unique<RouterContact>();
|
||||
return nextRC->BDecode(buffer);
|
||||
}
|
||||
if (!BEncodeMaybeVerifyVersion(
|
||||
"v", version, llarp::constants::proto_version, read, *key, buffer))
|
||||
return false;
|
||||
if (key->startswith("w"))
|
||||
{
|
||||
// check for duplicate
|
||||
if (work)
|
||||
{
|
||||
llarp::LogWarn("duplicate POW in LRCR");
|
||||
return false;
|
||||
}
|
||||
|
||||
work = std::make_unique<PoW>();
|
||||
return bencode_decode_dict(*work, buffer);
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
return bencode_read_dict(util::memFn(&LR_CommitRecord::OnKey, this), buf);
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::operator==(const LR_CommitRecord& other) const
|
||||
{
|
||||
if (work && other.work)
|
||||
{
|
||||
if (*work != *other.work)
|
||||
return false;
|
||||
}
|
||||
return nextHop == other.nextHop && commkey == other.commkey && txid == other.txid
|
||||
&& rxid == other.rxid;
|
||||
}
|
||||
|
||||
struct LRCMFrameDecrypt
|
||||
{
|
||||
using Context = llarp::path::PathContext;
|
||||
using Hop = llarp::path::TransitHop;
|
||||
using Decrypter = AsyncFrameDecrypter<LRCMFrameDecrypt>;
|
||||
using Decrypter_ptr = std::unique_ptr<Decrypter>;
|
||||
Decrypter_ptr decrypter;
|
||||
std::array<EncryptedFrame, 8> frames;
|
||||
Context* context;
|
||||
// decrypted record
|
||||
LR_CommitRecord record;
|
||||
// the actual hop
|
||||
std::shared_ptr<Hop> hop;
|
||||
|
||||
oxen::quic::Address from_addr;
|
||||
|
||||
LRCMFrameDecrypt(Context* ctx, Decrypter_ptr dec, const LR_CommitMessage* commit)
|
||||
: decrypter(std::move(dec))
|
||||
, frames(commit->frames)
|
||||
, context(ctx)
|
||||
, hop(std::make_shared<Hop>())
|
||||
, from_addr{
|
||||
commit->conn->remote_rc.IsPublicRouter() ? oxen::quic::Address{}
|
||||
: commit->conn->remote_rc.addr}
|
||||
{
|
||||
hop->info.downstream = commit->conn->remote_rc.pubkey;
|
||||
}
|
||||
|
||||
~LRCMFrameDecrypt() = default;
|
||||
|
||||
static void
|
||||
OnForwardLRCMResult(
|
||||
Router* router,
|
||||
std::shared_ptr<path::TransitHop> path,
|
||||
const PathID_t pathid,
|
||||
const RouterID nextHop,
|
||||
const SharedSecret pathKey,
|
||||
SendStatus sendStatus)
|
||||
{
|
||||
uint64_t status = LR_StatusRecord::FAIL_DEST_INVALID;
|
||||
|
||||
switch (sendStatus)
|
||||
{
|
||||
case SendStatus::Success:
|
||||
// do nothing, will forward success message later
|
||||
return;
|
||||
case SendStatus::Timeout:
|
||||
status = LR_StatusRecord::FAIL_TIMEOUT;
|
||||
break;
|
||||
case SendStatus::NoLink:
|
||||
status = LR_StatusRecord::FAIL_CANNOT_CONNECT;
|
||||
break;
|
||||
case SendStatus::InvalidRouter:
|
||||
status = LR_StatusRecord::FAIL_DEST_INVALID;
|
||||
break;
|
||||
case SendStatus::RouterNotFound:
|
||||
status = LR_StatusRecord::FAIL_DEST_UNKNOWN;
|
||||
break;
|
||||
case SendStatus::Congestion:
|
||||
status = LR_StatusRecord::FAIL_CONGESTION;
|
||||
break;
|
||||
default:
|
||||
LogError("llarp::SendStatus value not in enum class");
|
||||
std::abort();
|
||||
break;
|
||||
}
|
||||
router->queue_work([router, path, pathid, nextHop, pathKey, status] {
|
||||
LR_StatusMessage::CreateAndSend(router, path, pathid, nextHop, pathKey, status);
|
||||
});
|
||||
}
|
||||
|
||||
/// this is done from logic thread
|
||||
static void
|
||||
SendLRCM(std::shared_ptr<LRCMFrameDecrypt> self)
|
||||
{
|
||||
if (self->context->HasTransitHop(self->hop->info))
|
||||
{
|
||||
llarp::LogError("duplicate transit hop ", self->hop->info);
|
||||
LR_StatusMessage::CreateAndSend(
|
||||
self->context->router(),
|
||||
self->hop,
|
||||
self->hop->info.rxID,
|
||||
self->hop->info.downstream,
|
||||
self->hop->pathKey,
|
||||
LR_StatusRecord::FAIL_DUPLICATE_HOP);
|
||||
self->hop = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->from_addr.is_addressable())
|
||||
{
|
||||
// only do ip limiting from non service nodes
|
||||
#ifndef LOKINET_HIVE
|
||||
if (self->context->CheckPathLimitHitByIP(self->from_addr.to_string()))
|
||||
{
|
||||
// we hit a limit so tell it to slow tf down
|
||||
llarp::LogError("client path build hit limit ", self->from_addr);
|
||||
OnForwardLRCMResult(
|
||||
self->context->router(),
|
||||
self->hop,
|
||||
self->hop->info.rxID,
|
||||
self->hop->info.downstream,
|
||||
self->hop->pathKey,
|
||||
SendStatus::Congestion);
|
||||
self->hop = nullptr;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (not self->context->router()->PathToRouterAllowed(self->hop->info.upstream))
|
||||
{
|
||||
// we are not allowed to forward it ... now what?
|
||||
llarp::LogError(
|
||||
"path to ",
|
||||
self->hop->info.upstream,
|
||||
"not allowed, dropping build request on the floor");
|
||||
OnForwardLRCMResult(
|
||||
self->context->router(),
|
||||
self->hop,
|
||||
self->hop->info.rxID,
|
||||
self->hop->info.downstream,
|
||||
self->hop->pathKey,
|
||||
SendStatus::InvalidRouter);
|
||||
self->hop = nullptr;
|
||||
return;
|
||||
}
|
||||
// persist sessions to upstream and downstream routers until the commit
|
||||
// ends
|
||||
self->context->router()->persist_connection_until(
|
||||
self->hop->info.downstream, self->hop->ExpireTime() + 10s);
|
||||
self->context->router()->persist_connection_until(
|
||||
self->hop->info.upstream, self->hop->ExpireTime() + 10s);
|
||||
// put hop
|
||||
self->context->PutTransitHop(self->hop);
|
||||
// forward to next hop
|
||||
using std::placeholders::_1;
|
||||
auto func = [self](auto status) {
|
||||
OnForwardLRCMResult(
|
||||
self->context->router(),
|
||||
self->hop,
|
||||
self->hop->info.rxID,
|
||||
self->hop->info.downstream,
|
||||
self->hop->pathKey,
|
||||
status);
|
||||
self->hop = nullptr;
|
||||
};
|
||||
self->context->ForwardLRCM(self->hop->info.upstream, self->frames, func);
|
||||
// trigger idempotent pump to ensure that the build messages propagate
|
||||
self->context->router()->TriggerPump();
|
||||
}
|
||||
|
||||
// this is called from the logic thread
|
||||
static void
|
||||
SendPathConfirm(std::shared_ptr<LRCMFrameDecrypt> self)
|
||||
{
|
||||
// send path confirmation
|
||||
// TODO: other status flags?
|
||||
uint64_t status = LR_StatusRecord::SUCCESS;
|
||||
if (self->context->HasTransitHop(self->hop->info))
|
||||
{
|
||||
status = LR_StatusRecord::FAIL_DUPLICATE_HOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
// persist session to downstream until path expiration
|
||||
self->context->router()->persist_connection_until(
|
||||
self->hop->info.downstream, self->hop->ExpireTime() + 10s);
|
||||
// put hop
|
||||
self->context->PutTransitHop(self->hop);
|
||||
}
|
||||
|
||||
if (!LR_StatusMessage::CreateAndSend(
|
||||
self->context->router(),
|
||||
self->hop,
|
||||
self->hop->info.rxID,
|
||||
self->hop->info.downstream,
|
||||
self->hop->pathKey,
|
||||
status))
|
||||
{
|
||||
llarp::LogError("failed to send path confirmation for ", self->hop->info);
|
||||
}
|
||||
self->hop = nullptr;
|
||||
}
|
||||
|
||||
// TODO: If decryption has succeeded here but we otherwise don't
|
||||
// want to or can't accept the path build request, send
|
||||
// a status message saying as much.
|
||||
static void
|
||||
HandleDecrypted(llarp_buffer_t* buf, std::shared_ptr<LRCMFrameDecrypt> self)
|
||||
{
|
||||
auto now = self->context->router()->now();
|
||||
auto& info = self->hop->info;
|
||||
if (!buf)
|
||||
{
|
||||
llarp::LogError("LRCM decrypt failed from ", info.downstream);
|
||||
self->decrypter = nullptr;
|
||||
return;
|
||||
}
|
||||
buf->cur = buf->base + EncryptedFrameOverheadSize;
|
||||
llarp::LogDebug("decrypted LRCM from ", info.downstream);
|
||||
// successful decrypt
|
||||
if (!self->record.BDecode(buf))
|
||||
{
|
||||
llarp::LogError("malformed frame inside LRCM from ", info.downstream);
|
||||
self->decrypter = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
info.txID = self->record.txid;
|
||||
info.rxID = self->record.rxid;
|
||||
|
||||
if (info.txID.IsZero() || info.rxID.IsZero())
|
||||
{
|
||||
llarp::LogError("LRCM refusing zero pathid");
|
||||
self->decrypter = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
info.upstream = self->record.nextHop;
|
||||
|
||||
// generate path key as we are in a worker thread
|
||||
auto crypto = CryptoManager::instance();
|
||||
if (!crypto->dh_server(
|
||||
self->hop->pathKey,
|
||||
self->record.commkey,
|
||||
self->context->EncryptionSecretKey(),
|
||||
self->record.tunnelNonce))
|
||||
{
|
||||
llarp::LogError("LRCM DH Failed ", info);
|
||||
self->decrypter = nullptr;
|
||||
return;
|
||||
}
|
||||
// generate hash of hop key for nonce mutation
|
||||
crypto->shorthash(self->hop->nonceXOR, self->hop->pathKey.data(), self->hop->pathKey.size());
|
||||
if (self->record.work && self->record.work->IsValid(now))
|
||||
{
|
||||
llarp::LogDebug(
|
||||
"LRCM extended lifetime by ",
|
||||
ToString(self->record.work->extendedLifetime),
|
||||
" for ",
|
||||
info);
|
||||
self->hop->lifetime += self->record.work->extendedLifetime;
|
||||
}
|
||||
else if (self->record.lifetime < path::DEFAULT_LIFETIME && self->record.lifetime > 10s)
|
||||
{
|
||||
self->hop->lifetime = self->record.lifetime;
|
||||
llarp::LogDebug(
|
||||
"LRCM short lifespan set to ", ToString(self->hop->lifetime), " for ", info);
|
||||
}
|
||||
|
||||
// TODO: check if we really want to accept it
|
||||
self->hop->started = now;
|
||||
|
||||
// self->context->router()->NotifyRouterEvent<tooling::PathRequestReceivedEvent>(
|
||||
// self->context->router()->pubkey(), self->hop);
|
||||
|
||||
size_t sz = self->frames[0].size();
|
||||
// shift
|
||||
std::array<EncryptedFrame, 8> frames;
|
||||
frames[0] = self->frames[1];
|
||||
frames[1] = self->frames[2];
|
||||
frames[2] = self->frames[3];
|
||||
frames[3] = self->frames[4];
|
||||
frames[4] = self->frames[5];
|
||||
frames[5] = self->frames[6];
|
||||
frames[6] = self->frames[7];
|
||||
// put our response on the end
|
||||
frames[7] = EncryptedFrame(sz - EncryptedFrameOverheadSize);
|
||||
// random junk for now
|
||||
frames[7].Randomize();
|
||||
self->frames = std::move(frames);
|
||||
if (self->context->HopIsUs(info.upstream))
|
||||
{
|
||||
// we are the farthest hop
|
||||
llarp::LogDebug("We are the farthest hop for ", info);
|
||||
// send a LRSM down the path
|
||||
self->context->loop()->call([self] {
|
||||
SendPathConfirm(self);
|
||||
self->decrypter = nullptr;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// forward upstream
|
||||
// we are still in the worker thread so post job to logic
|
||||
self->context->loop()->call([self] {
|
||||
SendLRCM(self);
|
||||
self->decrypter = nullptr;
|
||||
});
|
||||
}
|
||||
// trigger idempotent pump to ensure that the build messages propagate
|
||||
self->context->router()->TriggerPump();
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
LR_CommitMessage::AsyncDecrypt(llarp::path::PathContext* context) const
|
||||
{
|
||||
auto decrypter = std::make_unique<LRCMFrameDecrypt::Decrypter>(
|
||||
context->EncryptionSecretKey(), &LRCMFrameDecrypt::HandleDecrypted);
|
||||
// copy frames so we own them
|
||||
auto frameDecrypt = std::make_shared<LRCMFrameDecrypt>(context, std::move(decrypter), this);
|
||||
|
||||
// decrypt frames async
|
||||
frameDecrypt->decrypter->AsyncDecrypt(
|
||||
frameDecrypt->frames[0], frameDecrypt, [r = context->router()](auto func) {
|
||||
r->loop()->call([&]() { func(); });
|
||||
});
|
||||
return true;
|
||||
}
|
||||
} // namespace llarp
|
@ -1,325 +0,0 @@
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/routing/path_confirm_message.hpp>
|
||||
#include <llarp/util/bencode.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
#include <llarp/util/meta/memfn.hpp>
|
||||
#include <llarp/tooling/path_event.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct LRSM_AsyncHandler : public std::enable_shared_from_this<LRSM_AsyncHandler>
|
||||
{
|
||||
using HopHandler_ptr = std::shared_ptr<llarp::path::AbstractHopHandler>;
|
||||
|
||||
std::array<EncryptedFrame, 8> frames;
|
||||
uint64_t status = 0;
|
||||
HopHandler_ptr hop;
|
||||
Router* router;
|
||||
PathID_t pathid;
|
||||
|
||||
LRSM_AsyncHandler(
|
||||
std::array<EncryptedFrame, 8> _frames,
|
||||
uint64_t _status,
|
||||
HopHandler_ptr _hop,
|
||||
Router* _router,
|
||||
PathID_t pathid)
|
||||
: frames{std::move(_frames)}
|
||||
, status{_status}
|
||||
, hop{std::move(_hop)}
|
||||
, router{_router}
|
||||
, pathid{std::move(pathid)}
|
||||
{}
|
||||
|
||||
~LRSM_AsyncHandler() = default;
|
||||
|
||||
void
|
||||
handle()
|
||||
{
|
||||
router->notify_router_event<tooling::PathStatusReceivedEvent>(
|
||||
router->pubkey(), pathid, status);
|
||||
hop->HandleLRSM(status, frames, router);
|
||||
}
|
||||
|
||||
void
|
||||
queue_handle()
|
||||
{
|
||||
auto func = [self = shared_from_this()] { self->handle(); };
|
||||
router->queue_work(func);
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
LR_StatusMessage::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (key.startswith("c"))
|
||||
{
|
||||
return BEncodeReadArray(frames, buf);
|
||||
}
|
||||
if (key.startswith("p"))
|
||||
{
|
||||
if (!BEncodeMaybeReadDictEntry("p", pathid, read, key, buf))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (key.startswith("s"))
|
||||
{
|
||||
if (!BEncodeMaybeReadDictInt("s", status, read, key, buf))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (key.startswith("v"))
|
||||
{
|
||||
if (!BEncodeMaybeVerifyVersion("v", version, llarp::constants::proto_version, read, key, buf))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
void
|
||||
LR_StatusMessage::clear()
|
||||
{
|
||||
std::for_each(frames.begin(), frames.end(), [](auto& f) { f.Clear(); });
|
||||
version = 0;
|
||||
status = 0;
|
||||
}
|
||||
|
||||
std::string
|
||||
LR_StatusMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("a", "s");
|
||||
|
||||
{
|
||||
auto sublist = btdp.append_list("c");
|
||||
|
||||
for (auto& f : frames)
|
||||
sublist.append({reinterpret_cast<const char*>(f.data()), f.size()});
|
||||
}
|
||||
|
||||
btdp.append("p", pathid.ToView());
|
||||
btdp.append("s", status);
|
||||
btdp.append("v", llarp::constants::proto_version);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(link_cat, "Error: LR_StatusMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
LR_StatusMessage::handle_message(Router* router) const
|
||||
{
|
||||
llarp::LogDebug("Received LR_Status message from (", conn->remote_rc.pubkey, ")");
|
||||
if (frames.size() != path::MAX_LEN)
|
||||
{
|
||||
llarp::LogError("LRSM invalid number of records, ", frames.size(), "!=", path::MAX_LEN);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto path = router->path_context().GetByUpstream(conn->remote_rc.pubkey, pathid);
|
||||
if (not path)
|
||||
{
|
||||
llarp::LogWarn("unhandled LR_Status message: no associated path found pathid=", pathid);
|
||||
return false;
|
||||
}
|
||||
auto handler = std::make_shared<LRSM_AsyncHandler>(frames, status, path, router, pathid);
|
||||
handler->queue_handle();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LR_StatusMessage::SetDummyFrames()
|
||||
{
|
||||
for (auto& f : frames)
|
||||
f.Randomize();
|
||||
}
|
||||
|
||||
// call this from a worker thread
|
||||
bool
|
||||
LR_StatusMessage::CreateAndSend(
|
||||
Router* router,
|
||||
std::shared_ptr<path::TransitHop> hop,
|
||||
const PathID_t pathid,
|
||||
const RouterID nextHop,
|
||||
const SharedSecret pathKey,
|
||||
uint64_t status)
|
||||
{
|
||||
auto message = std::make_shared<LR_StatusMessage>();
|
||||
|
||||
message->status = status;
|
||||
message->pathid = pathid;
|
||||
|
||||
message->SetDummyFrames();
|
||||
|
||||
message->AddFrame(pathKey, status);
|
||||
|
||||
QueueSendMessage(router, nextHop, message, hop);
|
||||
return true; // can't guarantee delivery here, as far as we know it's fine
|
||||
}
|
||||
|
||||
bool
|
||||
LR_StatusMessage::AddFrame(const SharedSecret& pathKey, uint64_t newStatus)
|
||||
{
|
||||
frames[7] = frames[6];
|
||||
frames[6] = frames[5];
|
||||
frames[5] = frames[4];
|
||||
frames[4] = frames[3];
|
||||
frames[3] = frames[2];
|
||||
frames[2] = frames[1];
|
||||
frames[1] = frames[0];
|
||||
|
||||
auto& frame = frames[0];
|
||||
|
||||
frame.Randomize();
|
||||
|
||||
LR_StatusRecord record;
|
||||
|
||||
record.status = newStatus;
|
||||
record.version = llarp::constants::proto_version;
|
||||
|
||||
llarp_buffer_t buf(frame.data(), frame.size());
|
||||
buf.cur = buf.base + EncryptedFrameOverheadSize;
|
||||
// encode record
|
||||
if (!record.BEncode(&buf))
|
||||
{
|
||||
// failed to encode?
|
||||
LogError(name(), " Failed to generate Status Record");
|
||||
DumpBuffer(buf);
|
||||
return false;
|
||||
}
|
||||
// use ephemeral keypair for frame
|
||||
if (!frame.DoEncrypt(pathKey, true))
|
||||
{
|
||||
LogError(name(), " Failed to encrypt LRSR");
|
||||
DumpBuffer(buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LR_StatusMessage::QueueSendMessage(
|
||||
Router* router,
|
||||
const RouterID nextHop,
|
||||
std::shared_ptr<LR_StatusMessage> msg,
|
||||
std::shared_ptr<path::TransitHop> hop)
|
||||
{
|
||||
router->loop()->call([router, nextHop, msg = std::move(msg), hop = std::move(hop)] {
|
||||
SendMessage(router, nextHop, msg, hop);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
LR_StatusMessage::SendMessage(
|
||||
Router* router,
|
||||
const RouterID nextHop,
|
||||
std::shared_ptr<LR_StatusMessage> msg,
|
||||
std::shared_ptr<path::TransitHop> hop)
|
||||
{
|
||||
llarp::LogDebug("Attempting to send LR_Status message to (", nextHop, ")");
|
||||
|
||||
auto resultCallback = [hop, router, msg, nextHop](auto status) {
|
||||
if ((msg->status & LR_StatusRecord::SUCCESS) != LR_StatusRecord::SUCCESS
|
||||
or status != SendStatus::Success)
|
||||
{
|
||||
llarp::LogError("Failed to propagate LR_Status message to ", nextHop);
|
||||
hop->QueueDestroySelf(router);
|
||||
}
|
||||
};
|
||||
|
||||
// send the status message to previous hop
|
||||
// if it fails we are hitting a failure case we can't cope with so ... drop.
|
||||
|
||||
// TODO: replace with new message serialization
|
||||
// if (not router->SendToOrQueue(nextHop, *msg, resultCallback))
|
||||
// resultCallback(SendStatus::Congestion);
|
||||
|
||||
// trigger idempotent pump to make sure stuff gets sent
|
||||
router->TriggerPump();
|
||||
}
|
||||
|
||||
bool
|
||||
LR_StatusRecord::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
return bencode_start_dict(buf) && BEncodeWriteDictInt("s", status, buf)
|
||||
&& bencode_write_uint64_entry(buf, "v", 1, llarp::constants::proto_version)
|
||||
&& bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
LR_StatusRecord::OnKey(llarp_buffer_t* buffer, llarp_buffer_t* key)
|
||||
{
|
||||
if (!key)
|
||||
return true;
|
||||
|
||||
bool read = false;
|
||||
|
||||
if (!BEncodeMaybeReadDictInt("s", status, read, *key, buffer))
|
||||
return false;
|
||||
if (!BEncodeMaybeVerifyVersion(
|
||||
"v", version, llarp::constants::proto_version, read, *key, buffer))
|
||||
return false;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
LR_StatusRecord::BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
return bencode_read_dict(util::memFn(&LR_StatusRecord::OnKey, this), buf);
|
||||
}
|
||||
|
||||
bool
|
||||
LR_StatusRecord::operator==(const LR_StatusRecord& other) const
|
||||
{
|
||||
return status == other.status;
|
||||
}
|
||||
|
||||
using namespace std::literals;
|
||||
static constexpr std::array code_strings = {
|
||||
std::make_pair(LR_StatusRecord::SUCCESS, "success"sv),
|
||||
std::make_pair(LR_StatusRecord::FAIL_TIMEOUT, "timeout"sv),
|
||||
std::make_pair(LR_StatusRecord::FAIL_CONGESTION, "congestion"sv),
|
||||
std::make_pair(LR_StatusRecord::FAIL_DEST_UNKNOWN, "destination unknown"sv),
|
||||
std::make_pair(LR_StatusRecord::FAIL_DECRYPT_ERROR, "decrypt error"sv),
|
||||
std::make_pair(LR_StatusRecord::FAIL_MALFORMED_RECORD, "malformed record"sv),
|
||||
std::make_pair(LR_StatusRecord::FAIL_DEST_INVALID, "destination invalid"sv),
|
||||
std::make_pair(LR_StatusRecord::FAIL_CANNOT_CONNECT, "cannot connect"sv),
|
||||
std::make_pair(LR_StatusRecord::FAIL_DUPLICATE_HOP, "duplicate hop"sv)};
|
||||
|
||||
std::string
|
||||
LRStatusCodeToString(uint64_t status)
|
||||
{
|
||||
std::string s = "[";
|
||||
for (const auto& [val, message] : code_strings)
|
||||
{
|
||||
if ((status & val) == val)
|
||||
{
|
||||
if (s.size() > 1)
|
||||
s += ", ";
|
||||
s += message;
|
||||
}
|
||||
}
|
||||
s += ']';
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace llarp
|
@ -1,5 +1,7 @@
|
||||
#include "traffic_policy.hpp"
|
||||
#include "llarp/util/str.hpp"
|
||||
|
||||
#include <llarp/util/bencode.hpp>
|
||||
#include <llarp/util/str.hpp>
|
||||
|
||||
namespace llarp::net
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ namespace llarp
|
||||
std::optional<RouterContact>
|
||||
GetRandom(Filter visit) const
|
||||
{
|
||||
return router.loop()->call_get([this, visit]() -> std::optional<RouterContact> {
|
||||
return router.loop()->call_get([visit]() -> std::optional<RouterContact> {
|
||||
std::vector<const decltype(entries)::value_type*> entries;
|
||||
for (const auto& entry : entries)
|
||||
entries.push_back(entry);
|
||||
|
@ -49,7 +49,7 @@ namespace llarp
|
||||
|
||||
/// send routing message and increment sequence number
|
||||
virtual bool
|
||||
SendRoutingMessage(const routing::AbstractRoutingMessage& msg, Router* r) = 0;
|
||||
SendRoutingMessage(std::string payload, Router* r) = 0;
|
||||
|
||||
// handle data in upstream direction
|
||||
virtual bool
|
||||
|
@ -2,16 +2,13 @@
|
||||
#include "pathbuilder.hpp"
|
||||
#include "transit_hop.hpp"
|
||||
|
||||
#include <llarp/exit/exit_messages.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/messages/dht.hpp>
|
||||
#include <llarp/messages/discard.hpp>
|
||||
#include <llarp/messages/exit.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/profiling.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/tooling/path_event.hpp>
|
||||
|
||||
#include <oxenc/endian.h>
|
||||
|
||||
@ -552,7 +549,7 @@ namespace llarp::path
|
||||
}
|
||||
|
||||
void
|
||||
Path::HandleAllDownstream(std::vector<RelayDownstreamMessage> msgs, Router* r)
|
||||
Path::HandleAllDownstream(std::vector<RelayDownstreamMessage> msgs, Router* /* r */)
|
||||
{
|
||||
for (const auto& msg : msgs)
|
||||
{
|
||||
@ -582,34 +579,27 @@ namespace llarp::path
|
||||
std::move around.
|
||||
*/
|
||||
bool
|
||||
Path::SendRoutingMessage(const routing::AbstractRoutingMessage& msg, Router* r)
|
||||
Path::SendRoutingMessage(std::string payload, Router*)
|
||||
{
|
||||
std::array<byte_t, MAX_LINK_MSG_SIZE / 2> tmp;
|
||||
llarp_buffer_t buf(tmp);
|
||||
|
||||
auto bte = msg.bt_encode();
|
||||
buf.write(bte.begin(), bte.end());
|
||||
std::string buf(MAX_LINK_MSG_SIZE / 2, '\0');
|
||||
buf.insert(0, payload);
|
||||
|
||||
// make nonce
|
||||
TunnelNonce N;
|
||||
N.Randomize();
|
||||
buf.sz = buf.cur - buf.base;
|
||||
|
||||
// pad smaller messages
|
||||
if (buf.sz < PAD_SIZE)
|
||||
if (payload.size() < PAD_SIZE)
|
||||
{
|
||||
// randomize padding
|
||||
CryptoManager::instance()->randbytes(buf.cur, PAD_SIZE - buf.sz);
|
||||
buf.sz = PAD_SIZE;
|
||||
CryptoManager::instance()->randbytes(
|
||||
reinterpret_cast<unsigned char*>(buf.data()) + payload.size(), PAD_SIZE - payload.size());
|
||||
}
|
||||
buf.cur = buf.base;
|
||||
LogDebug(
|
||||
"send routing message ",
|
||||
msg.sequence_number,
|
||||
" with ",
|
||||
buf.sz,
|
||||
" bytes to endpoint ",
|
||||
Endpoint());
|
||||
return HandleUpstream(buf, N, r);
|
||||
log::debug(path_cat, "Sending {}B routing message to {}", buf.size(), Endpoint());
|
||||
|
||||
// TODO: path relaying here
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Samples_t>
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "abstracthophandler.hpp"
|
||||
#include "path_types.hpp"
|
||||
#include "pathset.hpp"
|
||||
// #include "pathbuilder.hpp"
|
||||
|
||||
#include <llarp/constants/path.hpp>
|
||||
#include <llarp/crypto/encrypted_frame.hpp>
|
||||
@ -27,7 +26,6 @@
|
||||
namespace llarp
|
||||
{
|
||||
struct Router;
|
||||
struct LR_CommitMessage;
|
||||
|
||||
namespace path
|
||||
{
|
||||
@ -219,7 +217,7 @@ namespace llarp
|
||||
std::function<void(oxen::quic::message m)> func = nullptr) override;
|
||||
|
||||
bool
|
||||
SendRoutingMessage(const routing::AbstractRoutingMessage& msg, Router* r) override;
|
||||
SendRoutingMessage(std::string payload, Router* r) override;
|
||||
|
||||
bool
|
||||
IsReady() const;
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "path.hpp"
|
||||
#include "path_context.hpp"
|
||||
|
||||
#include <llarp/messages/relay_commit.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
|
||||
namespace llarp::path
|
||||
@ -375,31 +374,6 @@ namespace llarp::path
|
||||
}
|
||||
}
|
||||
|
||||
routing::MessageHandler_ptr
|
||||
PathContext::GetHandler(const PathID_t& id)
|
||||
{
|
||||
routing::MessageHandler_ptr h = nullptr;
|
||||
auto pathset = GetLocalPathSet(id);
|
||||
if (pathset)
|
||||
{
|
||||
h = pathset->GetPathByID(id);
|
||||
}
|
||||
if (h)
|
||||
return h;
|
||||
const RouterID us(OurRouterID());
|
||||
auto& map = m_TransitPaths;
|
||||
{
|
||||
SyncTransitMap_t::Lock_t lock(map.first);
|
||||
auto range = map.second.equal_range(id);
|
||||
for (auto i = range.first; i != range.second; ++i)
|
||||
{
|
||||
if (i->second->info.upstream == us)
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PathContext::RemovePathSet(PathSet_ptr)
|
||||
{}
|
||||
|
@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/crypto/encrypted_frame.hpp>
|
||||
#include <llarp/net/ip_address.hpp>
|
||||
#include "abstracthophandler.hpp"
|
||||
#include "path_types.hpp"
|
||||
#include "pathset.hpp"
|
||||
#include "transit_hop.hpp"
|
||||
#include <llarp/routing/handler.hpp>
|
||||
|
||||
#include <llarp/crypto/encrypted_frame.hpp>
|
||||
#include <llarp/net/ip_address.hpp>
|
||||
#include <llarp/util/compare_ptr.hpp>
|
||||
#include <llarp/util/decaying_hashset.hpp>
|
||||
#include <llarp/util/types.hpp>
|
||||
@ -17,9 +17,6 @@
|
||||
namespace llarp
|
||||
{
|
||||
struct Router;
|
||||
struct LR_CommitMessage;
|
||||
struct RelayDownstreamMessage;
|
||||
struct RelayUpstreamMessage;
|
||||
struct RouterID;
|
||||
|
||||
namespace path
|
||||
@ -61,9 +58,6 @@ namespace llarp
|
||||
bool
|
||||
HasTransitHop(const TransitHopInfo& info);
|
||||
|
||||
bool
|
||||
HandleRelayCommit(const LR_CommitMessage& msg);
|
||||
|
||||
void
|
||||
PutTransitHop(std::shared_ptr<TransitHop> hop);
|
||||
|
||||
@ -88,9 +82,6 @@ namespace llarp
|
||||
PathSet_ptr
|
||||
GetLocalPathSet(const PathID_t& id);
|
||||
|
||||
routing::MessageHandler_ptr
|
||||
GetHandler(const PathID_t& id);
|
||||
|
||||
using EndpointPathPtrSet = std::set<Path_ptr, ComparePtr<Path_ptr>>;
|
||||
/// get a set of all paths that we own who's endpoint is r
|
||||
EndpointPathPtrSet
|
||||
@ -99,12 +90,6 @@ namespace llarp
|
||||
bool
|
||||
HopIsUs(const RouterID& k) const;
|
||||
|
||||
bool
|
||||
HandleLRUM(const RelayUpstreamMessage& msg);
|
||||
|
||||
bool
|
||||
HandleLRDM(const RelayDownstreamMessage& msg);
|
||||
|
||||
void
|
||||
AddOwnPath(PathSet_ptr set, Path_ptr p);
|
||||
|
||||
|
@ -5,12 +5,10 @@
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/messages/path.hpp>
|
||||
#include <llarp/messages/relay_commit.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/profiling.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/router/rc_lookup_handler.hpp>
|
||||
#include <llarp/tooling/path_event.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
|
||||
@ -420,7 +418,9 @@ namespace llarp
|
||||
|
||||
std::string path_shortName = "[path " + router->ShortName() + "-";
|
||||
path_shortName = path_shortName + std::to_string(router->NextPathBuildNumber()) + "]";
|
||||
auto path = std::make_shared<path::Path>(hops, GetWeak(), roles, std::move(path_shortName));
|
||||
|
||||
auto path =
|
||||
std::make_shared<path::Path>(router, hops, GetWeak(), roles, std::move(path_shortName));
|
||||
|
||||
log::info(
|
||||
path_cat, "{} building path -> {} : {}", Name(), path->ShortName(), path->HopsString());
|
||||
|
@ -3,9 +3,7 @@
|
||||
#include "transit_hop.hpp"
|
||||
|
||||
#include <llarp/exit/context.hpp>
|
||||
#include <llarp/exit/exit_messages.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/messages/discard.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
|
||||
@ -43,8 +41,7 @@ namespace llarp::path
|
||||
return started + lifetime;
|
||||
}
|
||||
|
||||
TransitHopInfo::TransitHopInfo(const RouterID& down, const LR_CommitRecord& record)
|
||||
: txID(record.txid), rxID(record.rxid), upstream(record.nextHop), downstream(down)
|
||||
TransitHopInfo::TransitHopInfo(const RouterID& down) : downstream(down)
|
||||
{}
|
||||
|
||||
/** Note: this is one of two places where AbstractRoutingMessage::bt_encode() is called, the
|
||||
@ -63,26 +60,26 @@ namespace llarp::path
|
||||
std::move around.
|
||||
*/
|
||||
bool
|
||||
TransitHop::SendRoutingMessage(const routing::AbstractRoutingMessage& msg, Router* r)
|
||||
TransitHop::SendRoutingMessage(std::string payload, Router* r)
|
||||
{
|
||||
if (!IsEndpoint(r->pubkey()))
|
||||
return false;
|
||||
|
||||
auto buf = msg.bt_encode();
|
||||
|
||||
TunnelNonce N;
|
||||
N.Randomize();
|
||||
// pad to nearest MESSAGE_PAD_SIZE bytes
|
||||
auto dlt = buf.size() % PAD_SIZE;
|
||||
auto dlt = payload.size() % PAD_SIZE;
|
||||
|
||||
if (dlt)
|
||||
{
|
||||
dlt = PAD_SIZE - dlt;
|
||||
// randomize padding
|
||||
CryptoManager::instance()->randbytes(reinterpret_cast<uint8_t*>(buf.data()), dlt);
|
||||
CryptoManager::instance()->randbytes(reinterpret_cast<uint8_t*>(payload.data()), dlt);
|
||||
}
|
||||
|
||||
return HandleDownstream(buf, N, r);
|
||||
// TODO: relay message along
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -166,7 +163,7 @@ namespace llarp::path
|
||||
for (const auto& msg : msgs)
|
||||
{
|
||||
const llarp_buffer_t buf(msg.enc);
|
||||
if (!r->ParseRoutingMessageBuffer(buf, this, info.rxID))
|
||||
if (!r->ParseRoutingMessageBuffer(buf, *this, info.rxID))
|
||||
{
|
||||
LogWarn("invalid upstream data on endpoint ", info);
|
||||
}
|
||||
@ -190,7 +187,7 @@ namespace llarp::path
|
||||
info.downstream,
|
||||
" to ",
|
||||
info.upstream);
|
||||
r->send_data_message(info.upstream, msg);
|
||||
r->send_data_message(info.upstream, msg.bt_encode());
|
||||
}
|
||||
}
|
||||
r->TriggerPump();
|
||||
@ -207,6 +204,7 @@ namespace llarp::path
|
||||
msg.enc.size(),
|
||||
info.upstream,
|
||||
info.downstream);
|
||||
// TODO: is this right?
|
||||
r->send_data_message(info.downstream, msg.bt_encode());
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct LR_CommitRecord;
|
||||
|
||||
namespace dht
|
||||
{
|
||||
struct GotIntroMessage;
|
||||
@ -21,7 +19,7 @@ namespace llarp
|
||||
struct TransitHopInfo
|
||||
{
|
||||
TransitHopInfo() = default;
|
||||
TransitHopInfo(const RouterID& down, const LR_CommitRecord& record);
|
||||
TransitHopInfo(const RouterID& down);
|
||||
|
||||
PathID_t txID, rxID;
|
||||
RouterID upstream;
|
||||
@ -116,10 +114,7 @@ namespace llarp
|
||||
|
||||
// send routing message when end of path
|
||||
bool
|
||||
SendRoutingMessage(const routing::AbstractRoutingMessage& msg, Router* r) override;
|
||||
|
||||
bool
|
||||
HandleDHTMessage(const dht::AbstractDHTMessage& msg, Router* r) override;
|
||||
SendRoutingMessage(std::string payload, Router* r) override;
|
||||
|
||||
void
|
||||
FlushUpstream(Router* r) override;
|
||||
|
@ -1,9 +1,7 @@
|
||||
#include "rc_gossiper.hpp"
|
||||
#include <llarp/messages/dht_immediate.hpp>
|
||||
#include <llarp/dht/messages/gotrouter.hpp>
|
||||
|
||||
#include <llarp/util/time.hpp>
|
||||
#include <llarp/constants/link_layer.hpp>
|
||||
#include <llarp/tooling/rc_event.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
|
||||
namespace llarp
|
||||
@ -95,10 +93,10 @@ namespace llarp
|
||||
}
|
||||
|
||||
// send a GRCM as gossip method
|
||||
DHTImmediateMessage gossip;
|
||||
gossip.msgs.emplace_back(new dht::GotRouterMessage(dht::Key_t{}, 0, {rc}, false));
|
||||
// DHTImmediateMessage gossip;
|
||||
// gossip.msgs.emplace_back(new dht::GotRouterMessage(dht::Key_t{}, 0, {rc}, false));
|
||||
|
||||
std::vector<RouterID> gossipTo;
|
||||
// std::vector<RouterID> gossipTo;
|
||||
|
||||
/*
|
||||
* TODO: gossip RC via libquic
|
||||
|
@ -17,11 +17,6 @@ namespace llarp
|
||||
struct Router;
|
||||
class EventLoop;
|
||||
|
||||
namespace dht
|
||||
{
|
||||
struct AbstractDHTMessageHandler;
|
||||
} // namespace dht
|
||||
|
||||
namespace service
|
||||
{
|
||||
struct Context;
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include <llarp/messages/dht.hpp>
|
||||
#include <llarp/messages/link_message.hpp>
|
||||
#include <llarp/net/net.hpp>
|
||||
#include <llarp/tooling/peer_stats_event.hpp>
|
||||
#include <llarp/tooling/router_event.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
#include <llarp/util/meta/memfn.hpp>
|
||||
@ -506,8 +504,9 @@ namespace llarp
|
||||
|
||||
bool
|
||||
Router::ParseRoutingMessageBuffer(
|
||||
const llarp_buffer_t&, routing::AbstractRoutingMessageHandler*, const PathID_t&)
|
||||
const llarp_buffer_t&, path::AbstractHopHandler&, const PathID_t&)
|
||||
{
|
||||
// TODO: will go away with the removal of flush upstream/downstream
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1539,10 +1538,4 @@ namespace llarp
|
||||
return *llarp::net::Platform::Default_ptr();
|
||||
}
|
||||
|
||||
void
|
||||
Router::handle_router_event(std::unique_ptr<tooling::RouterEvent> event) const
|
||||
{
|
||||
LogDebug(event->ToString());
|
||||
}
|
||||
|
||||
} // namespace llarp
|
||||
|
@ -18,13 +18,9 @@
|
||||
#include <llarp/profiling.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/consensus/reachability_testing.hpp>
|
||||
#include <llarp/tooling/router_event.hpp>
|
||||
#include <llarp/routing/handler.hpp>
|
||||
#include <llarp/routing/message_parser.hpp>
|
||||
#include <llarp/rpc/lokid_rpc_client.hpp>
|
||||
#include <llarp/rpc/rpc_server.hpp>
|
||||
#include <llarp/service/context.hpp>
|
||||
#include <stdexcept>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/fs.hpp>
|
||||
#include <llarp/util/mem.hpp>
|
||||
@ -33,6 +29,7 @@
|
||||
#include <llarp/util/time.hpp>
|
||||
#include <llarp/util/service_manager.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
@ -109,7 +106,6 @@ namespace llarp
|
||||
exit::Context _exit_context;
|
||||
SecretKey _identity;
|
||||
SecretKey _encryption;
|
||||
std::shared_ptr<dht::AbstractDHTMessageHandler> _dh_t;
|
||||
std::shared_ptr<Contacts> _contacts;
|
||||
std::shared_ptr<NodeDB> _node_db;
|
||||
llarp_time_t _started_at;
|
||||
@ -162,10 +158,6 @@ namespace llarp
|
||||
bool
|
||||
insufficient_peers() const;
|
||||
|
||||
protected:
|
||||
void
|
||||
handle_router_event(std::unique_ptr<tooling::RouterEvent> event) const;
|
||||
|
||||
public:
|
||||
void
|
||||
for_each_connection(std::function<void(link::Connection&)> func);
|
||||
@ -320,15 +312,6 @@ namespace llarp
|
||||
const std::vector<RouterID>& greylist,
|
||||
const std::vector<RouterID>& unfunded);
|
||||
|
||||
template <class EventType, class... Params>
|
||||
void
|
||||
notify_router_event([[maybe_unused]] Params&&... args) const
|
||||
{
|
||||
// TODO: no-op when appropriate
|
||||
auto event = std::make_unique<EventType>(args...);
|
||||
handle_router_event(std::move(event));
|
||||
}
|
||||
|
||||
void
|
||||
queue_work(std::function<void(void)> func);
|
||||
|
||||
@ -536,7 +519,7 @@ namespace llarp
|
||||
/// return false
|
||||
bool
|
||||
ParseRoutingMessageBuffer(
|
||||
const llarp_buffer_t& buf, routing::AbstractRoutingMessageHandler* h, const PathID_t& rxid);
|
||||
const llarp_buffer_t& buf, path::AbstractHopHandler& p, const PathID_t& rxid);
|
||||
|
||||
void
|
||||
ConnectToRandomRouters(int N);
|
||||
|
@ -95,10 +95,12 @@ namespace llarp
|
||||
|
||||
signature.from_string(btlc.consume_string());
|
||||
signed_bt_dict = btlc.consume_string();
|
||||
|
||||
// TODO: parse bt dict
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(llarp_cat, "Error: RouterContact failed to populate bt encoded contents!");
|
||||
log::warning(llarp_cat, "Error: RouterContact failed to populate bt encoded contents!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +116,7 @@ namespace llarp
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(llarp_cat, "Error: RouterContact failed to bt encode contents!");
|
||||
log::warning(llarp_cat, "Error: RouterContact failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btlp).str();
|
||||
@ -154,7 +156,7 @@ namespace llarp
|
||||
btdp.append("i", netID.ToView());
|
||||
btdp.append("k", pubkey.bt_encode());
|
||||
btdp.append("p", enckey.ToView());
|
||||
btdp.append("r", routerVersion);
|
||||
btdp.append("r", routerVersion->ToString());
|
||||
|
||||
if (not srvRecords.empty())
|
||||
{
|
||||
@ -280,8 +282,10 @@ namespace llarp
|
||||
RouterContact::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictList("a", addr, read, key, buf))
|
||||
return false;
|
||||
|
||||
// TOFIX: fuck everything about llarp_buffer_t
|
||||
// if (!BEncodeMaybeReadDictEntry("a", addr, read, key, buf))
|
||||
// return false;
|
||||
|
||||
if (!BEncodeMaybeReadDictEntry("i", netID, read, key, buf))
|
||||
return false;
|
||||
|
@ -131,8 +131,8 @@ namespace llarp
|
||||
operator==(const RouterContact& other) const
|
||||
{
|
||||
return addr == other.addr && enckey == other.enckey && pubkey == other.pubkey
|
||||
&& signature == other.signature
|
||||
&& last_updated == other.last_updated && netID == other.netID;
|
||||
&& signature == other.signature && last_updated == other.last_updated
|
||||
&& netID == other.netID;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "endpoint_rpc.hpp"
|
||||
|
||||
#include <llarp/service/endpoint.hpp>
|
||||
|
||||
namespace llarp::rpc
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/service/auth.hpp>
|
||||
#include <llarp/service/convotag.hpp>
|
||||
|
||||
#include <oxenmq/oxenmq.h>
|
||||
|
||||
namespace llarp::service
|
||||
@ -24,7 +26,8 @@ namespace llarp::rpc
|
||||
std::unordered_set<std::string> token_whitelist,
|
||||
LMQ_ptr lmq,
|
||||
Endpoint_ptr endpoint);
|
||||
virtual ~EndpointAuthRPC() = default;
|
||||
|
||||
~EndpointAuthRPC() override = default;
|
||||
|
||||
void
|
||||
Start();
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <llarp/exit/context.hpp>
|
||||
#include <llarp/net/ip_range.hpp>
|
||||
#include <llarp/quic/tunnel.hpp>
|
||||
#include <llarp/service/context.hpp>
|
||||
#include <llarp/service/outbound_context.hpp>
|
||||
#include <llarp/service/auth.hpp>
|
||||
@ -214,7 +213,8 @@ namespace llarp::rpc
|
||||
|
||||
if (quicconnect.request.closeID)
|
||||
{
|
||||
quic->forget(quicconnect.request.closeID);
|
||||
// TODO:
|
||||
// quic->forget(quicconnect.request.closeID);
|
||||
SetJSONResponse("OK", quicconnect.response);
|
||||
return;
|
||||
}
|
||||
@ -223,12 +223,13 @@ namespace llarp::rpc
|
||||
|
||||
try
|
||||
{
|
||||
auto [addr, id] = quic->open(
|
||||
quicconnect.request.remoteHost, quicconnect.request.port, [](auto&&) {}, laddr);
|
||||
// TODO:
|
||||
// auto [addr, id] = quic->open(
|
||||
// quicconnect.request.remoteHost, quicconnect.request.port, [](auto&&) {}, laddr);
|
||||
|
||||
util::StatusObject status;
|
||||
status["addr"] = addr.ToString();
|
||||
status["id"] = id;
|
||||
// status["addr"] = addr.ToString();
|
||||
// status["id"] = id;
|
||||
|
||||
SetJSONResponse(status, quicconnect.response);
|
||||
}
|
||||
@ -269,7 +270,8 @@ namespace llarp::rpc
|
||||
|
||||
if (quiclistener.request.closeID)
|
||||
{
|
||||
quic->forget(quiclistener.request.closeID);
|
||||
// TODO:
|
||||
// quic->forget(quiclistener.request.closeID);
|
||||
SetJSONResponse("OK", quiclistener.response);
|
||||
return;
|
||||
}
|
||||
@ -280,7 +282,8 @@ namespace llarp::rpc
|
||||
try
|
||||
{
|
||||
SockAddr addr{quiclistener.request.remoteHost, huint16_t{quiclistener.request.port}};
|
||||
id = quic->listen(addr);
|
||||
// TODO:
|
||||
// id = quic->listen(addr);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
@ -1,11 +1,12 @@
|
||||
#include "auth.hpp"
|
||||
#include <unordered_map>
|
||||
#include "protocol.hpp"
|
||||
|
||||
#include <llarp/router/router.hpp>
|
||||
#include "protocol.hpp"
|
||||
#include <llarp/util/str.hpp>
|
||||
#include <llarp/util/fs.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace llarp::service
|
||||
{
|
||||
/// maybe get auth result from string
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <llarp/dht/key.hpp>
|
||||
#include <llarp/link/contacts.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/link/tunnel.hpp>
|
||||
#include <llarp/messages/dht.hpp>
|
||||
#include <llarp/net/ip.hpp>
|
||||
#include <llarp/net/ip_range.hpp>
|
||||
@ -19,7 +20,6 @@
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/router/route_poker.hpp>
|
||||
|
||||
#include <llarp/tooling/dht_event.hpp>
|
||||
#include <llarp/util/str.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/meta/memfn.hpp>
|
||||
@ -50,7 +50,7 @@ namespace llarp::service
|
||||
_recv_event_queue.enable();
|
||||
|
||||
if (Loop()->MaybeGetUVWLoop())
|
||||
_tunnel_manager = std::make_unique<quic::TunnelManager>(*this);
|
||||
_tunnel_manager = std::make_unique<link::TunnelManager>(*this);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -167,7 +167,7 @@ namespace llarp::service
|
||||
|
||||
auto result = ptr->EnsurePathToService(
|
||||
saddr,
|
||||
[ptr, name, ranges, result_handler, poker](auto addr, auto* ctx) {
|
||||
[ptr, name, ranges, result_handler, poker](auto addr, OutboundContext* ctx) {
|
||||
if (ctx == nullptr)
|
||||
{
|
||||
result_handler(false, "could not establish flow to {}"_format(name));
|
||||
@ -175,24 +175,23 @@ namespace llarp::service
|
||||
}
|
||||
|
||||
// make a lambda that sends the reply after doing auth
|
||||
auto apply_result =
|
||||
[ptr, poker, addr, result_handler, ranges](AuthResult result) {
|
||||
if (result.code != AuthResultCode::eAuthAccepted)
|
||||
{
|
||||
result_handler(false, result.reason);
|
||||
return;
|
||||
}
|
||||
auto apply_result = [ptr, poker, addr, result_handler, ranges](
|
||||
std::string result, bool success) {
|
||||
if (success)
|
||||
{
|
||||
for (const auto& range : ranges)
|
||||
ptr->MapExitRange(range, addr);
|
||||
|
||||
for (const auto& range : ranges)
|
||||
ptr->MapExitRange(range, addr);
|
||||
if (poker)
|
||||
poker->put_up();
|
||||
|
||||
if (poker)
|
||||
poker->put_up();
|
||||
result_handler(true, result);
|
||||
}
|
||||
|
||||
result_handler(true, result.reason);
|
||||
};
|
||||
result_handler(false, result);
|
||||
};
|
||||
|
||||
ctx->AsyncSendAuth(apply_result);
|
||||
ctx->send_auth_async(apply_result);
|
||||
},
|
||||
ptr->PathAlignmentTimeout());
|
||||
|
||||
@ -662,11 +661,12 @@ namespace llarp::service
|
||||
}
|
||||
}
|
||||
// add quic ethertype if we have listeners set up
|
||||
if (auto* quic = GetQUICTunnel())
|
||||
{
|
||||
if (quic->hasListeners())
|
||||
intro_set().supported_protocols.push_back(ProtocolType::QUIC);
|
||||
}
|
||||
// if (auto* quic = GetQUICTunnel())
|
||||
// {
|
||||
// TODO:
|
||||
// if (quic->hasListeners())
|
||||
// intro_set().supported_protocols.push_back(ProtocolType::QUIC);
|
||||
// }
|
||||
|
||||
intro_set().intros.clear();
|
||||
for (auto& intro : intros)
|
||||
@ -730,7 +730,7 @@ namespace llarp::service
|
||||
return _state->remote_sessions.size() + _state->snode_sessions.size();
|
||||
}
|
||||
|
||||
constexpr auto PublishIntrosetTimeout = 20s;
|
||||
[[maybe_unused]] constexpr auto PublishIntrosetTimeout = 20s;
|
||||
|
||||
void
|
||||
Endpoint::ResetInternalState()
|
||||
@ -784,7 +784,7 @@ namespace llarp::service
|
||||
constexpr auto MaxOutboundContextPerRemote = 1;
|
||||
|
||||
void
|
||||
Endpoint::PutNewOutboundContext(const service::IntroSet& introset, llarp_time_t left)
|
||||
Endpoint::PutNewOutboundContext(const service::IntroSet& introset, llarp_time_t)
|
||||
{
|
||||
const Address addr{introset.address_keys.Addr()};
|
||||
|
||||
@ -799,8 +799,9 @@ namespace llarp::service
|
||||
auto sessionRange = remoteSessions.equal_range(addr);
|
||||
for (auto itr = sessionRange.first; itr != sessionRange.second; ++itr)
|
||||
{
|
||||
itr->second->AddReadyHook(
|
||||
[addr, this](auto session) { InformPathToService(addr, session); }, left);
|
||||
// TODO:
|
||||
// itr->second->AddReadyHook(
|
||||
// [addr, this](auto session) { InformPathToService(addr, session); }, left);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1058,7 +1059,7 @@ namespace llarp::service
|
||||
|
||||
void
|
||||
Endpoint::SendAuthResult(
|
||||
path::Path_ptr path, PathID_t replyPath, ConvoTag tag, std::string result, bool success)
|
||||
path::Path_ptr path, PathID_t /* replyPath */, ConvoTag tag, std::string result, bool success)
|
||||
{
|
||||
// not applicable because we are not an exit or don't have an endpoint auth policy
|
||||
if ((not _state->is_exit_enabled) or _auth_policy == nullptr)
|
||||
@ -1109,8 +1110,10 @@ namespace llarp::service
|
||||
return;
|
||||
}
|
||||
}
|
||||
_send_queue.tryPushBack(
|
||||
SendEvent{std::make_shared<routing::PathTransferMessage>(f, replyPath), path});
|
||||
|
||||
// TODO:
|
||||
// _send_queue.tryPushBack(
|
||||
// SendEvent{std::make_shared<routing::PathTransferMessage>(f, replyPath), path});
|
||||
}
|
||||
|
||||
void
|
||||
@ -1120,7 +1123,7 @@ namespace llarp::service
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::ResetConvoTag(ConvoTag tag, path::Path_ptr p, PathID_t from)
|
||||
Endpoint::ResetConvoTag(ConvoTag tag, path::Path_ptr p, PathID_t /* from */)
|
||||
{
|
||||
// send reset convo tag message
|
||||
ProtocolFrameMessage f{};
|
||||
@ -1131,8 +1134,9 @@ namespace llarp::service
|
||||
{
|
||||
LogWarn("invalidating convotag T=", tag);
|
||||
RemoveConvoTag(tag);
|
||||
_send_queue.tryPushBack(
|
||||
SendEvent{std::make_shared<routing::PathTransferMessage>(f, from), p});
|
||||
// TODO:
|
||||
// _send_queue.tryPushBack(
|
||||
// SendEvent{std::make_shared<routing::PathTransferMessage>(f, from), p});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1235,12 +1239,12 @@ namespace llarp::service
|
||||
[hook](auto, auto* ctx) -> bool {
|
||||
if (ctx)
|
||||
{
|
||||
hook(ctx->currentConvoTag);
|
||||
}
|
||||
else
|
||||
{
|
||||
hook(std::nullopt);
|
||||
hook(ctx->get_current_tag());
|
||||
return true;
|
||||
}
|
||||
|
||||
hook(std::nullopt);
|
||||
return false;
|
||||
},
|
||||
timeout);
|
||||
}
|
||||
@ -1436,7 +1440,7 @@ namespace llarp::service
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::Pump(llarp_time_t now)
|
||||
Endpoint::Pump(llarp_time_t)
|
||||
{
|
||||
FlushRecvData();
|
||||
// send downstream packets to user for snode
|
||||
@ -1462,39 +1466,38 @@ namespace llarp::service
|
||||
msg.tag,
|
||||
msg.payload.size());
|
||||
|
||||
if (HandleInboundPacket(msg.tag, msg.payload, msg.proto, msg.seqno))
|
||||
{
|
||||
ConvoTagRX(msg.tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogWarn("Failed to handle inbound message");
|
||||
}
|
||||
// if (HandleInboundPacket(msg.tag, msg.payload, msg.proto, msg.seqno))
|
||||
// {
|
||||
// ConvoTagRX(msg.tag);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// LogWarn("Failed to handle inbound message");
|
||||
// }
|
||||
|
||||
queue.pop();
|
||||
a
|
||||
}
|
||||
|
||||
auto r = router();
|
||||
|
||||
// TODO: locking on this container
|
||||
for (const auto& [addr, outctx] : _state->remote_sessions)
|
||||
{
|
||||
outctx->FlushUpstream();
|
||||
outctx->Pump(now);
|
||||
}
|
||||
// TODO: locking on this container
|
||||
for (const auto& [r, session] : _state->snode_sessions)
|
||||
session->FlushUpstream();
|
||||
// for (const auto& [addr, outctx] : _state->remote_sessions)
|
||||
// {
|
||||
// outctx->FlushUpstream();
|
||||
// outctx->Pump(now);
|
||||
// }
|
||||
// // TODO: locking on this container
|
||||
// for (const auto& [r, session] : _state->snode_sessions)
|
||||
// session->FlushUpstream();
|
||||
|
||||
// send queue flush
|
||||
while (not _send_queue.empty())
|
||||
{
|
||||
SendEvent item = _send_queue.popFront();
|
||||
item.first->sequence_number = item.second->NextSeqNo();
|
||||
if (item.second->SendRoutingMessage(*item.first, r))
|
||||
ConvoTagTX(item.first->protocol_frame_msg.convo_tag);
|
||||
}
|
||||
// // send queue flush
|
||||
// while (not _send_queue.empty())
|
||||
// {
|
||||
// SendEvent item = _send_queue.popFront();
|
||||
// item.first->sequence_number = item.second->NextSeqNo();
|
||||
// if (item.second->SendRoutingMessage(*item.first, r))
|
||||
// ConvoTagTX(item.first->protocol_frame_msg.convo_tag);
|
||||
// }
|
||||
|
||||
UpstreamFlush(r);
|
||||
}
|
||||
@ -1544,14 +1547,15 @@ namespace llarp::service
|
||||
auto itr = range.first;
|
||||
while (itr != range.second)
|
||||
{
|
||||
if (itr->second->ReadyToSend() and itr->second->estimatedRTT > 0s)
|
||||
{
|
||||
if (itr->second->estimatedRTT < rtt)
|
||||
{
|
||||
ret = tag;
|
||||
rtt = itr->second->estimatedRTT;
|
||||
}
|
||||
}
|
||||
// TODO:
|
||||
// if (itr->second->ReadyToSend() and itr->second->estimatedRTT > 0s)
|
||||
// {
|
||||
// if (itr->second->estimatedRTT < rtt)
|
||||
// {
|
||||
// ret = tag;
|
||||
// rtt = itr->second->estimatedRTT;
|
||||
// }
|
||||
// }
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
@ -1712,7 +1716,7 @@ namespace llarp::service
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
quic::TunnelManager*
|
||||
link::TunnelManager*
|
||||
Endpoint::GetQUICTunnel()
|
||||
{
|
||||
return _tunnel_manager.get();
|
||||
|
@ -68,9 +68,8 @@ namespace llarp
|
||||
std::shared_ptr<ProtocolMessage> msg;
|
||||
};
|
||||
|
||||
struct Endpoint : public path::Builder,
|
||||
public EndpointBase,
|
||||
public std::enable_shared_from_this<Endpoint>
|
||||
struct Endpoint : public path::Builder, public EndpointBase
|
||||
// public std::enable_shared_from_this<Endpoint>
|
||||
{
|
||||
Endpoint(Router* r, Context* parent);
|
||||
~Endpoint() override;
|
||||
@ -446,7 +445,7 @@ namespace llarp
|
||||
|
||||
/// Returns a pointer to the quic::Tunnel object handling quic connections for this endpoint.
|
||||
/// Returns nullptr if quic is not supported.
|
||||
quic::TunnelManager*
|
||||
link::TunnelManager*
|
||||
GetQUICTunnel() override;
|
||||
|
||||
protected:
|
||||
@ -500,7 +499,7 @@ namespace llarp
|
||||
std::unique_ptr<EndpointState> _state;
|
||||
std::shared_ptr<IAuthPolicy> _auth_policy;
|
||||
std::unordered_map<Address, AuthInfo> _remote_auth_infos;
|
||||
std::unique_ptr<quic::TunnelManager> _tunnel_manager;
|
||||
std::unique_ptr<link::TunnelManager> _tunnel_manager;
|
||||
|
||||
/// (ons name, optional exit range, optional auth info) for looking up on startup
|
||||
std::unordered_map<std::string, std::pair<std::optional<IPRange>, std::optional<AuthInfo>>>
|
||||
|
@ -5,68 +5,61 @@
|
||||
#include "outbound_context.hpp"
|
||||
#include <llarp/util/str.hpp>
|
||||
|
||||
namespace llarp
|
||||
namespace llarp::service
|
||||
{
|
||||
namespace service
|
||||
bool
|
||||
EndpointState::Configure(const NetworkConfig& conf)
|
||||
{
|
||||
bool
|
||||
EndpointState::Configure(const NetworkConfig& conf)
|
||||
if (conf.m_keyfile.has_value())
|
||||
key_file = conf.m_keyfile->string();
|
||||
snode_blacklist = conf.m_snodeBlacklist;
|
||||
is_exit_enabled = conf.m_AllowExit;
|
||||
|
||||
for (const auto& record : conf.m_SRVRecords)
|
||||
{
|
||||
if (conf.m_keyfile.has_value())
|
||||
key_file = conf.m_keyfile->string();
|
||||
snode_blacklist = conf.m_snodeBlacklist;
|
||||
is_exit_enabled = conf.m_AllowExit;
|
||||
|
||||
for (const auto& record : conf.m_SRVRecords)
|
||||
{
|
||||
local_introset.SRVs.push_back(record.toTuple());
|
||||
}
|
||||
|
||||
return true;
|
||||
local_introset.SRVs.push_back(record.toTuple());
|
||||
}
|
||||
|
||||
util::StatusObject
|
||||
EndpointState::ExtractStatus(util::StatusObject& obj) const
|
||||
{
|
||||
obj["lastPublished"] = to_json(last_publish);
|
||||
obj["lastPublishAttempt"] = to_json(last_publish_attempt);
|
||||
obj["introset"] = local_introset.ExtractStatus();
|
||||
static auto getSecond = [](const auto& item) -> auto
|
||||
{
|
||||
return item.second->ExtractStatus();
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
std::transform(
|
||||
dead_sessions.begin(),
|
||||
dead_sessions.end(),
|
||||
std::back_inserter(obj["deadSessions"]),
|
||||
getSecond);
|
||||
std::transform(
|
||||
remote_sessions.begin(),
|
||||
remote_sessions.end(),
|
||||
std::back_inserter(obj["remoteSessions"]),
|
||||
getSecond);
|
||||
std::transform(
|
||||
pending_lookups.begin(),
|
||||
pending_lookups.end(),
|
||||
std::back_inserter(obj["lookups"]),
|
||||
getSecond);
|
||||
std::transform(
|
||||
snode_sessions.begin(),
|
||||
snode_sessions.end(),
|
||||
std::back_inserter(obj["snodeSessions"]),
|
||||
[](const auto& item) { return item.second->ExtractStatus(); });
|
||||
util::StatusObject
|
||||
EndpointState::ExtractStatus(util::StatusObject& obj) const
|
||||
{
|
||||
obj["lastPublished"] = to_json(last_publish);
|
||||
obj["lastPublishAttempt"] = to_json(last_publish_attempt);
|
||||
obj["introset"] = local_introset.ExtractStatus();
|
||||
// static auto getSecond = [](const auto& item) -> auto
|
||||
// {
|
||||
// return item.second.ExtractStatus();
|
||||
// };
|
||||
|
||||
util::StatusObject sessionObj{};
|
||||
// std::transform(
|
||||
// dead_sessions.begin(),
|
||||
// dead_sessions.end(),
|
||||
// std::back_inserter(obj["deadSessions"]),
|
||||
// getSecond);
|
||||
// std::transform(
|
||||
// remote_sessions.begin(),
|
||||
// remote_sessions.end(),
|
||||
// std::back_inserter(obj["remoteSessions"]),
|
||||
// getSecond);
|
||||
// std::transform(
|
||||
// snode_sessions.begin(),
|
||||
// snode_sessions.end(),
|
||||
// std::back_inserter(obj["snodeSessions"]),
|
||||
// [](const auto& item) { return item.second->ExtractStatus(); });
|
||||
|
||||
for (const auto& item : m_Sessions)
|
||||
{
|
||||
std::string k = item.first.ToHex();
|
||||
sessionObj[k] = item.second.ExtractStatus();
|
||||
}
|
||||
util::StatusObject sessionObj{};
|
||||
|
||||
obj["converstations"] = sessionObj;
|
||||
return obj;
|
||||
}
|
||||
} // namespace service
|
||||
} // namespace llarp
|
||||
// TODO:
|
||||
// for (const auto& item : m_Sessions)
|
||||
// {
|
||||
// std::string k = item.first.ToHex();
|
||||
// sessionObj[k] = item.second.ExtractStatus();
|
||||
// }
|
||||
|
||||
obj["converstations"] = sessionObj;
|
||||
return obj;
|
||||
}
|
||||
} // namespace llarp::service
|
||||
|
@ -1,197 +1,172 @@
|
||||
#include "endpoint_util.hpp"
|
||||
|
||||
#include <llarp/exit/session.hpp>
|
||||
#include "outbound_context.hpp"
|
||||
#include "lookup.hpp"
|
||||
|
||||
#include <llarp/exit/session.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
|
||||
namespace llarp
|
||||
namespace llarp::service
|
||||
{
|
||||
namespace service
|
||||
void
|
||||
EndpointUtil::ExpireSNodeSessions(llarp_time_t now, SNodeConnectionMap& sessions)
|
||||
{
|
||||
void
|
||||
EndpointUtil::ExpireSNodeSessions(llarp_time_t now, SNodeConnectionMap& sessions)
|
||||
auto itr = sessions.begin();
|
||||
while (itr != sessions.end())
|
||||
{
|
||||
auto itr = sessions.begin();
|
||||
while (itr != sessions.end())
|
||||
if (itr->second->ShouldRemove() && itr->second->IsStopped())
|
||||
{
|
||||
if (itr->second->ShouldRemove() && itr->second->IsStopped())
|
||||
{
|
||||
itr = sessions.erase(itr);
|
||||
continue;
|
||||
}
|
||||
// expunge next tick
|
||||
if (itr->second->IsExpired(now))
|
||||
{
|
||||
itr->second->Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
itr->second->Tick(now);
|
||||
}
|
||||
|
||||
++itr;
|
||||
itr = sessions.erase(itr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::ExpirePendingTx(llarp_time_t now, PendingLookupsMap& lookups)
|
||||
{
|
||||
std::vector<std::unique_ptr<IServiceLookup>> timedout;
|
||||
for (auto itr = lookups.begin(); itr != lookups.end();)
|
||||
// expunge next tick
|
||||
if (itr->second->IsExpired(now))
|
||||
{
|
||||
if (!itr->second->IsTimedOut(now))
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
timedout.emplace_back(std::move(itr->second));
|
||||
itr = lookups.erase(itr);
|
||||
itr->second->Stop();
|
||||
}
|
||||
|
||||
for (const auto& lookup : timedout)
|
||||
{
|
||||
LogWarn(lookup->name, " timed out txid=", lookup->txid);
|
||||
lookup->HandleTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::ExpirePendingRouterLookups(llarp_time_t now, PendingRoutersMap& routers)
|
||||
{
|
||||
for (auto itr = routers.begin(); itr != routers.end();)
|
||||
{
|
||||
if (!itr->second.IsExpired(now))
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
LogWarn("lookup for ", itr->first, " timed out");
|
||||
itr->second.InformResult({});
|
||||
itr = routers.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::DeregisterDeadSessions(llarp_time_t now, ConnectionMap& sessions)
|
||||
{
|
||||
auto itr = sessions.begin();
|
||||
while (itr != sessions.end())
|
||||
{
|
||||
if (itr->second->IsDone(now))
|
||||
{
|
||||
itr = sessions.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::TickRemoteSessions(
|
||||
llarp_time_t now,
|
||||
ConnectionMap& remoteSessions,
|
||||
ConnectionMap& deadSessions,
|
||||
std::unordered_map<ConvoTag, Session>& sessions)
|
||||
{
|
||||
auto itr = remoteSessions.begin();
|
||||
while (itr != remoteSessions.end())
|
||||
else
|
||||
{
|
||||
itr->second->Tick(now);
|
||||
if (itr->second->Pump(now))
|
||||
{
|
||||
LogInfo(
|
||||
"marking session as dead T=",
|
||||
itr->second->currentConvoTag,
|
||||
" to ",
|
||||
itr->second->Addr());
|
||||
itr->second->Stop();
|
||||
sessions.erase(itr->second->currentConvoTag);
|
||||
deadSessions.emplace(std::move(*itr));
|
||||
itr = remoteSessions.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
for (auto& item : deadSessions)
|
||||
{
|
||||
item.second->Tick(now);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::ExpireConvoSessions(
|
||||
llarp_time_t now, std::unordered_map<ConvoTag, Session>& sessions)
|
||||
{
|
||||
auto itr = sessions.begin();
|
||||
while (itr != sessions.end())
|
||||
{
|
||||
if (itr->second.IsExpired(now))
|
||||
{
|
||||
LogInfo("Expire session T=", itr->first, " to ", itr->second.Addr());
|
||||
itr = sessions.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::StopRemoteSessions(ConnectionMap& remoteSessions)
|
||||
void
|
||||
EndpointUtil::ExpirePendingRouterLookups(llarp_time_t now, PendingRoutersMap& routers)
|
||||
{
|
||||
for (auto itr = routers.begin(); itr != routers.end();)
|
||||
{
|
||||
for (auto& item : remoteSessions)
|
||||
if (!itr->second.IsExpired(now))
|
||||
{
|
||||
item.second->Stop();
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
LogWarn("lookup for ", itr->first, " timed out");
|
||||
itr->second.InformResult({});
|
||||
itr = routers.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::StopSnodeSessions(SNodeConnectionMap& sessions)
|
||||
void
|
||||
EndpointUtil::DeregisterDeadSessions(llarp_time_t now, ConnectionMap& sessions)
|
||||
{
|
||||
auto itr = sessions.begin();
|
||||
while (itr != sessions.end())
|
||||
{
|
||||
for (auto& item : sessions)
|
||||
if (itr->second->IsDone(now))
|
||||
{
|
||||
item.second->Stop();
|
||||
itr = sessions.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
EndpointUtil::HasPathToService(const Address& addr, const ConnectionMap& remoteSessions)
|
||||
{
|
||||
auto range = remoteSessions.equal_range(addr);
|
||||
auto itr = range.first;
|
||||
while (itr != range.second)
|
||||
else
|
||||
{
|
||||
if (itr->second->ReadyToSend())
|
||||
return true;
|
||||
++itr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
EndpointUtil::GetConvoTagsForService(
|
||||
const std::unordered_map<ConvoTag, Session>& sessions,
|
||||
const Address& info,
|
||||
std::set<ConvoTag>& tags)
|
||||
void
|
||||
EndpointUtil::TickRemoteSessions(
|
||||
llarp_time_t now,
|
||||
ConnectionMap& remoteSessions,
|
||||
ConnectionMap& deadSessions,
|
||||
std::unordered_map<ConvoTag, Session>& sessions)
|
||||
{
|
||||
auto itr = remoteSessions.begin();
|
||||
while (itr != remoteSessions.end())
|
||||
{
|
||||
bool inserted = false;
|
||||
auto itr = sessions.begin();
|
||||
while (itr != sessions.end())
|
||||
itr->second->Tick(now);
|
||||
if (itr->second->Pump(now))
|
||||
{
|
||||
LogInfo(
|
||||
"marking session as dead T=",
|
||||
itr->second->get_current_tag(),
|
||||
" to ",
|
||||
itr->second->Addr());
|
||||
itr->second->Stop();
|
||||
sessions.erase(itr->second->get_current_tag());
|
||||
deadSessions.emplace(std::move(*itr));
|
||||
itr = remoteSessions.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itr->second.remote.Addr() == info)
|
||||
{
|
||||
if (tags.emplace(itr->first).second)
|
||||
{
|
||||
inserted = true;
|
||||
}
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
} // namespace service
|
||||
} // namespace llarp
|
||||
for (auto& item : deadSessions)
|
||||
{
|
||||
item.second->Tick(now);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::ExpireConvoSessions(
|
||||
llarp_time_t now, std::unordered_map<ConvoTag, Session>& sessions)
|
||||
{
|
||||
auto itr = sessions.begin();
|
||||
while (itr != sessions.end())
|
||||
{
|
||||
if (itr->second.IsExpired(now))
|
||||
{
|
||||
LogInfo("Expire session T=", itr->first, " to ", itr->second.Addr());
|
||||
itr = sessions.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::StopRemoteSessions(ConnectionMap& remoteSessions)
|
||||
{
|
||||
for (auto& item : remoteSessions)
|
||||
{
|
||||
item.second->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndpointUtil::StopSnodeSessions(SNodeConnectionMap& sessions)
|
||||
{
|
||||
for (auto& item : sessions)
|
||||
{
|
||||
item.second->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
EndpointUtil::HasPathToService(const Address& addr, const ConnectionMap& remoteSessions)
|
||||
{
|
||||
auto range = remoteSessions.equal_range(addr);
|
||||
auto itr = range.first;
|
||||
while (itr != range.second)
|
||||
{
|
||||
if (itr->second->ReadyToSend())
|
||||
return true;
|
||||
++itr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
EndpointUtil::GetConvoTagsForService(
|
||||
const std::unordered_map<ConvoTag, Session>& sessions,
|
||||
const Address& info,
|
||||
std::set<ConvoTag>& tags)
|
||||
{
|
||||
bool inserted = false;
|
||||
auto itr = sessions.begin();
|
||||
while (itr != sessions.end())
|
||||
{
|
||||
if (itr->second.remote.Addr() == info)
|
||||
{
|
||||
if (tags.emplace(itr->first).second)
|
||||
{
|
||||
inserted = true;
|
||||
}
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
} // namespace llarp::service
|
||||
|
@ -9,9 +9,6 @@ namespace llarp::service
|
||||
static void
|
||||
ExpireSNodeSessions(llarp_time_t now, SNodeConnectionMap& sessions);
|
||||
|
||||
static void
|
||||
ExpirePendingTx(llarp_time_t now, PendingLookupsMap& lookups);
|
||||
|
||||
static void
|
||||
ExpirePendingRouterLookups(llarp_time_t now, PendingRoutersMap& routers);
|
||||
|
||||
|
@ -334,7 +334,7 @@ namespace llarp::service
|
||||
auto sublist = btdc.consume_list_consumer();
|
||||
while (not sublist.is_finished())
|
||||
{
|
||||
supported_protocols.emplace_back(sublist.consume_integer<uint64_t>());
|
||||
supported_protocols.emplace_back(ProtocolType{sublist.consume_integer<uint64_t>()});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,47 +84,6 @@ namespace llarp::service
|
||||
return addr;
|
||||
}
|
||||
|
||||
bool
|
||||
OutboundContext::OnIntroSetUpdate(
|
||||
const Address&,
|
||||
std::optional<IntroSet> foundIntro,
|
||||
const RouterID& endpoint,
|
||||
std::chrono::milliseconds,
|
||||
uint64_t relayOrder)
|
||||
{
|
||||
if (marked_bad)
|
||||
return true;
|
||||
updatingIntroSet = false;
|
||||
if (foundIntro)
|
||||
{
|
||||
if (foundIntro->time_signed == 0s)
|
||||
{
|
||||
LogWarn(Name(), " got introset with zero timestamp: ", *foundIntro);
|
||||
return true;
|
||||
}
|
||||
if (current_intro.time_signed > foundIntro->time_signed)
|
||||
{
|
||||
LogInfo("introset is old, dropping");
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::chrono::milliseconds now = Now();
|
||||
if (foundIntro->IsExpired(now))
|
||||
{
|
||||
LogError("got expired introset from lookup from ", endpoint);
|
||||
return true;
|
||||
}
|
||||
current_intro = *foundIntro;
|
||||
ShiftIntroRouter(RouterID{});
|
||||
}
|
||||
else if (relayOrder > 0)
|
||||
{
|
||||
++lookup_fails;
|
||||
LogWarn(Name(), " failed to look up introset, fails=", lookup_fails);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
OutboundContext::ReadyToSend() const
|
||||
{
|
||||
@ -215,28 +174,58 @@ namespace llarp::service
|
||||
log::info(link_cat, "{} updating introset", Name());
|
||||
last_introset_update = now;
|
||||
|
||||
// we want to use the parent endpoint's paths because outbound context
|
||||
// does not implement path::PathSet::HandleGotIntroMessage
|
||||
const auto paths = GetManyPathsWithUniqueEndpoints(&ep, 2, location);
|
||||
[[maybe_unused]] uint64_t relayOrder = 0;
|
||||
uint64_t relayOrder = 0;
|
||||
|
||||
for ([[maybe_unused]] const auto& path : paths)
|
||||
for (const auto& path : paths)
|
||||
{
|
||||
// TODO: implement this
|
||||
path->find_intro(location, false, relayOrder, [this](oxen::quic::message m) mutable {
|
||||
if (marked_bad)
|
||||
{
|
||||
log::info(link_cat, "Outbound context has been marked bad (whatever that means)");
|
||||
return;
|
||||
}
|
||||
|
||||
// HiddenServiceAddressLookup* job = new HiddenServiceAddressLookup(
|
||||
// m_Endpoint,
|
||||
// util::memFn(&OutboundContext::OnIntroSetUpdate, shared_from_this()),
|
||||
// location,
|
||||
// PubKey{addr.as_array()},
|
||||
// path->Endpoint(),
|
||||
// relayOrder,
|
||||
// m_Endpoint->GenTXID(),
|
||||
// (IntrosetUpdateInterval / 2) + (2 * path->intro.latency) +
|
||||
// IntrosetLookupGraceInterval);
|
||||
// relayOrder++;
|
||||
// if (job->SendRequestViaPath(path, m_Endpoint->router()))
|
||||
// updatingIntroSet = true;
|
||||
updatingIntroSet = false;
|
||||
|
||||
if (m)
|
||||
{
|
||||
std::string introset;
|
||||
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
introset = btdc.require<std::string>("INTROSET");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::warning(link_cat, "Failed to parse find name response!");
|
||||
throw;
|
||||
}
|
||||
|
||||
service::EncryptedIntroSet enc{introset};
|
||||
const auto intro = enc.decrypt(PubKey{addr.as_array()});
|
||||
|
||||
if (intro.time_signed == 0s)
|
||||
{
|
||||
log::warning(link_cat, "{} recieved introset with zero timestamp");
|
||||
return;
|
||||
}
|
||||
if (current_intro.time_signed > intro.time_signed)
|
||||
{
|
||||
log::info(link_cat, "{} received outdated introset; dropping", Name());
|
||||
return;
|
||||
}
|
||||
if (intro.IsExpired(llarp::time_now_ms()))
|
||||
{
|
||||
log::warning(link_cat, "{} received expired introset", Name());
|
||||
return;
|
||||
}
|
||||
|
||||
current_intro = intro;
|
||||
ShiftIntroRouter();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -544,7 +533,7 @@ namespace llarp::service
|
||||
ep.GetIdentity(),
|
||||
current_intro.sntru_pubkey,
|
||||
remote_intro,
|
||||
ep,
|
||||
&ep,
|
||||
current_tag);
|
||||
|
||||
if (const auto maybe = ep.MaybeGetAuthInfoForEndpoint(remote_identity.Addr()); not maybe)
|
||||
|
@ -58,6 +58,12 @@ namespace llarp::service
|
||||
|
||||
~OutboundContext() override;
|
||||
|
||||
ConvoTag
|
||||
get_current_tag() const
|
||||
{
|
||||
return current_tag;
|
||||
}
|
||||
|
||||
void
|
||||
gen_intro_async(std::string payload);
|
||||
|
||||
@ -111,7 +117,7 @@ namespace llarp::service
|
||||
|
||||
/// shift the intro off the current router it is using
|
||||
void
|
||||
ShiftIntroRouter(const RouterID remote);
|
||||
ShiftIntroRouter(const RouterID remote = RouterID{});
|
||||
|
||||
/// return true if we are ready to send
|
||||
bool
|
||||
@ -166,14 +172,6 @@ namespace llarp::service
|
||||
std::chrono::milliseconds
|
||||
RTT() const;
|
||||
|
||||
bool
|
||||
OnIntroSetUpdate(
|
||||
const Address& addr,
|
||||
std::optional<IntroSet> i,
|
||||
const RouterID& endpoint,
|
||||
std::chrono::milliseconds,
|
||||
uint64_t relayOrder);
|
||||
|
||||
private:
|
||||
/// swap remoteIntro with next intro
|
||||
void
|
||||
|
@ -275,7 +275,7 @@ namespace llarp::service
|
||||
if (bte.empty())
|
||||
{
|
||||
log::error(logcat, "Failed to decode inner protocol message");
|
||||
DumpBuffer(*buf);
|
||||
// DumpBuffer(*buf);
|
||||
self->msg.reset();
|
||||
return;
|
||||
}
|
||||
@ -304,8 +304,12 @@ namespace llarp::service
|
||||
|
||||
// PKE (A, B, N)
|
||||
SharedSecret shared_secret;
|
||||
path_dh_func dh_server = [crypto = CryptoManager::instance()](auto&& params...) -> bool {
|
||||
return crypto->dh_server(std::forward<decltype(params)>(params));
|
||||
path_dh_func dh_server = [crypto = CryptoManager::instance()](
|
||||
llarp::SharedSecret& shared,
|
||||
const PubKey& pk,
|
||||
const SecretKey& sk,
|
||||
const TunnelNonce& n) -> bool {
|
||||
return crypto->dh_server(shared, pk, sk, n);
|
||||
};
|
||||
|
||||
if (!self->m_LocalIdentity.KeyExchange(
|
||||
|
@ -1,168 +0,0 @@
|
||||
#include "sendcontext.hpp"
|
||||
|
||||
#include <llarp/path/path.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/routing/path_transfer_message.hpp>
|
||||
#include "endpoint.hpp"
|
||||
#include <utility>
|
||||
#include <unordered_set>
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
|
||||
namespace llarp::service
|
||||
{
|
||||
static constexpr size_t SendContextQueueSize = 512;
|
||||
|
||||
SendContext::SendContext(
|
||||
ServiceInfo ident, const Introduction& intro, path::PathSet* send, Endpoint* ep)
|
||||
: remoteIdent(std::move(ident))
|
||||
, remoteIntro(intro)
|
||||
, m_PathSet(send)
|
||||
, service_endpoint(ep)
|
||||
, createdAt(ep->Now())
|
||||
{}
|
||||
|
||||
bool
|
||||
SendContext::Send(std::shared_ptr<ProtocolFrameMessage> msg, path::Path_ptr path)
|
||||
{
|
||||
if (path->IsReady()
|
||||
and m_SendQueue.tryPushBack(std::make_pair(
|
||||
std::make_shared<routing::PathTransferMessage>(*msg, remoteIntro.path_id), path))
|
||||
== thread::QueueReturn::Success)
|
||||
{
|
||||
service_endpoint->router()->TriggerPump();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
SendContext::FlushUpstream()
|
||||
{
|
||||
auto r = service_endpoint->router();
|
||||
std::unordered_set<path::Path_ptr, path::Ptr_Hash> flushpaths;
|
||||
auto rttRMS = 0ms;
|
||||
while (auto maybe = m_SendQueue.tryPopFront())
|
||||
{
|
||||
auto& [msg, path] = *maybe;
|
||||
msg->sequence_number = path->NextSeqNo();
|
||||
if (path->SendRoutingMessage(*msg, r))
|
||||
{
|
||||
lastGoodSend = r->now();
|
||||
flushpaths.emplace(path);
|
||||
service_endpoint->ConvoTagTX(msg->protocol_frame_msg.convo_tag);
|
||||
const auto rtt = (path->intro.latency + remoteIntro.latency) * 2;
|
||||
rttRMS += rtt * rtt.count();
|
||||
}
|
||||
}
|
||||
// flush the select path's upstream
|
||||
for (const auto& path : flushpaths)
|
||||
{
|
||||
path->FlushUpstream(r);
|
||||
}
|
||||
if (flushpaths.empty())
|
||||
return;
|
||||
estimatedRTT = std::chrono::milliseconds{
|
||||
static_cast<int64_t>(std::sqrt(rttRMS.count() / flushpaths.size()))};
|
||||
}
|
||||
|
||||
/// send on an established convo tag
|
||||
void
|
||||
SendContext::EncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t)
|
||||
{
|
||||
SharedSecret shared;
|
||||
auto f = std::make_shared<ProtocolFrameMessage>();
|
||||
f->flag = 0;
|
||||
f->nonce.Randomize();
|
||||
f->convo_tag = currentConvoTag;
|
||||
f->sequence_number = ++sequenceNo;
|
||||
|
||||
auto path = m_PathSet->GetPathByRouter(remoteIntro.router);
|
||||
if (!path)
|
||||
{
|
||||
ShiftIntroRouter(remoteIntro.router);
|
||||
LogWarn(m_PathSet->Name(), " cannot encrypt and send: no path for intro ", remoteIntro);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!service_endpoint->GetCachedSessionKeyFor(f->convo_tag, shared))
|
||||
{
|
||||
LogWarn(
|
||||
m_PathSet->Name(),
|
||||
" could not send, has no cached session key on session T=",
|
||||
f->convo_tag);
|
||||
return;
|
||||
}
|
||||
|
||||
auto m = std::make_shared<ProtocolMessage>();
|
||||
service_endpoint->PutIntroFor(f->convo_tag, remoteIntro);
|
||||
service_endpoint->PutReplyIntroFor(f->convo_tag, path->intro);
|
||||
m->proto = t;
|
||||
if (auto maybe = service_endpoint->GetSeqNoForConvo(f->convo_tag))
|
||||
{
|
||||
m->seqno = *maybe;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogWarn(m_PathSet->Name(), " could not get sequence number for session T=", f->convo_tag);
|
||||
return;
|
||||
}
|
||||
m->introReply = path->intro;
|
||||
f->path_id = m->introReply.path_id;
|
||||
m->sender = service_endpoint->GetIdentity().pub;
|
||||
m->tag = f->convo_tag;
|
||||
m->put_buffer(payload);
|
||||
service_endpoint->router()->queue_work([f, m, shared, path, this] {
|
||||
if (not f->EncryptAndSign(*m, shared, service_endpoint->GetIdentity()))
|
||||
{
|
||||
LogError(m_PathSet->Name(), " failed to sign message");
|
||||
return;
|
||||
}
|
||||
Send(f, path);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
SendContext::AsyncSendAuth(std::function<void(AuthResult)> resultHandler)
|
||||
{
|
||||
if (const auto maybe = service_endpoint->MaybeGetAuthInfoForEndpoint(remoteIdent.Addr()))
|
||||
{
|
||||
// send auth message
|
||||
const llarp_buffer_t authdata{maybe->token};
|
||||
AsyncGenIntro(authdata, ProtocolType::Auth);
|
||||
authResultListener = resultHandler;
|
||||
}
|
||||
else
|
||||
resultHandler({AuthResultCode::eAuthAccepted, "no auth needed"});
|
||||
}
|
||||
|
||||
void
|
||||
SendContext::AsyncEncryptAndSendTo(const llarp_buffer_t& data, ProtocolType protocol)
|
||||
{
|
||||
if (IntroSent())
|
||||
{
|
||||
EncryptAndSendTo(data, protocol);
|
||||
return;
|
||||
}
|
||||
// have we generated the initial intro but not sent it yet? bail here so we don't cause
|
||||
// bullshittery
|
||||
if (IntroGenerated() and not IntroSent())
|
||||
{
|
||||
LogWarn(
|
||||
m_PathSet->Name(),
|
||||
" we have generated an intial handshake but have not sent it yet so we drop a packet "
|
||||
"to prevent bullshittery");
|
||||
return;
|
||||
}
|
||||
const auto maybe = service_endpoint->MaybeGetAuthInfoForEndpoint(remoteIdent.Addr());
|
||||
if (maybe.has_value())
|
||||
{
|
||||
// send auth message
|
||||
const llarp_buffer_t authdata(maybe->token);
|
||||
AsyncGenIntro(authdata, ProtocolType::Auth);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncGenIntro(data, protocol);
|
||||
}
|
||||
}
|
||||
} // namespace llarp::service
|
@ -1,85 +0,0 @@
|
||||
#pragma once
|
||||
#include "intro.hpp"
|
||||
#include "protocol.hpp"
|
||||
|
||||
#include <llarp/path/pathset.hpp>
|
||||
#include <llarp/constants/path.hpp>
|
||||
#include <llarp/service/convotag.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/types.hpp>
|
||||
#include <llarp/util/thread/queue.hpp>
|
||||
|
||||
#include <deque>
|
||||
|
||||
namespace llarp::service
|
||||
{
|
||||
struct ServiceInfo;
|
||||
struct Endpoint;
|
||||
struct Introduction;
|
||||
|
||||
struct SendContext
|
||||
{
|
||||
SendContext(ServiceInfo ident, const Introduction& intro, path::PathSet* send, Endpoint* ep);
|
||||
|
||||
void
|
||||
AsyncEncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t);
|
||||
|
||||
/// queue send a fully encrypted hidden service frame
|
||||
/// via a path
|
||||
bool
|
||||
Send(std::shared_ptr<ProtocolFrameMessage> f, path::Path_ptr path);
|
||||
|
||||
/// flush upstream traffic when in router thread
|
||||
void
|
||||
FlushUpstream();
|
||||
|
||||
SharedSecret sharedKey;
|
||||
ServiceInfo remoteIdent;
|
||||
Introduction remoteIntro;
|
||||
ConvoTag currentConvoTag;
|
||||
path::PathSet* const m_PathSet;
|
||||
// Endpoint* const m_DataHandler;
|
||||
Endpoint* const service_endpoint;
|
||||
uint64_t sequenceNo = 0;
|
||||
llarp_time_t lastGoodSend = 0s;
|
||||
const llarp_time_t createdAt;
|
||||
llarp_time_t sendTimeout = path::BUILD_TIMEOUT;
|
||||
llarp_time_t connectTimeout = path::BUILD_TIMEOUT * 2;
|
||||
llarp_time_t shiftTimeout = (path::BUILD_TIMEOUT * 5) / 2;
|
||||
llarp_time_t estimatedRTT = 0s;
|
||||
bool markedBad = false;
|
||||
|
||||
std::function<void(AuthResult)> authResultListener;
|
||||
|
||||
virtual bool
|
||||
ShiftIntroduction(bool rebuild = true)
|
||||
{
|
||||
(void)rebuild;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void
|
||||
ShiftIntroRouter(const RouterID) = 0;
|
||||
|
||||
virtual void
|
||||
UpdateIntroSet() = 0;
|
||||
|
||||
virtual void
|
||||
MarkCurrentIntroBad(llarp_time_t now) = 0;
|
||||
|
||||
void
|
||||
AsyncSendAuth(std::function<void(AuthResult)> replyHandler);
|
||||
|
||||
private:
|
||||
virtual bool
|
||||
IntroGenerated() const = 0;
|
||||
virtual bool
|
||||
IntroSent() const = 0;
|
||||
|
||||
void
|
||||
EncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t);
|
||||
|
||||
virtual void
|
||||
AsyncGenIntro(const llarp_buffer_t& payload, ProtocolType t) = 0;
|
||||
};
|
||||
} // namespace llarp::service
|
@ -1,130 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "router_event.hpp"
|
||||
#include <llarp/dht/key.hpp>
|
||||
#include <llarp/service/intro_set.hpp>
|
||||
#include <llarp/dht/messages/findrouter.hpp>
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
struct PubIntroSentEvent : public RouterEvent
|
||||
{
|
||||
llarp::dht::Key_t introsetPubkey;
|
||||
llarp::RouterID relay;
|
||||
uint64_t relayIndex;
|
||||
|
||||
PubIntroSentEvent(
|
||||
const llarp::RouterID& ourRouter,
|
||||
const llarp::dht::Key_t& introsetPubkey_,
|
||||
const llarp::RouterID& relay_,
|
||||
uint64_t relayIndex_)
|
||||
: RouterEvent("DHT: PubIntroSentEvent", ourRouter, false)
|
||||
, introsetPubkey(introsetPubkey_)
|
||||
, relay(relay_)
|
||||
, relayIndex(relayIndex_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const
|
||||
{
|
||||
return RouterEvent::ToString() + " ---- introset pubkey: " + introsetPubkey.ShortHex()
|
||||
+ ", relay: " + relay.ShortString() + ", relayIndex: " + std::to_string(relayIndex);
|
||||
}
|
||||
};
|
||||
|
||||
struct PubIntroReceivedEvent : public RouterEvent
|
||||
{
|
||||
llarp::dht::Key_t from;
|
||||
llarp::dht::Key_t location;
|
||||
uint64_t txid;
|
||||
uint64_t relayOrder;
|
||||
|
||||
PubIntroReceivedEvent(
|
||||
const llarp::RouterID& ourRouter,
|
||||
const llarp::dht::Key_t& from_,
|
||||
const llarp::dht::Key_t& location_,
|
||||
uint64_t txid_,
|
||||
uint64_t relayOrder_)
|
||||
: RouterEvent("DHT: PubIntroReceivedEvent", ourRouter, true)
|
||||
, from(from_)
|
||||
, location(location_)
|
||||
, txid(txid_)
|
||||
, relayOrder(relayOrder_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const override
|
||||
{
|
||||
return RouterEvent::ToString() + "from " + from.ShortHex()
|
||||
+ " location=" + location.ShortHex() + " order=" + std::to_string(relayOrder)
|
||||
+ " txid=" + std::to_string(txid);
|
||||
}
|
||||
};
|
||||
|
||||
struct GotIntroReceivedEvent : public RouterEvent
|
||||
{
|
||||
llarp::dht::Key_t From;
|
||||
llarp::service::EncryptedIntroSet Introset;
|
||||
uint64_t RelayOrder;
|
||||
uint64_t TxID;
|
||||
|
||||
GotIntroReceivedEvent(
|
||||
const llarp::RouterID& ourRouter_,
|
||||
const llarp::dht::Key_t& from_,
|
||||
const llarp::service::EncryptedIntroSet& introset_,
|
||||
uint64_t txid_)
|
||||
: RouterEvent("DHT:: GotIntroReceivedEvent", ourRouter_, true)
|
||||
, From(from_)
|
||||
, Introset(introset_)
|
||||
, TxID(txid_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const override
|
||||
{
|
||||
return RouterEvent::ToString() + "from " + From.ShortHex()
|
||||
+ " location=" + Introset.derivedSigningKey.ShortHex()
|
||||
+ " order=" + std::to_string(RelayOrder) + " txid=" + std::to_string(TxID);
|
||||
}
|
||||
};
|
||||
|
||||
struct FindRouterEvent : public RouterEvent
|
||||
{
|
||||
llarp::dht::Key_t from;
|
||||
llarp::RouterID targetKey;
|
||||
bool iterative;
|
||||
bool exploritory;
|
||||
uint64_t txid;
|
||||
uint64_t version;
|
||||
|
||||
FindRouterEvent(const llarp::RouterID& ourRouter, const llarp::dht::FindRouterMessage& msg)
|
||||
: RouterEvent("DHT: FindRouterEvent", ourRouter, true)
|
||||
, from(msg.From)
|
||||
, targetKey(msg.targetKey)
|
||||
, iterative(msg.iterative)
|
||||
, exploritory(msg.exploratory)
|
||||
, txid(msg.txid)
|
||||
, version(msg.version)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const override
|
||||
{
|
||||
return RouterEvent::ToString() + " from " + from.ShortHex()
|
||||
+ ", targetKey: " + targetKey.ToString() + ", iterative: " + std::to_string(iterative)
|
||||
+ ", exploritory " + std::to_string(exploritory) + ", txid " + std::to_string(txid)
|
||||
+ ", version " + std::to_string(version);
|
||||
}
|
||||
};
|
||||
|
||||
struct FindRouterReceivedEvent : public FindRouterEvent
|
||||
{
|
||||
using FindRouterEvent::FindRouterEvent;
|
||||
};
|
||||
|
||||
struct FindRouterSentEvent : public FindRouterEvent
|
||||
{
|
||||
using FindRouterEvent::FindRouterEvent;
|
||||
};
|
||||
|
||||
} // namespace tooling
|
@ -1,30 +0,0 @@
|
||||
#include "hive_context.hpp"
|
||||
|
||||
#include "hive_router.hpp"
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
HiveContext::HiveContext(RouterHive* hive) : m_hive(hive)
|
||||
{}
|
||||
|
||||
std::shared_ptr<llarp::Router>
|
||||
HiveContext::makeRouter(const llarp::EventLoop_ptr& loop)
|
||||
{
|
||||
return std::make_shared<HiveRouter>(loop, makeVPNPlatform(), m_hive);
|
||||
}
|
||||
|
||||
HiveRouter*
|
||||
HiveContext::getRouterAsHiveRouter()
|
||||
{
|
||||
if (not router)
|
||||
return nullptr;
|
||||
|
||||
HiveRouter* hiveRouter = dynamic_cast<HiveRouter*>(router.get());
|
||||
|
||||
if (hiveRouter == nullptr)
|
||||
throw std::runtime_error("HiveContext has a router not of type HiveRouter");
|
||||
|
||||
return hiveRouter;
|
||||
}
|
||||
|
||||
} // namespace tooling
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp.hpp>
|
||||
#include "hive_router.hpp"
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
/// HiveContext is a subclass of llarp::Context which allows RouterHive to
|
||||
/// perform custom behavior which might be undesirable in production code.
|
||||
struct HiveContext : public llarp::Context
|
||||
{
|
||||
HiveContext(RouterHive* hive);
|
||||
|
||||
std::shared_ptr<llarp::Router>
|
||||
makeRouter(const llarp::EventLoop_ptr& loop) override;
|
||||
|
||||
/// Get this context's router as a HiveRouter.
|
||||
///
|
||||
/// Returns nullptr if there is no router or throws an exception if the
|
||||
/// router is somehow not an instance of HiveRouter.
|
||||
HiveRouter*
|
||||
getRouterAsHiveRouter();
|
||||
|
||||
protected:
|
||||
RouterHive* m_hive = nullptr;
|
||||
};
|
||||
|
||||
} // namespace tooling
|
@ -1,36 +0,0 @@
|
||||
#include "hive_router.hpp"
|
||||
|
||||
#include "router_hive.hpp"
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
HiveRouter::HiveRouter(
|
||||
llarp::EventLoop_ptr loop, std::shared_ptr<llarp::vpn::Platform> plat, RouterHive* hive)
|
||||
: Router(loop, plat), m_hive(hive)
|
||||
{}
|
||||
|
||||
bool
|
||||
HiveRouter::disableGossipingRC_TestingOnly()
|
||||
{
|
||||
return m_disableGossiping;
|
||||
}
|
||||
|
||||
void
|
||||
HiveRouter::disableGossiping()
|
||||
{
|
||||
m_disableGossiping = true;
|
||||
}
|
||||
|
||||
void
|
||||
HiveRouter::enableGossiping()
|
||||
{
|
||||
m_disableGossiping = false;
|
||||
}
|
||||
|
||||
void
|
||||
HiveRouter::HandleRouterEvent(RouterEventPtr event) const
|
||||
{
|
||||
m_hive->NotifyEvent(std::move(event));
|
||||
}
|
||||
|
||||
} // namespace tooling
|
@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/router/router.hpp>
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
/// HiveRouter is a subclass of Router which overrides specific behavior in
|
||||
/// order to perform testing-related functions. It exists largely to prevent
|
||||
/// this behavior (which may often be "dangerous") from leaking into release
|
||||
/// code.
|
||||
struct HiveRouter : public llarp::Router
|
||||
{
|
||||
explicit HiveRouter(
|
||||
llarp::EventLoop_ptr loop,
|
||||
std::shared_ptr<llarp::vpn::Platform> vpnPlatform,
|
||||
RouterHive* hive);
|
||||
|
||||
virtual ~HiveRouter() = default;
|
||||
|
||||
/// Override logic to prevent base Router class from gossiping its RC.
|
||||
virtual bool
|
||||
disableGossipingRC_TestingOnly() override;
|
||||
|
||||
void
|
||||
disableGossiping();
|
||||
|
||||
void
|
||||
enableGossiping();
|
||||
|
||||
protected:
|
||||
bool m_disableGossiping = false;
|
||||
RouterHive* m_hive = nullptr;
|
||||
|
||||
virtual void
|
||||
HandleRouterEvent(RouterEventPtr event) const override;
|
||||
};
|
||||
|
||||
} // namespace tooling
|
@ -1,132 +0,0 @@
|
||||
#include "router_event.hpp"
|
||||
|
||||
#include <llarp/path/path_types.hpp>
|
||||
#include <llarp/path/path.hpp>
|
||||
#include <llarp/path/transit_hop.hpp>
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
struct PathAttemptEvent : public RouterEvent
|
||||
{
|
||||
std::vector<llarp::path::PathHopConfig> hops;
|
||||
llarp::PathID_t pathid;
|
||||
|
||||
PathAttemptEvent(const llarp::RouterID& routerID, std::shared_ptr<const llarp::path::Path> path)
|
||||
: RouterEvent("PathAttemptEvent", routerID, false)
|
||||
, hops(path->hops)
|
||||
, pathid(path->hops[0].rxID)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const
|
||||
{
|
||||
std::string result = RouterEvent::ToString();
|
||||
result += "---- [";
|
||||
|
||||
size_t i = 0;
|
||||
for (const auto& hop : hops)
|
||||
{
|
||||
i++;
|
||||
|
||||
result += llarp::RouterID(hop.rc.pubkey).ShortString();
|
||||
result += "]";
|
||||
|
||||
if (i != hops.size())
|
||||
{
|
||||
result += " -> [";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct PathRequestReceivedEvent : public RouterEvent
|
||||
{
|
||||
llarp::RouterID prevHop;
|
||||
llarp::RouterID nextHop;
|
||||
llarp::PathID_t txid;
|
||||
llarp::PathID_t rxid;
|
||||
bool isEndpoint = false;
|
||||
|
||||
PathRequestReceivedEvent(
|
||||
const llarp::RouterID& routerID, std::shared_ptr<const llarp::path::TransitHop> hop)
|
||||
: RouterEvent("PathRequestReceivedEvent", routerID, true)
|
||||
, prevHop(hop->info.downstream)
|
||||
, nextHop(hop->info.upstream)
|
||||
, txid(hop->info.txID)
|
||||
, rxid(hop->info.rxID)
|
||||
, isEndpoint(routerID == nextHop ? true : false)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const
|
||||
{
|
||||
std::string result = RouterEvent::ToString();
|
||||
result += "---- [";
|
||||
result += prevHop.ShortString();
|
||||
result += "] -> [*";
|
||||
result += routerID.ShortString();
|
||||
result += "] -> [";
|
||||
|
||||
if (isEndpoint)
|
||||
{
|
||||
result += "nowhere]";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += nextHop.ShortString();
|
||||
result += "]";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct PathStatusReceivedEvent : public RouterEvent
|
||||
{
|
||||
llarp::PathID_t rxid;
|
||||
uint64_t status;
|
||||
|
||||
PathStatusReceivedEvent(
|
||||
const llarp::RouterID& routerID, const llarp::PathID_t rxid_, uint64_t status_)
|
||||
: RouterEvent("PathStatusReceivedEvent", routerID, true), rxid(rxid_), status(status_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const
|
||||
{
|
||||
std::string result = RouterEvent::ToString();
|
||||
result += "---- path rxid: " + rxid.ShortHex();
|
||||
result += ", status: " + std::to_string(status);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct PathBuildRejectedEvent : public RouterEvent
|
||||
{
|
||||
llarp::PathID_t rxid;
|
||||
llarp::RouterID rejectedBy;
|
||||
|
||||
PathBuildRejectedEvent(
|
||||
const llarp::RouterID& routerID,
|
||||
const llarp::PathID_t rxid_,
|
||||
const llarp::RouterID& rejectedBy_)
|
||||
: RouterEvent("PathBuildRejectedEvent", routerID, false)
|
||||
, rxid(rxid_)
|
||||
, rejectedBy(rejectedBy_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const
|
||||
{
|
||||
std::string result = RouterEvent::ToString();
|
||||
result += "---- path rxid: " + rxid.ShortHex();
|
||||
result += ", rejectedBy: " + rejectedBy.ShortString();
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tooling
|
@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "router_event.hpp"
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
struct LinkSessionEstablishedEvent : public RouterEvent
|
||||
{
|
||||
llarp::RouterID remoteId;
|
||||
bool inbound = false;
|
||||
|
||||
LinkSessionEstablishedEvent(
|
||||
const llarp::RouterID& ourRouterId, const llarp::RouterID& remoteId_, bool inbound_)
|
||||
: RouterEvent("Link: LinkSessionEstablishedEvent", ourRouterId, false)
|
||||
, remoteId(remoteId_)
|
||||
, inbound(inbound_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const
|
||||
{
|
||||
return RouterEvent::ToString() + (inbound ? "inbound" : "outbound")
|
||||
+ " : LinkSessionEstablished with " + remoteId.ToString();
|
||||
}
|
||||
};
|
||||
|
||||
struct ConnectionAttemptEvent : public RouterEvent
|
||||
{
|
||||
llarp::RouterID remoteId;
|
||||
|
||||
ConnectionAttemptEvent(const llarp::RouterID& ourRouterId, const llarp::RouterID& remoteId_)
|
||||
: RouterEvent("Link: ConnectionAttemptEvent", ourRouterId, false), remoteId(remoteId_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const
|
||||
{
|
||||
return RouterEvent::ToString() + " : LinkSessionEstablished with " + remoteId.ToString();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tooling
|
@ -1,53 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "router_event.hpp"
|
||||
|
||||
#include <llarp/router_contact.hpp>
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
struct RCGossipReceivedEvent : public RouterEvent
|
||||
{
|
||||
RCGossipReceivedEvent(const llarp::RouterID& routerID, const llarp::RouterContact& rc_)
|
||||
: RouterEvent("RCGossipReceivedEvent", routerID, true), rc(rc_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const override
|
||||
{
|
||||
return RouterEvent::ToString()
|
||||
+ " ---- other RouterID: " + llarp::RouterID(rc.pubkey).ShortString();
|
||||
}
|
||||
|
||||
std::string
|
||||
LongString() const
|
||||
{
|
||||
return RouterEvent::ToString() + " ---- RC: " + rc.ToString();
|
||||
}
|
||||
|
||||
llarp::RouterContact rc;
|
||||
};
|
||||
|
||||
struct RCGossipSentEvent : public RouterEvent
|
||||
{
|
||||
RCGossipSentEvent(const llarp::RouterID& routerID, const llarp::RouterContact& rc_)
|
||||
: RouterEvent("RCGossipSentEvent", routerID, true), rc(rc_)
|
||||
{}
|
||||
|
||||
std::string
|
||||
ToString() const override
|
||||
{
|
||||
return RouterEvent::ToString()
|
||||
+ " ---- sending RC for RouterID: " + llarp::RouterID(rc.pubkey).ShortString();
|
||||
}
|
||||
|
||||
std::string
|
||||
LongString() const
|
||||
{
|
||||
return RouterEvent::ToString() + " ---- RC: " + rc.ToString();
|
||||
}
|
||||
|
||||
llarp::RouterContact rc;
|
||||
};
|
||||
|
||||
} // namespace tooling
|
@ -1,56 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct PathID_t;
|
||||
|
||||
namespace path
|
||||
{
|
||||
struct Path;
|
||||
struct PathHopConfig;
|
||||
|
||||
struct TransitHop;
|
||||
|
||||
} // namespace path
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
struct RouterHive;
|
||||
|
||||
struct RouterEvent
|
||||
{
|
||||
RouterEvent(std::string eventType, llarp::RouterID routerID, bool triggered)
|
||||
: eventType(eventType), routerID(routerID), triggered(triggered)
|
||||
{}
|
||||
|
||||
virtual ~RouterEvent() = default;
|
||||
|
||||
virtual std::string
|
||||
ToString() const
|
||||
{
|
||||
std::string result;
|
||||
result += eventType;
|
||||
result += " [";
|
||||
result += routerID.ShortString();
|
||||
result += "] -- ";
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::string eventType;
|
||||
|
||||
llarp::RouterID routerID;
|
||||
|
||||
bool triggered = false;
|
||||
};
|
||||
|
||||
using RouterEventPtr = std::unique_ptr<RouterEvent>;
|
||||
|
||||
} // namespace tooling
|
@ -1,249 +0,0 @@
|
||||
#include "router_hive.hpp"
|
||||
|
||||
#include <llarp.hpp>
|
||||
#include <llarp/util/str.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
#include <csignal>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
void
|
||||
RouterHive::AddRouter(const std::shared_ptr<llarp::Config>& config, bool isSNode)
|
||||
{
|
||||
auto& container = (isSNode ? relays : clients);
|
||||
|
||||
llarp::RuntimeOptions opts;
|
||||
opts.isSNode = isSNode;
|
||||
|
||||
Context_ptr context = std::make_shared<HiveContext>(this);
|
||||
context->Configure(config);
|
||||
context->Setup(opts);
|
||||
|
||||
auto routerId = llarp::RouterID(context->router->pubkey());
|
||||
container[routerId] = context;
|
||||
fmt::print("Generated router with ID {}\n", routerId);
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::AddRelay(const std::shared_ptr<llarp::Config>& config)
|
||||
{
|
||||
AddRouter(config, true);
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::AddClient(const std::shared_ptr<llarp::Config>& config)
|
||||
{
|
||||
AddRouter(config, false);
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::StartRouters(bool isRelay)
|
||||
{
|
||||
auto& container = (isRelay ? relays : clients);
|
||||
|
||||
for (const auto& [routerId, ctx] : container)
|
||||
{
|
||||
routerMainThreads.emplace_back([ctx = ctx, isRelay = isRelay]() {
|
||||
ctx->Run(llarp::RuntimeOptions{false, false, isRelay});
|
||||
});
|
||||
std::this_thread::sleep_for(2ms);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::StartRelays()
|
||||
{
|
||||
StartRouters(true);
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::StartClients()
|
||||
{
|
||||
StartRouters(false);
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::StopRouters()
|
||||
{
|
||||
llarp::LogInfo("Signalling all routers to stop");
|
||||
for (auto& [routerId, ctx] : relays)
|
||||
{
|
||||
ctx->loop->call([ctx = ctx]() { ctx->HandleSignal(SIGINT); });
|
||||
}
|
||||
for (auto& [routerId, ctx] : clients)
|
||||
{
|
||||
ctx->loop->call([ctx = ctx]() { ctx->HandleSignal(SIGINT); });
|
||||
}
|
||||
|
||||
llarp::LogInfo("Waiting on routers to be stopped");
|
||||
for (auto [routerId, ctx] : relays)
|
||||
{
|
||||
while (ctx->IsUp())
|
||||
{
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
}
|
||||
for (auto [routerId, ctx] : clients)
|
||||
{
|
||||
while (ctx->IsUp())
|
||||
{
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
}
|
||||
|
||||
llarp::LogInfo("Joining all router threads");
|
||||
for (auto& thread : routerMainThreads)
|
||||
{
|
||||
while (not thread.joinable())
|
||||
{
|
||||
std::this_thread::sleep_for(500ms);
|
||||
}
|
||||
thread.join();
|
||||
}
|
||||
|
||||
llarp::LogInfo("RouterHive::StopRouters finished");
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::NotifyEvent(RouterEventPtr event)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard{eventQueueMutex};
|
||||
|
||||
eventQueue.push_back(std::move(event));
|
||||
}
|
||||
|
||||
RouterEventPtr
|
||||
RouterHive::GetNextEvent()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard{eventQueueMutex};
|
||||
|
||||
if (not eventQueue.empty())
|
||||
{
|
||||
auto ptr = std::move(eventQueue.front());
|
||||
eventQueue.pop_front();
|
||||
return ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::deque<RouterEventPtr>
|
||||
RouterHive::GetAllEvents()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard{eventQueueMutex};
|
||||
|
||||
std::deque<RouterEventPtr> events;
|
||||
if (not eventQueue.empty())
|
||||
{
|
||||
eventQueue.swap(events);
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::VisitRouter(Context_ptr ctx, std::function<void(Context_ptr)> visit)
|
||||
{
|
||||
// TODO: this should be called from each router's appropriate Loop, e.g.:
|
||||
// ctx->loop->call([visit, ctx]() { visit(ctx); });
|
||||
// however, this causes visit calls to be deferred
|
||||
visit(ctx);
|
||||
}
|
||||
|
||||
HiveRouter*
|
||||
RouterHive::GetRelay(const llarp::RouterID& id, bool needMutexLock)
|
||||
{
|
||||
auto guard =
|
||||
needMutexLock ? std::make_optional<std::lock_guard<std::mutex>>(routerMutex) : std::nullopt;
|
||||
|
||||
auto itr = relays.find(id);
|
||||
if (itr == relays.end())
|
||||
return nullptr;
|
||||
|
||||
auto ctx = itr->second;
|
||||
return ctx->getRouterAsHiveRouter();
|
||||
}
|
||||
|
||||
std::vector<size_t>
|
||||
RouterHive::RelayConnectedRelays()
|
||||
{
|
||||
std::lock_guard guard{routerMutex};
|
||||
std::vector<size_t> results;
|
||||
results.resize(relays.size());
|
||||
std::mutex results_lock;
|
||||
|
||||
size_t i = 0;
|
||||
size_t done_count = 0;
|
||||
for (auto& [routerId, ctx] : relays)
|
||||
{
|
||||
ctx->loop->call([&, i, ctx = ctx]() {
|
||||
size_t count = ctx->router->NumberOfConnectedRouters();
|
||||
std::lock_guard guard{results_lock};
|
||||
results[i] = count;
|
||||
done_count++;
|
||||
});
|
||||
i++;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
size_t read_done_count = 0;
|
||||
{
|
||||
std::lock_guard guard{results_lock};
|
||||
read_done_count = done_count;
|
||||
}
|
||||
if (read_done_count == relays.size())
|
||||
break;
|
||||
|
||||
std::this_thread::sleep_for(100ms);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
// TODO: DRY -- this smells a lot like RelayConnectedRelays()
|
||||
std::vector<llarp::RouterContact>
|
||||
RouterHive::GetRelayRCs()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard{routerMutex};
|
||||
std::vector<llarp::RouterContact> results;
|
||||
results.resize(relays.size());
|
||||
|
||||
size_t i = 0;
|
||||
for (auto [routerId, ctx] : relays)
|
||||
{
|
||||
results[i] = ctx->router->rc();
|
||||
i++;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::ForEachRelay(std::function<void(Context_ptr)> visit)
|
||||
{
|
||||
for (auto [routerId, ctx] : relays)
|
||||
{
|
||||
VisitRouter(ctx, visit);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouterHive::ForEachClient(std::function<void(Context_ptr)> visit)
|
||||
{
|
||||
for (auto [routerId, ctx] : clients)
|
||||
{
|
||||
VisitRouter(ctx, visit);
|
||||
}
|
||||
}
|
||||
|
||||
/// safely visit every router context
|
||||
void
|
||||
RouterHive::ForEachRouter(std::function<void(Context_ptr)> visit)
|
||||
{
|
||||
ForEachRelay(visit);
|
||||
ForEachClient(visit);
|
||||
}
|
||||
|
||||
} // namespace tooling
|
@ -1,95 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "router_event.hpp"
|
||||
|
||||
#include <llarp.hpp>
|
||||
#include <llarp/config/config.hpp>
|
||||
#include <llarp/tooling/hive_context.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
struct llarp_config;
|
||||
struct llarp_main;
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct Context;
|
||||
} // namespace llarp
|
||||
|
||||
namespace tooling
|
||||
{
|
||||
struct HiveRouter; // Hive's version of Router
|
||||
|
||||
struct RouterHive
|
||||
{
|
||||
using Context_ptr = std::shared_ptr<HiveContext>;
|
||||
|
||||
private:
|
||||
void
|
||||
StartRouters(bool isRelay);
|
||||
|
||||
void
|
||||
AddRouter(const std::shared_ptr<llarp::Config>& config, bool isRelay);
|
||||
|
||||
/// safely visit router (asynchronously)
|
||||
void
|
||||
VisitRouter(Context_ptr ctx, std::function<void(Context_ptr)> visit);
|
||||
|
||||
public:
|
||||
RouterHive() = default;
|
||||
|
||||
void
|
||||
AddRelay(const std::shared_ptr<llarp::Config>& conf);
|
||||
|
||||
void
|
||||
AddClient(const std::shared_ptr<llarp::Config>& conf);
|
||||
|
||||
void
|
||||
StartRelays();
|
||||
|
||||
void
|
||||
StartClients();
|
||||
|
||||
void
|
||||
StopRouters();
|
||||
|
||||
void
|
||||
NotifyEvent(RouterEventPtr event);
|
||||
|
||||
RouterEventPtr
|
||||
GetNextEvent();
|
||||
|
||||
std::deque<RouterEventPtr>
|
||||
GetAllEvents();
|
||||
|
||||
// functions to safely visit each relay and/or client's HiveContext
|
||||
void
|
||||
ForEachRelay(std::function<void(Context_ptr)> visit);
|
||||
void
|
||||
ForEachClient(std::function<void(Context_ptr)> visit);
|
||||
void
|
||||
ForEachRouter(std::function<void(Context_ptr)> visit);
|
||||
|
||||
HiveRouter*
|
||||
GetRelay(const llarp::RouterID& id, bool needMutexLock = true);
|
||||
|
||||
std::vector<size_t>
|
||||
RelayConnectedRelays();
|
||||
|
||||
std::vector<llarp::RouterContact>
|
||||
GetRelayRCs();
|
||||
|
||||
std::mutex routerMutex;
|
||||
std::unordered_map<llarp::RouterID, Context_ptr> relays;
|
||||
std::unordered_map<llarp::RouterID, Context_ptr> clients;
|
||||
|
||||
std::vector<std::thread> routerMainThreads;
|
||||
|
||||
std::mutex eventQueueMutex;
|
||||
std::deque<RouterEventPtr> eventQueue;
|
||||
};
|
||||
|
||||
} // namespace tooling
|
@ -92,4 +92,7 @@ namespace llarp
|
||||
|
||||
std::string
|
||||
lowercase_ascii_string(std::string src);
|
||||
|
||||
std::string_view
|
||||
TrimWhitespace(std::string_view str);
|
||||
} // namespace llarp
|
||||
|
Loading…
Reference in New Issue
Block a user