mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-03 23:15:52 +00:00
commit
f458727ff3
@ -17,7 +17,9 @@ struct dotLokiLookup
|
|||||||
{
|
{
|
||||||
/// for timers (MAYBEFIXME? maybe we decouple this, yes pls have a generic
|
/// for timers (MAYBEFIXME? maybe we decouple this, yes pls have a generic
|
||||||
/// passed in)
|
/// passed in)
|
||||||
|
// we can use DNSc for access to the logic
|
||||||
struct llarp_logic *logic;
|
struct llarp_logic *logic;
|
||||||
|
|
||||||
/// which ip tracker to use
|
/// which ip tracker to use
|
||||||
struct dns_iptracker *ip_tracker;
|
struct dns_iptracker *ip_tracker;
|
||||||
|
|
||||||
|
@ -80,6 +80,10 @@ namespace llarp
|
|||||||
static void
|
static void
|
||||||
handleTickTun(void* u);
|
handleTickTun(void* u);
|
||||||
|
|
||||||
|
/// get a service address for ip address
|
||||||
|
service::Address
|
||||||
|
ObtainAddrForIP(huint32_t ip);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef llarp::util::CoDelQueue<
|
typedef llarp::util::CoDelQueue<
|
||||||
net::IPv4Packet, net::IPv4Packet::GetTime, net::IPv4Packet::PutTime,
|
net::IPv4Packet, net::IPv4Packet::GetTime, net::IPv4Packet::PutTime,
|
||||||
@ -92,6 +96,7 @@ namespace llarp
|
|||||||
/// return true if we have a remote loki address for this ip address
|
/// return true if we have a remote loki address for this ip address
|
||||||
bool
|
bool
|
||||||
HasRemoteForIP(huint32_t ipv4) const;
|
HasRemoteForIP(huint32_t ipv4) const;
|
||||||
|
|
||||||
/// get ip address for service address unconditionally
|
/// get ip address for service address unconditionally
|
||||||
huint32_t
|
huint32_t
|
||||||
ObtainIPForAddr(const service::Address& addr);
|
ObtainIPForAddr(const service::Address& addr);
|
||||||
|
@ -76,7 +76,7 @@ namespace llarp
|
|||||||
|
|
||||||
constexpr bool operator <(huint32_t x) const { return h < x.h; }
|
constexpr bool operator <(huint32_t x) const { return h < x.h; }
|
||||||
constexpr bool operator ==(huint32_t x) const { return h == x.h; }
|
constexpr bool operator ==(huint32_t x) const { return h == x.h; }
|
||||||
|
|
||||||
struct Hash
|
struct Hash
|
||||||
{
|
{
|
||||||
inline size_t
|
inline size_t
|
||||||
@ -272,7 +272,7 @@ namespace llarp
|
|||||||
{
|
{
|
||||||
// network order
|
// network order
|
||||||
sockaddr_in6 _addr;
|
sockaddr_in6 _addr;
|
||||||
sockaddr_in _addr4; // why do we even have this?
|
sockaddr_in _addr4; // why do we even have this? favor cpu over memory
|
||||||
~Addr(){};
|
~Addr(){};
|
||||||
|
|
||||||
Addr(){};
|
Addr(){};
|
||||||
|
@ -43,7 +43,8 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left)
|
|||||||
if(!dll)
|
if(!dll)
|
||||||
{
|
{
|
||||||
llarp::LogError("DNSd dotLokiLookup is not configured");
|
llarp::LogError("DNSd dotLokiLookup is not configured");
|
||||||
// FIXME: send 404
|
write404_dnss_response(qr->from, qr->request);
|
||||||
|
delete qr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left)
|
|||||||
{
|
{
|
||||||
llarp::LogWarn("Could not base32 decode address: ",
|
llarp::LogWarn("Could not base32 decode address: ",
|
||||||
qr->request->question.name);
|
qr->request->question.name);
|
||||||
// FIXME: send 404
|
write404_dnss_response(qr->from, qr->request);
|
||||||
delete qr;
|
delete qr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -64,7 +65,9 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left)
|
|||||||
auto itr = loki_tld_lookup_cache.find(addr.ToString());
|
auto itr = loki_tld_lookup_cache.find(addr.ToString());
|
||||||
if(itr != loki_tld_lookup_cache.end())
|
if(itr != loki_tld_lookup_cache.end())
|
||||||
{
|
{
|
||||||
|
llarp::LogDebug("Found in .loki lookup cache");
|
||||||
writesend_dnss_response(itr->second->returnThis, qr->from, qr->request);
|
writesend_dnss_response(itr->second->returnThis, qr->from, qr->request);
|
||||||
|
delete qr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,13 +96,16 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left)
|
|||||||
if(!routerHiddenServiceContext)
|
if(!routerHiddenServiceContext)
|
||||||
{
|
{
|
||||||
llarp::LogWarn("dotLokiLookup user isnt a service::Context: ", dll->user);
|
llarp::LogWarn("dotLokiLookup user isnt a service::Context: ", dll->user);
|
||||||
|
write404_dnss_response(qr->from, qr->request);
|
||||||
|
delete qr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool mapResult = routerHiddenServiceContext->MapAddressAll(
|
bool mapResult = routerHiddenServiceContext->MapAddressAll(
|
||||||
addr, free_private->hostResult);
|
addr, free_private->hostResult);
|
||||||
if(!mapResult)
|
if(!mapResult)
|
||||||
{
|
{
|
||||||
// FIXME: send 404
|
llarp::LogWarn("dotLokiLookup failed to map address");
|
||||||
|
write404_dnss_response(qr->from, qr->request);
|
||||||
delete qr;
|
delete qr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -129,22 +135,158 @@ llarp_dotlokilookup_checkQuery(void *u, uint64_t orig, uint64_t left)
|
|||||||
delete qr;
|
delete qr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector< std::string >
|
||||||
|
split(std::string str)
|
||||||
|
{
|
||||||
|
size_t pos = 0;
|
||||||
|
std::string token;
|
||||||
|
std::string s(str);
|
||||||
|
std::vector< std::string > tokens;
|
||||||
|
while((pos = s.find(".")) != std::string::npos)
|
||||||
|
{
|
||||||
|
token = s.substr(0, pos);
|
||||||
|
// llarp::LogInfo("token [", token, "]");
|
||||||
|
tokens.push_back(token);
|
||||||
|
s.erase(0, pos + 1);
|
||||||
|
}
|
||||||
|
token = s.substr(0, pos);
|
||||||
|
tokens.push_back(token);
|
||||||
|
// llarp::LogInfo("token [", token, "]");
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct reverse_handler_iter_context
|
||||||
|
{
|
||||||
|
std::string lName;
|
||||||
|
const struct sockaddr *from;
|
||||||
|
const struct dnsd_question_request *request;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
|
||||||
|
{
|
||||||
|
reverse_handler_iter_context *context =
|
||||||
|
(reverse_handler_iter_context *)endpointCfg->user;
|
||||||
|
// llarp::LogInfo("context ", context->request->question.name);
|
||||||
|
// llarp::LogInfo("Checking ", lName);
|
||||||
|
llarp::handlers::TunEndpoint *tunEndpoint =
|
||||||
|
(llarp::handlers::TunEndpoint *)endpointCfg->endpoint;
|
||||||
|
if(!tunEndpoint)
|
||||||
|
{
|
||||||
|
llarp::LogError("No tunnel endpoint found");
|
||||||
|
return true; // still continue
|
||||||
|
}
|
||||||
|
// llarp::LogInfo("for ", tunEndpoint->tunif.ifaddr);
|
||||||
|
std::string checkStr(tunEndpoint->tunif.ifaddr);
|
||||||
|
std::vector< std::string > tokensSearch = split(context->lName);
|
||||||
|
std::vector< std::string > tokensCheck = split(checkStr);
|
||||||
|
|
||||||
|
// well the tunif is just one ip on a network range...
|
||||||
|
// support "b._dns-sd._udp.0.0.200.10.in-addr.arpa"
|
||||||
|
size_t searchTokens = tokensSearch.size();
|
||||||
|
std::string searchIp = tokensSearch[searchTokens - 3] + "."
|
||||||
|
+ tokensSearch[searchTokens - 4] + "." + tokensSearch[searchTokens - 5]
|
||||||
|
+ "." + tokensSearch[searchTokens - 6];
|
||||||
|
std::string checkIp = tokensCheck[0] + "." + tokensCheck[1] + "."
|
||||||
|
+ tokensCheck[2] + "." + tokensCheck[3];
|
||||||
|
llarp::LogDebug(searchIp, " vs ", checkIp);
|
||||||
|
|
||||||
|
llarp::IPRange range = llarp::iprange_ipv4(
|
||||||
|
stoi(tokensCheck[0]), stoi(tokensCheck[1]), stoi(tokensCheck[2]),
|
||||||
|
stoi(tokensCheck[3]), tunEndpoint->tunif.netmask); // create range
|
||||||
|
// hack atm to work around limitations in ipaddr_ipv4_bits and llarp::IPRange
|
||||||
|
llarp::huint32_t searchIPv4_fixed = llarp::ipaddr_ipv4_bits(
|
||||||
|
stoi(tokensSearch[searchTokens - 6]),
|
||||||
|
stoi(tokensSearch[searchTokens - 5]),
|
||||||
|
stoi(tokensSearch[searchTokens - 4]),
|
||||||
|
stoi(tokensSearch[searchTokens
|
||||||
|
- 3])); // create ip (llarp::Addr is untrustworthy atm)
|
||||||
|
llarp::huint32_t searchIPv4_search = llarp::ipaddr_ipv4_bits(
|
||||||
|
stoi(tokensSearch[searchTokens - 3]),
|
||||||
|
stoi(tokensSearch[searchTokens - 4]),
|
||||||
|
stoi(tokensSearch[searchTokens - 5]),
|
||||||
|
stoi(tokensSearch[searchTokens
|
||||||
|
- 6])); // create ip (llarp::Addr is untrustworthy atm)
|
||||||
|
|
||||||
|
// bool inRange = range.Contains(searchAddr.xtohl());
|
||||||
|
bool inRange = range.Contains(searchIPv4_search);
|
||||||
|
|
||||||
|
llarp::Addr searchAddr(searchIp);
|
||||||
|
llarp::Addr checkAddr(checkIp);
|
||||||
|
llarp::LogDebug(searchAddr, " vs ", range.ToString(), " = ",
|
||||||
|
inRange ? "inRange" : "not match");
|
||||||
|
|
||||||
|
if(inRange)
|
||||||
|
{
|
||||||
|
llarp::service::Address addr =
|
||||||
|
tunEndpoint->ObtainAddrForIP(searchIPv4_fixed);
|
||||||
|
if(addr.ToString()
|
||||||
|
== "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.loki")
|
||||||
|
{
|
||||||
|
write404_dnss_response(context->from,
|
||||||
|
(dnsd_question_request *)context->request);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writesend_dnss_revresponse(addr.ToString(), context->from,
|
||||||
|
(dnsd_question_request *)context->request);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true; // we don't do anything with the result yet
|
||||||
|
}
|
||||||
|
|
||||||
dnsd_query_hook_response *
|
dnsd_query_hook_response *
|
||||||
llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
|
llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
|
||||||
struct dnsd_question_request *const request)
|
struct dnsd_question_request *const request)
|
||||||
{
|
{
|
||||||
dnsd_query_hook_response *response = new dnsd_query_hook_response;
|
dnsd_query_hook_response *response = new dnsd_query_hook_response;
|
||||||
// dotLokiLookup *dll = (dotLokiLookup
|
response->dontLookUp = false;
|
||||||
// *)request->context->user;
|
response->dontSendResponse = false;
|
||||||
response->dontLookUp = false;
|
response->returnThis = nullptr;
|
||||||
response->dontSendResponse = false;
|
|
||||||
response->returnThis = nullptr;
|
|
||||||
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);
|
||||||
|
// llarp::LogDebug("Transformed ", lName);
|
||||||
|
|
||||||
// FIXME: probably should just read the last 5 bytes
|
// 253.0.200.10.in-addr.arpa
|
||||||
if(lName.find(".loki") != std::string::npos)
|
if(lName.find(".in-addr.arpa") != std::string::npos)
|
||||||
|
{
|
||||||
|
// llarp::LogDebug("Checking ", lName);
|
||||||
|
dotLokiLookup *dll = (dotLokiLookup *)request->context->user;
|
||||||
|
llarp::service::Context *routerHiddenServiceContext =
|
||||||
|
(llarp::service::Context *)dll->user;
|
||||||
|
if(!routerHiddenServiceContext)
|
||||||
|
{
|
||||||
|
llarp::LogWarn("dotLokiLookup user isnt a service::Context: ", dll->user);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
// llarp::LogDebug("Starting rev iter for ", lName);
|
||||||
|
// which range?
|
||||||
|
// for each tun interface
|
||||||
|
struct reverse_handler_iter_context context;
|
||||||
|
context.lName = lName;
|
||||||
|
context.from = from;
|
||||||
|
context.request = request;
|
||||||
|
|
||||||
|
struct llarp::service::Context::endpoint_iter i;
|
||||||
|
i.user = &context;
|
||||||
|
i.index = 0;
|
||||||
|
i.visit = &ReverseHandlerIter;
|
||||||
|
bool res = routerHiddenServiceContext->iterate(i);
|
||||||
|
if(!res)
|
||||||
|
{
|
||||||
|
llarp::LogInfo("Reverse is ours");
|
||||||
|
response->dontSendResponse = true; // should have already sent it
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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."))
|
||||||
{
|
{
|
||||||
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);
|
||||||
@ -179,7 +321,7 @@ llarp_dotlokilookup_handler(std::string name, const struct sockaddr *from,
|
|||||||
llarp_logic_call_later(request->context->client.logic,
|
llarp_logic_call_later(request->context->client.logic,
|
||||||
{2000, qr, &llarp_dotlokilookup_checkQuery});
|
{2000, qr, &llarp_dotlokilookup_checkQuery});
|
||||||
|
|
||||||
response->dontSendResponse = true;
|
response->dontSendResponse = true; // will send it shortly
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +134,7 @@ namespace llarp
|
|||||||
}
|
}
|
||||||
llarp::LogInfo(Name() + " map ", addr.ToString(), " to ",
|
llarp::LogInfo(Name() + " map ", addr.ToString(), " to ",
|
||||||
inet_ntoa({nip.n}));
|
inet_ntoa({nip.n}));
|
||||||
|
|
||||||
m_IPToAddr.insert(std::make_pair(ip, addr));
|
m_IPToAddr.insert(std::make_pair(ip, addr));
|
||||||
m_AddrToIP.insert(std::make_pair(addr, ip));
|
m_AddrToIP.insert(std::make_pair(addr, ip));
|
||||||
MarkIPActiveForever(ip);
|
MarkIPActiveForever(ip);
|
||||||
@ -351,6 +352,22 @@ namespace llarp
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
service::Address
|
||||||
|
TunEndpoint::ObtainAddrForIP(huint32_t ip)
|
||||||
|
{
|
||||||
|
auto itr = m_IPToAddr.find(ip);
|
||||||
|
if(itr == m_IPToAddr.end())
|
||||||
|
{
|
||||||
|
// not found
|
||||||
|
// llarp::Addr test(ip); // "/", test,
|
||||||
|
service::Address addr;
|
||||||
|
llarp::LogWarn(" not found in tun map. Sending ", addr.ToString());
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
// found
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
|
||||||
huint32_t
|
huint32_t
|
||||||
TunEndpoint::ObtainIPForAddr(const service::Address &addr)
|
TunEndpoint::ObtainIPForAddr(const service::Address &addr)
|
||||||
{
|
{
|
||||||
|
@ -64,8 +64,8 @@ namespace llarp
|
|||||||
while(itr != m_Endpoints.end())
|
while(itr != m_Endpoints.end())
|
||||||
{
|
{
|
||||||
i.endpoint = itr->second.get();
|
i.endpoint = itr->second.get();
|
||||||
i.visit(&i);
|
if(!i.visit(&i))
|
||||||
|
return false;
|
||||||
// advance
|
// advance
|
||||||
i.index++;
|
i.index++;
|
||||||
itr++;
|
itr++;
|
||||||
@ -136,7 +136,7 @@ namespace llarp
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MappAddressAllIter(struct Context::endpoint_iter *endpointCfg)
|
MapAddressAllIter(struct Context::endpoint_iter *endpointCfg)
|
||||||
{
|
{
|
||||||
Context::mapAddressAll_context *context =
|
Context::mapAddressAll_context *context =
|
||||||
(Context::mapAddressAll_context *)endpointCfg->user;
|
(Context::mapAddressAll_context *)endpointCfg->user;
|
||||||
@ -145,7 +145,7 @@ namespace llarp
|
|||||||
if(!tunEndpoint)
|
if(!tunEndpoint)
|
||||||
{
|
{
|
||||||
llarp::LogError("No tunnel endpoint found");
|
llarp::LogError("No tunnel endpoint found");
|
||||||
return false;
|
return true; // still continue
|
||||||
}
|
}
|
||||||
return tunEndpoint->MapAddress(context->serviceAddr,
|
return tunEndpoint->MapAddress(context->serviceAddr,
|
||||||
context->localPrivateIpAddr.xtohl());
|
context->localPrivateIpAddr.xtohl());
|
||||||
@ -162,7 +162,7 @@ namespace llarp
|
|||||||
struct Context::endpoint_iter i;
|
struct Context::endpoint_iter i;
|
||||||
i.user = &context;
|
i.user = &context;
|
||||||
i.index = 0;
|
i.index = 0;
|
||||||
i.visit = &MappAddressAllIter;
|
i.visit = &MapAddressAllIter;
|
||||||
return this->iterate(i);
|
return this->iterate(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,25 @@ struct NetTest : public ::testing::Test
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(NetTest, TestRangeContains)
|
TEST_F(NetTest, TestRangeContains8)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 0, 8)
|
ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 0, 8)
|
||||||
.Contains(llarp::ipaddr_ipv4_bits(10, 40, 11, 6)));
|
.Contains(llarp::ipaddr_ipv4_bits(10, 40, 11, 6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(NetTest, TestRangeContains24)
|
||||||
|
{
|
||||||
|
ASSERT_TRUE(llarp::iprange_ipv4(10, 200, 0, 1, 24)
|
||||||
|
.Contains(llarp::ipaddr_ipv4_bits(10, 200, 0, 253)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(NetTest, TestRangeContainsFail)
|
||||||
|
{
|
||||||
|
ASSERT_TRUE(!llarp::iprange_ipv4(192, 168, 0, 1, 24)
|
||||||
|
.Contains(llarp::ipaddr_ipv4_bits(10, 200, 0, 253)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_F(NetTest, TestIPv4Netmask)
|
TEST_F(NetTest, TestIPv4Netmask)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(llarp::xhtonl(llarp::netmask_ipv4_bits(8))
|
ASSERT_TRUE(llarp::xhtonl(llarp::netmask_ipv4_bits(8))
|
||||||
|
Loading…
Reference in New Issue
Block a user