2018-10-10 12:06:28 +00:00
|
|
|
#include <algorithm>
|
2018-08-22 07:35:49 +00:00
|
|
|
// harmless on other platforms
|
|
|
|
#define __USE_MINGW_ANSI_STDIO 1
|
2018-12-12 01:12:59 +00:00
|
|
|
#include <handlers/tun.hpp>
|
2018-09-23 16:48:43 +00:00
|
|
|
#include <sys/types.h>
|
2018-09-25 08:31:29 +00:00
|
|
|
#ifndef _WIN32
|
2018-09-23 16:48:43 +00:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netdb.h>
|
2018-09-25 08:31:29 +00:00
|
|
|
#endif
|
2018-08-15 15:36:34 +00:00
|
|
|
|
2018-12-13 16:14:44 +00:00
|
|
|
#include <dns/dns.hpp>
|
2019-01-11 01:19:36 +00:00
|
|
|
#include <ev/ev.hpp>
|
2019-02-11 19:45:42 +00:00
|
|
|
#include <router/abstractrouter.hpp>
|
|
|
|
#include <service/context.hpp>
|
2019-09-01 12:38:03 +00:00
|
|
|
#include <util/meta/memfn.hpp>
|
2019-09-01 13:26:16 +00:00
|
|
|
#include <util/thread/logic.hpp>
|
2019-05-06 12:42:21 +00:00
|
|
|
#include <nodedb.hpp>
|
2018-12-10 16:26:46 +00:00
|
|
|
|
2019-05-22 16:20:03 +00:00
|
|
|
#include <util/str.hpp>
|
|
|
|
|
2019-09-03 15:56:56 +00:00
|
|
|
#include <absl/strings/ascii.h>
|
|
|
|
|
2018-08-15 15:36:34 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
2018-08-16 14:34:15 +00:00
|
|
|
namespace handlers
|
2018-08-15 15:36:34 +00:00
|
|
|
{
|
2018-12-02 18:07:07 +00:00
|
|
|
static llarp_fd_promise *
|
|
|
|
get_tun_fd_promise(llarp_tun_io *tun)
|
2018-11-26 22:46:22 +00:00
|
|
|
{
|
2018-12-02 18:07:07 +00:00
|
|
|
return static_cast< TunEndpoint * >(tun->user)->Promise.get();
|
2018-11-26 22:46:22 +00:00
|
|
|
}
|
|
|
|
|
2018-12-15 16:56:35 +00:00
|
|
|
static void
|
|
|
|
tunifTick(llarp_tun_io *tun)
|
|
|
|
{
|
2019-07-30 23:42:13 +00:00
|
|
|
auto *self = static_cast< TunEndpoint * >(tun->user);
|
2018-12-15 16:56:35 +00:00
|
|
|
self->Flush();
|
|
|
|
}
|
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
TunEndpoint::TunEndpoint(const std::string &nickname, AbstractRouter *r,
|
2019-01-28 15:26:35 +00:00
|
|
|
service::Context *parent)
|
|
|
|
: service::Endpoint(nickname, r, parent)
|
2019-02-11 19:45:42 +00:00
|
|
|
, m_UserToNetworkPktQueue(nickname + "_sendq", r->netloop(),
|
|
|
|
r->netloop())
|
|
|
|
, m_NetworkToUserPktQueue(nickname + "_recvq", r->netloop(),
|
|
|
|
r->netloop())
|
2019-05-23 12:22:48 +00:00
|
|
|
, m_Resolver(std::make_shared< dns::Proxy >(
|
|
|
|
r->netloop(), r->logic(), r->netloop(), r->logic(), this))
|
2018-08-15 15:36:34 +00:00
|
|
|
{
|
2019-07-08 15:26:06 +00:00
|
|
|
std::fill(tunif.ifaddr, tunif.ifaddr + sizeof(tunif.ifaddr), 0);
|
|
|
|
std::fill(tunif.ifname, tunif.ifname + sizeof(tunif.ifname), 0);
|
|
|
|
tunif.netmask = 0;
|
|
|
|
|
2018-12-02 18:07:07 +00:00
|
|
|
#ifdef ANDROID
|
2018-11-26 22:46:22 +00:00
|
|
|
tunif.get_fd_promise = &get_tun_fd_promise;
|
|
|
|
Promise.reset(new llarp_fd_promise(&m_VPNPromise));
|
2018-12-02 18:07:07 +00:00
|
|
|
#else
|
2018-11-26 22:46:22 +00:00
|
|
|
tunif.get_fd_promise = nullptr;
|
|
|
|
#endif
|
2019-07-08 15:26:06 +00:00
|
|
|
tunif.user = this;
|
2018-12-14 00:15:15 +00:00
|
|
|
|
2018-12-23 13:29:11 +00:00
|
|
|
// eh this shouldn't do anything on windows anyway
|
2018-12-15 16:56:35 +00:00
|
|
|
tunif.tick = &tunifTick;
|
2018-12-03 22:22:59 +00:00
|
|
|
tunif.before_write = &tunifBeforeWrite;
|
|
|
|
tunif.recvpkt = &tunifRecvPkt;
|
2018-08-16 14:34:15 +00:00
|
|
|
}
|
|
|
|
|
2019-02-11 17:14:43 +00:00
|
|
|
util::StatusObject
|
|
|
|
TunEndpoint::ExtractStatus() const
|
2019-02-08 19:43:25 +00:00
|
|
|
{
|
2019-08-19 09:33:26 +00:00
|
|
|
auto obj = service::Endpoint::ExtractStatus();
|
|
|
|
obj["ifaddr"] = m_OurRange.ToString();
|
2019-02-08 19:43:25 +00:00
|
|
|
|
|
|
|
std::vector< std::string > resolvers;
|
|
|
|
for(const auto &addr : m_UpstreamResolvers)
|
|
|
|
resolvers.emplace_back(addr.ToString());
|
2019-08-19 09:33:26 +00:00
|
|
|
obj["ustreamResolvers"] = resolvers;
|
|
|
|
obj["localResolver"] = m_LocalResolverAddr.ToString();
|
2019-02-11 17:14:43 +00:00
|
|
|
util::StatusObject ips{};
|
2019-02-08 19:43:25 +00:00
|
|
|
for(const auto &item : m_IPActivity)
|
|
|
|
{
|
2019-02-11 17:14:43 +00:00
|
|
|
util::StatusObject ipObj{{"lastActive", item.second}};
|
2019-02-08 19:43:25 +00:00
|
|
|
std::string remoteStr;
|
|
|
|
AlignedBuffer< 32 > addr = m_IPToAddr.at(item.first);
|
|
|
|
if(m_SNodes.at(addr))
|
|
|
|
remoteStr = RouterID(addr.as_array()).ToString();
|
|
|
|
else
|
|
|
|
remoteStr = service::Address(addr.as_array()).ToString();
|
2019-08-19 09:33:26 +00:00
|
|
|
ipObj["remote"] = remoteStr;
|
2019-02-08 19:43:25 +00:00
|
|
|
std::string ipaddr = item.first.ToString();
|
2019-08-19 09:33:26 +00:00
|
|
|
ips[ipaddr] = ipObj;
|
2019-02-08 19:43:25 +00:00
|
|
|
}
|
2019-08-19 09:33:26 +00:00
|
|
|
obj["addrs"] = ips;
|
|
|
|
obj["ourIP"] = m_OurIP.ToString();
|
|
|
|
obj["nextIP"] = m_NextIP.ToString();
|
|
|
|
obj["maxIP"] = m_MaxIP.ToString();
|
2019-02-11 17:14:43 +00:00
|
|
|
return obj;
|
2019-02-08 19:43:25 +00:00
|
|
|
}
|
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::SetOption(const std::string &k, const std::string &v)
|
|
|
|
{
|
2019-05-22 16:20:03 +00:00
|
|
|
if(k == "isolate-network" && IsTrueValue(v.c_str()))
|
|
|
|
{
|
2019-05-22 16:20:50 +00:00
|
|
|
#if defined(__linux__)
|
|
|
|
LogInfo(Name(), " isolating network...");
|
|
|
|
if(!SpawnIsolatedNetwork())
|
|
|
|
{
|
|
|
|
LogError(Name(), " failed to spawn isolated network");
|
2019-05-22 16:20:03 +00:00
|
|
|
return false;
|
2019-05-22 16:20:50 +00:00
|
|
|
}
|
|
|
|
LogInfo(Name(), " booyeah network isolation succeeded");
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
LogError(Name(),
|
|
|
|
" network isolation is not supported on your platform");
|
|
|
|
return false;
|
|
|
|
#endif
|
2019-05-22 16:20:03 +00:00
|
|
|
}
|
2019-05-06 12:42:21 +00:00
|
|
|
if(k == "strict-connect")
|
|
|
|
{
|
|
|
|
RouterID connect;
|
|
|
|
if(!connect.FromString(v))
|
|
|
|
{
|
|
|
|
LogError(Name(), " invalid snode for strict-connect: ", v);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
RouterContact rc;
|
2019-08-02 09:27:27 +00:00
|
|
|
if(!m_router->nodedb()->Get(connect, rc))
|
2019-05-06 12:42:21 +00:00
|
|
|
{
|
|
|
|
LogError(Name(), " we don't have the RC for ", v,
|
|
|
|
" so we can't use it in strict-connect");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for(const auto &ai : rc.addrs)
|
|
|
|
{
|
|
|
|
m_StrictConnectAddrs.emplace_back(ai);
|
|
|
|
LogInfo(Name(), " added ", m_StrictConnectAddrs.back(),
|
|
|
|
" to strict connect");
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2019-01-16 21:08:00 +00:00
|
|
|
// Name won't be set because we need to read the config before we can read
|
|
|
|
// the keyfile
|
2018-11-14 19:34:17 +00:00
|
|
|
if(k == "exit-node")
|
|
|
|
{
|
2019-09-03 15:56:56 +00:00
|
|
|
IPRange exitRange;
|
2018-11-14 19:34:17 +00:00
|
|
|
llarp::RouterID exitRouter;
|
2019-09-03 15:56:56 +00:00
|
|
|
std::string routerStr;
|
|
|
|
const auto pos = v.find(",");
|
|
|
|
if(pos != std::string::npos)
|
|
|
|
{
|
|
|
|
auto range_str = v.substr(1 + pos);
|
|
|
|
if(!exitRange.FromString(range_str))
|
|
|
|
{
|
|
|
|
LogError("bad exit range: '", range_str, "'");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
routerStr = v.substr(0, pos);
|
|
|
|
}
|
|
|
|
else
|
2018-11-14 19:34:17 +00:00
|
|
|
{
|
2019-09-03 15:56:56 +00:00
|
|
|
routerStr = v;
|
|
|
|
}
|
|
|
|
absl::StripAsciiWhitespace(&routerStr);
|
|
|
|
if(!(exitRouter.FromString(routerStr)
|
|
|
|
|| HexDecode(routerStr.c_str(), exitRouter.begin(),
|
|
|
|
exitRouter.size())))
|
|
|
|
{
|
|
|
|
llarp::LogError(Name(), " bad exit router key: ", routerStr);
|
2018-11-14 19:34:17 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-09-03 15:56:56 +00:00
|
|
|
auto exit = std::make_shared< llarp::exit::ExitSession >(
|
2018-11-14 19:34:17 +00:00
|
|
|
exitRouter,
|
2019-08-02 09:27:27 +00:00
|
|
|
util::memFn(&TunEndpoint::QueueInboundPacketForExit, this),
|
|
|
|
m_router, numPaths, numHops, ShouldBundleRC());
|
2019-09-03 15:56:56 +00:00
|
|
|
m_ExitMap.Insert(exitRange, exit);
|
|
|
|
llarp::LogInfo(Name(), " using exit at ", exitRouter, " for ",
|
|
|
|
exitRange);
|
2018-11-14 19:34:17 +00:00
|
|
|
}
|
2018-11-11 13:14:19 +00:00
|
|
|
if(k == "local-dns")
|
|
|
|
{
|
|
|
|
std::string resolverAddr = v;
|
2018-11-18 17:41:09 +00:00
|
|
|
uint16_t dnsport = 53;
|
2018-11-11 13:14:19 +00:00
|
|
|
auto pos = v.find(":");
|
|
|
|
if(pos != std::string::npos)
|
|
|
|
{
|
|
|
|
resolverAddr = v.substr(0, pos);
|
2018-11-11 13:30:54 +00:00
|
|
|
dnsport = std::atoi(v.substr(pos + 1).c_str());
|
2018-11-11 13:14:19 +00:00
|
|
|
}
|
|
|
|
m_LocalResolverAddr = llarp::Addr(resolverAddr, dnsport);
|
2019-01-16 21:08:00 +00:00
|
|
|
llarp::LogInfo(Name(), " binding DNS server to ", m_LocalResolverAddr);
|
2018-11-11 13:14:19 +00:00
|
|
|
}
|
|
|
|
if(k == "upstream-dns")
|
|
|
|
{
|
|
|
|
std::string resolverAddr = v;
|
2018-11-18 17:41:09 +00:00
|
|
|
uint16_t dnsport = 53;
|
2018-11-11 13:14:19 +00:00
|
|
|
auto pos = v.find(":");
|
|
|
|
if(pos != std::string::npos)
|
|
|
|
{
|
|
|
|
resolverAddr = v.substr(0, pos);
|
2018-11-11 13:30:54 +00:00
|
|
|
dnsport = std::atoi(v.substr(pos + 1).c_str());
|
2018-11-11 13:14:19 +00:00
|
|
|
}
|
2018-12-03 22:22:59 +00:00
|
|
|
m_UpstreamResolvers.emplace_back(resolverAddr, dnsport);
|
2019-01-16 21:08:00 +00:00
|
|
|
llarp::LogInfo(Name(), " adding upstream DNS server ", resolverAddr,
|
2018-12-17 20:47:08 +00:00
|
|
|
":", dnsport);
|
2018-11-11 13:14:19 +00:00
|
|
|
}
|
2018-08-22 15:52:10 +00:00
|
|
|
if(k == "mapaddr")
|
|
|
|
{
|
|
|
|
auto pos = v.find(":");
|
|
|
|
if(pos == std::string::npos)
|
|
|
|
{
|
|
|
|
llarp::LogError("Cannot map address ", v,
|
2018-11-03 13:19:18 +00:00
|
|
|
" invalid format, missing colon (:), expects "
|
2018-08-22 15:52:10 +00:00
|
|
|
"address.loki:ip.address.goes.here");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
service::Address addr;
|
|
|
|
auto addr_str = v.substr(0, pos);
|
|
|
|
if(!addr.FromString(addr_str))
|
|
|
|
{
|
2018-09-10 11:08:09 +00:00
|
|
|
llarp::LogError(Name() + " cannot map invalid address ", addr_str);
|
2018-08-22 15:52:10 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto ip_str = v.substr(pos + 1);
|
2019-06-11 16:44:05 +00:00
|
|
|
huint32_t ip;
|
|
|
|
huint128_t ipv6;
|
|
|
|
if(ip.FromString(ip_str))
|
2018-08-22 15:52:10 +00:00
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
ipv6 = net::IPPacket::ExpandV4(ip);
|
|
|
|
}
|
|
|
|
else if(ipv6.FromString(ip_str))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
llarp::LogError(Name(), "failed to map ", ip_str,
|
|
|
|
" failed to parse IP");
|
2018-08-22 15:52:10 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-06-11 16:44:05 +00:00
|
|
|
return MapAddress(addr, ipv6, false);
|
2018-08-22 15:52:10 +00:00
|
|
|
}
|
2018-08-16 14:34:15 +00:00
|
|
|
if(k == "ifname")
|
|
|
|
{
|
2018-12-28 15:10:05 +00:00
|
|
|
if(v.length() >= sizeof(tunif.ifname))
|
|
|
|
{
|
|
|
|
llarp::LogError(Name() + " ifname '", v, "' is too long");
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-16 14:34:15 +00:00
|
|
|
strncpy(tunif.ifname, v.c_str(), sizeof(tunif.ifname) - 1);
|
2018-09-10 11:08:09 +00:00
|
|
|
llarp::LogInfo(Name() + " setting ifname to ", tunif.ifname);
|
2018-08-16 14:34:15 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(k == "ifaddr")
|
|
|
|
{
|
|
|
|
std::string addr;
|
2019-06-11 16:44:05 +00:00
|
|
|
m_UseV6 = addr.find(":") != std::string::npos;
|
2018-08-16 14:34:15 +00:00
|
|
|
auto pos = v.find("/");
|
|
|
|
if(pos != std::string::npos)
|
|
|
|
{
|
2018-11-06 14:06:09 +00:00
|
|
|
int num;
|
|
|
|
std::string part = v.substr(pos + 1);
|
2018-11-08 12:31:50 +00:00
|
|
|
#if defined(ANDROID) || defined(RPI)
|
2018-11-06 14:06:09 +00:00
|
|
|
num = atoi(part.c_str());
|
|
|
|
#else
|
|
|
|
num = std::stoi(part);
|
|
|
|
#endif
|
2018-08-16 14:34:15 +00:00
|
|
|
if(num > 0)
|
|
|
|
{
|
|
|
|
tunif.netmask = num;
|
|
|
|
addr = v.substr(0, pos);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
llarp::LogError("bad ifaddr value: ", v);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
if(m_UseV6)
|
|
|
|
tunif.netmask = 128;
|
|
|
|
else
|
|
|
|
tunif.netmask = 32;
|
|
|
|
addr = v;
|
2018-08-16 14:34:15 +00:00
|
|
|
}
|
2018-09-10 11:08:09 +00:00
|
|
|
llarp::LogInfo(Name() + " set ifaddr to ", addr, " with netmask ",
|
|
|
|
tunif.netmask);
|
2018-08-16 14:34:15 +00:00
|
|
|
strncpy(tunif.ifaddr, addr.c_str(), sizeof(tunif.ifaddr) - 1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return Endpoint::SetOption(k, v);
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:23:08 +00:00
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
TunEndpoint::HasLocalIP(const huint128_t &ip) const
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
|
|
|
return m_IPToAddr.find(ip) != m_IPToAddr.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
TunEndpoint::QueueOutboundTraffic(llarp::net::IPPacket &&pkt)
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
|
|
|
return m_NetworkToUserPktQueue.EmplaceIf(
|
2019-06-11 16:44:05 +00:00
|
|
|
[](llarp::net::IPPacket &) -> bool { return true; }, std::move(pkt));
|
2018-11-14 12:23:08 +00:00
|
|
|
}
|
|
|
|
|
2018-12-15 16:56:35 +00:00
|
|
|
void
|
|
|
|
TunEndpoint::Flush()
|
|
|
|
{
|
2019-04-30 16:07:17 +00:00
|
|
|
auto self = shared_from_this();
|
2018-12-15 16:56:35 +00:00
|
|
|
FlushSend();
|
2019-09-03 15:56:56 +00:00
|
|
|
RouterLogic()->queue_func([=] {
|
|
|
|
self->m_ExitMap.ForEachValue(
|
|
|
|
[](const auto &exit) { exit->FlushUpstream(); });
|
2019-04-30 16:07:17 +00:00
|
|
|
self->Pump(self->Now());
|
|
|
|
});
|
2018-12-15 16:56:35 +00:00
|
|
|
}
|
|
|
|
|
2019-03-20 15:48:23 +00:00
|
|
|
static bool
|
|
|
|
is_random_snode(const dns::Message &msg)
|
|
|
|
{
|
2019-04-26 12:11:34 +00:00
|
|
|
return msg.questions[0].IsName("random.snode");
|
2019-03-20 15:48:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
is_localhost_loki(const dns::Message &msg)
|
|
|
|
{
|
2019-04-26 12:11:34 +00:00
|
|
|
return msg.questions[0].IsName("localhost.loki");
|
2019-03-20 15:48:23 +00:00
|
|
|
}
|
|
|
|
|
2018-12-03 22:22:59 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::HandleHookedDNSMessage(
|
2019-01-07 22:15:31 +00:00
|
|
|
dns::Message &&msg, std::function< void(dns::Message) > reply)
|
2018-12-03 22:22:59 +00:00
|
|
|
{
|
2019-03-27 13:36:11 +00:00
|
|
|
// llarp::LogInfo("Tun.HandleHookedDNSMessage ", msg.questions[0].qname, "
|
|
|
|
// of type", msg.questions[0].qtype);
|
2018-12-03 22:22:59 +00:00
|
|
|
if(msg.questions.size() != 1)
|
|
|
|
{
|
|
|
|
llarp::LogWarn("bad number of dns questions: ", msg.questions.size());
|
|
|
|
return false;
|
|
|
|
}
|
2019-04-26 12:11:34 +00:00
|
|
|
const std::string qname = msg.questions[0].Name();
|
2019-01-28 15:26:35 +00:00
|
|
|
if(msg.questions[0].qtype == dns::qTypeMX)
|
2018-12-07 21:52:19 +00:00
|
|
|
{
|
|
|
|
// mx record
|
2019-02-05 14:23:51 +00:00
|
|
|
service::Address addr;
|
2019-02-05 14:22:02 +00:00
|
|
|
if(addr.FromString(qname, ".loki") || addr.FromString(qname, ".snode")
|
|
|
|
|| is_random_snode(msg) || is_localhost_loki(msg))
|
2018-12-07 21:52:19 +00:00
|
|
|
msg.AddMXReply(qname, 1);
|
|
|
|
else
|
|
|
|
msg.AddNXReply();
|
2018-12-07 22:08:23 +00:00
|
|
|
reply(msg);
|
2018-12-07 21:52:19 +00:00
|
|
|
}
|
2019-01-10 15:49:08 +00:00
|
|
|
else if(msg.questions[0].qtype == dns::qTypeCNAME)
|
|
|
|
{
|
2019-02-05 14:22:02 +00:00
|
|
|
if(is_random_snode(msg))
|
2019-01-10 15:49:08 +00:00
|
|
|
{
|
|
|
|
RouterID random;
|
|
|
|
if(Router()->GetRandomGoodRouter(random))
|
|
|
|
msg.AddCNAMEReply(random.ToString(), 1);
|
|
|
|
else
|
|
|
|
msg.AddNXReply();
|
|
|
|
}
|
2019-02-05 14:22:02 +00:00
|
|
|
else if(is_localhost_loki(msg))
|
2019-01-28 15:26:35 +00:00
|
|
|
{
|
|
|
|
size_t counter = 0;
|
|
|
|
context->ForEachService(
|
|
|
|
[&](const std::string &,
|
2019-04-23 14:47:23 +00:00
|
|
|
const std::shared_ptr< service::Endpoint > &service) -> bool {
|
2019-07-05 14:41:26 +00:00
|
|
|
const service::Address addr = service->GetIdentity().pub.Addr();
|
2019-01-28 15:26:35 +00:00
|
|
|
msg.AddCNAMEReply(addr.ToString(), 1);
|
|
|
|
++counter;
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
if(counter == 0)
|
|
|
|
msg.AddNXReply();
|
|
|
|
}
|
2019-01-10 15:49:08 +00:00
|
|
|
else
|
|
|
|
msg.AddNXReply();
|
2019-02-05 14:03:38 +00:00
|
|
|
reply(msg);
|
2019-01-10 15:49:08 +00:00
|
|
|
}
|
2019-03-27 13:36:11 +00:00
|
|
|
else if(msg.questions[0].qtype == dns::qTypeA
|
|
|
|
|| msg.questions[0].qtype == dns::qTypeAAAA)
|
2018-12-03 22:22:59 +00:00
|
|
|
{
|
2019-06-11 21:28:55 +00:00
|
|
|
const bool isV6 =
|
|
|
|
msg.questions[0].qtype == dns::qTypeAAAA && SupportsV6();
|
2019-06-11 16:44:05 +00:00
|
|
|
const bool isV4 = msg.questions[0].qtype == dns::qTypeA;
|
2018-12-03 22:22:59 +00:00
|
|
|
llarp::service::Address addr;
|
2019-02-05 03:19:06 +00:00
|
|
|
// on MacOS this is a typeA query
|
2019-02-05 14:22:02 +00:00
|
|
|
if(is_random_snode(msg))
|
2019-02-05 03:19:06 +00:00
|
|
|
{
|
2019-02-05 21:04:30 +00:00
|
|
|
RouterID random;
|
|
|
|
if(Router()->GetRandomGoodRouter(random))
|
|
|
|
msg.AddCNAMEReply(random.ToString(), 1);
|
|
|
|
else
|
|
|
|
msg.AddNXReply();
|
2019-02-05 03:19:06 +00:00
|
|
|
}
|
2019-02-05 14:22:02 +00:00
|
|
|
else if(is_localhost_loki(msg))
|
2018-12-13 00:03:19 +00:00
|
|
|
{
|
2019-01-28 15:26:35 +00:00
|
|
|
size_t counter = 0;
|
|
|
|
context->ForEachService(
|
|
|
|
[&](const std::string &,
|
2019-04-23 14:47:23 +00:00
|
|
|
const std::shared_ptr< service::Endpoint > &service) -> bool {
|
2019-07-01 13:44:25 +00:00
|
|
|
if(!service->HasIfAddr())
|
|
|
|
return true;
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t ip = service->GetIfAddr();
|
2019-02-06 13:02:17 +00:00
|
|
|
if(ip.h)
|
2019-01-28 15:26:35 +00:00
|
|
|
{
|
2019-03-27 13:36:11 +00:00
|
|
|
msg.AddINReply(ip, isV6);
|
2019-01-28 15:26:35 +00:00
|
|
|
++counter;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
if(counter == 0)
|
2018-12-13 00:03:19 +00:00
|
|
|
msg.AddNXReply();
|
|
|
|
}
|
|
|
|
else if(addr.FromString(qname, ".loki"))
|
2018-12-03 22:22:59 +00:00
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
if(isV4 && SupportsV6())
|
2018-12-07 20:56:01 +00:00
|
|
|
{
|
2019-06-11 18:23:53 +00:00
|
|
|
msg.hdr_fields |= dns::flags_QR | dns::flags_AA | dns::flags_RA;
|
2019-06-11 16:44:05 +00:00
|
|
|
}
|
|
|
|
else if(HasAddress(addr))
|
|
|
|
{
|
|
|
|
huint128_t ip = ObtainIPForAddr(addr, false);
|
2019-06-11 21:28:55 +00:00
|
|
|
msg.AddINReply(ip, isV6);
|
2018-12-07 20:56:01 +00:00
|
|
|
}
|
|
|
|
else
|
2019-01-07 22:15:31 +00:00
|
|
|
{
|
2019-07-30 23:42:13 +00:00
|
|
|
auto *replyMsg = new dns::Message(std::move(msg));
|
2019-04-21 16:44:27 +00:00
|
|
|
using service::Address;
|
|
|
|
using service::OutboundContext;
|
2019-03-01 19:10:42 +00:00
|
|
|
return EnsurePathToService(
|
|
|
|
addr,
|
2019-04-26 12:11:34 +00:00
|
|
|
[=](const Address &, OutboundContext *ctx) {
|
2019-06-11 21:28:55 +00:00
|
|
|
SendDNSReply(addr, ctx, replyMsg, reply, false,
|
|
|
|
isV6 || !isV4);
|
2019-03-01 19:10:42 +00:00
|
|
|
},
|
|
|
|
2000);
|
2019-01-07 22:15:31 +00:00
|
|
|
}
|
2018-12-03 22:22:59 +00:00
|
|
|
}
|
|
|
|
else if(addr.FromString(qname, ".snode"))
|
|
|
|
{
|
2019-06-12 13:48:14 +00:00
|
|
|
if(isV4 && SupportsV6())
|
|
|
|
{
|
|
|
|
msg.hdr_fields |= dns::flags_QR | dns::flags_AA | dns::flags_RA;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-30 23:42:13 +00:00
|
|
|
auto *replyMsg = new dns::Message(std::move(msg));
|
2019-06-12 13:48:14 +00:00
|
|
|
EnsurePathToSNode(addr.as_array(),
|
|
|
|
[=](const RouterID &, exit::BaseSession_ptr s) {
|
|
|
|
SendDNSReply(addr, s, replyMsg, reply, true,
|
|
|
|
isV6);
|
|
|
|
});
|
|
|
|
return true;
|
|
|
|
}
|
2018-12-03 22:22:59 +00:00
|
|
|
}
|
|
|
|
else
|
2018-12-04 16:16:43 +00:00
|
|
|
msg.AddNXReply();
|
|
|
|
|
|
|
|
reply(msg);
|
2018-12-03 22:22:59 +00:00
|
|
|
}
|
2019-01-10 15:49:08 +00:00
|
|
|
else if(msg.questions[0].qtype == dns::qTypePTR)
|
2018-12-03 22:22:59 +00:00
|
|
|
{
|
2018-12-04 16:16:43 +00:00
|
|
|
// reverse dns
|
2019-06-12 13:48:14 +00:00
|
|
|
huint128_t ip = {0};
|
2018-12-03 22:22:59 +00:00
|
|
|
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
|
|
|
{
|
2018-12-04 16:16:43 +00:00
|
|
|
msg.AddNXReply();
|
|
|
|
reply(msg);
|
2018-12-03 22:22:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
2019-01-02 01:04:08 +00:00
|
|
|
llarp::service::Address addr(
|
2019-06-12 13:48:14 +00:00
|
|
|
ObtainAddrForIP< llarp::service::Address >(ip, true));
|
2018-12-03 22:22:59 +00:00
|
|
|
if(!addr.IsZero())
|
|
|
|
{
|
2018-12-04 16:16:43 +00:00
|
|
|
msg.AddAReply(addr.ToString(".snode"));
|
|
|
|
reply(msg);
|
2018-12-03 22:22:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
2019-06-12 13:48:14 +00:00
|
|
|
addr = ObtainAddrForIP< llarp::service::Address >(ip, false);
|
2018-12-03 22:22:59 +00:00
|
|
|
if(!addr.IsZero())
|
|
|
|
{
|
2018-12-04 16:16:43 +00:00
|
|
|
msg.AddAReply(addr.ToString(".loki"));
|
|
|
|
reply(msg);
|
2018-12-03 22:22:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
2018-12-04 16:16:43 +00:00
|
|
|
msg.AddNXReply();
|
|
|
|
reply(msg);
|
2018-12-03 22:22:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
2018-12-04 16:16:43 +00:00
|
|
|
{
|
|
|
|
msg.AddNXReply();
|
|
|
|
reply(msg);
|
|
|
|
}
|
2018-12-03 22:22:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-05-07 17:46:38 +00:00
|
|
|
void
|
|
|
|
TunEndpoint::ResetInternalState()
|
|
|
|
{
|
|
|
|
service::Endpoint::ResetInternalState();
|
2019-09-03 15:56:56 +00:00
|
|
|
m_ExitMap.ForEachValue(
|
|
|
|
[](const auto &exit) { exit->ResetInternalState(); });
|
2019-05-07 17:46:38 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 16:44:05 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::SupportsV6() const
|
|
|
|
{
|
|
|
|
return m_UseV6;
|
|
|
|
}
|
|
|
|
|
2019-03-20 03:18:38 +00:00
|
|
|
// FIXME: pass in which question it should be addressing
|
2018-12-03 22:22:59 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::ShouldHookDNSMessage(const dns::Message &msg) const
|
|
|
|
{
|
|
|
|
llarp::service::Address addr;
|
|
|
|
if(msg.questions.size() == 1)
|
|
|
|
{
|
2019-05-01 13:40:10 +00:00
|
|
|
/// hook every .loki
|
|
|
|
if(msg.questions[0].HasTLD(".loki"))
|
2018-12-13 00:03:19 +00:00
|
|
|
return true;
|
2019-05-01 13:40:10 +00:00
|
|
|
/// hook every .snode
|
|
|
|
if(msg.questions[0].HasTLD(".snode"))
|
2018-12-03 22:22:59 +00:00
|
|
|
return true;
|
2019-01-10 15:49:08 +00:00
|
|
|
// hook any ranges we own
|
2018-12-13 16:14:44 +00:00
|
|
|
if(msg.questions[0].qtype == llarp::dns::qTypePTR)
|
2018-12-03 22:22:59 +00:00
|
|
|
{
|
2019-06-12 13:48:14 +00:00
|
|
|
huint128_t ip = {0};
|
2018-12-03 22:22:59 +00:00
|
|
|
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
|
|
|
return false;
|
2019-06-12 13:48:14 +00:00
|
|
|
return m_OurRange.Contains(ip);
|
2018-12-03 22:22:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-22 15:52:10 +00:00
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
TunEndpoint::MapAddress(const service::Address &addr, huint128_t ip,
|
2018-12-02 18:07:07 +00:00
|
|
|
bool SNode)
|
2018-08-22 15:52:10 +00:00
|
|
|
{
|
|
|
|
auto itr = m_IPToAddr.find(ip);
|
|
|
|
if(itr != m_IPToAddr.end())
|
|
|
|
{
|
2018-11-14 12:23:08 +00:00
|
|
|
llarp::LogWarn(ip, " already mapped to ",
|
2019-01-02 01:04:01 +00:00
|
|
|
service::Address(itr->second.as_array()).ToString());
|
2018-08-22 15:52:10 +00:00
|
|
|
return false;
|
|
|
|
}
|
2018-11-03 13:19:18 +00:00
|
|
|
llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", ip);
|
2018-10-19 15:04:14 +00:00
|
|
|
|
2019-01-02 01:04:08 +00:00
|
|
|
m_IPToAddr[ip] = addr;
|
|
|
|
m_AddrToIP[addr] = ip;
|
|
|
|
m_SNodes[addr] = SNode;
|
2018-09-10 11:08:09 +00:00
|
|
|
MarkIPActiveForever(ip);
|
2018-08-22 15:52:10 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::Start()
|
|
|
|
{
|
|
|
|
if(!Endpoint::Start())
|
2019-01-16 21:08:00 +00:00
|
|
|
{
|
|
|
|
llarp::LogWarn("Couldn't start endpoint");
|
2018-08-16 14:34:15 +00:00
|
|
|
return false;
|
2019-01-16 21:08:00 +00:00
|
|
|
}
|
2019-09-03 15:56:56 +00:00
|
|
|
const auto blacklist = SnodeBlacklist();
|
|
|
|
m_ExitMap.ForEachValue([blacklist](const auto &exit) {
|
|
|
|
for(const auto &snode : blacklist)
|
|
|
|
exit->BlacklistSnode(snode);
|
|
|
|
});
|
2018-08-21 18:39:18 +00:00
|
|
|
return SetupNetworking();
|
2018-08-16 14:34:15 +00:00
|
|
|
}
|
|
|
|
|
2018-12-02 18:07:07 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::IsSNode() const
|
2018-11-30 14:14:30 +00:00
|
|
|
{
|
|
|
|
// TODO : implement me
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::SetupTun()
|
|
|
|
{
|
2019-04-08 12:01:52 +00:00
|
|
|
auto loop = EndpointNetLoop();
|
|
|
|
if(!llarp_ev_add_tun(loop.get(), &tunif))
|
2018-08-20 19:12:12 +00:00
|
|
|
{
|
2019-01-16 21:08:00 +00:00
|
|
|
llarp::LogError(Name(),
|
|
|
|
" failed to set up tun interface: ", tunif.ifaddr,
|
|
|
|
" on ", tunif.ifname);
|
2018-08-20 19:12:12 +00:00
|
|
|
return false;
|
|
|
|
}
|
2018-09-23 16:48:43 +00:00
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
struct addrinfo hint, *res = nullptr;
|
2018-09-23 16:48:43 +00:00
|
|
|
int ret;
|
|
|
|
|
2018-11-26 17:10:18 +00:00
|
|
|
memset(&hint, 0, sizeof hint);
|
2018-09-23 16:48:43 +00:00
|
|
|
|
|
|
|
hint.ai_family = PF_UNSPEC;
|
|
|
|
hint.ai_flags = AI_NUMERICHOST;
|
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
ret = getaddrinfo(tunif.ifaddr, nullptr, &hint, &res);
|
2018-09-23 16:48:43 +00:00
|
|
|
if(ret)
|
|
|
|
{
|
|
|
|
llarp::LogError(Name(),
|
|
|
|
" failed to set up tun interface, cant determine "
|
|
|
|
"family from ",
|
|
|
|
tunif.ifaddr);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
// output is in network byte order
|
|
|
|
unsigned char buf[sizeof(struct in6_addr)];
|
|
|
|
int s = inet_pton(res->ai_family, tunif.ifaddr, buf);
|
|
|
|
if (s <= 0)
|
|
|
|
{
|
2018-12-03 22:22:59 +00:00
|
|
|
llarp::LogError(Name(), " failed to set up tun interface, cant parse
|
|
|
|
", tunif.ifaddr); return false;
|
2018-09-23 16:48:43 +00:00
|
|
|
}
|
|
|
|
*/
|
|
|
|
if(res->ai_family == AF_INET6)
|
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
m_UseV6 = true;
|
2018-09-23 16:48:43 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 16:44:05 +00:00
|
|
|
freeaddrinfo(res);
|
|
|
|
if(m_UseV6)
|
2018-09-23 16:48:43 +00:00
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
llarp::LogInfo(Name(), " using IPV6");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct in_addr addr; // network byte order
|
|
|
|
if(inet_aton(tunif.ifaddr, &addr) == 0)
|
|
|
|
{
|
|
|
|
llarp::LogError(Name(),
|
|
|
|
" failed to set up tun interface, cant parse ",
|
|
|
|
tunif.ifaddr);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
huint32_t ip;
|
|
|
|
if(ip.FromString(tunif.ifaddr))
|
|
|
|
{
|
|
|
|
m_OurIP = net::IPPacket::ExpandV4(ip);
|
|
|
|
m_OurRange.netmask_bits = netmask_ipv6_bits(tunif.netmask + 96);
|
|
|
|
}
|
|
|
|
else if(m_OurIP.FromString(tunif.ifaddr))
|
|
|
|
{
|
|
|
|
m_OurRange.netmask_bits = netmask_ipv6_bits(tunif.netmask);
|
2018-09-23 16:48:43 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 16:44:05 +00:00
|
|
|
m_NextIP = m_OurIP;
|
|
|
|
m_OurRange.addr = m_OurIP;
|
2019-09-03 15:56:56 +00:00
|
|
|
m_MaxIP = m_OurRange.HighestAddr();
|
2019-06-11 16:44:05 +00:00
|
|
|
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ",
|
|
|
|
m_OurIP);
|
2018-12-03 22:22:59 +00:00
|
|
|
llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ",
|
|
|
|
m_OurRange);
|
2019-06-11 16:44:05 +00:00
|
|
|
|
2018-11-30 14:14:30 +00:00
|
|
|
MapAddress(m_Identity.pub.Addr(), m_OurIP, IsSNode());
|
2019-04-22 12:25:25 +00:00
|
|
|
if(m_OnUp)
|
|
|
|
{
|
2019-04-22 14:00:59 +00:00
|
|
|
m_OnUp->NotifyAsync(NotifyParams());
|
2019-04-22 12:25:25 +00:00
|
|
|
}
|
2018-08-20 19:12:12 +00:00
|
|
|
return true;
|
2018-08-16 14:34:15 +00:00
|
|
|
}
|
|
|
|
|
2019-04-22 14:00:59 +00:00
|
|
|
std::unordered_map< std::string, std::string >
|
|
|
|
TunEndpoint::NotifyParams() const
|
|
|
|
{
|
|
|
|
auto env = Endpoint::NotifyParams();
|
|
|
|
env.emplace("IP_ADDR", m_OurIP.ToString());
|
|
|
|
env.emplace("IF_ADDR", m_OurRange.ToString());
|
|
|
|
env.emplace("IF_NAME", tunif.ifname);
|
2019-05-06 12:42:21 +00:00
|
|
|
std::string strictConnect;
|
|
|
|
for(const auto &addr : m_StrictConnectAddrs)
|
|
|
|
strictConnect += addr.ToString() + " ";
|
|
|
|
env.emplace("STRICT_CONNECT_ADDRS", strictConnect);
|
2019-04-22 14:00:59 +00:00
|
|
|
return env;
|
|
|
|
}
|
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::SetupNetworking()
|
|
|
|
{
|
2018-08-17 19:49:58 +00:00
|
|
|
llarp::LogInfo("Set Up networking for ", Name());
|
2018-12-03 22:22:59 +00:00
|
|
|
if(!SetupTun())
|
2018-10-04 13:42:22 +00:00
|
|
|
{
|
2018-12-03 22:22:59 +00:00
|
|
|
llarp::LogError(Name(), " failed to set up network interface");
|
|
|
|
return false;
|
2018-10-04 13:42:22 +00:00
|
|
|
}
|
2019-05-22 16:20:03 +00:00
|
|
|
if(!m_Resolver->Start(m_LocalResolverAddr, m_UpstreamResolvers))
|
2018-09-22 10:25:16 +00:00
|
|
|
{
|
2019-01-29 11:17:21 +00:00
|
|
|
// downgrade DNS server failure to a warning
|
|
|
|
llarp::LogWarn(Name(), " failed to start dns server");
|
|
|
|
// return false;
|
2018-09-22 10:25:16 +00:00
|
|
|
}
|
2018-12-03 22:22:59 +00:00
|
|
|
return true;
|
2018-08-16 14:34:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TunEndpoint::Tick(llarp_time_t now)
|
|
|
|
{
|
2019-09-05 21:28:50 +00:00
|
|
|
EndpointLogic()->queue_func([&]() {
|
|
|
|
m_ExitMap.ForEachValue([&](const auto &exit) {
|
|
|
|
this->EnsureRouterIsKnown(exit->Endpoint());
|
|
|
|
exit->Tick(now);
|
|
|
|
});
|
|
|
|
Endpoint::Tick(now);
|
2019-09-03 15:56:56 +00:00
|
|
|
});
|
2018-08-16 14:34:15 +00:00
|
|
|
}
|
|
|
|
|
2018-12-24 16:09:05 +00:00
|
|
|
bool
|
|
|
|
TunEndpoint::Stop()
|
|
|
|
{
|
2019-09-03 15:56:56 +00:00
|
|
|
m_ExitMap.ForEachValue([](const auto &exit) { exit->Stop(); });
|
2018-12-24 16:09:05 +00:00
|
|
|
return llarp::service::Endpoint::Stop();
|
|
|
|
}
|
|
|
|
|
2018-08-22 15:52:10 +00:00
|
|
|
void
|
|
|
|
TunEndpoint::FlushSend()
|
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
m_UserToNetworkPktQueue.Process([&](net::IPPacket &pkt) {
|
2019-02-02 23:12:42 +00:00
|
|
|
std::function< bool(const llarp_buffer_t &) > sendFunc;
|
2019-06-11 16:44:05 +00:00
|
|
|
|
|
|
|
huint128_t dst;
|
|
|
|
if(pkt.IsV4())
|
|
|
|
dst = net::IPPacket::ExpandV4(pkt.dstv4());
|
|
|
|
else
|
|
|
|
dst = pkt.dstv6();
|
|
|
|
|
|
|
|
auto itr = m_IPToAddr.find(dst);
|
2018-08-22 15:52:10 +00:00
|
|
|
if(itr == m_IPToAddr.end())
|
|
|
|
{
|
2019-09-03 15:56:56 +00:00
|
|
|
const auto exits = m_ExitMap.FindAll(dst);
|
|
|
|
if(exits.empty())
|
2018-11-14 19:34:17 +00:00
|
|
|
{
|
2019-09-03 15:56:56 +00:00
|
|
|
llarp::LogWarn(Name(), " has no exit mapped for ", dst);
|
|
|
|
return;
|
2018-11-14 19:34:17 +00:00
|
|
|
}
|
2019-09-03 15:56:56 +00:00
|
|
|
for(const auto &exit : exits)
|
2019-06-11 19:48:21 +00:00
|
|
|
{
|
2019-09-03 15:56:56 +00:00
|
|
|
if(pkt.IsV4() && !llarp::IsIPv4Bogon(pkt.dstv4()))
|
|
|
|
{
|
|
|
|
pkt.UpdateIPv4Address({0}, xhtonl(pkt.dstv4()));
|
|
|
|
exit->QueueUpstreamTraffic(std::move(pkt),
|
2019-06-11 19:48:21 +00:00
|
|
|
llarp::routing::ExitPadSize);
|
2019-09-03 15:56:56 +00:00
|
|
|
}
|
|
|
|
else if(pkt.IsV6())
|
|
|
|
{
|
|
|
|
pkt.UpdateIPv6Address({0}, pkt.dstv6());
|
|
|
|
exit->QueueUpstreamTraffic(std::move(pkt),
|
|
|
|
llarp::routing::ExitPadSize);
|
|
|
|
}
|
2019-06-11 16:44:05 +00:00
|
|
|
}
|
|
|
|
return;
|
2018-08-22 15:52:10 +00:00
|
|
|
}
|
2018-11-29 13:12:35 +00:00
|
|
|
if(m_SNodes.at(itr->second))
|
|
|
|
{
|
2018-12-02 18:07:07 +00:00
|
|
|
sendFunc = std::bind(&TunEndpoint::SendToSNodeOrQueue, this,
|
2019-01-02 01:03:53 +00:00
|
|
|
itr->second.as_array(), std::placeholders::_1);
|
2018-11-29 13:12:35 +00:00
|
|
|
}
|
2018-12-02 18:07:07 +00:00
|
|
|
else
|
2018-11-29 13:12:35 +00:00
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
sendFunc = std::bind(&TunEndpoint::SendToServiceOrQueue, this,
|
|
|
|
service::Address(itr->second.as_array()),
|
|
|
|
std::placeholders::_1, pkt.ServiceProtocol());
|
2018-11-29 13:12:35 +00:00
|
|
|
}
|
2018-10-10 00:28:53 +00:00
|
|
|
// prepare packet for insertion into network
|
2018-10-10 21:29:49 +00:00
|
|
|
// this includes clearing IP addresses, recalculating checksums, etc
|
2019-06-11 16:44:05 +00:00
|
|
|
if(pkt.IsV4())
|
2019-06-11 21:27:06 +00:00
|
|
|
pkt.UpdateIPv4Address({0}, {0});
|
2019-06-11 16:44:05 +00:00
|
|
|
else
|
2019-06-11 21:27:06 +00:00
|
|
|
pkt.UpdateIPv6Address({0}, {0});
|
2018-10-10 00:28:53 +00:00
|
|
|
|
2018-11-29 13:12:35 +00:00
|
|
|
if(sendFunc && sendFunc(pkt.Buffer()))
|
2019-08-01 12:20:51 +00:00
|
|
|
{
|
|
|
|
MarkIPActive(dst);
|
2019-06-11 16:44:05 +00:00
|
|
|
return;
|
2019-08-01 12:20:51 +00:00
|
|
|
}
|
2018-11-29 13:12:35 +00:00
|
|
|
llarp::LogWarn(Name(), " did not flush packets");
|
2018-08-22 15:52:10 +00:00
|
|
|
});
|
2019-09-16 10:21:12 +00:00
|
|
|
SendAllDownstream(Router());
|
2018-08-22 15:52:10 +00:00
|
|
|
}
|
|
|
|
|
2018-09-18 11:08:47 +00:00
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
TunEndpoint::HandleWriteIPPacket(
|
|
|
|
const llarp_buffer_t &b, std::function< huint128_t(void) > getFromIP)
|
2018-08-18 14:01:21 +00:00
|
|
|
{
|
2018-11-03 13:19:18 +00:00
|
|
|
// llarp::LogInfo("got packet from ", msg->sender.Addr());
|
2018-11-29 13:12:35 +00:00
|
|
|
auto themIP = getFromIP();
|
2018-11-03 13:19:18 +00:00
|
|
|
// llarp::LogInfo("themIP ", themIP);
|
|
|
|
auto usIP = m_OurIP;
|
2019-02-03 00:48:10 +00:00
|
|
|
ManagedBuffer buf(b);
|
2018-11-29 13:12:35 +00:00
|
|
|
return m_NetworkToUserPktQueue.EmplaceIf(
|
2019-06-11 16:44:05 +00:00
|
|
|
[buf, themIP, usIP](net::IPPacket &pkt) -> bool {
|
2018-12-02 18:07:07 +00:00
|
|
|
// load
|
2019-02-03 01:44:09 +00:00
|
|
|
if(!pkt.Load(buf))
|
2018-12-02 18:07:07 +00:00
|
|
|
return false;
|
|
|
|
// filter out:
|
|
|
|
// - packets smaller than minimal IPv4 header
|
|
|
|
// - non-IPv4 packets
|
|
|
|
// - packets with weird src/dst addresses
|
|
|
|
// (0.0.0.0/8 but not 0.0.0.0)
|
|
|
|
// - packets with 0 src but non-0 dst and oposite
|
2019-06-11 16:44:05 +00:00
|
|
|
if(pkt.IsV4())
|
2018-12-02 18:07:07 +00:00
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
auto hdr = pkt.Header();
|
|
|
|
if(pkt.sz < sizeof(*hdr)
|
|
|
|
|| (hdr->saddr != 0 && *(byte_t *)&(hdr->saddr) == 0)
|
|
|
|
|| (hdr->daddr != 0 && *(byte_t *)&(hdr->daddr) == 0)
|
|
|
|
|| ((hdr->saddr == 0) != (hdr->daddr == 0)))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2019-06-11 21:28:55 +00:00
|
|
|
pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(themIP)),
|
|
|
|
xhtonl(net::IPPacket::TruncateV6(usIP)));
|
2019-06-11 16:44:05 +00:00
|
|
|
}
|
|
|
|
else if(pkt.IsV6())
|
|
|
|
{
|
2019-06-11 21:27:06 +00:00
|
|
|
pkt.UpdateIPv6Address(themIP, usIP);
|
2018-12-02 18:07:07 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
2018-08-20 19:12:12 +00:00
|
|
|
}
|
2018-10-19 15:04:14 +00:00
|
|
|
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t
|
2018-11-14 12:23:08 +00:00
|
|
|
TunEndpoint::GetIfAddr() const
|
2018-10-19 14:53:06 +00:00
|
|
|
{
|
2018-11-14 12:23:08 +00:00
|
|
|
return m_OurIP;
|
2018-10-19 14:53:06 +00:00
|
|
|
}
|
2018-08-20 19:12:12 +00:00
|
|
|
|
2019-06-11 16:44:05 +00:00
|
|
|
huint128_t
|
2019-01-02 01:04:01 +00:00
|
|
|
TunEndpoint::ObtainIPForAddr(const AlignedBuffer< 32 > &addr, bool snode)
|
2018-08-20 19:12:12 +00:00
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
llarp_time_t now = Now();
|
|
|
|
huint128_t nextIP = {0};
|
2019-01-02 01:03:53 +00:00
|
|
|
AlignedBuffer< 32 > ident(addr);
|
2018-08-21 18:17:16 +00:00
|
|
|
{
|
|
|
|
// previously allocated address
|
2018-11-14 20:56:54 +00:00
|
|
|
auto itr = m_AddrToIP.find(ident);
|
2018-08-21 18:17:16 +00:00
|
|
|
if(itr != m_AddrToIP.end())
|
2018-08-22 15:52:10 +00:00
|
|
|
{
|
|
|
|
// mark ip active
|
2018-09-16 12:25:17 +00:00
|
|
|
MarkIPActive(itr->second);
|
2018-08-21 18:17:16 +00:00
|
|
|
return itr->second;
|
2018-08-22 15:52:10 +00:00
|
|
|
}
|
2018-08-21 18:17:16 +00:00
|
|
|
}
|
2018-09-13 16:41:53 +00:00
|
|
|
// allocate new address
|
2018-08-21 18:17:16 +00:00
|
|
|
if(m_NextIP < m_MaxIP)
|
|
|
|
{
|
2018-09-19 14:49:42 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
nextIP = ++m_NextIP;
|
|
|
|
} while(m_IPToAddr.find(nextIP) != m_IPToAddr.end()
|
|
|
|
&& m_NextIP < m_MaxIP);
|
|
|
|
if(nextIP < m_MaxIP)
|
|
|
|
{
|
2018-11-14 21:40:44 +00:00
|
|
|
m_AddrToIP[ident] = nextIP;
|
|
|
|
m_IPToAddr[nextIP] = ident;
|
2018-12-02 18:07:07 +00:00
|
|
|
m_SNodes[ident] = snode;
|
2018-11-14 20:56:54 +00:00
|
|
|
llarp::LogInfo(Name(), " mapped ", ident, " to ", nextIP);
|
2018-09-19 14:49:42 +00:00
|
|
|
MarkIPActive(nextIP);
|
|
|
|
return nextIP;
|
|
|
|
}
|
2018-08-21 18:17:16 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 14:49:42 +00:00
|
|
|
// we are full
|
|
|
|
// expire least active ip
|
|
|
|
// TODO: prevent DoS
|
2019-06-11 16:44:05 +00:00
|
|
|
std::pair< huint128_t, llarp_time_t > oldest = {huint128_t{0}, 0};
|
2018-09-19 14:49:42 +00:00
|
|
|
|
|
|
|
// find oldest entry
|
|
|
|
auto itr = m_IPActivity.begin();
|
|
|
|
while(itr != m_IPActivity.end())
|
|
|
|
{
|
|
|
|
if(itr->second <= now)
|
2018-08-21 18:17:16 +00:00
|
|
|
{
|
2018-09-19 14:49:42 +00:00
|
|
|
if((now - itr->second) > oldest.second)
|
2018-08-21 18:17:16 +00:00
|
|
|
{
|
2018-09-19 14:49:42 +00:00
|
|
|
oldest.first = itr->first;
|
|
|
|
oldest.second = itr->second;
|
2018-08-21 18:17:16 +00:00
|
|
|
}
|
|
|
|
}
|
2018-09-19 14:49:42 +00:00
|
|
|
++itr;
|
2018-08-21 18:17:16 +00:00
|
|
|
}
|
2018-09-19 14:49:42 +00:00
|
|
|
// remap address
|
2018-11-14 21:47:58 +00:00
|
|
|
m_IPToAddr[oldest.first] = ident;
|
|
|
|
m_AddrToIP[ident] = oldest.first;
|
2018-12-02 18:07:07 +00:00
|
|
|
m_SNodes[ident] = snode;
|
2018-09-19 14:49:42 +00:00
|
|
|
nextIP = oldest.first;
|
2018-08-21 18:17:16 +00:00
|
|
|
|
|
|
|
// mark ip active
|
2018-09-10 16:36:36 +00:00
|
|
|
m_IPActivity[nextIP] = std::max(m_IPActivity[nextIP], now);
|
2018-08-20 19:12:12 +00:00
|
|
|
|
|
|
|
return nextIP;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-06-11 16:44:05 +00:00
|
|
|
TunEndpoint::HasRemoteForIP(huint128_t ip) const
|
2018-08-20 19:12:12 +00:00
|
|
|
{
|
|
|
|
return m_IPToAddr.find(ip) != m_IPToAddr.end();
|
2018-08-18 14:01:21 +00:00
|
|
|
}
|
|
|
|
|
2018-08-21 18:17:16 +00:00
|
|
|
void
|
2019-06-11 16:44:05 +00:00
|
|
|
TunEndpoint::MarkIPActive(huint128_t ip)
|
2018-08-21 18:17:16 +00:00
|
|
|
{
|
2019-06-11 21:28:55 +00:00
|
|
|
llarp::LogDebug(Name(), " address ", ip, " is active");
|
2018-10-29 16:48:36 +00:00
|
|
|
m_IPActivity[ip] = std::max(Now(), m_IPActivity[ip]);
|
2018-08-21 18:17:16 +00:00
|
|
|
}
|
|
|
|
|
2018-09-10 11:08:09 +00:00
|
|
|
void
|
2019-06-11 16:44:05 +00:00
|
|
|
TunEndpoint::MarkIPActiveForever(huint128_t ip)
|
2018-09-10 11:08:09 +00:00
|
|
|
{
|
|
|
|
m_IPActivity[ip] = std::numeric_limits< uint64_t >::max();
|
|
|
|
}
|
|
|
|
|
2018-08-17 19:49:58 +00:00
|
|
|
void
|
2018-11-07 15:30:22 +00:00
|
|
|
TunEndpoint::TickTun(__attribute__((unused)) llarp_time_t now)
|
2018-08-17 19:49:58 +00:00
|
|
|
{
|
|
|
|
// called in the isolated thread
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TunEndpoint::tunifBeforeWrite(llarp_tun_io *tun)
|
|
|
|
{
|
2018-08-21 18:17:16 +00:00
|
|
|
// called in the isolated network thread
|
2019-07-30 23:42:13 +00:00
|
|
|
auto *self = static_cast< TunEndpoint * >(tun->user);
|
2018-12-20 13:04:00 +00:00
|
|
|
// flush user to network
|
2019-09-05 21:28:50 +00:00
|
|
|
self->EndpointLogic()->queue_func(
|
|
|
|
std::bind(&TunEndpoint::FlushSend, self));
|
2018-12-20 13:04:00 +00:00
|
|
|
// flush exit traffic queues if it's there
|
2019-09-05 21:28:50 +00:00
|
|
|
self->EndpointLogic()->queue_func([self] {
|
|
|
|
self->m_ExitMap.ForEachValue(
|
|
|
|
[](const auto &exit) { exit->FlushDownstream(); });
|
|
|
|
});
|
2018-12-20 13:04:00 +00:00
|
|
|
// flush network to user
|
2019-06-11 16:44:05 +00:00
|
|
|
self->m_NetworkToUserPktQueue.Process([tun](net::IPPacket &pkt) {
|
2018-11-23 14:37:26 +00:00
|
|
|
if(!llarp_ev_tun_async_write(tun, pkt.Buffer()))
|
2018-08-22 15:52:10 +00:00
|
|
|
llarp::LogWarn("packet dropped");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-08-17 19:49:58 +00:00
|
|
|
void
|
2019-02-01 01:58:06 +00:00
|
|
|
TunEndpoint::tunifRecvPkt(llarp_tun_io *tun, const llarp_buffer_t &b)
|
2018-08-17 19:49:58 +00:00
|
|
|
{
|
|
|
|
// called for every packet read from user in isolated network thread
|
2019-07-30 23:42:13 +00:00
|
|
|
auto *self = static_cast< TunEndpoint * >(tun->user);
|
2019-09-05 21:28:50 +00:00
|
|
|
const ManagedBuffer pkt(b);
|
2019-07-09 19:17:27 +00:00
|
|
|
self->m_UserToNetworkPktQueue.EmplaceIf(
|
2019-09-05 21:28:50 +00:00
|
|
|
[&pkt](net::IPPacket &p) -> bool { return p.Load(pkt); });
|
2018-08-17 19:49:58 +00:00
|
|
|
}
|
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
TunEndpoint::~TunEndpoint() = default;
|
2018-08-15 15:36:34 +00:00
|
|
|
|
2018-08-16 14:34:15 +00:00
|
|
|
} // namespace handlers
|
|
|
|
} // namespace llarp
|