From 159415c3635f16a5330764d333d36fd6f9a900d8 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 1 Mar 2019 14:10:42 -0500 Subject: [PATCH] delay dns resolution for snode until we have a session with it --- llarp/ev/ev.hpp | 2 +- llarp/ev/ev_epoll.cpp | 4 ++-- llarp/exit/session.cpp | 17 +++++++++++++- llarp/exit/session.hpp | 9 ++++++++ llarp/handlers/tun.cpp | 46 +++++++++++++------------------------- llarp/handlers/tun.hpp | 17 +++++++++++--- llarp/router/router.cpp | 3 +-- llarp/router_contact.hpp | 6 ++--- llarp/service/endpoint.cpp | 9 +++++++- llarp/service/endpoint.hpp | 2 +- 10 files changed, 71 insertions(+), 44 deletions(-) diff --git a/llarp/ev/ev.hpp b/llarp/ev/ev.hpp index f79ef8867..25462a885 100644 --- a/llarp/ev/ev.hpp +++ b/llarp/ev/ev.hpp @@ -560,7 +560,7 @@ namespace llarp { sockaddr_storage st; socklen_t sl; - if (getpeername(fd, (sockaddr*)&st, &sl) == 0) + if(getpeername(fd, (sockaddr*)&st, &sl) == 0) { // we are connected yeh boi if(_conn) diff --git a/llarp/ev/ev_epoll.cpp b/llarp/ev/ev_epoll.cpp index 3dbb4bf9d..e7ecfe5bb 100644 --- a/llarp/ev/ev_epoll.cpp +++ b/llarp/ev/ev_epoll.cpp @@ -322,7 +322,7 @@ llarp_epoll_loop::tick(int ms) { epoll_event events[1024]; int result; - result = epoll_wait(epollfd, events, 1024, ms); + result = epoll_wait(epollfd, events, 1024, ms); bool didIO = false; if(result > 0) { @@ -339,7 +339,7 @@ llarp_epoll_loop::tick(int ms) llarp::LogDebug("epoll error"); ev->error(); } - else + else { // write THEN READ don't revert me if(events[idx].events & EPOLLOUT) diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 17d7d2fc1..8506c8562 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -101,19 +101,34 @@ namespace llarp llarp::LogError("failed to send exit request"); } + void + BaseSession::AddReadyHook(SessionReadyFunc func) + { + m_PendingCallbacks.emplace_back(func); + } + bool BaseSession::HandleGotExit(llarp::path::Path* p, llarp_time_t b) { - m_LastUse = router->Now(); + BaseSession* self = this; + m_LastUse = router->Now(); if(b == 0) llarp::LogInfo("obtained an exit via ", p->Endpoint()); + else + self = nullptr; + for(auto& f : m_PendingCallbacks) + f(self); + m_PendingCallbacks.clear(); return true; } bool BaseSession::Stop() { + for(auto& f : m_PendingCallbacks) + f(nullptr); + m_PendingCallbacks.clear(); auto sendExitClose = [&](llarp::path::Path* p) { if(p->SupportsAnyRoles(llarp::path::ePathRoleExit)) { diff --git a/llarp/exit/session.hpp b/llarp/exit/session.hpp index b669e67ee..edf903b17 100644 --- a/llarp/exit/session.hpp +++ b/llarp/exit/session.hpp @@ -13,6 +13,10 @@ namespace llarp { namespace exit { + struct BaseSession; + + using SessionReadyFunc = std::function< void(BaseSession*) >; + /// a persisting exit session with an exit router struct BaseSession : public llarp::path::Builder { @@ -64,6 +68,9 @@ namespace llarp bool LoadIdentityFromFile(const char* fname); + void + AddReadyHook(SessionReadyFunc func); + protected: llarp::RouterID m_ExitRouter; llarp::SecretKey m_ExitIdentity; @@ -107,6 +114,8 @@ namespace llarp uint64_t m_Counter; llarp_time_t m_LastUse; + + std::vector< SessionReadyFunc > m_PendingCallbacks; }; struct ExitSession final : public BaseSession diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index fedbc7c92..556466577 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -333,24 +333,28 @@ namespace llarp else { dns::Message *replyMsg = new dns::Message(std::move(msg)); - service::Endpoint::PathEnsureHook hook = std::bind( - &TunEndpoint::SendDNSReply, this, std::placeholders::_1, - std::placeholders::_2, replyMsg, reply); - return EnsurePathToService(addr, hook, 2000); + return EnsurePathToService( + addr, + [=](const service::Address &remote, OutboundContext *ctx) { + SendDNSReply(remote, ctx, replyMsg, reply, false); + }, + 2000); } } else if(addr.FromString(qname, ".snode")) { - // TODO: add hook to EnsurePathToSNode - EnsurePathToSNode(addr.as_array()); - huint32_t ip = ObtainIPForAddr(addr, true); - if(ip.h) - msg.AddINReply(ip); - else + if(HasPathToSNode(addr.as_array())) { - llarp::LogWarn("no ip found for ", addr); - msg.AddNXReply(); + msg.AddINReply(ObtainIPForAddr(addr, true)); + reply(msg); + return true; } + dns::Message *replyMsg = new dns::Message(std::move(msg)); + EnsurePathToSNode(addr.as_array(), + [=](const RouterID &remote, exit::BaseSession *s) { + SendDNSReply(remote, s, replyMsg, reply, true); + }); + return true; } else // forward dns @@ -430,24 +434,6 @@ namespace llarp return false; } - void - TunEndpoint::SendDNSReply(service::Address addr, - service::Endpoint::OutboundContext *ctx, - dns::Message *request, - std::function< void(dns::Message) > reply) - { - if(ctx) - { - huint32_t ip = ObtainIPForAddr(addr, false); - request->AddINReply(ip); - } - else - request->AddNXReply(); - - reply(*request); - delete request; - } - bool TunEndpoint::MapAddress(const service::Address &addr, huint32_t ip, bool SNode) diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 573ec2360..cb7d8149c 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -192,10 +192,21 @@ namespace llarp }); } + template < typename Addr_t, typename Endpoint_t > void - SendDNSReply(service::Address addr, - service::Endpoint::OutboundContext* ctx, dns::Message* query, - std::function< void(dns::Message) > reply); + SendDNSReply(Addr_t addr, Endpoint_t* ctx, dns::Message* query, + std::function< void(dns::Message) > reply, bool snode) + { + if(ctx) + { + huint32_t ip = ObtainIPForAddr(addr, snode); + query->AddINReply(ip); + } + else + query->AddNXReply(); + reply(*query); + delete query; + } #ifndef WIN32 /// handles fd injection force android diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 2c8555638..f3a52711b 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -193,7 +193,7 @@ namespace llarp } bool - Router::OnSessionEstablished(ILinkSession * s) + Router::OnSessionEstablished(ILinkSession *s) { return async_verify_RC(s->GetRemoteRC()); } @@ -1228,7 +1228,6 @@ namespace llarp bool Router::async_verify_RC(const RouterContact &rc) { - if(rc.IsPublicRouter() && whitelistRouters && IsServiceNode()) { if(lokinetRouters.find(rc.pubkey) == lokinetRouters.end()) diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 8681f87bf..4ee9278e4 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -130,9 +130,9 @@ namespace llarp && nickname == other.nickname && last_updated == other.last_updated && netID == other.netID; } - - bool - operator!=(const RouterContact & other) const + + bool + operator!=(const RouterContact &other) const { return !(*this == other); } diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 12bf459bd..08ed36b3b 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1205,7 +1205,7 @@ namespace llarp } void - Endpoint::EnsurePathToSNode(const RouterID& snode) + Endpoint::EnsurePathToSNode(const RouterID& snode, SNodeEnsureHook h) { if(m_SNodeSessions.count(snode) == 0) { @@ -1219,6 +1219,13 @@ namespace llarp [themIP]() -> huint32_t { return themIP; }), m_Router, 2, numHops)); } + auto range = m_SNodeSessions.equal_range(snode); + auto itr = range.first; + while(itr != range.second) + { + itr->second->AddReadyHook(std::bind(h, snode, std::placeholders::_1)); + ++itr; + } } bool diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 76781c4c3..342417120 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -366,7 +366,7 @@ namespace llarp /// ensure a path to a service node by public key void - EnsurePathToSNode(const RouterID& remote); + EnsurePathToSNode(const RouterID& remote, SNodeEnsureHook h); bool HasPathToSNode(const RouterID& remote) const;