|
|
|
@ -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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|