Merge branch 'route-poker-bugfix-duplicate-removals' into dev

dev
jeff (codeaholic) 2 weeks ago
commit 8aaba44b16
Signed by: jeff
GPG Key ID: 025C02EE3A092F2D

@ -94,7 +94,20 @@ namespace llarp::platform
/// are we a mobile phone ?
inline constexpr bool is_mobile = is_android or is_iphone;
/// does this platform support native ipv6 ?
// TODO: make windows support ipv6
inline constexpr bool supports_ipv6 = not is_windows;
/// every platform is a special snowflake.
/// we document every single workaround for their excentricities here.
namespace quarks
{
/// this is set to true on all platforms were we cannot enable a route when we have duplicate
/// gateways
inline constexpr bool duplicate_gateways_routes_fail = llarp::platform::is_windows;
/// set to true on platforms we cannot do os level ipv6 with tunneling.
inline constexpr bool disable_ipv6 = is_windows or is_android;
} // namespace quarks
/// compat value, lokinet is ipv6 inside.
inline constexpr bool supports_ipv6 = not quarks::disable_ipv6;
} // namespace llarp::platform

@ -4,6 +4,7 @@
#include <llarp/service/context.hpp>
#include <llarp/dns/platform.hpp>
#include <unordered_set>
#include <llarp/constants/platform.hpp>
namespace llarp
{
@ -12,23 +13,12 @@ namespace llarp
void
RoutePoker::AddRoute(net::ipv4addr_t ip)
{
if (not m_up)
return;
bool has_existing = m_PokedRoutes.count(ip);
// set up route and apply as needed
auto& gw = m_PokedRoutes[ip];
if (m_CurrentGateway)
{
// remove existing mapping as needed
if (has_existing)
DisableRoute(ip, gw);
// update and add new mapping
gw = *m_CurrentGateway;
log::info(logcat, "add route {} via {}", ip, gw);
EnableRoute(ip, gw);
}
else
gw = net::ipv4addr_t{};
auto [itr, inserted] =
m_PokedRoutes.try_emplace(ip, m_CurrentGateway.value_or(net::ipv4addr_t{}), 0);
if (inserted)
EnableRoute(itr->first, std::get<0>(itr->second));
std::get<1>(itr->second) += 1;
}
void
@ -36,6 +26,7 @@ namespace llarp
{
if (ip.n and gateway.n and IsEnabled())
{
log::info(logcat, "delete route {} via {}", ip, gateway);
vpn::IRouteManager& route = m_Router->GetVPNPlatform()->RouteManager();
route.DelRoute(ip, gateway);
}
@ -46,6 +37,7 @@ namespace llarp
{
if (ip.n and gateway.n and IsEnabled())
{
log::info(logcat, "add route {} via {}", ip, gateway);
vpn::IRouteManager& route = m_Router->GetVPNPlatform()->RouteManager();
route.AddRoute(ip, gateway);
}
@ -54,11 +46,19 @@ namespace llarp
void
RoutePoker::DelRoute(net::ipv4addr_t ip)
{
const auto itr = m_PokedRoutes.find(ip);
auto itr = m_PokedRoutes.find(ip);
if (itr == m_PokedRoutes.end())
return;
log::info(logcat, "del route {} via {}", itr->first, itr->second);
DisableRoute(itr->first, itr->second);
auto& [gw, refs] = itr->second;
// decrement reference count and then early return if we have uses still.
--refs;
if (refs)
return;
// unamp route if we have no uses of it left.
DisableRoute(ip, gw);
m_PokedRoutes.erase(itr);
}
@ -76,27 +76,34 @@ namespace llarp
}
void
RoutePoker::DeleteAllRoutes()
RoutePoker::RefreshAllRoutes()
{
// DelRoute will check enabled, so no need here
for (const auto& item : m_PokedRoutes)
DelRoute(item.first);
}
if (not m_CurrentGateway)
return;
void
RoutePoker::DisableAllRoutes()
{
for (const auto& [ip, gateway] : m_PokedRoutes)
const auto& current_gw = *m_CurrentGateway;
for (auto& [ip, entry] : m_PokedRoutes)
{
DisableRoute(ip, gateway);
}
}
auto& gw = std::get<0>(entry);
if (gw != current_gw)
{
if constexpr (not llarp::platform::quarks::duplicate_gateways_routes_fail)
{
// normal behavior
EnableRoute(ip, current_gw);
DisableRoute(ip, gw);
}
else
{
// reverse order because platform quark
DisableRoute(ip, gw);
EnableRoute(ip, current_gw);
}
void
RoutePoker::RefreshAllRoutes()
{
for (const auto& item : m_PokedRoutes)
AddRoute(item.first);
gw = current_gw;
}
}
}
RoutePoker::~RoutePoker()
@ -105,10 +112,12 @@ namespace llarp
return;
auto& route = m_Router->GetVPNPlatform()->RouteManager();
for (const auto& [ip, gateway] : m_PokedRoutes)
for (const auto& [ip, entry] : m_PokedRoutes)
{
if (gateway.n and ip.n)
route.DelRoute(ip, gateway);
const auto& gw = std::get<0>(entry);
if (gw.n and ip.n)
route.DelRoute(ip, gw);
}
route.DelBlackhole();
}
@ -179,9 +188,11 @@ namespace llarp
{
log::info(logcat, "default gateway found at {}", *next_gw);
m_CurrentGateway = next_gw;
if (not m_PokedRoutes.empty())
RefreshAllRoutes();
}
}
else if (m_Router->HasClientExit())
if (m_Router->HasClientExit())
Up();
}

@ -12,9 +12,16 @@ namespace llarp
struct RoutePoker : public std::enable_shared_from_this<RoutePoker>
{
/// add a route exception to an edge by ip
/// if we have a default gateway and our routes are set to be "up" we will enable this route.
/// if there is an existing entry for this ip, we increment a reference counter and keep the
/// route previously added in.
void
AddRoute(net::ipv4addr_t ip);
/// remove a route exception to an edge by ip.
/// decrements the number of edges that use this ip. when the reference counter hits zero and we
/// are "up" we unmap the route.
void
DelRoute(net::ipv4addr_t ip);
@ -43,12 +50,6 @@ namespace llarp
bool
IsEnabled() const;
void
DeleteAllRoutes();
void
DisableAllRoutes();
void
RefreshAllRoutes();
@ -58,7 +59,7 @@ namespace llarp
void
DisableRoute(net::ipv4addr_t ip, net::ipv4addr_t gateway);
std::unordered_map<net::ipv4addr_t, net::ipv4addr_t> m_PokedRoutes;
std::unordered_map<net::ipv4addr_t, std::tuple<net::ipv4addr_t, int>> m_PokedRoutes;
std::optional<net::ipv4addr_t> m_CurrentGateway;

Loading…
Cancel
Save