proper route poking (#1330)

* route poking:

* remove popen() call, replace with reading /proc/net/route for getting default route
* dynamically poke and unpoke routes on runtime

* swap intros and fix rpc endpoint for version to return what the ui expects

* use std::string::find_first_not_of instead of using a lambda
pull/1336/head
Jeff 4 years ago committed by GitHub
parent 2c6e7b86c3
commit 60f4d96ba5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -13,6 +13,7 @@ namespace llarp
GetRCFunc getrc, GetRCFunc getrc,
LinkMessageHandler h, LinkMessageHandler h,
SignBufferFunc sign, SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, TimeoutHandler timeout,
@ -21,7 +22,7 @@ namespace llarp
WorkerFunc_t work) WorkerFunc_t work)
{ {
return std::make_shared<LinkLayer>( return std::make_shared<LinkLayer>(
keyManager, getrc, h, sign, est, reneg, timeout, closed, pumpDone, work, true); keyManager, getrc, h, sign, before, est, reneg, timeout, closed, pumpDone, work, true);
} }
LinkLayer_ptr LinkLayer_ptr
@ -30,6 +31,7 @@ namespace llarp
GetRCFunc getrc, GetRCFunc getrc,
LinkMessageHandler h, LinkMessageHandler h,
SignBufferFunc sign, SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, TimeoutHandler timeout,
@ -38,7 +40,7 @@ namespace llarp
WorkerFunc_t work) WorkerFunc_t work)
{ {
return std::make_shared<LinkLayer>( return std::make_shared<LinkLayer>(
keyManager, getrc, h, sign, est, reneg, timeout, closed, pumpDone, work, false); keyManager, getrc, h, sign, before, est, reneg, timeout, closed, pumpDone, work, false);
} }
} // namespace iwp } // namespace iwp
} // namespace llarp } // namespace llarp

@ -14,6 +14,7 @@ namespace llarp::iwp
GetRCFunc getrc, GetRCFunc getrc,
LinkMessageHandler h, LinkMessageHandler h,
SignBufferFunc sign, SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, TimeoutHandler timeout,
@ -27,6 +28,7 @@ namespace llarp::iwp
GetRCFunc getrc, GetRCFunc getrc,
LinkMessageHandler h, LinkMessageHandler h,
SignBufferFunc sign, SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, TimeoutHandler timeout,

@ -13,6 +13,7 @@ namespace llarp
GetRCFunc getrc, GetRCFunc getrc,
LinkMessageHandler h, LinkMessageHandler h,
SignBufferFunc sign, SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, TimeoutHandler timeout,
@ -20,7 +21,8 @@ namespace llarp
PumpDoneHandler pumpDone, PumpDoneHandler pumpDone,
WorkerFunc_t worker, WorkerFunc_t worker,
bool allowInbound) bool allowInbound)
: ILinkLayer(keyManager, getrc, h, sign, est, reneg, timeout, closed, pumpDone, worker) : ILinkLayer(
keyManager, getrc, h, sign, before, est, reneg, timeout, closed, pumpDone, worker)
, permitInbound{allowInbound} , permitInbound{allowInbound}
{ {
} }

@ -21,6 +21,7 @@ namespace llarp
GetRCFunc getrc, GetRCFunc getrc,
LinkMessageHandler h, LinkMessageHandler h,
SignBufferFunc sign, SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, TimeoutHandler timeout,

@ -18,6 +18,7 @@ namespace llarp
GetRCFunc getrc, GetRCFunc getrc,
LinkMessageHandler handler, LinkMessageHandler handler,
SignBufferFunc signbuf, SignBufferFunc signbuf,
BeforeConnectFunc_t before,
SessionEstablishedHandler establishedSession, SessionEstablishedHandler establishedSession,
SessionRenegotiateHandler reneg, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, TimeoutHandler timeout,
@ -28,6 +29,7 @@ namespace llarp
, HandleTimeout(std::move(timeout)) , HandleTimeout(std::move(timeout))
, Sign(std::move(signbuf)) , Sign(std::move(signbuf))
, GetOurRC(std::move(getrc)) , GetOurRC(std::move(getrc))
, BeforeConnect(std::move(before))
, SessionEstablished(std::move(establishedSession)) , SessionEstablished(std::move(establishedSession))
, SessionClosed(std::move(closed)) , SessionClosed(std::move(closed))
, SessionRenegotiate(std::move(reneg)) , SessionRenegotiate(std::move(reneg))
@ -311,6 +313,10 @@ namespace llarp
} }
} }
std::shared_ptr<ILinkSession> s = NewOutboundSession(rc, to); std::shared_ptr<ILinkSession> s = NewOutboundSession(rc, to);
if (BeforeConnect)
{
BeforeConnect(std::move(rc));
}
if (PutSession(s)) if (PutSession(s))
{ {
s->Start(); s->Start();

@ -70,6 +70,9 @@ namespace llarp
/// queue work to worker thread /// queue work to worker thread
using WorkerFunc_t = std::function<void(Work_t)>; using WorkerFunc_t = std::function<void(Work_t)>;
/// before connection hook, called before we try connecting via outbound link
using BeforeConnectFunc_t = std::function<void(llarp::RouterContact)>;
struct ILinkLayer struct ILinkLayer
{ {
ILinkLayer( ILinkLayer(
@ -77,6 +80,7 @@ namespace llarp
GetRCFunc getrc, GetRCFunc getrc,
LinkMessageHandler handler, LinkMessageHandler handler,
SignBufferFunc signFunc, SignBufferFunc signFunc,
BeforeConnectFunc_t before,
SessionEstablishedHandler sessionEstablish, SessionEstablishedHandler sessionEstablish,
SessionRenegotiateHandler renegotiate, SessionRenegotiateHandler renegotiate,
TimeoutHandler timeout, TimeoutHandler timeout,
@ -195,6 +199,7 @@ namespace llarp
TimeoutHandler HandleTimeout; TimeoutHandler HandleTimeout;
SignBufferFunc Sign; SignBufferFunc Sign;
GetRCFunc GetOurRC; GetRCFunc GetOurRC;
BeforeConnectFunc_t BeforeConnect;
SessionEstablishedHandler SessionEstablished; SessionEstablishedHandler SessionEstablished;
SessionClosedHandler SessionClosed; SessionClosedHandler SessionClosed;
SessionRenegotiateHandler SessionRenegotiate; SessionRenegotiateHandler SessionRenegotiate;

@ -10,6 +10,7 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <net/net.hpp> #include <net/net.hpp>
#include <exception> #include <exception>
#include <charconv>
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
#include <net/net.hpp> #include <net/net.hpp>
@ -25,6 +26,7 @@
#include <sstream> #include <sstream>
#include <util/logging/logger.hpp> #include <util/logging/logger.hpp>
#include <util/str.hpp>
namespace llarp::net namespace llarp::net
{ {
@ -338,28 +340,22 @@ namespace llarp::net
{ {
std::vector<std::string> gateways; std::vector<std::string> gateways;
#ifdef __linux__ #ifdef __linux__
std::ifstream inf("/proc/net/route");
FILE* p = popen("ip route", "r"); for (std::string line; std::getline(inf, line);)
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); const auto parts = split(line, '\t');
std::vector<std::string> words; if (parts[1].find_first_not_of('0') == std::string::npos and parts[0] != ifname)
std::istringstream instr(line_str);
for (std::string word; std::getline(instr, word, ' ');)
{
words.emplace_back(std::move(word));
}
if (words[0] == "default" and words[1] == "via" and words[3] == "dev" and words[4] != ifname)
{ {
gateways.emplace_back(std::move(words[2])); const auto& ip = parts[2];
if ((ip.size() == sizeof(uint32_t) * 2) and lokimq::is_hex(ip))
{
huint32_t x{};
lokimq::from_hex(ip.begin(), ip.end(), reinterpret_cast<char*>(&x.h));
gateways.emplace_back(x.ToString());
}
} }
} }
pclose(p);
return gateways; return gateways;
#elif _WIN32 #elif _WIN32
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))

@ -12,6 +12,7 @@
#include <link/server.hpp> #include <link/server.hpp>
#include <messages/link_message.hpp> #include <messages/link_message.hpp>
#include <net/net.hpp> #include <net/net.hpp>
#include <net/route.hpp>
#include <stdexcept> #include <stdexcept>
#include <util/buffer.hpp> #include <util/buffer.hpp>
#include <util/logging/file_logger.hpp> #include <util/logging/file_logger.hpp>
@ -332,6 +333,10 @@ namespace llarp
void void
Router::Close() Router::Close()
{ {
for (const auto& [ip, gateway] : m_PokedRoutes)
{
net::DelRoute(ip, gateway);
}
if (_onDown) if (_onDown)
_onDown(); _onDown();
LogInfo("closing router"); LogInfo("closing router");
@ -574,6 +579,7 @@ namespace llarp
util::memFn(&AbstractRouter::rc, this), util::memFn(&AbstractRouter::rc, this),
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this), util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this),
util::memFn(&AbstractRouter::Sign, this), util::memFn(&AbstractRouter::Sign, this),
nullptr,
util::memFn(&Router::ConnectionEstablished, this), util::memFn(&Router::ConnectionEstablished, this),
util::memFn(&AbstractRouter::CheckRenegotiateValid, this), util::memFn(&AbstractRouter::CheckRenegotiateValid, this),
util::memFn(&Router::ConnectionTimedOut, this), util::memFn(&Router::ConnectionTimedOut, this),
@ -853,6 +859,12 @@ namespace llarp
dht()->impl->Nodes()->DelNode(k); dht()->impl->Nodes()->DelNode(k);
LogInfo("Session to ", remote, " fully closed"); LogInfo("Session to ", remote, " fully closed");
if (IsServiceNode())
return;
RouterContact rc;
if (not nodedb()->Get(remote, rc))
return;
DelRoute(rc.addrs[0].toIpAddress().toHost());
} }
void void
@ -1216,6 +1228,34 @@ namespace llarp
return true; return true;
} }
std::string
Router::GetDefaultGateway() const
{
const auto ep = hiddenServiceContext().GetDefault();
const auto gateways = net::GetGatewaysNotOnInterface(ep->GetIfName());
if (gateways.empty())
throw std::runtime_error("no gateways?");
return gateways[0];
}
void
Router::AddRoute(std::string ip)
{
const auto gateway = GetDefaultGateway();
m_PokedRoutes.emplace(ip, gateway);
net::AddRoute(ip, gateway);
}
void
Router::DelRoute(std::string ip)
{
const auto itr = m_PokedRoutes.find(ip);
if (itr == m_PokedRoutes.end())
return;
net::DelRoute(itr->first, itr->second);
m_PokedRoutes.erase(itr);
}
bool bool
Router::InitOutboundLinks() Router::InitOutboundLinks()
{ {
@ -1224,6 +1264,11 @@ namespace llarp
util::memFn(&AbstractRouter::rc, this), util::memFn(&AbstractRouter::rc, this),
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this), util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this),
util::memFn(&AbstractRouter::Sign, this), util::memFn(&AbstractRouter::Sign, this),
[&](llarp::RouterContact rc) {
if (IsServiceNode())
return;
AddRoute(rc.addrs[0].toIpAddress().toHost());
},
util::memFn(&Router::ConnectionEstablished, this), util::memFn(&Router::ConnectionEstablished, this),
util::memFn(&AbstractRouter::CheckRenegotiateValid, this), util::memFn(&AbstractRouter::CheckRenegotiateValid, this),
util::memFn(&Router::ConnectionTimedOut, this), util::memFn(&Router::ConnectionTimedOut, this),

@ -260,6 +260,17 @@ namespace llarp
*/ */
} }
std::string
GetDefaultGateway() const;
void
AddRoute(std::string ip);
void
DelRoute(std::string ip);
std::unordered_map<std::string, std::string> m_PokedRoutes;
void void
PumpLL() override; PumpLL() override;

@ -98,7 +98,11 @@ namespace llarp::rpc
}) })
.add_request_command( .add_request_command(
"version", "version",
[](lokimq::Message& msg) { msg.send_reply(CreateJSONResponse(llarp::VERSION_FULL)); }) [r = m_Router](lokimq::Message& msg) {
util::StatusObject result{{"version", llarp::VERSION_FULL},
{"uptime", to_json(r->Uptime())}};
msg.send_reply(CreateJSONResponse(result));
})
.add_request_command( .add_request_command(
"status", "status",
[&](lokimq::Message& msg) { [&](lokimq::Message& msg) {

@ -153,7 +153,7 @@ namespace llarp
} }
Endpoint_ptr Endpoint_ptr
Context::GetEndpointByName(const std::string& name) Context::GetEndpointByName(const std::string& name) const
{ {
auto itr = m_Endpoints.find(name); auto itr = m_Endpoints.find(name);
if (itr != m_Endpoints.end()) if (itr != m_Endpoints.end())

@ -51,10 +51,10 @@ namespace llarp
RemoveEndpoint(const std::string& name); RemoveEndpoint(const std::string& name);
Endpoint_ptr Endpoint_ptr
GetEndpointByName(const std::string& name); GetEndpointByName(const std::string& name) const;
Endpoint_ptr Endpoint_ptr
GetDefault() GetDefault() const
{ {
return GetEndpointByName("default"); return GetEndpointByName("default");
} }

@ -110,7 +110,7 @@ namespace llarp
return true; return true;
} }
currentIntroSet = *foundIntro; currentIntroSet = *foundIntro;
ShiftIntroduction(false); SwapIntros();
} }
else else
{ {

@ -85,6 +85,8 @@ struct IWPLinkContext
REQUIRE(llarp::CryptoManager::instance()->sign(sig, keyManager->identityKey, buf)); REQUIRE(llarp::CryptoManager::instance()->sign(sig, keyManager->identityKey, buf));
return true; return true;
}, },
// before connect
nullptr,
// established handler // established handler
[established](llarp::ILinkSession* s, bool linkIsInbound) { [established](llarp::ILinkSession* s, bool linkIsInbound) {
REQUIRE(s != nullptr); REQUIRE(s != nullptr);

Loading…
Cancel
Save