From 877443d95ce3106c07ece17bf48d9979fd7a694a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 28 Feb 2020 11:29:15 -0500 Subject: [PATCH] more introspection code --- contrib/py/pyllarp/hive.py | 29 ++++++++- include/llarp.hpp | 2 +- llarp/context.cpp | 7 ++- llarp/ev/vpnio.cpp | 2 +- llarp/handlers/null.hpp | 3 +- llarp/router/router.hpp | 1 + llarp/service/address.hpp | 6 ++ llarp/service/context.cpp | 10 ++++ llarp/service/context.hpp | 10 ++++ llarp/service/endpoint.cpp | 19 +++--- llarp/service/endpoint.hpp | 5 +- llarp/tooling/router_hive.cpp | 16 +++++ llarp/tooling/router_hive.hpp | 21 +++++++ pybind/CMakeLists.txt | 2 + pybind/common.hpp | 12 ++++ pybind/llarp/context.cpp | 4 ++ pybind/llarp/handlers/pyhandler.cpp | 88 ++++++++++++++++++++++++++++ pybind/llarp/service/address.cpp | 16 +++++ pybind/llarp/tooling/router_hive.cpp | 2 + pybind/module.cpp | 2 + 20 files changed, 239 insertions(+), 18 deletions(-) create mode 100644 pybind/llarp/handlers/pyhandler.cpp create mode 100644 pybind/llarp/service/address.cpp diff --git a/contrib/py/pyllarp/hive.py b/contrib/py/pyllarp/hive.py index 8d7161b54..25de61948 100644 --- a/contrib/py/pyllarp/hive.py +++ b/contrib/py/pyllarp/hive.py @@ -17,7 +17,12 @@ def RemoveTmpDir(dirname): else: print("not removing dir %s because it doesn't start with /tmp/" % dirname) -def AddRouter(hive, index, netid="hive"): +def MakeEndpoint(router, idx, after): + ep = pyllarp.Endpoint("pyllarp-{}".format(idx), router) + if after is not None: + router.SafeCall(lambda : after(ep)) + +def AddRouter(hive, index, gotEndpoint=None, netid="hive"): dirname = "%s/routers/%d" % (tmpdir, index) makedirs("%s/netdb" % dirname, exist_ok=True) @@ -56,6 +61,10 @@ def AddRouter(hive, index, netid="hive"): config.bootstrap.routers = ["%s/routers/1/rc.signed" % tmpdir] hive.AddRouter(config) + if index != 1: + hive.VisitRouter(index, lambda r : MakeEndpoint(r, index, gotEndpoint)) + + def main(): @@ -82,8 +91,22 @@ def main(): hive = pyllarp.RouterHive() + addrs = [] + + def onGotEndpoint(ep): + addr = ep.OurAddress() + print("got endpoint: {}".format(addr)) + addrs.append(addr) + + def sendToAddress(router, toaddr, pkt): + print("sending {} bytes to {}".format(len(pkt), toaddr)) + router.TrySendPacket(toaddr, pkt) + + def broadcastTo(addr, pkt): + hive.ForEach(lambda r : sendToAddress(r, addr, pkt)) + for i in range(1, 11): - AddRouter(hive, i) + AddRouter(hive, i, onGotEndpoint) hive.StartAll() @@ -91,6 +114,8 @@ def main(): event = hive.GetNextEvent() if event: print(event) + for addr in addrs: + broadcastTo(addr, "packet lol") hive.StopAll() diff --git a/include/llarp.hpp b/include/llarp.hpp index 2cdc61f13..af5af3bcc 100644 --- a/include/llarp.hpp +++ b/include/llarp.hpp @@ -39,7 +39,7 @@ namespace llarp struct Context { /// get context from main pointer - static Context * + static std::shared_ptr Get(llarp_main *); Context() = default; diff --git a/llarp/context.cpp b/llarp/context.cpp index bf56b25e3..cbbc29991 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -314,7 +314,7 @@ struct llarp_main { llarp_main(llarp_config *conf); ~llarp_main() = default; - std::unique_ptr< llarp::Context > ctx; + std::shared_ptr< llarp::Context > ctx; }; struct llarp_config @@ -560,11 +560,12 @@ llarp_main::llarp_main(llarp_config *conf) namespace llarp { - Context * + + std::shared_ptr Context::Get(llarp_main *m) { if(m == nullptr || m->ctx == nullptr) return nullptr; - return m->ctx.get(); + return m->ctx; } } // namespace llarp diff --git a/llarp/ev/vpnio.cpp b/llarp/ev/vpnio.cpp index ba107752f..c8dac8ab9 100644 --- a/llarp/ev/vpnio.cpp +++ b/llarp/ev/vpnio.cpp @@ -14,7 +14,7 @@ llarp_vpn_io_impl::AsyncClose() void llarp_vpn_io_impl::CallSafe(std::function< void(void) > f) { - llarp::Context* ctx = llarp::Context::Get(ptr); + auto ctx = llarp::Context::Get(ptr); if(ctx && ctx->CallSafe(f)) return; else if(ctx == nullptr || ctx->logic == nullptr) diff --git a/llarp/handlers/null.hpp b/llarp/handlers/null.hpp index b6f1650bd..c54a52338 100644 --- a/llarp/handlers/null.hpp +++ b/llarp/handlers/null.hpp @@ -11,13 +11,14 @@ namespace llarp : public llarp::service::Endpoint, public std::enable_shared_from_this< NullEndpoint > { + NullEndpoint(const std::string &name, AbstractRouter *r, llarp::service::Context *parent) : llarp::service::Endpoint(name, r, parent) { } - bool + virtual bool HandleInboundPacket(const service::ConvoTag, const llarp_buffer_t &, service::ProtocolType) override { diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index fcfef22d0..2fd7e877f 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -228,6 +228,7 @@ namespace llarp return _hiddenServiceContext; } + llarp_time_t _lastTick = 0s; bool diff --git a/llarp/service/address.hpp b/llarp/service/address.hpp index 84e75eed1..881a751a0 100644 --- a/llarp/service/address.hpp +++ b/llarp/service/address.hpp @@ -39,6 +39,12 @@ namespace llarp { } + explicit Address(const std::string & str) : AlignedBuffer<32>() + { + if(not FromString(str)) + throw std::runtime_error("invalid address"); + } + explicit Address(const Data& buf) : AlignedBuffer< 32 >(buf) { } diff --git a/llarp/service/context.cpp b/llarp/service/context.cpp index 03f324bc8..5b5400097 100644 --- a/llarp/service/context.cpp +++ b/llarp/service/context.cpp @@ -192,6 +192,16 @@ namespace llarp return nullptr; } + + void + Context::InjectEndpoint(std::string name, std::shared_ptr ep) + { + if(ep->Start()) + { + m_Endpoints.emplace(std::move(name), std::move(ep)); + } + } + bool Context::AddEndpoint(const Config::section_t &conf, bool autostart) { diff --git a/llarp/service/context.hpp b/llarp/service/context.hpp index abc5fb716..6256aa7ae 100644 --- a/llarp/service/context.hpp +++ b/llarp/service/context.hpp @@ -46,6 +46,10 @@ namespace llarp bool AddEndpoint(const Config::section_t &conf, bool autostart = false); + /// inject endpoint instance + void + InjectEndpoint(std::string name, std::shared_ptr ep); + /// stop and remove an endpoint by name /// return false if we don't have the hidden service with that name bool @@ -54,6 +58,12 @@ namespace llarp Endpoint_ptr GetEndpointByName(const std::string &name); + Endpoint_ptr + GetDefault() + { + return GetEndpointByName("default"); + } + bool StartAll(); diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 29dc8a75d..b6ad5049d 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -197,14 +197,17 @@ namespace llarp // prefetch addrs for(const auto& addr : m_state->m_PrefetchAddrs) { - if(!EndpointUtil::HasPathToService(addr, m_state->m_RemoteSessions)) - { - if(!EnsurePathToService( - addr, [](Address, OutboundContext*) {}, 10s)) - { - LogWarn("failed to ensure path to ", addr); - } - } + EnsurePathToService( + addr, [](Address, OutboundContext* ctx) { + #ifdef LOKINET_HIVE + std::vector discard; + discard.resize(128); + ctx->AsyncEncryptAndSendTo(llarp_buffer_t(discard), eProtocolControl); + #else + (void)ctx; + #endif + }, 10s); + } // deregister dead sessions diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 81d1cee50..93d980173 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -369,13 +369,14 @@ namespace llarp const std::set< RouterID >& SnodeBlacklist() const; - protected: + bool SendToServiceOrQueue(const service::Address& addr, const llarp_buffer_t& payload, ProtocolType t); bool SendToSNodeOrQueue(const RouterID& addr, const llarp_buffer_t& payload); - + + protected: /// parent context that owns this endpoint Context* const context; diff --git a/llarp/tooling/router_hive.cpp b/llarp/tooling/router_hive.cpp index ff6d177e0..99ee0d34c 100644 --- a/llarp/tooling/router_hive.cpp +++ b/llarp/tooling/router_hive.cpp @@ -2,6 +2,7 @@ #include "llarp.h" #include "llarp.hpp" +#include "util/thread/logic.hpp" #include @@ -105,4 +106,19 @@ namespace tooling } + void + RouterHive::VisitRouter(size_t index, std::function visit) + { + if(index >= routers.size()) + { + visit(nullptr); + return; + } + auto * r = routers[index]; + auto ctx = llarp::Context::Get(r); + LogicCall(ctx->logic, [visit, ctx]() { + visit(ctx); + }); + } + } // namespace tooling diff --git a/llarp/tooling/router_hive.hpp b/llarp/tooling/router_hive.hpp index 774edc46c..f8d34d352 100644 --- a/llarp/tooling/router_hive.hpp +++ b/llarp/tooling/router_hive.hpp @@ -12,6 +12,11 @@ struct llarp_config; struct llarp_main; +namespace llarp +{ + struct Context; +} + namespace tooling { @@ -40,6 +45,22 @@ namespace tooling GetNextEvent(); + using Context_ptr = std::shared_ptr; + + /// safely visit every router context + void + ForEachRouter(std::function visit) + { + for(size_t idx = 0; idx < routers.size(); ++idx) + { + VisitRouter(idx, visit); + } + } + + /// safely visit router at index N + void + VisitRouter(size_t index, std::function visit); + /* * Event processing function declarations */ diff --git a/pybind/CMakeLists.txt b/pybind/CMakeLists.txt index 7eb79ad03..4b8e30f4c 100644 --- a/pybind/CMakeLists.txt +++ b/pybind/CMakeLists.txt @@ -6,8 +6,10 @@ set(LLARP_PYBIND_SRC llarp/router_contact.cpp llarp/crypto/types.cpp llarp/config.cpp + llarp/handlers/pyhandler.cpp llarp/tooling/router_hive.cpp llarp/tooling/router_event.cpp + llarp/service/address.cpp ) pybind11_add_module(pyllarp MODULE ${LLARP_PYBIND_SRC}) diff --git a/pybind/common.hpp b/pybind/common.hpp index cc08e1ebb..a72908ecd 100644 --- a/pybind/common.hpp +++ b/pybind/common.hpp @@ -45,6 +45,18 @@ namespace llarp void Config_Init(py::module & mod); + namespace handlers + { + void + PyHandler_Init(py::module & mod); + } + + namespace service + { + void + Address_Init(py::module &mod); + } + } // namespace llarp namespace tooling diff --git a/pybind/llarp/context.cpp b/pybind/llarp/context.cpp index a0d7b738b..889980cd1 100644 --- a/pybind/llarp/context.cpp +++ b/pybind/llarp/context.cpp @@ -17,6 +17,10 @@ namespace llarp .def("IsUp", &Context::IsUp) .def("LooksAlive", &Context::LooksAlive) .def("Configure", &Context::Configure) + .def("TrySendPacket", [](Context_ptr self, service::Address to, std::vector pkt) { + auto ep = self->router->hiddenServiceContext().GetDefault(); + return ep->SendToServiceOrQueue(to, pkt, service::eProtocolControl); + }) .def("CallSafe", &Context::CallSafe); } } // namespace llarp diff --git a/pybind/llarp/handlers/pyhandler.cpp b/pybind/llarp/handlers/pyhandler.cpp new file mode 100644 index 000000000..a97afbf15 --- /dev/null +++ b/pybind/llarp/handlers/pyhandler.cpp @@ -0,0 +1,88 @@ +#include "common.hpp" +#include "llarp.hpp" +#include "service/context.hpp" +#include "service/endpoint.hpp" +#include "router/abstractrouter.hpp" + +namespace llarp +{ + namespace handlers + { + using Context_ptr = std::shared_ptr; + + struct PythonEndpoint final + : public llarp::service::Endpoint, + public std::enable_shared_from_this< PythonEndpoint > + { + + PythonEndpoint(std::string name, Context_ptr routerContext) + : llarp::service::Endpoint(name, routerContext->router.get(), &routerContext->router->hiddenServiceContext()) + { + routerContext->router->hiddenServiceContext().InjectEndpoint(name, shared_from_this()); + } + + bool + HandleInboundPacket(const service::ConvoTag tag, const llarp_buffer_t & pktbuf, + service::ProtocolType proto) override + { + if(handlePacket) + { + AlignedBuffer<32> addr; + bool isSnode = false; + if(not GetEndpointWithConvoTag(tag, addr, isSnode)) + return false; + if(isSnode) + return true; + std::vector pkt; + pkt.resize(pktbuf.sz); + std::copy_n(pktbuf.base, pktbuf.sz, pkt.data()); + handlePacket(service::Address(addr), std::move(pkt), proto); + } + return true; + } + + path::PathSet_ptr + GetSelf() override + { + return shared_from_this(); + } + + bool + SupportsV6() const override + { + return false; + } + + using PacketHandler_t = std::function, service::ProtocolType)>; + + PacketHandler_t handlePacket; + + void + SendPacket(service::Address remote, std::vector pkt, service::ProtocolType proto) + { + LogicCall(m_router->logic(), [remote, pkt, proto, self=shared_from_this()]() { + self->SendToServiceOrQueue(remote, llarp_buffer_t(pkt), proto); + }); + } + + std::string + GetOurAddress() const + { + return m_Identity.pub.Addr().ToString(); + } + }; + + + void + PyHandler_Init(py::module & mod) + { + py::class_ >(mod, "Endpoint") + .def(py::init()) + .def("SendTo", &PythonEndpoint::SendPacket) + .def("OurAddress", &PythonEndpoint::GetOurAddress) + .def_readwrite("GotPacket", &PythonEndpoint::handlePacket); + } + + } // namespace handlers + +} \ No newline at end of file diff --git a/pybind/llarp/service/address.cpp b/pybind/llarp/service/address.cpp new file mode 100644 index 000000000..a659d434b --- /dev/null +++ b/pybind/llarp/service/address.cpp @@ -0,0 +1,16 @@ +#include "common.hpp" +#include "service/address.hpp" + +namespace llarp +{ + namespace service + { + void + Address_Init(py::module & mod) + { + py::class_
(mod, "ServiceAddress") + .def(py::init()) + .def("__str__", &Address::ToString); + } + } +} \ No newline at end of file diff --git a/pybind/llarp/tooling/router_hive.cpp b/pybind/llarp/tooling/router_hive.cpp index 572824ccf..d9b7aab48 100644 --- a/pybind/llarp/tooling/router_hive.cpp +++ b/pybind/llarp/tooling/router_hive.cpp @@ -12,6 +12,8 @@ namespace tooling .def("AddRouter", &RouterHive::AddRouter) .def("StartAll", &RouterHive::StartRouters) .def("StopAll", &RouterHive::StopRouters) + .def("ForEachRouter", &RouterHive::ForEachRouter) + .def("VisitRouter", &RouterHive::VisitRouter) .def("GetNextEvent", &RouterHive::GetNextEvent); } diff --git a/pybind/module.cpp b/pybind/module.cpp index 255882dde..0b134c81a 100644 --- a/pybind/module.cpp +++ b/pybind/module.cpp @@ -8,4 +8,6 @@ PYBIND11_MODULE(pyllarp, m) llarp::CryptoTypes_Init(m); llarp::Context_Init(m); llarp::Config_Init(m); + llarp::handlers::PyHandler_Init(m); + llarp::service::Address_Init(m); }