dont poke routes if we have no exit (#1352)

* * refactor route poking out of llarp::Router and into llarp::RoutePoker
* only poke routes when we have an exit enabled as a client

* add route_poker header so it compiles
pull/1367/head
Jeff 4 years ago committed by GitHub
parent 10e3d80559
commit 252692a55b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -175,6 +175,7 @@ add_library(liblokinet
router/rc_lookup_handler.cpp
router/rc_gossiper.cpp
router/router.cpp
router/route_poker.cpp
router_contact.cpp
router_id.cpp
router_version.cpp

@ -154,6 +154,14 @@ namespace llarp
return m_ipAddress;
}
huint32_t
IpAddress::toIP() const
{
huint32_t ip;
ip.FromString(toHost());
return ip;
}
bool
IpAddress::operator<(const IpAddress& other) const
{

@ -6,6 +6,8 @@
#include <string_view>
#include <string>
#include <net/net_int.hpp>
namespace llarp
{
/// A struct that can represent either an IPv4 or IPv6 address. It is meant for representation
@ -121,6 +123,9 @@ namespace llarp
std::string
toHost() const;
huint32_t
toIP() const;
// TODO: other utility functions left over from Addr which may be useful
// IsBogon() const;
// isPrivate() const;

@ -32,6 +32,12 @@ namespace llarp
return all;
}
bool
Empty() const
{
return m_Entries.empty();
}
bool
ContainsValue(const Value_t& val) const
{

@ -43,6 +43,7 @@ namespace llarp
struct IOutboundSessionMaker;
struct ILinkManager;
struct I_RCLookupHandler;
struct RoutePoker;
namespace exit
{
@ -156,6 +157,9 @@ namespace llarp
virtual ILinkManager&
linkManager() = 0;
virtual RoutePoker&
routePoker() = 0;
virtual I_RCLookupHandler&
rcLookupHandler() = 0;

@ -0,0 +1,77 @@
#include <router/route_poker.hpp>
#include <router/abstractrouter.hpp>
#include <net/route.hpp>
#include <service/context.hpp>
#include <unordered_set>
namespace llarp
{
void
RoutePoker::AddRoute(huint32_t ip)
{
if (m_CurrentGateway.h == 0)
return;
m_PokedRoutes.emplace(ip, m_CurrentGateway);
net::AddRoute(ip.ToString(), m_CurrentGateway.ToString());
}
void
RoutePoker::DelRoute(huint32_t ip)
{
const auto itr = m_PokedRoutes.find(ip);
if (itr == m_PokedRoutes.end())
return;
net::DelRoute(itr->first.ToString(), itr->second.ToString());
m_PokedRoutes.erase(itr);
}
RoutePoker::~RoutePoker()
{
for (const auto& [ip, gateway] : m_PokedRoutes)
net::DelRoute(ip.ToString(), gateway.ToString());
}
std::optional<huint32_t>
RoutePoker::GetDefaultGateway(const AbstractRouter& router) const
{
const auto ep = router.hiddenServiceContext().GetDefault();
const auto gateways = net::GetGatewaysNotOnInterface(ep->GetIfName());
huint32_t addr{};
if (not gateways.empty())
addr.FromString(gateways[0]);
return addr;
}
void
RoutePoker::Update(const AbstractRouter& router)
{
const auto maybe = GetDefaultGateway(router);
if (not maybe.has_value())
{
LogError("Network is down");
return;
}
const huint32_t gateway = *maybe;
if (m_CurrentGateway != gateway)
{
LogInfo("found default gateway: ", gateway);
// unpoke current routes
std::unordered_set<huint32_t> holes;
for (const auto& [ip, gw] : m_PokedRoutes)
{
// save hole
holes.emplace(ip);
// unpoke route
net::DelRoute(ip.ToString(), gw.ToString());
}
m_PokedRoutes.clear();
m_CurrentGateway = gateway;
for (const auto& ip : holes)
{
AddRoute(ip);
}
}
}
} // namespace llarp

@ -0,0 +1,31 @@
#pragma once
#include <unordered_map>
#include <string>
#include <net/net_int.hpp>
namespace llarp
{
struct AbstractRouter;
struct RoutePoker
{
void
AddRoute(huint32_t ip);
void
DelRoute(huint32_t ip);
~RoutePoker();
void
Update(const AbstractRouter& router);
private:
std::optional<huint32_t>
GetDefaultGateway(const AbstractRouter& router) const;
std::unordered_map<huint32_t, huint32_t> m_PokedRoutes;
huint32_t m_CurrentGateway;
};
} // namespace llarp

@ -333,10 +333,6 @@ namespace llarp
void
Router::Close()
{
for (const auto& [ip, gateway] : m_PokedRoutes)
{
net::DelRoute(ip, gateway);
}
if (_onDown)
_onDown();
LogInfo("closing router");
@ -770,45 +766,9 @@ namespace llarp
_linkManager.CheckPersistingSessions(now);
if (not IsServiceNode())
if (HasClientExit())
{
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);
}
}
}
m_RoutePoker.Update(*this);
}
size_t connected = NumberOfConnectedRouters();
@ -905,7 +865,7 @@ namespace llarp
RouterContact rc;
if (not nodedb()->Get(remote, rc))
return;
DelRoute(rc.addrs[0].toIpAddress().toHost());
m_RoutePoker.DelRoute(rc.addrs[0].toIpAddress().toIP());
}
void
@ -1269,31 +1229,13 @@ namespace llarp
return true;
}
std::string
Router::GetDefaultGateway() const
bool
Router::HasClientExit() const
{
if (IsServiceNode())
return false;
const auto ep = hiddenServiceContext().GetDefault();
const auto gateways = net::GetGatewaysNotOnInterface(ep->GetIfName());
if (gateways.empty())
return "";
return gateways[0];
}
void
Router::AddRoute(std::string ip)
{
m_PokedRoutes.emplace(ip, m_CurrentGateway);
net::AddRoute(ip, m_CurrentGateway);
}
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);
return ep and ep->HasExit();
}
bool
@ -1307,7 +1249,7 @@ namespace llarp
[&](llarp::RouterContact rc) {
if (IsServiceNode())
return;
AddRoute(rc.addrs[0].toIpAddress().toHost());
m_RoutePoker.AddRoute(rc.addrs[0].toIpAddress().toIP());
},
util::memFn(&Router::ConnectionEstablished, this),
util::memFn(&AbstractRouter::CheckRenegotiateValid, this),

@ -23,6 +23,7 @@
#include <router/outbound_session_maker.hpp>
#include <router/rc_gossiper.hpp>
#include <router/rc_lookup_handler.hpp>
#include <router/route_poker.hpp>
#include <routing/handler.hpp>
#include <routing/message_parser.hpp>
#include <rpc/lokid_rpc_client.hpp>
@ -260,17 +261,13 @@ namespace llarp
*/
}
std::string
GetDefaultGateway() const;
void
AddRoute(std::string ip);
void
DelRoute(std::string ip);
RoutePoker&
routePoker() override
{
return m_RoutePoker;
}
std::unordered_map<std::string, std::string> m_PokedRoutes;
std::string m_CurrentGateway;
RoutePoker m_RoutePoker;
void
PumpLL() override;
@ -403,6 +400,10 @@ namespace llarp
bool
SaveRC();
/// return true if we are a client with an exit configured
bool
HasClientExit() const;
const byte_t*
pubkey() const override
{

@ -1,5 +1,5 @@
#include "rpc_server.hpp"
#include <router/abstractrouter.hpp>
#include <router/route_poker.hpp>
#include <util/thread/logic.hpp>
#include <constants/version.hpp>
#include <nlohmann/json.hpp>
@ -167,7 +167,7 @@ namespace llarp::rpc
{
endpoint = endpoint_itr->get<std::string>();
}
LogicCall(r->logic(), [map, exit, range, token, endpoint, r, reply]() {
LogicCall(r->logic(), [map, exit, range, token, endpoint, r, reply]() mutable {
auto ep = r->hiddenServiceContext().GetEndpointByName(endpoint);
if (ep == nullptr)
{
@ -183,12 +183,18 @@ namespace llarp::rpc
}
ep->EnsurePathToService(
*exit,
[reply, ep](auto, service::OutboundContext* ctx) {
[reply, ep, r](auto, service::OutboundContext* ctx) {
if (ctx == nullptr)
{
reply(CreateJSONError("could not find exit"));
return;
}
r->ForEachPeer(
[r](auto session, auto) mutable {
const auto ip = session->GetRemoteEndpoint().toIP();
r->routePoker().AddRoute(ip);
},
false);
net::AddDefaultRouteViaInterface(ep->GetIfName());
reply(CreateJSONResponse("OK"));
},
@ -203,6 +209,13 @@ namespace llarp::rpc
else if (not map)
{
net::DelDefaultRouteViaInterface(ep->GetIfName());
r->ForEachPeer(
[r](auto session, auto) mutable {
const auto ip = session->GetRemoteEndpoint().toIP();
r->routePoker().DelRoute(ip);
},
false);
ep->UnmapExitRange(range);
}
reply(CreateJSONResponse("OK"));

@ -764,6 +764,12 @@ namespace llarp
}
};
bool
Endpoint::HasExit() const
{
return not m_ExitMap.Empty();
}
bool
Endpoint::LookupNameAsync(std::string name, std::function<void(std::optional<Address>)> handler)
{

@ -360,6 +360,9 @@ namespace llarp
uint64_t
GetSeqNoForConvo(const ConvoTag& tag);
bool
HasExit() const;
bool
SelectHop(
llarp_nodedb* db,

Loading…
Cancel
Save