From 7de2ce72ad3103ecc9ac3263a7da88bfaff3953b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 29 Nov 2018 09:01:13 -0500 Subject: [PATCH] wire up snode to dns (maybe) --- include/llarp/dns_dotlokilookup.hpp | 2 +- include/llarp/dnsd.hpp | 2 +- include/llarp/handlers/tun.hpp | 4 +- include/llarp/service/context.hpp | 5 +- llarp/dns_dotlokilookup.cpp | 131 ++++++++++++++++++++-------- llarp/dnsd.cpp | 4 +- llarp/service/context.cpp | 22 +---- llarp/service/endpoint.cpp | 16 ++++ 8 files changed, 124 insertions(+), 62 deletions(-) diff --git a/include/llarp/dns_dotlokilookup.hpp b/include/llarp/dns_dotlokilookup.hpp index 988df96f9..9e0dcfbc9 100644 --- a/include/llarp/dns_dotlokilookup.hpp +++ b/include/llarp/dns_dotlokilookup.hpp @@ -6,7 +6,7 @@ #include "dnsd.hpp" 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 struct dotLokiLookup diff --git a/include/llarp/dnsd.hpp b/include/llarp/dnsd.hpp index df0d70c7c..670e18992 100644 --- a/include/llarp/dnsd.hpp +++ b/include/llarp/dnsd.hpp @@ -46,7 +46,7 @@ struct dnsd_query_hook_response /// turn off recursion bool dontLookUp; /// potential address - llarp::huint32_t *returnThis; + llarp::huint32_t returnThis; }; /// builds and fires a request based based on llarp_udp_io udp event diff --git a/include/llarp/handlers/tun.hpp b/include/llarp/handlers/tun.hpp index 08615c49c..8ca57cc68 100644 --- a/include/llarp/handlers/tun.hpp +++ b/include/llarp/handlers/tun.hpp @@ -94,10 +94,10 @@ namespace llarp /// get a key for ip address template < typename Addr > Addr - ObtainAddrForIP(huint32_t ip) + ObtainAddrForIP(huint32_t ip, bool isSNode) { auto itr = m_IPToAddr.find(ip); - if(itr == m_IPToAddr.end()) + if(itr == m_IPToAddr.end() || m_SNodes[itr->second] != isSNode) { // not found Addr addr; diff --git a/include/llarp/service/context.hpp b/include/llarp/service/context.hpp index 1cce5c32b..40cde905d 100644 --- a/include/llarp/service/context.hpp +++ b/include/llarp/service/context.hpp @@ -28,7 +28,7 @@ namespace llarp getFirstEndpoint(); bool - FindBestAddressFor(const llarp::service::Address &, huint32_t &); + FindBestAddressFor(const byte_t* addr, bool isSNode, huint32_t &); /// DRY refactor llarp::handlers::TunEndpoint * @@ -55,9 +55,6 @@ namespace llarp bool iterate(struct endpoint_iter &i); - huint32_t - GetIpForAddr(const llarp::service::Address &addr); - /// hint at possible path usage and trigger building early bool Prefetch(const llarp::service::Address &addr); diff --git a/llarp/dns_dotlokilookup.cpp b/llarp/dns_dotlokilookup.cpp index 5e8f63547..1543dca50 100644 --- a/llarp/dns_dotlokilookup.cpp +++ b/llarp/dns_dotlokilookup.cpp @@ -31,6 +31,32 @@ struct check_query_simple_request std::unordered_map< std::string, struct dnsd_query_hook_response * > 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 llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig, uint64_t left) @@ -54,15 +80,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig, // if so send that // else // 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 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; return; } - - llarp::huint32_t *tunIp = - new llarp::huint32_t(routerHiddenServiceContext->GetIpForAddr(addr)); - if(!tunIp->h) + llarp::huint32_t serviceIP; + llarp::AlignedBuffer<32> addr; + bool isSNode = false; + 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"); write404_dnss_response(qr->request); delete qr; return; } + /* 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::LogInfo("IP Test: ", test); // response->returnThis = &free_private->hostResult; - response->returnThis = tunIp; + response->returnThis = serviceIP; llarp::LogInfo("Saving ", qr->request->question.name); loki_tld_lookup_cache[qr->request->question.name] = response; // we can't delete response now... @@ -141,7 +167,7 @@ llarp_dotlokilookup_checkQuery(void *u, __attribute__((unused)) uint64_t orig, } */ llarp::huint32_t foundAddr; - if(!routerHiddenServiceContext->FindBestAddressFor(addr, foundAddr)) + if(!routerHiddenServiceContext->FindBestAddressFor(addr, isSNode, foundAddr)) { write404_dnss_response(qr->request); delete qr; @@ -256,17 +282,30 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg) if(inRange) { - llarp::service::Address addr = - tunEndpoint->ObtainAddrForIP< llarp::service::Address >( - searchIPv4_fixed); + llarp::AlignedBuffer<32> addr = + tunEndpoint->ObtainAddrForIP< llarp::AlignedBuffer<32> >( + searchIPv4_fixed, false); 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 { // 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); } 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 } +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 * llarp_dotlokilookup_handler(std::string name, 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; response->dontLookUp = false; response->dontSendResponse = false; - response->returnThis = nullptr; + response->returnThis.h = 0; llarp::LogDebug("Hooked ", name); std::string lName = name; 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"); } } - else if((lName.length() > 5 && lName.substr(lName.length() - 5, 5) == ".loki") - || (lName.length() > 6 - && lName.substr(lName.length() - 6, 6) == ".loki.")) + else if(should_intercept_query_with_name(lName)) { llarp::LogInfo("Detect Loki Lookup for ", lName); auto cache_check = loki_tld_lookup_cache.find(lName); @@ -337,15 +389,14 @@ llarp_dotlokilookup_handler(std::string name, return cache_check->second; } - // decode string into HS addr - llarp::service::Address addr; - if(!addr.FromString(lName)) + // decode address + llarp::AlignedBuffer<32> addr; + bool isSNode = false; + if(!decode_request_name(lName, addr, isSNode)) { - llarp::LogWarn("Could not base32 decode address"); - response->dontLookUp = true; // will return nullptr which will give a 404 + response->dontLookUp = true; return response; } - llarp::LogDebug("Base32 decoded address ", addr); dotLokiLookup *dll = (dotLokiLookup *)request->context->user; llarp::service::Context *routerHiddenServiceContext = @@ -366,11 +417,23 @@ llarp_dotlokilookup_handler(std::string name, qr->request = request; auto tun = routerHiddenServiceContext->getFirstTun(); - if(tun->HasPathToService(addr)) + if(isSNode) { - llarp_dotlokilookup_checkQuery(qr, 0, 0); - response->dontSendResponse = true; // will send it shortly - return response; + if(tun->HasPathToSNode(addr.data())) + { + 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 diff --git a/llarp/dnsd.cpp b/llarp/dnsd.cpp index 0122e1182..d57ed97e3 100644 --- a/llarp/dnsd.cpp +++ b/llarp/dnsd.cpp @@ -462,11 +462,11 @@ handle_recvfrom(llarp_buffer_t buffer, dnsd_question_request *request) llarp::LogDebug("HOOKED: Not sending a response"); return; } - if(intercept->dontLookUp == true && intercept->returnThis) + if(intercept->dontLookUp == true && intercept->returnThis.h) { llarp::LogDebug("HOOKED: sending an immediate override"); // told that hook will handle overrides - writesend_dnss_response(intercept->returnThis, request); + writesend_dnss_response(&intercept->returnThis, request); return; } } diff --git a/llarp/service/context.cpp b/llarp/service/context.cpp index 02e2faa1f..88dd67204 100644 --- a/llarp/service/context.cpp +++ b/llarp/service/context.cpp @@ -100,15 +100,15 @@ namespace llarp } bool - Context::FindBestAddressFor(const llarp::service::Address &addr, + Context::FindBestAddressFor(const byte_t * addr, bool isSNode, huint32_t &ip) { auto itr = m_Endpoints.begin(); 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; } ++itr; @@ -116,7 +116,7 @@ namespace llarp itr = m_Endpoints.find("default"); if(itr != m_Endpoints.end()) { - ip = itr->second->ObtainIPForAddr(addr.data(), false); + ip = itr->second->ObtainIPForAddr(addr, isSNode); return true; } return false; @@ -141,20 +141,6 @@ namespace llarp 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 Context::MapAddress(const llarp::service::Address &addr, huint32_t ip) { diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 198bbf644..e4cedb0d8 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -783,6 +783,22 @@ namespace llarp 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 Endpoint::ProcessDataMessage(ProtocolMessage *msg) {