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,
LinkMessageHandler h,
SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg,
TimeoutHandler timeout,
@ -21,7 +22,7 @@ namespace llarp
WorkerFunc_t work)
{
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
@ -30,6 +31,7 @@ namespace llarp
GetRCFunc getrc,
LinkMessageHandler h,
SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg,
TimeoutHandler timeout,
@ -38,7 +40,7 @@ namespace llarp
WorkerFunc_t work)
{
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 llarp

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

@ -13,6 +13,7 @@ namespace llarp
GetRCFunc getrc,
LinkMessageHandler h,
SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg,
TimeoutHandler timeout,
@ -20,7 +21,8 @@ namespace llarp
PumpDoneHandler pumpDone,
WorkerFunc_t worker,
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}
{
}

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

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

@ -70,6 +70,9 @@ namespace llarp
/// queue work to worker thread
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
{
ILinkLayer(
@ -77,6 +80,7 @@ namespace llarp
GetRCFunc getrc,
LinkMessageHandler handler,
SignBufferFunc signFunc,
BeforeConnectFunc_t before,
SessionEstablishedHandler sessionEstablish,
SessionRenegotiateHandler renegotiate,
TimeoutHandler timeout,
@ -195,6 +199,7 @@ namespace llarp
TimeoutHandler HandleTimeout;
SignBufferFunc Sign;
GetRCFunc GetOurRC;
BeforeConnectFunc_t BeforeConnect;
SessionEstablishedHandler SessionEstablished;
SessionClosedHandler SessionClosed;
SessionRenegotiateHandler SessionRenegotiate;

@ -10,6 +10,7 @@
#include <linux/rtnetlink.h>
#include <net/net.hpp>
#include <exception>
#include <charconv>
#endif
#ifdef __APPLE__
#include <net/net.hpp>
@ -25,6 +26,7 @@
#include <sstream>
#include <util/logging/logger.hpp>
#include <util/str.hpp>
namespace llarp::net
{
@ -338,28 +340,22 @@ namespace llarp::net
{
std::vector<std::string> gateways;
#ifdef __linux__
FILE* p = popen("ip route", "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::ifstream inf("/proc/net/route");
for (std::string line; std::getline(inf, line);)
{
std::string line_str(line, len);
std::vector<std::string> words;
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)
const auto parts = split(line, '\t');
if (parts[1].find_first_not_of('0') == std::string::npos and parts[0] != 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;
#elif _WIN32
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))

@ -12,6 +12,7 @@
#include <link/server.hpp>
#include <messages/link_message.hpp>
#include <net/net.hpp>
#include <net/route.hpp>
#include <stdexcept>
#include <util/buffer.hpp>
#include <util/logging/file_logger.hpp>
@ -332,6 +333,10 @@ namespace llarp
void
Router::Close()
{
for (const auto& [ip, gateway] : m_PokedRoutes)
{
net::DelRoute(ip, gateway);
}
if (_onDown)
_onDown();
LogInfo("closing router");
@ -574,6 +579,7 @@ namespace llarp
util::memFn(&AbstractRouter::rc, this),
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this),
util::memFn(&AbstractRouter::Sign, this),
nullptr,
util::memFn(&Router::ConnectionEstablished, this),
util::memFn(&AbstractRouter::CheckRenegotiateValid, this),
util::memFn(&Router::ConnectionTimedOut, this),
@ -853,6 +859,12 @@ namespace llarp
dht()->impl->Nodes()->DelNode(k);
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
@ -1216,6 +1228,34 @@ namespace llarp
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
Router::InitOutboundLinks()
{
@ -1224,6 +1264,11 @@ namespace llarp
util::memFn(&AbstractRouter::rc, this),
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, 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(&AbstractRouter::CheckRenegotiateValid, 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
PumpLL() override;

@ -98,7 +98,11 @@ namespace llarp::rpc
})
.add_request_command(
"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(
"status",
[&](lokimq::Message& msg) {

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

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

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

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

Loading…
Cancel
Save