wire up snode to dns (maybe)

pull/90/head
Jeff Becker 6 years ago
parent 85f9f46362
commit 7de2ce72ad
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -6,7 +6,7 @@
#include "dnsd.hpp" #include "dnsd.hpp"
using map_address_hook_func = using map_address_hook_func =
std::function< bool(const llarp::service::Address &addr, uint32_t ip) >; std::function< bool(const byte_t* addr,bool isSNode, uint32_t ip) >;
/// dotLokiLookup context/config /// dotLokiLookup context/config
struct dotLokiLookup struct dotLokiLookup

@ -46,7 +46,7 @@ struct dnsd_query_hook_response
/// turn off recursion /// turn off recursion
bool dontLookUp; bool dontLookUp;
/// potential address /// potential address
llarp::huint32_t *returnThis; llarp::huint32_t returnThis;
}; };
/// builds and fires a request based based on llarp_udp_io udp event /// builds and fires a request based based on llarp_udp_io udp event

@ -94,10 +94,10 @@ namespace llarp
/// get a key for ip address /// get a key for ip address
template < typename Addr > template < typename Addr >
Addr Addr
ObtainAddrForIP(huint32_t ip) ObtainAddrForIP(huint32_t ip, bool isSNode)
{ {
auto itr = m_IPToAddr.find(ip); auto itr = m_IPToAddr.find(ip);
if(itr == m_IPToAddr.end()) if(itr == m_IPToAddr.end() || m_SNodes[itr->second] != isSNode)
{ {
// not found // not found
Addr addr; Addr addr;

@ -28,7 +28,7 @@ namespace llarp
getFirstEndpoint(); getFirstEndpoint();
bool bool
FindBestAddressFor(const llarp::service::Address &, huint32_t &); FindBestAddressFor(const byte_t* addr, bool isSNode, huint32_t &);
/// DRY refactor /// DRY refactor
llarp::handlers::TunEndpoint * llarp::handlers::TunEndpoint *
@ -55,9 +55,6 @@ namespace llarp
bool bool
iterate(struct endpoint_iter &i); iterate(struct endpoint_iter &i);
huint32_t
GetIpForAddr(const llarp::service::Address &addr);
/// 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);

@ -31,6 +31,32 @@ struct check_query_simple_request
std::unordered_map< std::string, struct dnsd_query_hook_response * > std::unordered_map< std::string, struct dnsd_query_hook_response * >
loki_tld_lookup_cache; loki_tld_lookup_cache;
static bool decode_request_name(const std::string & name, llarp::AlignedBuffer<32> & addr, bool &isSNode)
{
llarp::service::Address serviceAddr;
llarp::RouterID snodeAddr;
auto pos = name.find(".snode");
if(pos != std::string::npos)
{
if(!llarp::HexDecode(name.substr(0, pos).c_str(), serviceAddr.data(), serviceAddr.size()))
{
return false;
}
addr = snodeAddr.data();
isSNode = true;
}
else
{
if(!serviceAddr.FromString(name))
{
return false;
}
addr = serviceAddr.data();
isSNode = false;
}
return true;
}
void void
llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig, llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
uint64_t left) uint64_t left)
@ -54,15 +80,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
// if so send that // if so send that
// else // else
// if we have a free private ip, send that // if we have a free private ip, send that
llarp::service::Address addr;
if(!addr.FromString(qr->request->question.name))
{
llarp::LogWarn("Could not base32 decode address: ",
qr->request->question.name);
write404_dnss_response(qr->request);
delete qr;
return;
}
/* /*
// cache hit // cache hit
auto itr = loki_tld_lookup_cache.find(addr.ToString()); auto itr = loki_tld_lookup_cache.find(addr.ToString());
@ -90,16 +108,24 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
delete qr; delete qr;
return; return;
} }
llarp::huint32_t serviceIP;
llarp::huint32_t *tunIp = llarp::AlignedBuffer<32> addr;
new llarp::huint32_t(routerHiddenServiceContext->GetIpForAddr(addr)); bool isSNode = false;
if(!tunIp->h) if(!decode_request_name(qr->request->question.name, addr, isSNode))
{
llarp::LogWarn("decode_request_name failed");
write404_dnss_response(qr->request);
delete qr;
return;
}
if(!routerHiddenServiceContext->FindBestAddressFor(addr, isSNode, serviceIP))
{ {
llarp::LogWarn("dotLokiLookup failed to map address"); llarp::LogWarn("dotLokiLookup failed to map address");
write404_dnss_response(qr->request); write404_dnss_response(qr->request);
delete qr; delete qr;
return; return;
} }
/* /*
bool mapResult = routerHiddenServiceContext->MapAddressAll( bool mapResult = routerHiddenServiceContext->MapAddressAll(
@ -120,7 +146,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
// llarp::Addr test(*free_private->hostResult.getSockAddr()); // llarp::Addr test(*free_private->hostResult.getSockAddr());
// llarp::LogInfo("IP Test: ", test); // llarp::LogInfo("IP Test: ", test);
// response->returnThis = &free_private->hostResult; // response->returnThis = &free_private->hostResult;
response->returnThis = tunIp; response->returnThis = serviceIP;
llarp::LogInfo("Saving ", qr->request->question.name); llarp::LogInfo("Saving ", qr->request->question.name);
loki_tld_lookup_cache[qr->request->question.name] = response; loki_tld_lookup_cache[qr->request->question.name] = response;
// we can't delete response now... // we can't delete response now...
@ -141,7 +167,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig,
} }
*/ */
llarp::huint32_t foundAddr; llarp::huint32_t foundAddr;
if(!routerHiddenServiceContext->FindBestAddressFor(addr, foundAddr)) if(!routerHiddenServiceContext->FindBestAddressFor(addr, isSNode, foundAddr))
{ {
write404_dnss_response(qr->request); write404_dnss_response(qr->request);
delete qr; delete qr;
@ -256,17 +282,30 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
if(inRange) if(inRange)
{ {
llarp::service::Address addr = llarp::AlignedBuffer<32> addr =
tunEndpoint->ObtainAddrForIP< llarp::service::Address >( tunEndpoint->ObtainAddrForIP< llarp::AlignedBuffer<32> >(
searchIPv4_fixed); searchIPv4_fixed, false);
if(addr.IsZero()) if(addr.IsZero())
{ {
write404_dnss_response((dnsd_question_request *)context->request); addr =
tunEndpoint->ObtainAddrForIP< llarp::AlignedBuffer<32> >(
searchIPv4_fixed, true);
if(!addr.IsZero())
{
char stack[128] = {0};
std::string saddr = llarp::HexEncode(addr, stack);
saddr += ".snode";
writesend_dnss_revresponse(saddr,
(dnsd_question_request *)context->request);
}
else
write404_dnss_response((dnsd_question_request *)context->request);
} }
else else
{ {
// llarp::LogInfo("Returning [", addr.ToString(), "]"); // llarp::LogInfo("Returning [", addr.ToString(), "]");
writesend_dnss_revresponse(addr.ToString(), llarp::service::Address saddr = addr.data();
writesend_dnss_revresponse(saddr.ToString(),
(dnsd_question_request *)context->request); (dnsd_question_request *)context->request);
} }
return false; return false;
@ -274,6 +313,21 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
return true; // we don't do anything with the result yet return true; // we don't do anything with the result yet
} }
static bool should_intercept_query_with_name(const std::string & lName)
{
// null terminated list
static const char * const matches[] = { ".loki", ".snode", ".loki.", ".snode.", 0};
size_t idx = 0;
while(matches[idx])
{
std::string match_str(matches[idx]);
if(lName.substr(lName.length() - match_str.length()) == match_str)
return true;
++idx;
}
return false;
}
dnsd_query_hook_response * dnsd_query_hook_response *
llarp_dotlokilookup_handler(std::string name, llarp_dotlokilookup_handler(std::string name,
struct dnsd_question_request *const request) struct dnsd_question_request *const request)
@ -281,7 +335,7 @@ llarp_dotlokilookup_handler(std::string name,
dnsd_query_hook_response *response = new dnsd_query_hook_response; dnsd_query_hook_response *response = new dnsd_query_hook_response;
response->dontLookUp = false; response->dontLookUp = false;
response->dontSendResponse = false; response->dontSendResponse = false;
response->returnThis = nullptr; response->returnThis.h = 0;
llarp::LogDebug("Hooked ", name); llarp::LogDebug("Hooked ", name);
std::string lName = name; std::string lName = name;
std::transform(lName.begin(), lName.end(), lName.begin(), ::tolower); std::transform(lName.begin(), lName.end(), lName.begin(), ::tolower);
@ -322,9 +376,7 @@ llarp_dotlokilookup_handler(std::string name,
llarp::LogInfo("Reverse is not ours"); llarp::LogInfo("Reverse is not ours");
} }
} }
else if((lName.length() > 5 && lName.substr(lName.length() - 5, 5) == ".loki") else if(should_intercept_query_with_name(lName))
|| (lName.length() > 6
&& lName.substr(lName.length() - 6, 6) == ".loki."))
{ {
llarp::LogInfo("Detect Loki Lookup for ", lName); llarp::LogInfo("Detect Loki Lookup for ", lName);
auto cache_check = loki_tld_lookup_cache.find(lName); auto cache_check = loki_tld_lookup_cache.find(lName);
@ -337,15 +389,14 @@ llarp_dotlokilookup_handler(std::string name,
return cache_check->second; return cache_check->second;
} }
// decode string into HS addr // decode address
llarp::service::Address addr; llarp::AlignedBuffer<32> addr;
if(!addr.FromString(lName)) bool isSNode = false;
if(!decode_request_name(lName, addr, isSNode))
{ {
llarp::LogWarn("Could not base32 decode address"); response->dontLookUp = true;
response->dontLookUp = true; // will return nullptr which will give a 404
return response; return response;
} }
llarp::LogDebug("Base32 decoded address ", addr);
dotLokiLookup *dll = (dotLokiLookup *)request->context->user; dotLokiLookup *dll = (dotLokiLookup *)request->context->user;
llarp::service::Context *routerHiddenServiceContext = llarp::service::Context *routerHiddenServiceContext =
@ -366,11 +417,23 @@ llarp_dotlokilookup_handler(std::string name,
qr->request = request; qr->request = request;
auto tun = routerHiddenServiceContext->getFirstTun(); auto tun = routerHiddenServiceContext->getFirstTun();
if(tun->HasPathToService(addr)) if(isSNode)
{ {
llarp_dotlokilookup_checkQuery(qr, 0, 0); if(tun->HasPathToSNode(addr.data()))
response->dontSendResponse = true; // will send it shortly {
return response; llarp_dotlokilookup_checkQuery(qr, 0, 0);
response->dontSendResponse = true; // will send it shortly
return response;
}
}
else
{
if(tun->HasPathToService(addr.data()))
{
llarp_dotlokilookup_checkQuery(qr, 0, 0);
response->dontSendResponse = true; // will send it shortly
return response;
}
} }
// nslookup on osx is about 5 sec before a retry, 2s on linux // nslookup on osx is about 5 sec before a retry, 2s on linux

@ -462,11 +462,11 @@ handle_recvfrom(llarp_buffer_t buffer, dnsd_question_request *request)
llarp::LogDebug("HOOKED: Not sending a response"); llarp::LogDebug("HOOKED: Not sending a response");
return; return;
} }
if(intercept->dontLookUp == true && intercept->returnThis) if(intercept->dontLookUp == true && intercept->returnThis.h)
{ {
llarp::LogDebug("HOOKED: sending an immediate override"); llarp::LogDebug("HOOKED: sending an immediate override");
// told that hook will handle overrides // told that hook will handle overrides
writesend_dnss_response(intercept->returnThis, request); writesend_dnss_response(&intercept->returnThis, request);
return; return;
} }
} }

@ -100,15 +100,15 @@ namespace llarp
} }
bool bool
Context::FindBestAddressFor(const llarp::service::Address &addr, Context::FindBestAddressFor(const byte_t * addr, bool isSNode,
huint32_t &ip) huint32_t &ip)
{ {
auto itr = m_Endpoints.begin(); auto itr = m_Endpoints.begin();
while(itr != m_Endpoints.end()) while(itr != m_Endpoints.end())
{ {
if(itr->second->HasAddress(addr.data())) if(itr->second->HasAddress(addr))
{ {
ip = itr->second->ObtainIPForAddr(addr.data(), false); ip = itr->second->ObtainIPForAddr(addr, isSNode);
return true; return true;
} }
++itr; ++itr;
@ -116,7 +116,7 @@ namespace llarp
itr = m_Endpoints.find("default"); itr = m_Endpoints.find("default");
if(itr != m_Endpoints.end()) if(itr != m_Endpoints.end())
{ {
ip = itr->second->ObtainIPForAddr(addr.data(), false); ip = itr->second->ObtainIPForAddr(addr, isSNode);
return true; return true;
} }
return false; return false;
@ -141,20 +141,6 @@ namespace llarp
10000); 10000);
} }
huint32_t
Context::GetIpForAddr(const llarp::service::Address &addr)
{
llarp::handlers::TunEndpoint *tunEndpoint = this->getFirstTun();
if(!tunEndpoint)
{
huint32_t zero;
zero.h = 0;
llarp::LogError("No tunnel endpoint found");
return zero;
}
return tunEndpoint->ObtainIPForAddr(addr.data(), false);
}
bool bool
Context::MapAddress(const llarp::service::Address &addr, huint32_t ip) Context::MapAddress(const llarp::service::Address &addr, huint32_t ip)
{ {

@ -783,6 +783,22 @@ namespace llarp
return ProcessDataMessage(msg); return ProcessDataMessage(msg);
} }
bool
Endpoint::HasPathToSNode(const llarp::RouterID & ident) const
{
auto range = m_SNodeSessions.equal_range(ident);
auto itr = range.first;
while(itr != range.second)
{
if(itr->second->IsReady())
{
return true;
}
++itr;
}
return false;
}
bool bool
Endpoint::ProcessDataMessage(ProtocolMessage *msg) Endpoint::ProcessDataMessage(ProtocolMessage *msg)
{ {

Loading…
Cancel
Save