add initial localhost.loki handling in dns

This commit is contained in:
Jeff Becker 2019-01-28 10:26:35 -05:00
parent 1e0d82848f
commit f1cf63fce7
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
7 changed files with 108 additions and 20 deletions

View File

@ -9,8 +9,9 @@ namespace llarp
{ {
struct NullEndpoint final : public llarp::service::Endpoint struct NullEndpoint final : public llarp::service::Endpoint
{ {
NullEndpoint(const std::string &name, llarp::Router *r) NullEndpoint(const std::string &name, llarp::Router *r,
: llarp::service::Endpoint(name, r){}; llarp::service::Context *parent)
: llarp::service::Endpoint(name, r, parent){};
bool HandleWriteIPPacket(llarp_buffer_t, bool HandleWriteIPPacket(llarp_buffer_t,
std::function< huint32_t(void) >) override std::function< huint32_t(void) >) override

View File

@ -29,8 +29,9 @@ namespace llarp
self->Flush(); self->Flush();
} }
TunEndpoint::TunEndpoint(const std::string &nickname, llarp::Router *r) TunEndpoint::TunEndpoint(const std::string &nickname, llarp::Router *r,
: service::Endpoint(nickname, r) service::Context *parent)
: service::Endpoint(nickname, r, parent)
, m_UserToNetworkPktQueue(nickname + "_sendq", r->netloop, r->netloop) , m_UserToNetworkPktQueue(nickname + "_sendq", r->netloop, r->netloop)
, m_NetworkToUserPktQueue(nickname + "_recvq", r->netloop, r->netloop) , m_NetworkToUserPktQueue(nickname + "_recvq", r->netloop, r->netloop)
, m_Resolver(r->netloop, this) , m_Resolver(r->netloop, this)
@ -204,10 +205,7 @@ namespace llarp
return false; return false;
} }
std::string qname = msg.questions[0].qname; std::string qname = msg.questions[0].qname;
if(msg.questions[0].qtype == dns::qTypeCNAME) if(msg.questions[0].qtype == dns::qTypeMX)
{
}
else if(msg.questions[0].qtype == dns::qTypeMX)
{ {
// mx record // mx record
llarp::service::Address addr; llarp::service::Address addr;
@ -228,6 +226,21 @@ namespace llarp
else else
msg.AddNXReply(); 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 else
msg.AddNXReply(); msg.AddNXReply();
} }
@ -243,6 +256,24 @@ namespace llarp
else else
msg.AddNXReply(); 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")) else if(addr.FromString(qname, ".loki"))
{ {
if(HasAddress(addr)) if(HasAddress(addr))
@ -321,6 +352,10 @@ namespace llarp
if(msg.questions[0].qname == "random.snode" if(msg.questions[0].qname == "random.snode"
|| msg.questions[0].qname == "random.snode.") || msg.questions[0].qname == "random.snode.")
return true; 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 // always hook .loki
if(addr.FromString(msg.questions[0].qname, ".loki")) if(addr.FromString(msg.questions[0].qname, ".loki"))
return true; return true;

View File

@ -20,7 +20,8 @@ namespace llarp
struct TunEndpoint : public service::Endpoint, public dns::IQueryHandler 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(); ~TunEndpoint();
virtual bool virtual bool
@ -70,6 +71,13 @@ namespace llarp
bool bool
QueueOutboundTraffic(llarp::net::IPv4Packet&& pkt); QueueOutboundTraffic(llarp::net::IPv4Packet&& pkt);
/// we have a resolvable ip address
bool
HasIfAddr() const override
{
return true;
}
/// get the local interface's address /// get the local interface's address
huint32_t huint32_t
GetIfAddr() const; GetIfAddr() const;

View File

@ -30,6 +30,22 @@ namespace llarp
return true; 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 bool
Context::RemoveEndpoint(const std::string &name) Context::RemoveEndpoint(const std::string &name)
{ {
@ -274,17 +290,18 @@ namespace llarp
static std::map< std::string, static std::map< std::string,
std::function< llarp::service::Endpoint *( std::function< llarp::service::Endpoint *(
const std::string &, llarp::Router *) > > const std::string &, llarp::Router *,
llarp::service::Context *) > >
endpointConstructors = { endpointConstructors = {
{"tun", {"tun",
[](const std::string &nick, [](const std::string &nick, llarp::Router *r,
llarp::Router *r) -> llarp::service::Endpoint * { llarp::service::Context *c) -> llarp::service::Endpoint * {
return new llarp::handlers::TunEndpoint(nick, r); return new llarp::handlers::TunEndpoint(nick, r, c);
}}, }},
{"null", {"null",
[](const std::string &nick, [](const std::string &nick, llarp::Router *r,
llarp::Router *r) -> llarp::service::Endpoint * { llarp::service::Context *c) -> llarp::service::Endpoint * {
return new llarp::handlers::NullEndpoint(nick, r); return new llarp::handlers::NullEndpoint(nick, r, c);
}}}; }}};
{ {
@ -297,7 +314,7 @@ namespace llarp
} }
// construct // 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 ephemeral, then we need to regen key
// if privkey file, then set it and load it // if privkey file, then set it and load it

View File

@ -61,6 +61,12 @@ namespace llarp
bool bool
iterate(struct endpoint_iter &i); 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 /// hint at possible path usage and trigger building early
bool bool
Prefetch(const llarp::service::Address &addr); Prefetch(const llarp::service::Address &addr);

View File

@ -16,8 +16,10 @@ namespace llarp
{ {
namespace service 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) : path::Builder(r, r->dht, 6, DEFAULT_HOP_LENGTH)
, context(parent)
, m_Router(r) , m_Router(r)
, m_Name(name) , m_Name(name)
{ {
@ -512,7 +514,7 @@ namespace llarp
Endpoint::Start() Endpoint::Start()
{ {
// how can I tell if a m_Identity isn't loaded? // how can I tell if a m_Identity isn't loaded?
//this->LoadKeyFile(); // this->LoadKeyFile();
if(!m_DataHandler) if(!m_DataHandler)
{ {
m_DataHandler = this; m_DataHandler = this;

View File

@ -20,6 +20,8 @@ namespace llarp
{ {
namespace service namespace service
{ {
// foward declare
struct Context;
// forward declare // forward declare
struct AsyncKeyExchange; struct AsyncKeyExchange;
@ -35,7 +37,7 @@ namespace llarp
static const size_t MAX_OUTBOUND_CONTEXT_COUNT = 4; 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(); ~Endpoint();
void void
@ -47,6 +49,20 @@ namespace llarp
virtual void virtual void
Tick(llarp_time_t now); 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 /// router's logic
llarp::Logic* llarp::Logic*
RouterLogic(); RouterLogic();
@ -381,6 +397,9 @@ namespace llarp
IntroSetPublished(); IntroSetPublished();
protected: protected:
/// parent context that owns this endpoint
Context* const context;
void void
RegenAndPublishIntroSet(llarp_time_t now, bool forceRebuild = false); RegenAndPublishIntroSet(llarp_time_t now, bool forceRebuild = false);