|
|
|
@ -54,162 +54,6 @@ handle_signal(int sig)
|
|
|
|
|
llarp_main_signal(ctx, sig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string const default_chars =
|
|
|
|
|
"abcdefghijklmnaoqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
|
|
|
|
|
|
|
|
|
#include <random>
|
|
|
|
|
|
|
|
|
|
std::string
|
|
|
|
|
random_string(size_t len = 15, std::string const &allowed_chars = default_chars)
|
|
|
|
|
{
|
|
|
|
|
std::mt19937_64 gen{std::random_device()()};
|
|
|
|
|
|
|
|
|
|
std::uniform_int_distribution< size_t > dist{0, allowed_chars.length() - 1};
|
|
|
|
|
|
|
|
|
|
std::string ret;
|
|
|
|
|
|
|
|
|
|
std::generate_n(std::back_inserter(ret), len,
|
|
|
|
|
[&] { return allowed_chars[dist(gen)]; });
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
/// check_online_request hook definition
|
|
|
|
|
typedef void (*check_query_request_hook_func)(struct check_query_request *);
|
|
|
|
|
|
|
|
|
|
struct check_query_request
|
|
|
|
|
{
|
|
|
|
|
bool done;
|
|
|
|
|
///hook
|
|
|
|
|
check_query_request_hook_func hook;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
llarp_dnsd_checkQuery_resolved(struct check_query_request *request)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
struct check_query_simple_request
|
|
|
|
|
{
|
|
|
|
|
const struct sockaddr *from; // source
|
|
|
|
|
dnsd_question_request *request;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::map< std::string, struct dnsd_query_hook_response * >
|
|
|
|
|
loki_tld_lookup_cache;
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
llarp_dnsd_checkQuery(void *u, uint64_t orig, uint64_t left)
|
|
|
|
|
{
|
|
|
|
|
if(left)
|
|
|
|
|
return;
|
|
|
|
|
// struct check_query_request *request = static_cast< struct
|
|
|
|
|
// check_query_request * >(u);
|
|
|
|
|
struct check_query_simple_request *qr =
|
|
|
|
|
static_cast< struct check_query_simple_request * >(u);
|
|
|
|
|
dotLokiLookup *dll = (dotLokiLookup *)qr->request->user;
|
|
|
|
|
|
|
|
|
|
// we do have result
|
|
|
|
|
// if so send that
|
|
|
|
|
// else
|
|
|
|
|
// if we have a free private ip, send that
|
|
|
|
|
struct dns_pointer *free_private = dns_iptracker_get_free(dll->ip_tracker);
|
|
|
|
|
if(free_private)
|
|
|
|
|
{
|
|
|
|
|
// do mapping
|
|
|
|
|
llarp::service::Address addr;
|
|
|
|
|
if(!addr.FromString(qr->request->question.name))
|
|
|
|
|
{
|
|
|
|
|
llarp::LogWarn("Could not base32 decode address: ",
|
|
|
|
|
qr->request->question.name);
|
|
|
|
|
delete qr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
in_addr ip_address = ((sockaddr_in *)free_private->hostResult)->sin_addr;
|
|
|
|
|
|
|
|
|
|
bool mapResult = main_router_mapAddress(
|
|
|
|
|
ctx, addr, ntohl(ip_address.s_addr)); // maybe ntohl on the s_addr
|
|
|
|
|
if(!mapResult)
|
|
|
|
|
{
|
|
|
|
|
delete qr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// make a dnsd_query_hook_response for the cache
|
|
|
|
|
dnsd_query_hook_response *response = new dnsd_query_hook_response;
|
|
|
|
|
response->dontLookUp = true;
|
|
|
|
|
response->dontSendResponse = false;
|
|
|
|
|
response->returnThis = free_private->hostResult;
|
|
|
|
|
llarp::LogInfo("Saving ", qr->request->question.name);
|
|
|
|
|
loki_tld_lookup_cache[qr->request->question.name] = response;
|
|
|
|
|
|
|
|
|
|
// FIXME: flush cache to disk
|
|
|
|
|
// on crash we'll need to bring up all the same IPs we assigned before...
|
|
|
|
|
writesend_dnss_response(free_private->hostResult, qr->from, qr->request);
|
|
|
|
|
delete qr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// else
|
|
|
|
|
llarp::LogInfo("Sending cname to delay");
|
|
|
|
|
writecname_dnss_response(
|
|
|
|
|
random_string(49, "abcdefghijklmnopqrstuvwxyz") + "bob.loki", qr->from,
|
|
|
|
|
qr->request);
|
|
|
|
|
delete qr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dnsd_query_hook_response *
|
|
|
|
|
hookChecker(std::string name, const struct sockaddr *from,
|
|
|
|
|
struct dnsd_question_request *request)
|
|
|
|
|
{
|
|
|
|
|
dnsd_query_hook_response *response = new dnsd_query_hook_response;
|
|
|
|
|
dotLokiLookup *dll = (dotLokiLookup *)request->context->user;
|
|
|
|
|
response->dontLookUp = false;
|
|
|
|
|
response->dontSendResponse = false;
|
|
|
|
|
response->returnThis = nullptr;
|
|
|
|
|
llarp::LogDebug("Hooked ", name);
|
|
|
|
|
std::string lName = name;
|
|
|
|
|
std::transform(lName.begin(), lName.end(), lName.begin(), ::tolower);
|
|
|
|
|
|
|
|
|
|
// FIXME: probably should just read the last 5 bytes
|
|
|
|
|
if(lName.find(".loki") != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
llarp::LogInfo("Detect Loki Lookup for ", lName);
|
|
|
|
|
auto cache_check = loki_tld_lookup_cache.find(lName);
|
|
|
|
|
if(cache_check != loki_tld_lookup_cache.end())
|
|
|
|
|
{
|
|
|
|
|
// was in cache
|
|
|
|
|
llarp::LogInfo("Reused address from LokiLookupCache");
|
|
|
|
|
// FIXME: avoid the allocation if you could
|
|
|
|
|
delete response;
|
|
|
|
|
return cache_check->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// decode string into HS addr
|
|
|
|
|
llarp::service::Address addr;
|
|
|
|
|
if(!addr.FromString(lName))
|
|
|
|
|
{
|
|
|
|
|
llarp::LogWarn("Could not base32 decode address");
|
|
|
|
|
response->dontSendResponse = true;
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
llarp::LogInfo("Got address", addr);
|
|
|
|
|
|
|
|
|
|
// start path build early (if you're looking it up, you're probably going to
|
|
|
|
|
// use it)
|
|
|
|
|
main_router_prefetch(ctx, addr);
|
|
|
|
|
|
|
|
|
|
// schedule future response
|
|
|
|
|
check_query_simple_request *qr = new check_query_simple_request;
|
|
|
|
|
qr->from = from;
|
|
|
|
|
qr->request = request;
|
|
|
|
|
// nslookup on osx is about 5 sec before a retry, 2s on linux
|
|
|
|
|
llarp_logic_call_later(dll->logic, {2000, qr, &llarp_dnsd_checkQuery});
|
|
|
|
|
|
|
|
|
|
response->dontSendResponse = true;
|
|
|
|
|
}
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct dns_relay_config
|
|
|
|
|
{
|
|
|
|
|
std::string upstream_host;
|
|
|
|
@ -291,7 +135,7 @@ main(int argc, char *argv[])
|
|
|
|
|
llarp::LogError("Couldnt init dns daemon");
|
|
|
|
|
}
|
|
|
|
|
// Configure intercept
|
|
|
|
|
dnsd.intercept = &hookChecker;
|
|
|
|
|
dnsd.intercept = &llarp_dotlokilookup_handler;
|
|
|
|
|
dotLokiLookup dll;
|
|
|
|
|
// should be a function...
|
|
|
|
|
// dll.tunEndpoint = main_router_getFirstTunEndpoint(ctx);
|
|
|
|
@ -341,7 +185,7 @@ main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
// configure main netloop
|
|
|
|
|
struct dnsd_context dnsd;
|
|
|
|
|
if(!llarp_dnsd_init(&dnsd, netloop, "*", server_port,
|
|
|
|
|
if(!llarp_dnsd_init(&dnsd, logic, netloop, "*", server_port,
|
|
|
|
|
(const char *)dnsr_config.upstream_host.c_str(),
|
|
|
|
|
dnsr_config.upstream_port))
|
|
|
|
|
{
|
|
|
|
@ -350,7 +194,7 @@ main(int argc, char *argv[])
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// Configure intercept
|
|
|
|
|
dnsd.intercept = &hookChecker;
|
|
|
|
|
dnsd.intercept = &llarp_dotlokilookup_handler;
|
|
|
|
|
|
|
|
|
|
llarp::LogInfo("singlethread start");
|
|
|
|
|
llarp_ev_loop_run_single_process(netloop, worker, logic);
|
|
|
|
@ -368,7 +212,7 @@ main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
// configure main netloop
|
|
|
|
|
struct dnsd_context dnsd;
|
|
|
|
|
if(!llarp_dnsd_init(&dnsd, nullptr, "*", server_port,
|
|
|
|
|
if(!llarp_dnsd_init(&dnsd, logic, nullptr, "*", server_port,
|
|
|
|
|
(const char *)dnsr_config.upstream_host.c_str(),
|
|
|
|
|
dnsr_config.upstream_port))
|
|
|
|
|
{
|
|
|
|
@ -377,7 +221,7 @@ main(int argc, char *argv[])
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// Configure intercept
|
|
|
|
|
dnsd.intercept = &hookChecker;
|
|
|
|
|
dnsd.intercept = &llarp_dotlokilookup_handler;
|
|
|
|
|
|
|
|
|
|
struct sockaddr_in m_address;
|
|
|
|
|
int m_sockfd;
|
|
|
|
|