From f1cf63fce7fe8b84c7e228670365ed84d50f0b06 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 28 Jan 2019 10:26:35 -0500 Subject: [PATCH] add initial localhost.loki handling in dns --- llarp/handlers/null.hpp | 5 ++-- llarp/handlers/tun.cpp | 47 +++++++++++++++++++++++++++++++++----- llarp/handlers/tun.hpp | 10 +++++++- llarp/service/context.cpp | 33 +++++++++++++++++++------- llarp/service/context.hpp | 6 +++++ llarp/service/endpoint.cpp | 6 +++-- llarp/service/endpoint.hpp | 21 ++++++++++++++++- 7 files changed, 108 insertions(+), 20 deletions(-) diff --git a/llarp/handlers/null.hpp b/llarp/handlers/null.hpp index 02b47314c..fb61d4d1c 100644 --- a/llarp/handlers/null.hpp +++ b/llarp/handlers/null.hpp @@ -9,8 +9,9 @@ namespace llarp { struct NullEndpoint final : public llarp::service::Endpoint { - NullEndpoint(const std::string &name, llarp::Router *r) - : llarp::service::Endpoint(name, r){}; + NullEndpoint(const std::string &name, llarp::Router *r, + llarp::service::Context *parent) + : llarp::service::Endpoint(name, r, parent){}; bool HandleWriteIPPacket(llarp_buffer_t, std::function< huint32_t(void) >) override diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index c585a19e3..7a7d42dde 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -29,8 +29,9 @@ namespace llarp self->Flush(); } - TunEndpoint::TunEndpoint(const std::string &nickname, llarp::Router *r) - : service::Endpoint(nickname, r) + TunEndpoint::TunEndpoint(const std::string &nickname, llarp::Router *r, + service::Context *parent) + : service::Endpoint(nickname, r, parent) , m_UserToNetworkPktQueue(nickname + "_sendq", r->netloop, r->netloop) , m_NetworkToUserPktQueue(nickname + "_recvq", r->netloop, r->netloop) , m_Resolver(r->netloop, this) @@ -204,10 +205,7 @@ namespace llarp return false; } std::string qname = msg.questions[0].qname; - if(msg.questions[0].qtype == dns::qTypeCNAME) - { - } - else if(msg.questions[0].qtype == dns::qTypeMX) + if(msg.questions[0].qtype == dns::qTypeMX) { // mx record llarp::service::Address addr; @@ -228,6 +226,21 @@ namespace llarp else msg.AddNXReply(); } + else if(msg.questions[0].qname == "localhost.loki" + || msg.questions[0].qname == "localhost.loki.") + { + size_t counter = 0; + context->ForEachService( + [&](const std::string &, + const std::unique_ptr< service::Endpoint > &service) -> bool { + service::Address addr = service->GetIdentity().pub.Addr(); + msg.AddCNAMEReply(addr.ToString(), 1); + ++counter; + return true; + }); + if(counter == 0) + msg.AddNXReply(); + } else msg.AddNXReply(); } @@ -243,6 +256,24 @@ namespace llarp else msg.AddNXReply(); } + else if(msg.questions[0].qname == "localhost.loki" + || msg.questions[0].qname == "localhost.loki.") + { + size_t counter = 0; + context->ForEachService( + [&](const std::string &, + const std::unique_ptr< service::Endpoint > &service) -> bool { + if(service->HasIfAddr()) + { + huint32_t ip = service->GetIfAddr(); + msg.AddINReply(ip); + ++counter; + } + return true; + }); + if(counter == 0) + msg.AddNXReply(); + } else if(addr.FromString(qname, ".loki")) { if(HasAddress(addr)) @@ -321,6 +352,10 @@ namespace llarp if(msg.questions[0].qname == "random.snode" || msg.questions[0].qname == "random.snode.") return true; + if(msg.questions[0].qname == "localhost.loki" + || msg.questions[0].qname == "localhost.loki.") + return msg.questions[0].qtype == llarp::dns::qTypeCNAME + || msg.questions[0].qtype == llarp::dns::qTypeA; // always hook .loki if(addr.FromString(msg.questions[0].qname, ".loki")) return true; diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index d7d36c65b..a11faaa36 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -20,7 +20,8 @@ namespace llarp struct TunEndpoint : public service::Endpoint, public dns::IQueryHandler { - TunEndpoint(const std::string& nickname, llarp::Router* r); + TunEndpoint(const std::string& nickname, llarp::Router* r, + llarp::service::Context* parent); ~TunEndpoint(); virtual bool @@ -70,6 +71,13 @@ namespace llarp bool QueueOutboundTraffic(llarp::net::IPv4Packet&& pkt); + /// we have a resolvable ip address + bool + HasIfAddr() const override + { + return true; + } + /// get the local interface's address huint32_t GetIfAddr() const; diff --git a/llarp/service/context.cpp b/llarp/service/context.cpp index 243346ec9..7a14a6c12 100644 --- a/llarp/service/context.cpp +++ b/llarp/service/context.cpp @@ -30,6 +30,22 @@ namespace llarp return true; } + void + Context::ForEachService( + std::function< bool(const std::string &, + const std::unique_ptr< Endpoint > &) > + visit) + { + auto itr = m_Endpoints.begin(); + while(itr != m_Endpoints.end()) + { + if(visit(itr->first, itr->second)) + ++itr; + else + return; + } + } + bool Context::RemoveEndpoint(const std::string &name) { @@ -274,17 +290,18 @@ namespace llarp static std::map< std::string, std::function< llarp::service::Endpoint *( - const std::string &, llarp::Router *) > > + const std::string &, llarp::Router *, + llarp::service::Context *) > > endpointConstructors = { {"tun", - [](const std::string &nick, - llarp::Router *r) -> llarp::service::Endpoint * { - return new llarp::handlers::TunEndpoint(nick, r); + [](const std::string &nick, llarp::Router *r, + llarp::service::Context *c) -> llarp::service::Endpoint * { + return new llarp::handlers::TunEndpoint(nick, r, c); }}, {"null", - [](const std::string &nick, - llarp::Router *r) -> llarp::service::Endpoint * { - return new llarp::handlers::NullEndpoint(nick, r); + [](const std::string &nick, llarp::Router *r, + llarp::service::Context *c) -> llarp::service::Endpoint * { + return new llarp::handlers::NullEndpoint(nick, r, c); }}}; { @@ -297,7 +314,7 @@ namespace llarp } // construct - service.reset(itr->second(conf.first, m_Router)); + service.reset(itr->second(conf.first, m_Router, this)); // if ephemeral, then we need to regen key // if privkey file, then set it and load it diff --git a/llarp/service/context.hpp b/llarp/service/context.hpp index 87cde2bc9..de002223f 100644 --- a/llarp/service/context.hpp +++ b/llarp/service/context.hpp @@ -61,6 +61,12 @@ namespace llarp bool iterate(struct endpoint_iter &i); + /// function visitor returns false to prematurely break iteration + void + ForEachService(std::function< bool(const std::string &, + const std::unique_ptr< Endpoint > &) > + visit); + /// hint at possible path usage and trigger building early bool Prefetch(const llarp::service::Address &addr); diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index f324faf78..2791ee678 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -16,8 +16,10 @@ namespace llarp { namespace service { - Endpoint::Endpoint(const std::string& name, llarp::Router* r) + Endpoint::Endpoint(const std::string& name, llarp::Router* r, + Context* parent) : path::Builder(r, r->dht, 6, DEFAULT_HOP_LENGTH) + , context(parent) , m_Router(r) , m_Name(name) { @@ -512,7 +514,7 @@ namespace llarp Endpoint::Start() { // how can I tell if a m_Identity isn't loaded? - //this->LoadKeyFile(); + // this->LoadKeyFile(); if(!m_DataHandler) { m_DataHandler = this; diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index e49acf4cf..1e2445723 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -20,6 +20,8 @@ namespace llarp { namespace service { + // foward declare + struct Context; // forward declare struct AsyncKeyExchange; @@ -35,7 +37,7 @@ namespace llarp static const size_t MAX_OUTBOUND_CONTEXT_COUNT = 4; - Endpoint(const std::string& nickname, llarp::Router* r); + Endpoint(const std::string& nickname, llarp::Router* r, Context* parent); ~Endpoint(); void @@ -47,6 +49,20 @@ namespace llarp virtual void Tick(llarp_time_t now); + /// return true if we have a resolvable ip address + virtual bool + HasIfAddr() const + { + return false; + } + + /// get our ifaddr if it is set + virtual huint32_t + GetIfAddr() const + { + return huint32_t{0}; + } + /// router's logic llarp::Logic* RouterLogic(); @@ -381,6 +397,9 @@ namespace llarp IntroSetPublished(); protected: + /// parent context that owns this endpoint + Context* const context; + void RegenAndPublishIntroSet(llarp_time_t now, bool forceRebuild = false);