mirror of https://github.com/oxen-io/lokinet
Merge pull request #1905 from majestrate/connect-out-2022-04-28
connect to routers even if we are decomissioned
This commit is contained in:
commit
0331db494e
|
@ -126,32 +126,23 @@ namespace llarp
|
|||
"provided the public-port option must also be specified.",
|
||||
},
|
||||
[this](std::string arg) {
|
||||
if (not arg.empty())
|
||||
{
|
||||
llarp::LogInfo("public ip ", arg, " size ", arg.size());
|
||||
if (arg.empty())
|
||||
return;
|
||||
nuint32_t addr{};
|
||||
if (not addr.FromString(arg))
|
||||
throw std::invalid_argument{stringify(arg, " is not a valid IPv4 address")};
|
||||
|
||||
if (arg.size() > 15)
|
||||
throw std::invalid_argument(stringify("Not a valid IPv4 addr: ", arg));
|
||||
if (IsIPv4Bogon(addr))
|
||||
throw std::invalid_argument{
|
||||
stringify(addr, " looks like it is not a publicly routable ip address")};
|
||||
|
||||
m_publicAddress.setAddress(arg);
|
||||
}
|
||||
m_PublicIP = addr;
|
||||
});
|
||||
|
||||
conf.defineOption<std::string>("router", "public-address", Hidden, [this](std::string arg) {
|
||||
if (not arg.empty())
|
||||
{
|
||||
llarp::LogWarn(
|
||||
"*** WARNING: The config option [router]:public-address=",
|
||||
arg,
|
||||
" is deprecated, use public-ip=",
|
||||
arg,
|
||||
" instead to avoid this warning and avoid future configuration problems.");
|
||||
|
||||
if (arg.size() > 15)
|
||||
throw std::invalid_argument(stringify("Not a valid IPv4 addr: ", arg));
|
||||
|
||||
m_publicAddress.setAddress(arg);
|
||||
}
|
||||
conf.defineOption<std::string>("router", "public-address", Hidden, [](std::string) {
|
||||
throw std::invalid_argument{
|
||||
"[router]:public-address option no longer supported, use [router]:public-ip and "
|
||||
"[router]:public-port instead"};
|
||||
});
|
||||
|
||||
conf.defineOption<int>(
|
||||
|
@ -166,8 +157,7 @@ namespace llarp
|
|||
[this](int arg) {
|
||||
if (arg <= 0 || arg > std::numeric_limits<uint16_t>::max())
|
||||
throw std::invalid_argument("public-port must be >= 0 and <= 65536");
|
||||
|
||||
m_publicAddress.setPort(arg);
|
||||
m_PublicPort = ToNet(huint16_t{static_cast<uint16_t>(arg)});
|
||||
});
|
||||
|
||||
conf.defineOption<int>(
|
||||
|
|
|
@ -54,7 +54,8 @@ namespace llarp
|
|||
|
||||
bool m_blockBogons = false;
|
||||
|
||||
IpAddress m_publicAddress;
|
||||
std::optional<nuint32_t> m_PublicIP;
|
||||
nuint16_t m_PublicPort;
|
||||
|
||||
int m_workerThreads = -1;
|
||||
int m_numNetThreads = -1;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <utility>
|
||||
#include <unordered_set>
|
||||
#include <llarp/router/abstractrouter.hpp>
|
||||
#include <oxenc/variant.h>
|
||||
|
||||
static constexpr auto LINK_LAYER_TICK_INTERVAL = 100ms;
|
||||
|
||||
|
@ -129,7 +130,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
ILinkLayer::Configure(AbstractRouter* router, const std::string& ifname, int af, uint16_t port)
|
||||
ILinkLayer::Configure(AbstractRouter* router, std::string ifname, int af, uint16_t port)
|
||||
{
|
||||
m_Router = router;
|
||||
m_udp = m_Router->loop()->make_udp(
|
||||
|
@ -142,11 +143,42 @@ namespace llarp
|
|||
|
||||
if (ifname == "*")
|
||||
{
|
||||
if (!AllInterfaces(af, m_ourAddr))
|
||||
if (router->IsServiceNode())
|
||||
{
|
||||
if (auto maybe = router->OurPublicIP())
|
||||
{
|
||||
auto addr = var::visit([](auto&& addr) { return SockAddr{addr}; }, *maybe);
|
||||
// service node outbound link
|
||||
if (HasInterfaceAddress(addr.getIP()))
|
||||
{
|
||||
// we have our ip claimed on a local net interface
|
||||
m_ourAddr = addr;
|
||||
}
|
||||
else if (auto maybe = net::AllInterfaces(addr))
|
||||
{
|
||||
// we do not have our claimed ip, nat or something?
|
||||
m_ourAddr = *maybe;
|
||||
}
|
||||
else
|
||||
return false; // the ultimate failure case
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (auto maybe = net::AllInterfaces(SockAddr{"0.0.0.0"}))
|
||||
{
|
||||
// client outbound link
|
||||
m_ourAddr = *maybe;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ifname == "0.0.0.0" and not GetBestNetIF(ifname))
|
||||
throw std::invalid_argument{
|
||||
"0.0.0.0 provided and we cannot find a valid ip to use, please set one "
|
||||
"explicitly instead in the bind section instead of 0.0.0.0"};
|
||||
if (const auto maybe = GetInterfaceAddr(ifname, af))
|
||||
{
|
||||
m_ourAddr = *maybe;
|
||||
|
@ -157,10 +189,11 @@ namespace llarp
|
|||
{
|
||||
m_ourAddr = SockAddr{ifname + ":0"};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
LogError(stringify("Could not use ifname ", ifname, " to configure ILinkLayer"));
|
||||
throw e;
|
||||
LogError(
|
||||
stringify("Could not use ifname ", ifname, " to configure ILinkLayer: ", ex.what()));
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace llarp
|
|||
SendTo_LL(const SockAddr& to, const llarp_buffer_t& pkt);
|
||||
|
||||
virtual bool
|
||||
Configure(AbstractRouter* loop, const std::string& ifname, int af, uint16_t port);
|
||||
Configure(AbstractRouter* loop, std::string ifname, int af, uint16_t port);
|
||||
|
||||
virtual std::shared_ptr<ILinkSession>
|
||||
NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) = 0;
|
||||
|
|
|
@ -27,6 +27,12 @@ namespace llarp
|
|||
return lhs.rank < rhs.rank || lhs.ip < rhs.ip || lhs.port < rhs.port;
|
||||
}
|
||||
|
||||
std::variant<nuint32_t, nuint128_t>
|
||||
AddressInfo::IP() const
|
||||
{
|
||||
return SockAddr{ip}.getIP();
|
||||
}
|
||||
|
||||
bool
|
||||
AddressInfo::DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <oxenc/variant.h>
|
||||
|
||||
/**
|
||||
* address_info.hpp
|
||||
*
|
||||
|
@ -47,6 +49,10 @@ namespace llarp
|
|||
void
|
||||
fromSockAddr(const SockAddr& address);
|
||||
|
||||
/// get this as an explicit v4 or explicit v6
|
||||
std::variant<nuint32_t, nuint128_t>
|
||||
IP() const;
|
||||
|
||||
std::ostream&
|
||||
print(std::ostream& stream, int level, int spaces) const;
|
||||
};
|
||||
|
|
|
@ -576,29 +576,60 @@ namespace llarp
|
|||
return addr.asIPv6();
|
||||
}
|
||||
|
||||
bool
|
||||
AllInterfaces(int af, SockAddr& result)
|
||||
namespace net
|
||||
{
|
||||
if (af == AF_INET)
|
||||
namespace
|
||||
{
|
||||
sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addr.sin_port = htons(0);
|
||||
result = SockAddr{addr};
|
||||
return true;
|
||||
}
|
||||
if (af == AF_INET6)
|
||||
SockAddr
|
||||
All(int af)
|
||||
{
|
||||
if (af == AF_INET)
|
||||
{
|
||||
sockaddr_in addr{};
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addr.sin_port = htons(0);
|
||||
return SockAddr{addr};
|
||||
}
|
||||
if (af == AF_INET6)
|
||||
{
|
||||
sockaddr_in6 addr6{};
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = htons(0);
|
||||
addr6.sin6_addr = IN6ADDR_ANY_INIT;
|
||||
return SockAddr{addr6};
|
||||
}
|
||||
throw llarp::make_exception<std::invalid_argument>(af, " is not a valid address family");
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::optional<SockAddr>
|
||||
AllInterfaces(SockAddr pub)
|
||||
{
|
||||
sockaddr_in6 addr6;
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = htons(0);
|
||||
addr6.sin6_addr = IN6ADDR_ANY_INIT;
|
||||
result = SockAddr{addr6};
|
||||
return true;
|
||||
std::optional<SockAddr> found;
|
||||
IterAllNetworkInterfaces([pub, &found](auto* ifa) {
|
||||
if (found)
|
||||
return;
|
||||
if (auto ifa_addr = ifa->ifa_addr)
|
||||
{
|
||||
if (ifa_addr->sa_family != pub.Family())
|
||||
return;
|
||||
|
||||
SockAddr addr{*ifa->ifa_addr};
|
||||
|
||||
if (addr == pub)
|
||||
found = addr;
|
||||
}
|
||||
});
|
||||
|
||||
// 0.0.0.0 is used in our compat shim as our public ip so we check for that special case
|
||||
const auto zero = IPRange::FromIPv4(0, 0, 0, 0, 8);
|
||||
// when we cannot find an address but we are looking for 0.0.0.0 just default to the old style
|
||||
if (not found and (pub.isIPv4() and zero.Contains(pub.asIPv4())))
|
||||
found = All(pub.Family());
|
||||
return found;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace net
|
||||
|
||||
#if !defined(TESTNET)
|
||||
static constexpr std::array bogonRanges_v6 = {
|
||||
|
@ -692,5 +723,20 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
bool
|
||||
HasInterfaceAddress(std::variant<nuint32_t, nuint128_t> ip)
|
||||
{
|
||||
bool found{false};
|
||||
IterAllNetworkInterfaces([ip, &found](const auto* iface) {
|
||||
if (found or iface == nullptr)
|
||||
return;
|
||||
if (auto addr = iface->ifa_addr;
|
||||
addr and (addr->sa_family == AF_INET or addr->sa_family == AF_INET6))
|
||||
{
|
||||
found = SockAddr{*iface->ifa_addr}.getIP() == ip;
|
||||
}
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
} // namespace llarp
|
||||
|
|
|
@ -52,6 +52,12 @@ namespace llarp
|
|||
bool
|
||||
IsIPv4Bogon(const huint32_t& addr);
|
||||
|
||||
inline bool
|
||||
IsIPv4Bogon(const nuint32_t& addr)
|
||||
{
|
||||
return IsIPv4Bogon(ToHost(addr));
|
||||
}
|
||||
|
||||
bool
|
||||
IsBogon(const in6_addr& addr);
|
||||
|
||||
|
@ -61,8 +67,25 @@ namespace llarp
|
|||
bool
|
||||
IsBogonRange(const in6_addr& host, const in6_addr& mask);
|
||||
|
||||
bool
|
||||
AllInterfaces(int af, SockAddr& addr);
|
||||
/// get a sock addr we can use for all interfaces given our public address
|
||||
namespace net
|
||||
{
|
||||
std::optional<SockAddr>
|
||||
AllInterfaces(SockAddr pubaddr);
|
||||
}
|
||||
|
||||
/// compat shim
|
||||
// TODO: remove me
|
||||
inline bool
|
||||
AllInterfaces(int af, SockAddr& addr)
|
||||
{
|
||||
if (auto maybe = net::AllInterfaces(SockAddr{af == AF_INET ? "0.0.0.0" : "::"}))
|
||||
{
|
||||
addr = *maybe;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// get first network interface with public address
|
||||
bool
|
||||
|
@ -92,4 +115,8 @@ namespace llarp
|
|||
}
|
||||
#endif
|
||||
|
||||
/// return true if we have a network interface with this ip
|
||||
bool
|
||||
HasInterfaceAddress(std::variant<nuint32_t, nuint128_t> ip);
|
||||
|
||||
} // namespace llarp
|
||||
|
|
|
@ -351,6 +351,14 @@ namespace llarp
|
|||
return a;
|
||||
}
|
||||
|
||||
std::variant<nuint32_t, nuint128_t>
|
||||
SockAddr::getIP() const
|
||||
{
|
||||
if (isIPv4())
|
||||
return getIPv4();
|
||||
return getIPv6();
|
||||
}
|
||||
|
||||
void
|
||||
SockAddr::setIPv4(nuint32_t ip)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <string_view>
|
||||
#include <string>
|
||||
#include "net_int.hpp"
|
||||
#include <oxenc/variant.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -81,6 +82,14 @@ namespace llarp
|
|||
std::string
|
||||
hostString() const;
|
||||
|
||||
inline int
|
||||
Family() const
|
||||
{
|
||||
if (isIPv6())
|
||||
return AF_INET6;
|
||||
return AF_INET;
|
||||
}
|
||||
|
||||
/// Returns true if this is an empty SockAddr, defined by having no IP address set. An empty IP
|
||||
/// address with a valid port is still considered empty.
|
||||
///
|
||||
|
@ -133,6 +142,8 @@ namespace llarp
|
|||
getIPv6() const;
|
||||
nuint32_t
|
||||
getIPv4() const;
|
||||
std::variant<nuint32_t, nuint128_t>
|
||||
getIP() const;
|
||||
|
||||
/// in host order
|
||||
huint128_t
|
||||
|
|
|
@ -220,6 +220,10 @@ namespace llarp
|
|||
virtual const byte_t*
|
||||
pubkey() const = 0;
|
||||
|
||||
/// get what our real public ip is if we can know it
|
||||
virtual std::optional<std::variant<nuint32_t, nuint128_t>>
|
||||
OurPublicIP() const = 0;
|
||||
|
||||
/// connect to N random routers
|
||||
virtual void
|
||||
ConnectToRandomRouters(int N) = 0;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/util/time.hpp>
|
||||
#include <optional>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -15,7 +17,7 @@ namespace llarp
|
|||
virtual bool
|
||||
GossipRC(const RouterContact& rc) = 0;
|
||||
|
||||
using Time_t = std::chrono::milliseconds;
|
||||
using Time_t = Duration_t;
|
||||
|
||||
virtual void
|
||||
Decay(Time_t now) = 0;
|
||||
|
@ -27,5 +29,17 @@ namespace llarp
|
|||
/// return true if that rc is owned by us
|
||||
virtual bool
|
||||
IsOurRC(const RouterContact& rc) const = 0;
|
||||
|
||||
/// forget the replay filter entry given pubkey
|
||||
virtual void
|
||||
Forget(const RouterID& router) = 0;
|
||||
|
||||
/// returns the time point when we will send our next gossip at
|
||||
virtual TimePoint_t
|
||||
NextGossipAt() const = 0;
|
||||
|
||||
/// returns the time point when we sent our last gossip at or nullopt if we never did
|
||||
virtual std::optional<TimePoint_t>
|
||||
LastGossipAt() const = 0;
|
||||
};
|
||||
} // namespace llarp
|
||||
|
|
|
@ -27,9 +27,7 @@ namespace llarp
|
|||
bool
|
||||
RCGossiper::ShouldGossipOurRC(Time_t now) const
|
||||
{
|
||||
bool should = now >= (m_LastGossipedOurRC + GossipOurRCInterval);
|
||||
LogWarn("ShouldGossipOurRC: ", should);
|
||||
return should;
|
||||
return now >= (m_LastGossipedOurRC + GossipOurRCInterval);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -44,6 +42,30 @@ namespace llarp
|
|||
m_Filter.Decay(now);
|
||||
}
|
||||
|
||||
void
|
||||
RCGossiper::Forget(const RouterID& pk)
|
||||
{
|
||||
m_Filter.Remove(pk);
|
||||
if (m_OurRouterID == pk)
|
||||
m_LastGossipedOurRC = 0s;
|
||||
}
|
||||
|
||||
TimePoint_t
|
||||
RCGossiper::NextGossipAt() const
|
||||
{
|
||||
if (auto maybe = LastGossipAt())
|
||||
return *maybe + GossipOurRCInterval;
|
||||
return DateClock_t::now();
|
||||
}
|
||||
|
||||
std::optional<TimePoint_t>
|
||||
RCGossiper::LastGossipAt() const
|
||||
{
|
||||
if (m_LastGossipedOurRC == 0s)
|
||||
return std::nullopt;
|
||||
return DateClock_t::time_point{m_LastGossipedOurRC};
|
||||
}
|
||||
|
||||
bool
|
||||
RCGossiper::GossipRC(const RouterContact& rc)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,15 @@ namespace llarp
|
|||
void
|
||||
Init(ILinkManager*, const RouterID&, AbstractRouter*);
|
||||
|
||||
void
|
||||
Forget(const RouterID& router) override;
|
||||
|
||||
TimePoint_t
|
||||
NextGossipAt() const override;
|
||||
|
||||
std::optional<TimePoint_t>
|
||||
LastGossipAt() const override;
|
||||
|
||||
private:
|
||||
RouterID m_OurRouterID;
|
||||
Time_t m_LastGossipedOurRC = 0s;
|
||||
|
|
|
@ -415,9 +415,6 @@ namespace llarp
|
|||
if (!FromConfig(conf))
|
||||
throw std::runtime_error("FromConfig() failed");
|
||||
|
||||
if (!InitOutboundLinks())
|
||||
throw std::runtime_error("InitOutboundLinks() failed");
|
||||
|
||||
if (not EnsureIdentity())
|
||||
throw std::runtime_error("EnsureIdentity() failed");
|
||||
|
||||
|
@ -479,6 +476,25 @@ namespace llarp
|
|||
and _rcLookupHandler.IsGreylisted(pubkey());
|
||||
}
|
||||
|
||||
bool
|
||||
Router::LooksDeregistered() const
|
||||
{
|
||||
return IsServiceNode() and whitelistRouters and _rcLookupHandler.HaveReceivedWhitelist()
|
||||
and not _rcLookupHandler.SessionIsAllowed(pubkey());
|
||||
}
|
||||
|
||||
bool
|
||||
Router::ShouldTestOtherRouters() const
|
||||
{
|
||||
if (not IsServiceNode())
|
||||
return false;
|
||||
if (not whitelistRouters)
|
||||
return true;
|
||||
if (not _rcLookupHandler.HaveReceivedWhitelist())
|
||||
return false;
|
||||
return _rcLookupHandler.SessionIsAllowed(pubkey());
|
||||
}
|
||||
|
||||
bool
|
||||
Router::SessionToRouterAllowed(const RouterID& router) const
|
||||
{
|
||||
|
@ -577,8 +593,8 @@ namespace llarp
|
|||
transport_keyfile = m_keyManager->m_transportKeyPath;
|
||||
ident_keyfile = m_keyManager->m_idKeyPath;
|
||||
|
||||
if (not conf.router.m_publicAddress.isEmpty())
|
||||
_ourAddress = conf.router.m_publicAddress.createSockAddr();
|
||||
if (auto maybe = conf.router.m_PublicIP)
|
||||
_ourAddress = SockAddr{*maybe, conf.router.m_PublicPort};
|
||||
|
||||
RouterContact::BlockBogons = conf.router.m_blockBogons;
|
||||
|
||||
|
@ -709,14 +725,15 @@ namespace llarp
|
|||
|
||||
if (inboundLinks.empty() and m_isServiceNode)
|
||||
{
|
||||
const auto& publicAddr = conf.router.m_publicAddress;
|
||||
if (publicAddr.isEmpty() or not publicAddr.hasPort())
|
||||
if (_ourAddress)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"service node enabled but could not find a public IP to bind to; you need to set the "
|
||||
"public-ip= and public-port= options");
|
||||
inboundLinks.push_back(LinksConfig::LinkInfo{
|
||||
_ourAddress->hostString(), _ourAddress->Family(), _ourAddress->getPort()});
|
||||
}
|
||||
inboundLinks.push_back(LinksConfig::LinkInfo{"0.0.0.0", AF_INET, *publicAddr.getPort()});
|
||||
else
|
||||
throw std::runtime_error{
|
||||
"service node enabled but could not find a public IP to bind to; you need to set the "
|
||||
"public-ip= and public-port= options"};
|
||||
}
|
||||
|
||||
// create inbound links, if we are a service node
|
||||
|
@ -850,7 +867,17 @@ namespace llarp
|
|||
ss << " snode | known/svc/clients: " << nodedb()->NumLoaded() << "/"
|
||||
<< NumberOfConnectedRouters() << "/" << NumberOfConnectedClients() << " | "
|
||||
<< pathContext().CurrentTransitPaths() << " active paths | "
|
||||
<< "block " << (m_lokidRpcClient ? m_lokidRpcClient->BlockHeight() : 0);
|
||||
<< "block " << (m_lokidRpcClient ? m_lokidRpcClient->BlockHeight() : 0) << " | gossip: "
|
||||
<< "(next/last) " << time_delta<std::chrono::seconds>{_rcGossiper.NextGossipAt()}
|
||||
<< " / ";
|
||||
if (auto maybe = _rcGossiper.LastGossipAt())
|
||||
{
|
||||
ss << time_delta<std::chrono::seconds>{*maybe};
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "never";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -889,15 +916,24 @@ namespace llarp
|
|||
const bool gotWhitelist = _rcLookupHandler.HaveReceivedWhitelist();
|
||||
const bool isSvcNode = IsServiceNode();
|
||||
const bool decom = LooksDecommissioned();
|
||||
bool shouldGossip = isSvcNode and whitelistRouters and gotWhitelist
|
||||
and _rcLookupHandler.SessionIsAllowed(pubkey());
|
||||
|
||||
if (_rc.ExpiresSoon(now, std::chrono::milliseconds(randint() % 10000))
|
||||
|| (now - _rc.last_updated) > rcRegenInterval)
|
||||
if (isSvcNode
|
||||
and (_rc.ExpiresSoon(now, std::chrono::milliseconds(randint() % 10000)) or (now - _rc.last_updated) > rcRegenInterval))
|
||||
{
|
||||
LogInfo("regenerating RC");
|
||||
if (!UpdateOurRC(false))
|
||||
LogError("Failed to update our RC");
|
||||
if (UpdateOurRC())
|
||||
{
|
||||
// our rc changed so we should gossip it
|
||||
shouldGossip = true;
|
||||
// remove our replay entry so it goes out
|
||||
_rcGossiper.Forget(pubkey());
|
||||
}
|
||||
else
|
||||
LogError("failed to update our RC");
|
||||
}
|
||||
else if (whitelistRouters and gotWhitelist and _rcLookupHandler.SessionIsAllowed(pubkey()))
|
||||
if (shouldGossip)
|
||||
{
|
||||
// if we have the whitelist enabled, we have fetched the list and we are in either
|
||||
// the white or grey list, we want to gossip our RC
|
||||
|
@ -982,17 +1018,19 @@ namespace llarp
|
|||
connectToNum = strictConnect;
|
||||
}
|
||||
|
||||
if (decom)
|
||||
if (auto dereg = LooksDeregistered(); (dereg or decom) and now >= m_NextDecommissionWarn)
|
||||
{
|
||||
// complain about being deregistered
|
||||
if (now >= m_NextDecommissionWarn)
|
||||
{
|
||||
constexpr auto DecommissionWarnInterval = 30s;
|
||||
LogError("We are running as a service node but we seem to be decommissioned");
|
||||
m_NextDecommissionWarn = now + DecommissionWarnInterval;
|
||||
}
|
||||
constexpr auto DecommissionWarnInterval = 30s;
|
||||
LogError(
|
||||
"We are running as a service node but we seem to be ",
|
||||
dereg ? "deregistered" : "decommissioned");
|
||||
m_NextDecommissionWarn = now + DecommissionWarnInterval;
|
||||
}
|
||||
else if (connected < connectToNum)
|
||||
|
||||
// if we need more sessions to routers and we are not a service node kicked from the network
|
||||
// we shall connect out to others
|
||||
if (connected < connectToNum and not LooksDeregistered())
|
||||
{
|
||||
size_t dlt = connectToNum - connected;
|
||||
LogDebug("connecting to ", dlt, " random routers to keep alive");
|
||||
|
@ -1013,7 +1051,8 @@ namespace llarp
|
|||
if (m_peerDb)
|
||||
{
|
||||
// TODO: throttle this?
|
||||
// TODO: need to capture session stats when session terminates / is removed from link manager
|
||||
// TODO: need to capture session stats when session terminates / is removed from link
|
||||
// manager
|
||||
_linkManager.updatePeerDb(m_peerDb);
|
||||
|
||||
if (m_peerDb->shouldFlush(now))
|
||||
|
@ -1212,6 +1251,12 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
|
||||
if (not InitOutboundLinks())
|
||||
{
|
||||
LogError("failed to init outbound links");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsServiceNode())
|
||||
{
|
||||
if (!SaveRC())
|
||||
|
@ -1293,8 +1338,10 @@ namespace llarp
|
|||
// dont run tests if we are not running or we are stopping
|
||||
if (not _running)
|
||||
return;
|
||||
// dont run tests if we are decommissioned
|
||||
if (LooksDecommissioned())
|
||||
// dont run tests if we think we should not test other routers
|
||||
// this occurs when we are deregistered or do not have the service node list
|
||||
// yet when we expect to have one.
|
||||
if (not ShouldTestOtherRouters())
|
||||
return;
|
||||
auto tests = m_routerTesting.get_failing();
|
||||
if (auto maybe = m_routerTesting.next_random(this))
|
||||
|
@ -1520,6 +1567,22 @@ namespace llarp
|
|||
return ep and ep->HasExit();
|
||||
}
|
||||
|
||||
std::optional<std::variant<nuint32_t, nuint128_t>>
|
||||
Router::OurPublicIP() const
|
||||
{
|
||||
if (_ourAddress)
|
||||
return _ourAddress->getIP();
|
||||
std::optional<std::variant<nuint32_t, nuint128_t>> found;
|
||||
_linkManager.ForEachInboundLink([&found](const auto& link) {
|
||||
if (found)
|
||||
return;
|
||||
AddressInfo ai;
|
||||
if (link->GetOurAddressInfo(ai))
|
||||
found = ai.IP();
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
Router::InitOutboundLinks()
|
||||
{
|
||||
|
|
|
@ -102,6 +102,9 @@ namespace llarp
|
|||
return _dht;
|
||||
}
|
||||
|
||||
std::optional<std::variant<nuint32_t, nuint128_t>>
|
||||
OurPublicIP() const override;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const override;
|
||||
|
||||
|
@ -197,6 +200,14 @@ namespace llarp
|
|||
bool
|
||||
LooksDecommissioned() const;
|
||||
|
||||
/// return true if we look like we are a deregistered service node
|
||||
bool
|
||||
LooksDeregistered() const;
|
||||
|
||||
/// return true if we look like we are allowed and able to test other routers
|
||||
bool
|
||||
ShouldTestOtherRouters() const;
|
||||
|
||||
std::optional<SockAddr> _ourAddress;
|
||||
|
||||
EventLoop_ptr _loop;
|
||||
|
|
|
@ -72,6 +72,12 @@ namespace llarp
|
|||
m_CacheInterval = interval;
|
||||
}
|
||||
|
||||
void
|
||||
Remove(const Val_t& val)
|
||||
{
|
||||
m_Values.erase(val);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Predicate_t>
|
||||
void
|
||||
|
|
|
@ -35,6 +35,17 @@ namespace llarp
|
|||
return o.str();
|
||||
}
|
||||
|
||||
/// util for constructing an exception with a message constructed from a set of whatever passed
|
||||
/// into stringify
|
||||
/// E must be derived from std::exception here
|
||||
template <typename E, typename... T>
|
||||
E
|
||||
make_exception(T&&... stuff)
|
||||
{
|
||||
static_assert(std::is_base_of_v<std::exception, E>);
|
||||
return E{stringify(std::forward<T>(stuff)...)};
|
||||
}
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
/// Returns true if the first string is equal to the second string, compared case-insensitively.
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
#include "time.hpp"
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
using Clock_t = std::chrono::system_clock;
|
||||
|
||||
template <typename Res, typename Clock>
|
||||
static Duration_t
|
||||
time_since_epoch(std::chrono::time_point<Clock> point)
|
||||
namespace
|
||||
{
|
||||
return std::chrono::duration_cast<Res>(point.time_since_epoch());
|
||||
}
|
||||
using Clock_t = std::chrono::system_clock;
|
||||
|
||||
const static auto started_at_system = Clock_t::now();
|
||||
template <typename Res, typename Clock>
|
||||
static Duration_t
|
||||
time_since_epoch(std::chrono::time_point<Clock> point)
|
||||
{
|
||||
return std::chrono::duration_cast<Res>(point.time_since_epoch());
|
||||
}
|
||||
|
||||
const static auto started_at_steady = std::chrono::steady_clock::now();
|
||||
const static auto started_at_system = Clock_t::now();
|
||||
|
||||
const static auto started_at_steady = std::chrono::steady_clock::now();
|
||||
} // namespace
|
||||
|
||||
uint64_t
|
||||
ToMS(Duration_t ms)
|
||||
|
@ -74,4 +78,11 @@ namespace llarp
|
|||
out.fill(old_fill);
|
||||
return out << "s";
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& out, const TimePoint_t& tp)
|
||||
{
|
||||
auto t = TimePoint_t::clock::to_time_t(tp);
|
||||
return out << std::put_time(std::localtime(&t), "%c %Z");
|
||||
}
|
||||
} // namespace llarp
|
||||
|
|
|
@ -26,4 +26,36 @@ namespace llarp
|
|||
nlohmann::json
|
||||
to_json(const Duration_t& t);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& out, const TimePoint_t& t);
|
||||
|
||||
template <typename Time_Duration>
|
||||
struct time_delta
|
||||
{
|
||||
const TimePoint_t at;
|
||||
|
||||
std::ostream&
|
||||
operator()(std::ostream& out) const
|
||||
{
|
||||
const auto dlt = std::chrono::duration_cast<Time_Duration>(TimePoint_t::clock::now() - at);
|
||||
if (dlt > 0s)
|
||||
return out << std::chrono::duration_cast<Duration_t>(dlt) << " ago ";
|
||||
else if (dlt < 0s)
|
||||
return out << "in " << std::chrono::duration_cast<Duration_t>(-dlt);
|
||||
else
|
||||
return out << "now";
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, const time_delta<std::chrono::seconds>& td)
|
||||
{
|
||||
return td(out);
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, const time_delta<std::chrono::milliseconds>& td)
|
||||
{
|
||||
return td(out);
|
||||
}
|
||||
} // namespace llarp
|
||||
|
|
|
@ -14,6 +14,9 @@ namespace llarp
|
|||
/// convert to milliseconds
|
||||
uint64_t
|
||||
ToMS(Duration_t duration);
|
||||
|
||||
using DateClock_t = std::chrono::system_clock;
|
||||
using TimePoint_t = DateClock_t::time_point;
|
||||
} // namespace llarp
|
||||
|
||||
using llarp_time_t = llarp::Duration_t;
|
||||
|
|
|
@ -39,11 +39,6 @@ namespace llarp
|
|||
[](RouterConfig& self) { return self.m_dataDir.c_str(); },
|
||||
[](RouterConfig& self, std::string dir) { self.m_dataDir = dir; })
|
||||
.def_readwrite("blockBogons", &RouterConfig::m_blockBogons)
|
||||
.def(
|
||||
"overrideAddress",
|
||||
[](RouterConfig& self, std::string addr) {
|
||||
self.m_publicAddress = llarp::IpAddress(addr);
|
||||
})
|
||||
.def_readwrite("workerThreads", &RouterConfig::m_workerThreads)
|
||||
.def_readwrite("numNetThreads", &RouterConfig::m_numNetThreads)
|
||||
.def_readwrite("JobQueueSize", &RouterConfig::m_JobQueueSize);
|
||||
|
|
Loading…
Reference in New Issue