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_lookup_handler.cpp
router/rc_gossiper.cpp router/rc_gossiper.cpp
router/router.cpp router/router.cpp
router/route_poker.cpp
router_contact.cpp router_contact.cpp
router_id.cpp router_id.cpp
router_version.cpp router_version.cpp

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

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

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

@ -43,6 +43,7 @@ namespace llarp
struct IOutboundSessionMaker; struct IOutboundSessionMaker;
struct ILinkManager; struct ILinkManager;
struct I_RCLookupHandler; struct I_RCLookupHandler;
struct RoutePoker;
namespace exit namespace exit
{ {
@ -156,6 +157,9 @@ namespace llarp
virtual ILinkManager& virtual ILinkManager&
linkManager() = 0; linkManager() = 0;
virtual RoutePoker&
routePoker() = 0;
virtual I_RCLookupHandler& virtual I_RCLookupHandler&
rcLookupHandler() = 0; 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 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");
@ -770,45 +766,9 @@ namespace llarp
_linkManager.CheckPersistingSessions(now); _linkManager.CheckPersistingSessions(now);
if (not IsServiceNode()) if (HasClientExit())
{ {
const auto gateway = GetDefaultGateway(); m_RoutePoker.Update(*this);
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(); size_t connected = NumberOfConnectedRouters();
@ -905,7 +865,7 @@ namespace llarp
RouterContact rc; RouterContact rc;
if (not nodedb()->Get(remote, rc)) if (not nodedb()->Get(remote, rc))
return; return;
DelRoute(rc.addrs[0].toIpAddress().toHost()); m_RoutePoker.DelRoute(rc.addrs[0].toIpAddress().toIP());
} }
void void
@ -1269,31 +1229,13 @@ namespace llarp
return true; return true;
} }
std::string bool
Router::GetDefaultGateway() const Router::HasClientExit() const
{ {
if (IsServiceNode())
return false;
const auto ep = hiddenServiceContext().GetDefault(); const auto ep = hiddenServiceContext().GetDefault();
const auto gateways = net::GetGatewaysNotOnInterface(ep->GetIfName()); return ep and ep->HasExit();
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);
} }
bool bool
@ -1307,7 +1249,7 @@ namespace llarp
[&](llarp::RouterContact rc) { [&](llarp::RouterContact rc) {
if (IsServiceNode()) if (IsServiceNode())
return; return;
AddRoute(rc.addrs[0].toIpAddress().toHost()); m_RoutePoker.AddRoute(rc.addrs[0].toIpAddress().toIP());
}, },
util::memFn(&Router::ConnectionEstablished, this), util::memFn(&Router::ConnectionEstablished, this),
util::memFn(&AbstractRouter::CheckRenegotiateValid, this), util::memFn(&AbstractRouter::CheckRenegotiateValid, this),

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

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

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

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

Loading…
Cancel
Save