mirror of https://github.com/oxen-io/lokinet
macos route poking (#1333)
* fix up macos route poker logic * fix typo * use string_view * add forgotten header * full paths * add debugging * catch exception on adding route * workarround for macos * typofix * typofix * fix for macos * fix command for macos * because we autopoke remove explicit route poking in rpc * probably final fix of macos route poking * split routes instead of deleting them * dynamic route poking * move log statement for introset lookup and dont consider bad sessions as able to send * send convotag reset frame when we have no session * add exit map to rpc * use split_any
This commit is contained in:
parent
60f4d96ba5
commit
3ab7db7723
|
@ -694,6 +694,9 @@ namespace libuv
|
|||
llarp::LogError("failed to start up ", m_Tun->ifname);
|
||||
return false;
|
||||
}
|
||||
// copy back
|
||||
memcpy(m_Tun->ifname, m_Device->if_name, sizeof(m_Tun->ifname));
|
||||
|
||||
if (tuntap_set_ip(m_Device, m_Tun->ifaddr, m_Tun->ifaddr, m_Tun->netmask) == -1)
|
||||
{
|
||||
llarp::LogError("failed to set address on ", m_Tun->ifname);
|
||||
|
|
|
@ -592,6 +592,8 @@ namespace llarp
|
|||
std::string
|
||||
TunEndpoint::GetIfName() const
|
||||
{
|
||||
if (tunif)
|
||||
return tunif->ifname;
|
||||
return m_IfName;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define LLARP_NET_IP_RANGE_MAP_HPP
|
||||
|
||||
#include <net/ip_range.hpp>
|
||||
#include <util/status.hpp>
|
||||
#include <list>
|
||||
|
||||
namespace llarp
|
||||
|
@ -114,6 +115,17 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const
|
||||
{
|
||||
util::StatusObject obj;
|
||||
for (const auto& [range, value] : m_Entries)
|
||||
{
|
||||
obj[range.ToString()] = value.ToString();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
Container_t m_Entries;
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <net/net.hpp>
|
||||
#include <util/str.hpp>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
@ -34,7 +35,6 @@ namespace llarp::net
|
|||
void
|
||||
Execute(std::string cmd)
|
||||
{
|
||||
std::cout << cmd << std::endl;
|
||||
#ifdef _WIN32
|
||||
system(cmd.c_str());
|
||||
#else
|
||||
|
@ -65,10 +65,6 @@ namespace llarp::net
|
|||
{
|
||||
std::cout << "failed: " << result << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ok" << std::endl;
|
||||
}
|
||||
exit(result);
|
||||
}
|
||||
else
|
||||
|
@ -225,6 +221,7 @@ namespace llarp::net
|
|||
void
|
||||
AddRoute(std::string ip, std::string gateway)
|
||||
{
|
||||
LogInfo("Add route: ", ip, " via ", gateway);
|
||||
#ifdef __linux__
|
||||
NLSocket sock;
|
||||
int default_gw = 0;
|
||||
|
@ -235,14 +232,13 @@ namespace llarp::net
|
|||
int nl_flags = NLM_F_CREATE | NLM_F_EXCL;
|
||||
read_addr(gateway.c_str(), &gw_addr);
|
||||
read_addr(ip.c_str(), &to_addr);
|
||||
LogInfo("add route: ", ip, " via ", gateway);
|
||||
do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, default_gw, if_idx);
|
||||
#else
|
||||
std::stringstream ss;
|
||||
#if _WIN32
|
||||
ss << "route ADD " << ip << " MASK 255.255.255.255 " << gateway << " METRIC 2";
|
||||
#elif __APPLE__
|
||||
ss << "route -n add -host " << ip << " " << gateway;
|
||||
ss << "/sbin/route -n add -host " << ip << " " << gateway;
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
|
@ -253,6 +249,7 @@ namespace llarp::net
|
|||
void
|
||||
DelRoute(std::string ip, std::string gateway)
|
||||
{
|
||||
LogInfo("Delete route: ", ip, " via ", gateway);
|
||||
#ifdef __linux__
|
||||
NLSocket sock;
|
||||
int default_gw = 0;
|
||||
|
@ -269,7 +266,7 @@ namespace llarp::net
|
|||
#if _WIN32
|
||||
ss << "route DELETE " << ip << " MASK 255.255.255.255 " << gateway << " METRIC 2";
|
||||
#elif __APPLE__
|
||||
ss << "route -n delete -host " << ip << " " << gateway;
|
||||
ss << "/sbin/route -n delete -host " << ip << " " << gateway;
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
|
@ -280,6 +277,7 @@ namespace llarp::net
|
|||
void
|
||||
AddDefaultRouteViaInterface(std::string ifname)
|
||||
{
|
||||
LogInfo("Add default route via ", ifname);
|
||||
#ifdef __linux__
|
||||
NLSocket sock;
|
||||
int default_gw = 1;
|
||||
|
@ -293,14 +291,14 @@ namespace llarp::net
|
|||
int nl_cmd = RTM_NEWROUTE;
|
||||
int nl_flags = NLM_F_CREATE | NLM_F_EXCL;
|
||||
read_addr(maybe->toHost().c_str(), &gw_addr);
|
||||
LogInfo("default route via ", ifname, " (", if_idx, ")");
|
||||
do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, default_gw, if_idx);
|
||||
#elif _WIN32
|
||||
ifname.back()++;
|
||||
Execute("route ADD 0.0.0.0 MASK 128.0.0.0 " + ifname);
|
||||
Execute("route ADD 128.0.0.0 MASK 128.0.0.0 " + ifname);
|
||||
#elif __APPLE__
|
||||
Execute("route -cloning add -net 0.0.0.0 -netmask 0.0.0.0 -interface " + ifname);
|
||||
Execute("/sbin/route -n add -cloning -net 0.0.0.0 -netmask 128.0.0.0 -interface " + ifname);
|
||||
Execute("/sbin/route -n add -cloning -net 128.0.0.0 -netmask 128.0.0.0 -interface " + ifname);
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
|
@ -309,8 +307,8 @@ namespace llarp::net
|
|||
void
|
||||
DelDefaultRouteViaInterface(std::string ifname)
|
||||
{
|
||||
LogInfo("Remove default route via ", ifname);
|
||||
#ifdef __linux__
|
||||
|
||||
NLSocket sock;
|
||||
int default_gw = 1;
|
||||
int if_idx = if_nametoindex(ifname.c_str());
|
||||
|
@ -329,7 +327,9 @@ namespace llarp::net
|
|||
Execute("route DELETE 0.0.0.0 MASK 128.0.0.0 " + ifname);
|
||||
Execute("route DELETE 128.0.0.0 MASK 128.0.0.0 " + ifname);
|
||||
#elif __APPLE__
|
||||
Execute("route -cloning delete -net 0.0.0.0 -netmask 0.0.0.0 -interface " + ifname);
|
||||
Execute("/sbin/route -n delete -cloning -net 0.0.0.0 -netmask 128.0.0.0 -interface " + ifname);
|
||||
Execute(
|
||||
"/sbin/route -n delete -cloning -net 128.0.0.0 -netmask 128.0.0.0 -interface " + ifname);
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
|
@ -399,34 +399,27 @@ namespace llarp::net
|
|||
#undef FREE
|
||||
return gateways;
|
||||
#elif __APPLE__
|
||||
LogDebug("get gateways not on ", ifname);
|
||||
const auto maybe = GetIFAddr(ifname);
|
||||
if (not maybe.has_value())
|
||||
return gateways;
|
||||
const auto interface = maybe->toString();
|
||||
// mac os is so godawful man
|
||||
FILE* p = popen("netstat -rn -f inet", "r");
|
||||
FILE* p = popen("/usr/sbin/netstat -rn -f inet", "r");
|
||||
if (p == nullptr)
|
||||
{
|
||||
return gateways;
|
||||
}
|
||||
char* line = nullptr;
|
||||
size_t len = 0;
|
||||
ssize_t read = 0;
|
||||
while ((read = getline(&line, &len, p)) != -1)
|
||||
{
|
||||
std::string line_str(line, len);
|
||||
if (line_str.find("default") == 0)
|
||||
const std::string line_str(line, len);
|
||||
const auto parts = llarp::split_any(line_str, " "sv, true);
|
||||
if (parts[0] == "default" and parts[3] != ifname)
|
||||
{
|
||||
line_str = line_str.substr(7);
|
||||
while (line_str[0] == ' ')
|
||||
{
|
||||
line_str = line_str.substr(1);
|
||||
}
|
||||
const auto pos = line_str.find(" ");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
auto gateway = line_str.substr(0, pos);
|
||||
if (gateway != interface)
|
||||
gateways.emplace_back(std::move(gateway));
|
||||
}
|
||||
gateways.emplace_back(parts[1]);
|
||||
}
|
||||
}
|
||||
pclose(p);
|
||||
|
|
|
@ -770,6 +770,47 @@ namespace llarp
|
|||
|
||||
_linkManager.CheckPersistingSessions(now);
|
||||
|
||||
if (not IsServiceNode())
|
||||
{
|
||||
const auto gateway = GetDefaultGateway();
|
||||
if (m_CurrentGateway != gateway)
|
||||
{
|
||||
// changed gateways
|
||||
if (m_CurrentGateway.empty())
|
||||
{
|
||||
LogInfo("found default gateway: ", gateway);
|
||||
}
|
||||
else if (not gateway.empty())
|
||||
{
|
||||
LogInfo("default gateway changed from ", m_CurrentGateway, " to ", gateway);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("Network is down");
|
||||
}
|
||||
// unpoke current routes
|
||||
std::unordered_set<std::string> holes;
|
||||
|
||||
for (const auto& [ip, gw] : m_PokedRoutes)
|
||||
{
|
||||
// save hole
|
||||
holes.emplace(ip);
|
||||
// unpoke route
|
||||
net::DelRoute(ip, gw);
|
||||
}
|
||||
m_PokedRoutes.clear();
|
||||
|
||||
if (not gateway.empty())
|
||||
{
|
||||
m_CurrentGateway = gateway;
|
||||
for (const auto& ip : holes)
|
||||
{
|
||||
AddRoute(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t connected = NumberOfConnectedRouters();
|
||||
if (not isSvcNode)
|
||||
{
|
||||
|
@ -1234,16 +1275,15 @@ namespace llarp
|
|||
const auto ep = hiddenServiceContext().GetDefault();
|
||||
const auto gateways = net::GetGatewaysNotOnInterface(ep->GetIfName());
|
||||
if (gateways.empty())
|
||||
throw std::runtime_error("no gateways?");
|
||||
return "";
|
||||
return gateways[0];
|
||||
}
|
||||
|
||||
void
|
||||
Router::AddRoute(std::string ip)
|
||||
{
|
||||
const auto gateway = GetDefaultGateway();
|
||||
m_PokedRoutes.emplace(ip, gateway);
|
||||
net::AddRoute(ip, gateway);
|
||||
m_PokedRoutes.emplace(ip, m_CurrentGateway);
|
||||
net::AddRoute(ip, m_CurrentGateway);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -270,6 +270,7 @@ namespace llarp
|
|||
DelRoute(std::string ip);
|
||||
|
||||
std::unordered_map<std::string, std::string> m_PokedRoutes;
|
||||
std::string m_CurrentGateway;
|
||||
|
||||
void
|
||||
PumpLL() override;
|
||||
|
|
|
@ -176,12 +176,6 @@ namespace llarp::rpc
|
|||
}
|
||||
if (map and exit.has_value())
|
||||
{
|
||||
const auto gateways = net::GetGatewaysNotOnInterface(ep->GetIfName());
|
||||
if (gateways.empty())
|
||||
{
|
||||
reply(CreateJSONError("no gateway found"));
|
||||
return;
|
||||
}
|
||||
ep->MapExitRange(range, *exit);
|
||||
if (token.has_value())
|
||||
{
|
||||
|
@ -189,29 +183,13 @@ namespace llarp::rpc
|
|||
}
|
||||
ep->EnsurePathToService(
|
||||
*exit,
|
||||
[r, gateway = gateways[0], reply, ep](auto, service::OutboundContext* ctx) {
|
||||
[reply, ep](auto, service::OutboundContext* ctx) {
|
||||
if (ctx == nullptr)
|
||||
{
|
||||
reply(CreateJSONError("could not find exit"));
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> firsthops;
|
||||
r->ForEachPeer(
|
||||
[&firsthops](const auto* link, bool) {
|
||||
firsthops.emplace_back(link->GetRemoteEndpoint().toHost());
|
||||
},
|
||||
false);
|
||||
for (const auto& hop : firsthops)
|
||||
{
|
||||
net::AddRoute(hop, gateway);
|
||||
}
|
||||
net::AddDefaultRouteViaInterface(ep->GetIfName());
|
||||
r->SetDownHook([firsthops, gateway]() {
|
||||
for (const auto& hop : firsthops)
|
||||
{
|
||||
net::DelRoute(hop, gateway);
|
||||
}
|
||||
});
|
||||
reply(CreateJSONResponse("OK"));
|
||||
},
|
||||
5s);
|
||||
|
@ -224,19 +202,7 @@ namespace llarp::rpc
|
|||
}
|
||||
else if (not map)
|
||||
{
|
||||
const auto gateways = net::GetGatewaysNotOnInterface(ep->GetIfName());
|
||||
if (gateways.empty())
|
||||
{
|
||||
reply(CreateJSONError("no gateway found"));
|
||||
return;
|
||||
}
|
||||
net::DelDefaultRouteViaInterface(ep->GetIfName());
|
||||
r->ForEachPeer(
|
||||
[gateway = gateways[0]](const auto* link, bool) {
|
||||
net::DelRoute(link->GetRemoteEndpoint().toHost(), gateway);
|
||||
},
|
||||
false);
|
||||
|
||||
ep->UnmapExitRange(range);
|
||||
}
|
||||
reply(CreateJSONResponse("OK"));
|
||||
|
|
|
@ -182,6 +182,7 @@ namespace llarp
|
|||
Endpoint::ExtractStatus() const
|
||||
{
|
||||
auto obj = path::Builder::ExtractStatus();
|
||||
obj["exitMap"] = m_ExitMap.ExtractStatus();
|
||||
obj["identity"] = m_Identity.pub.Addr().ToString();
|
||||
return m_state->ExtractStatus(obj);
|
||||
}
|
||||
|
@ -914,7 +915,24 @@ namespace llarp
|
|||
RemoveConvoTag(frame.T);
|
||||
return true;
|
||||
}
|
||||
return frame.AsyncDecryptAndVerify(EndpointLogic(), p, m_Identity, this);
|
||||
if (not frame.AsyncDecryptAndVerify(EndpointLogic(), p, m_Identity, this))
|
||||
{
|
||||
// send reset convo tag message
|
||||
ProtocolFrame f;
|
||||
f.R = 1;
|
||||
f.T = frame.T;
|
||||
f.F = p->intro.pathID;
|
||||
|
||||
f.Sign(m_Identity);
|
||||
{
|
||||
LogWarn("invalidating convotag T=", frame.T);
|
||||
RemoveConvoTag(frame.T);
|
||||
util::Lock lock(m_state->m_SendQueueMutex);
|
||||
m_state->m_SendQueue.emplace_back(
|
||||
std::make_shared<const routing::PathTransferMessage>(f, frame.F), p);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Endpoint::HandlePathDied(path::Path_ptr)
|
||||
|
|
|
@ -59,7 +59,6 @@ namespace llarp
|
|||
obj["lastPublished"] = to_json(m_LastPublish);
|
||||
obj["lastPublishAttempt"] = to_json(m_LastPublishAttempt);
|
||||
obj["introset"] = m_IntroSet.ExtractStatus();
|
||||
|
||||
static auto getSecond = [](const auto& item) -> auto
|
||||
{
|
||||
return item.second->ExtractStatus();
|
||||
|
|
|
@ -28,7 +28,6 @@ namespace llarp
|
|||
{
|
||||
std::optional<IntroSet> found;
|
||||
const Address remote(rootkey);
|
||||
LogInfo("found ", results.size(), " for ", remote.ToString());
|
||||
if (results.size() > 0)
|
||||
{
|
||||
EncryptedIntroSet selected;
|
||||
|
@ -39,7 +38,10 @@ namespace llarp
|
|||
}
|
||||
const auto maybe = selected.MaybeDecrypt(rootkey);
|
||||
if (maybe)
|
||||
{
|
||||
LogInfo("found result for ", remote.ToString());
|
||||
found = *maybe;
|
||||
}
|
||||
}
|
||||
return handle(remote, found, endpoint);
|
||||
}
|
||||
|
|
|
@ -123,6 +123,8 @@ namespace llarp
|
|||
bool
|
||||
OutboundContext::ReadyToSend() const
|
||||
{
|
||||
if (markedBad)
|
||||
return false;
|
||||
return (!remoteIntro.router.IsZero()) && GetPathByRouter(remoteIntro.router) != nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -433,7 +433,7 @@ namespace llarp
|
|||
if (!handler->GetCachedSessionKeyFor(T, v->shared))
|
||||
{
|
||||
LogError("No cached session for T=", T);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!handler->GetSenderFor(T, v->si))
|
||||
|
|
Loading…
Reference in New Issue