diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 2055126d0..49d725dc9 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -424,8 +424,11 @@ namespace libuv Close() override { uv_check_stop(&m_Ticker); - m_Ticker.data = nullptr; - delete this; + uv_close((uv_handle_t*)&m_Ticker, [](auto h) { + ticker_glue* self = (ticker_glue*)h->data; + h->data = nullptr; + delete self; + }); } uv_check_t m_Ticker; @@ -663,7 +666,7 @@ namespace libuv OnTick(uv_check_t* timer) { tun_glue* tun = static_cast< tun_glue* >(timer->data); - LoopCall(timer, std::bind(&tun_glue::Tick, tun)); + tun->Tick(); } static void @@ -682,7 +685,7 @@ namespace libuv if(sz > 0) { llarp::LogDebug("tun read ", sz); - llarp_buffer_t pkt(m_Buffer, sz); + const llarp_buffer_t pkt(m_Buffer, sz); if(m_Tun && m_Tun->recvpkt) m_Tun->recvpkt(m_Tun, pkt); } @@ -711,9 +714,14 @@ namespace libuv void Close() override { + if(m_Tun->impl == nullptr) + return; m_Tun->impl = nullptr; uv_check_stop(&m_Ticker); - uv_close((uv_handle_t*)&m_Handle, &OnClosed); + uv_close((uv_handle_t*)&m_Ticker, [](uv_handle_t* h) { + tun_glue* glue = static_cast< tun_glue* >(h->data); + uv_close((uv_handle_t*)&glue->m_Handle, &OnClosed); + }); } bool @@ -824,18 +832,24 @@ namespace libuv int Loop::tick(int ms) { - uv_timer_start(&m_TickTimer, &OnTickTimeout, ms, 0); - uv_run(&m_Impl, UV_RUN_ONCE); + if(m_Run) + { + uv_timer_start(&m_TickTimer, &OnTickTimeout, ms, 0); + uv_run(&m_Impl, UV_RUN_ONCE); + } return 0; } void Loop::stop() { - uv_stop(&m_Impl); - llarp::LogInfo("stopping event loop"); + if(m_Run) + { + llarp::LogInfo("stopping event loop"); + CloseAll(); + // uv_stop(&m_Impl); + } m_Run.store(false); - CloseAll(); } void diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index c8d5431c5..7c5c490d6 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -16,7 +16,13 @@ namespace llarp static void ExitHandlerRecvPkt(llarp_tun_io *tun, const llarp_buffer_t &buf) { - static_cast< ExitEndpoint * >(tun->user)->OnInetPacket(buf); + std::vector< byte_t > pkt; + pkt.resize(buf.sz); + std::copy_n(buf.base, buf.sz, pkt.data()); + auto self = static_cast< ExitEndpoint * >(tun->user); + LogicCall(self->GetRouter()->logic(), [self, pktbuf = std::move(pkt)]() { + self->OnInetPacket(std::move(pktbuf)); + }); } static void @@ -457,10 +463,13 @@ namespace llarp } void - ExitEndpoint::OnInetPacket(const llarp_buffer_t &buf) + ExitEndpoint::OnInetPacket(std::vector< byte_t > buf) { + const llarp_buffer_t buffer(buf); m_InetToNetwork.EmplaceIf( - [b = ManagedBuffer(buf)](Pkt_t &pkt) -> bool { return pkt.Load(b); }); + [b = ManagedBuffer(buffer)](Pkt_t &pkt) -> bool { + return pkt.Load(b); + }); } bool diff --git a/llarp/handlers/exit.hpp b/llarp/handlers/exit.hpp index 21a499160..170535fa5 100644 --- a/llarp/handlers/exit.hpp +++ b/llarp/handlers/exit.hpp @@ -57,7 +57,7 @@ namespace llarp /// handle ip packet from outside void - OnInetPacket(const llarp_buffer_t& buf); + OnInetPacket(std::vector< byte_t > buf); AbstractRouter* GetRouter(); diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index cdd538094..40e9e842f 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -32,11 +32,11 @@ namespace llarp m_NetworkToUserPktQueue.Process(send); } - static void - tunifTick(llarp_tun_io *tun) + void + TunEndpoint::tunifTick(llarp_tun_io *tun) { auto *self = static_cast< TunEndpoint * >(tun->user); - self->Flush(); + LogicCall(self->m_router->logic(), [self]() { self->Flush(); }); } TunEndpoint::TunEndpoint(const std::string &nickname, AbstractRouter *r, @@ -308,13 +308,20 @@ namespace llarp void TunEndpoint::Flush() { - auto self = shared_from_this(); - FlushSend(); - LogicCall(RouterLogic(), [=] { + static const auto func = [](auto self) { + self->FlushSend(); self->m_ExitMap.ForEachValue( [](const auto &exit) { exit->FlushUpstream(); }); self->Pump(self->Now()); - }); + }; + if(NetworkIsIsolated()) + { + LogicCall(RouterLogic(), std::bind(func, shared_from_this())); + } + else + { + func(this); + } } static bool @@ -749,13 +756,11 @@ namespace llarp void TunEndpoint::Tick(llarp_time_t now) { - LogicCall(EndpointLogic(), [&]() { - m_ExitMap.ForEachValue([&](const auto &exit) { - this->EnsureRouterIsKnown(exit->Endpoint()); - exit->Tick(now); - }); - Endpoint::Tick(now); + m_ExitMap.ForEachValue([&](const auto &exit) { + this->EnsureRouterIsKnown(exit->Endpoint()); + exit->Tick(now); }); + Endpoint::Tick(now); } bool @@ -983,8 +988,7 @@ namespace llarp return false; }; LogicCall(self->EndpointLogic(), - std::bind(&TunEndpoint::FlushToUser, self->shared_from_this(), - sendpkt)); + std::bind(&TunEndpoint::FlushToUser, self, sendpkt)); } void @@ -992,9 +996,14 @@ namespace llarp { // called for every packet read from user in isolated network thread auto *self = static_cast< TunEndpoint * >(tun->user); - const ManagedBuffer pkt(b); - self->m_UserToNetworkPktQueue.EmplaceIf( - [&pkt](net::IPPacket &p) -> bool { return p.Load(pkt); }); + std::vector< byte_t > pkt; + pkt.resize(b.sz); + std::copy_n(b.base, b.sz, pkt.data()); + LogicCall(self->RouterLogic(), [self, buffer = std::move(pkt)]() { + const llarp_buffer_t pbuf(buffer); + self->m_UserToNetworkPktQueue.EmplaceIf( + [&pbuf](net::IPPacket &p) -> bool { return p.Load(pbuf); }); + }); } TunEndpoint::~TunEndpoint() = default; diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index fc48ec547..2889e7a5d 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -56,6 +56,9 @@ namespace llarp void TickTun(llarp_time_t now); + static void + tunifTick(llarp_tun_io*); + bool MapAddress(const service::Address& remote, huint128_t ip, bool SNode);