mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
wire up snode to dns (maybe)
This commit is contained in:
parent
85f9f46362
commit
7de2ce72ad
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue