Merge pull request #1532 from majestrate/network-thaw-2021-02-08

thaw network when default gateway changes
pull/1544/head
Jeff 3 years ago committed by GitHub
commit 0c869600df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -279,6 +279,7 @@ run_main_context(std::optional<fs::path> confFile, const llarp::RuntimeOptions o
signal(SIGTERM, handle_signal);
#ifndef _WIN32
signal(SIGHUP, handle_signal);
signal(SIGUSR1, handle_signal);
#endif
ctx->Setup(opts);

@ -86,6 +86,16 @@ namespace llarp
return *itr;
}
void
Proxy::Restart()
{
if (m_UnboundResolver)
{
LogInfo("reset libunbound's internal stuff");
m_UnboundResolver->Init();
}
}
bool
Proxy::SetupUnboundResolver(const std::vector<IpAddress>& resolvers)
{

@ -43,6 +43,9 @@ namespace llarp
void
Stop();
void
Restart();
using Buffer_t = std::vector<uint8_t>;
private:

@ -76,6 +76,13 @@ namespace llarp
return obj;
}
void
TunEndpoint::Thaw()
{
if (m_Resolver)
m_Resolver->Restart();
}
bool
TunEndpoint::Configure(const NetworkConfig& conf, const DnsConfig& dnsConf)
{

@ -31,6 +31,9 @@ namespace llarp
return shared_from_this();
}
void
Thaw() override;
bool
Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) override;

@ -70,6 +70,9 @@ namespace llarp
virtual void
ForEachInboundLink(std::function<void(LinkLayer_ptr)> visit) const = 0;
virtual void
ForEachOutboundLink(std::function<void(LinkLayer_ptr)> visit) const = 0;
/// close all connections to this peer
/// remove all link layer commits
virtual void

@ -225,6 +225,15 @@ namespace llarp
}
}
void
LinkManager::ForEachOutboundLink(std::function<void(LinkLayer_ptr)> visit) const
{
for (const auto& link : outboundLinks)
{
visit(link);
}
}
size_t
LinkManager::NumberOfConnectedRouters() const
{

@ -65,6 +65,9 @@ namespace llarp
void
ForEachInboundLink(std::function<void(LinkLayer_ptr)> visit) const override;
void
ForEachOutboundLink(std::function<void(LinkLayer_ptr)> visit) const override;
size_t
NumberOfConnectedRouters() const override;

@ -407,17 +407,20 @@ namespace llarp
{
static constexpr auto CloseGraceWindow = 500ms;
const auto now = Now();
Lock_t l(m_AuthedLinksMutex);
RouterID r = remote;
llarp::LogInfo("Closing all to ", r);
auto range = m_AuthedLinks.equal_range(r);
auto itr = range.first;
while (itr != range.second)
{
itr->second->Close();
m_RecentlyClosed.emplace(itr->second->GetRemoteEndpoint(), now + CloseGraceWindow);
itr = m_AuthedLinks.erase(itr);
Lock_t l(m_AuthedLinksMutex);
RouterID r = remote;
llarp::LogInfo("Closing all to ", r);
auto range = m_AuthedLinks.equal_range(r);
auto itr = range.first;
while (itr != range.second)
{
itr->second->Close();
m_RecentlyClosed.emplace(itr->second->GetRemoteEndpoint(), now + CloseGraceWindow);
itr = m_AuthedLinks.erase(itr);
}
}
SessionClosed(remote);
}
void

@ -198,6 +198,10 @@ namespace llarp
virtual void
Stop() = 0;
/// thaw from long sleep or network changed event
virtual void
Thaw() = 0;
/// non gracefully stop the router
virtual void
Die() = 0;

@ -9,7 +9,7 @@ namespace llarp
void
RoutePoker::AddRoute(huint32_t ip)
{
m_PokedRoutes.emplace(ip, m_CurrentGateway);
m_PokedRoutes[ip] = m_CurrentGateway;
if (m_CurrentGateway.h == 0)
{
llarp::LogDebug("RoutePoker::AddRoute no current gateway, cannot enable route.");
@ -44,10 +44,10 @@ namespace llarp
const auto itr = m_PokedRoutes.find(ip);
if (itr == m_PokedRoutes.end())
return;
m_PokedRoutes.erase(itr);
if (m_Enabled)
DisableRoute(itr->first, itr->second);
m_PokedRoutes.erase(itr);
}
void
@ -115,23 +115,35 @@ namespace llarp
if (not m_Router)
throw std::runtime_error("Attempting to use RoutePoker before calling Init");
// check for network
const auto maybe = GetDefaultGateway();
if (not maybe.has_value())
{
LogError("Network is down");
// mark network lost
m_HasNetwork = false;
return;
}
const huint32_t gateway = *maybe;
if (m_CurrentGateway != gateway or m_Enabling)
const bool gatewayChanged = m_CurrentGateway.h != 0 and m_CurrentGateway != gateway;
if (m_CurrentGateway != gateway)
{
LogInfo("found default gateway: ", gateway);
m_CurrentGateway = gateway;
if (not m_Enabling) // if route was already set up
DisableAllRoutes();
EnableAllRoutes();
Up();
if (m_Enabling)
{
EnableAllRoutes();
Up();
}
}
// revive network connectitivity on gateway change or network wakeup
if (gatewayChanged or not m_HasNetwork)
{
LogInfo("our network changed, thawing router state");
m_Router->Thaw();
m_HasNetwork = true;
}
}
@ -154,6 +166,7 @@ namespace llarp
return;
DisableAllRoutes();
m_Enabled = false;
}
void

@ -69,5 +69,7 @@ namespace llarp
bool m_Enabling = false;
AbstractRouter* m_Router = nullptr;
bool m_HasNetwork = true;
};
} // namespace llarp

@ -121,6 +121,30 @@ namespace llarp
return inbound_link_msg_parser.ProcessFrom(session, buf);
}
void
Router::Thaw()
{
// get pubkeys we are connected to
std::unordered_set<RouterID> peerPubkeys;
linkManager().ForEachPeer([&peerPubkeys](auto peer) {
if (not peer)
return;
peerPubkeys.emplace(peer->GetPubKey());
});
// close our sessions to them on link layer
linkManager().ForEachOutboundLink([peerPubkeys](const auto& link) {
for (const auto& remote : peerPubkeys)
link->CloseSessionTo(remote);
});
// thaw endpoints
hiddenServiceContext().ForEachService([](const auto& name, const auto& ep) -> bool {
LogInfo(name, " thawing...");
ep->Thaw();
return true;
});
LogInfo("We are ready to go bruh... probably");
}
void
Router::PersistSessionUntil(const RouterID& remote, llarp_time_t until)
{
@ -802,13 +826,18 @@ namespace llarp
_linkManager.CheckPersistingSessions(now);
if (HasClientExit())
if (not isSvcNode)
{
m_RoutePoker.Enable();
if (HasClientExit())
{
m_RoutePoker.Enable();
}
else
{
m_RoutePoker.Disable();
}
m_RoutePoker.Update();
}
else
m_RoutePoker.Disable();
size_t connected = NumberOfConnectedRouters();
if (not isSvcNode)

@ -363,6 +363,9 @@ namespace llarp
bool
StartRpcServer() override;
void
Thaw() override;
bool
Run() override;

@ -1367,6 +1367,23 @@ namespace llarp
return false;
}
std::optional<ConvoTag>
Endpoint::GetBestConvoTagForService(Address remote) const
{
llarp_time_t time = 0s;
std::optional<ConvoTag> ret = std::nullopt;
// get convotag with higest timestamp
for (const auto& [tag, session] : Sessions())
{
if (session.remote.Addr() == remote and session.lastUsed > time)
{
time = session.lastUsed;
ret = tag;
}
}
return ret;
}
bool
Endpoint::SendToServiceOrQueue(
const service::Address& remote, const llarp_buffer_t& data, ProtocolType t)
@ -1382,44 +1399,37 @@ namespace llarp
ProtocolFrame& f = transfer->T;
f.R = 0;
std::shared_ptr<path::Path> p;
std::set<ConvoTag> tags;
if (GetConvoTagsForService(remote, tags))
if (const auto maybe = GetBestConvoTagForService(remote))
{
// the remote guy's intro
Introduction remoteIntro;
Introduction replyPath;
SharedSecret K;
// pick tag
for (const auto& tag : tags)
{
if (tag.IsZero())
continue;
if (!GetCachedSessionKeyFor(tag, K))
continue;
if (!GetReplyIntroFor(tag, replyPath))
continue;
if (!GetIntroFor(tag, remoteIntro))
continue;
// get path for intro
ForEachPath([&](path::Path_ptr path) {
if (path->intro == replyPath)
{
p = path;
return;
}
if (p && p->ExpiresSoon(now) && path->IsReady()
&& path->intro.router == replyPath.router)
{
p = path;
}
});
if (p)
const auto tag = *maybe;
if (!GetCachedSessionKeyFor(tag, K))
return false;
if (!GetReplyIntroFor(tag, replyPath))
return false;
if (!GetIntroFor(tag, remoteIntro))
return false;
// get path for intro
ForEachPath([&](path::Path_ptr path) {
if (path->intro == replyPath)
{
f.T = tag;
p = path;
return;
}
}
if (p && p->ExpiresSoon(now) && path->IsReady()
&& path->intro.router == replyPath.router)
{
p = path;
}
});
if (p)
{
f.T = tag;
// TODO: check expiration of our end
auto m = std::make_shared<ProtocolMessage>(f.T);
m->PutBuffer(data);

@ -112,6 +112,9 @@ namespace llarp
virtual std::string
GetIfName() const = 0;
std::optional<ConvoTag>
GetBestConvoTagForService(Address addr) const;
/// inject vpn io
/// return false if not supported
virtual bool
@ -127,6 +130,9 @@ namespace llarp
return {0};
}
virtual void
Thaw(){};
void
ResetInternalState() override;

Loading…
Cancel
Save