mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-15 12:13:24 +00:00
C++ version, clang-format
- C++ bumped 17 -> 20 - clang-format (plus all clangs) -> 17
This commit is contained in:
parent
b7b93981fe
commit
8cc152a3c0
@ -1,29 +1,19 @@
|
||||
BasedOnStyle: Google
|
||||
|
||||
# alignment
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: 'false'
|
||||
AlignConsecutiveDeclarations: 'false'
|
||||
AlignEscapedNewlinesLeft: 'true'
|
||||
AlignOperands: 'false'
|
||||
AlignTrailingComments: 'true'
|
||||
AllowShortBlocksOnASingleLine: 'false'
|
||||
AllowShortCaseLabelsOnASingleLine: 'false'
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: 'false'
|
||||
AllowShortLoopsOnASingleLine: 'false'
|
||||
ColumnLimit: 120
|
||||
KeepEmptyLinesAtTheStartOfBlocks: 'false'
|
||||
NamespaceIndentation: All
|
||||
PenaltyBreakString: '3'
|
||||
SortIncludes: CaseInsensitive
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpacesInAngles: 'false'
|
||||
SpacesInContainerLiterals: 'false'
|
||||
SpacesInParentheses: 'false'
|
||||
SpacesInSquareBrackets: 'false'
|
||||
Standard: Cpp11
|
||||
UseTab: Never
|
||||
PointerAlignment: Left
|
||||
QualifierAlignment: Custom
|
||||
QualifierOrder: ['inline', 'static', 'constexpr', 'const', 'type']
|
||||
|
||||
# bracing
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
@ -46,20 +36,34 @@ AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakTemplateDeclarations: 'true'
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: 'true'
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
|
||||
# indent width
|
||||
IndentWidth: 4
|
||||
# indentation
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
IndentWidth: 4
|
||||
NamespaceIndentation: All
|
||||
|
||||
# treat pointers and reference declarations as if part of the type
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
# shorties
|
||||
AllowShortBlocksOnASingleLine: 'false'
|
||||
AllowShortCaseLabelsOnASingleLine: 'false'
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: 'false'
|
||||
AllowShortLoopsOnASingleLine: 'false'
|
||||
|
||||
# when wrapping function calls/declarations, force each parameter to have its own line
|
||||
# spacing
|
||||
KeepEmptyLinesAtTheStartOfBlocks: 'false'
|
||||
PenaltyBreakString: '3'
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpacesInAngles: 'false'
|
||||
SpacesInContainerLiterals: 'false'
|
||||
SpacesInParentheses: 'false'
|
||||
SpacesInSquareBrackets: 'false'
|
||||
Standard: Cpp11
|
||||
UseTab: Never
|
||||
|
||||
# wrapping
|
||||
PackConstructorInitializers: NextLine
|
||||
BinPackParameters: 'false'
|
||||
BinPackArguments: 'false'
|
||||
@ -70,6 +74,7 @@ BinPackArguments: 'false'
|
||||
# - Absolute path includes in angle brackets
|
||||
# - External dependencies
|
||||
# - System dependencies
|
||||
SortIncludes: CaseInsensitive
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '".+\.h'
|
||||
|
@ -384,7 +384,7 @@ local docs_pipeline(name, image, extra_cmds=[], allow_fail=false) = {
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
apt_get_quiet + ' update',
|
||||
apt_get_quiet + ' install -y eatmydata',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y git clang-format-15 jsonnet',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y git clang-format-17 jsonnet',
|
||||
'./contrib/ci/drone-format-verify.sh',
|
||||
],
|
||||
}],
|
||||
|
@ -104,7 +104,7 @@ option(WARN_DEPRECATED "show deprecation warnings" OFF)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CheckLibraryExists)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
CLANG_FORMAT_DESIRED_VERSION=15
|
||||
CLANG_FORMAT_DESIRED_VERSION=17
|
||||
|
||||
CLANG_FORMAT=$(command -v clang-format-$CLANG_FORMAT_DESIRED_VERSION 2>/dev/null)
|
||||
if [ $? -ne 0 ]; then
|
||||
|
@ -256,8 +256,8 @@ namespace
|
||||
/// will make a coredump when there is an unhandled exception
|
||||
LONG GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
|
||||
{
|
||||
const auto flags =
|
||||
(MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithFullMemoryInfo | MiniDumpWithHandleData | MiniDumpWithUnloadedModules | MiniDumpWithThreadInfo);
|
||||
const auto flags = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithFullMemoryInfo | MiniDumpWithHandleData
|
||||
| MiniDumpWithUnloadedModules | MiniDumpWithThreadInfo);
|
||||
|
||||
const std::string fname = fmt::format("C:\\ProgramData\\lokinet\\crash-{}.dump", llarp::time_now_ms().count());
|
||||
|
||||
|
@ -38,7 +38,7 @@ namespace llarp::apple
|
||||
// Called when we are ready to start reading packets
|
||||
on_readable_callback _on_readable;
|
||||
|
||||
static inline constexpr auto PacketQueueSize = 1024;
|
||||
inline static constexpr auto PacketQueueSize = 1024;
|
||||
|
||||
thread::Queue<IPPacket> _read_que{PacketQueueSize};
|
||||
|
||||
|
@ -288,7 +288,7 @@ namespace llarp
|
||||
return other == key;
|
||||
}
|
||||
|
||||
constexpr static char derived_key_hash_str[161] =
|
||||
static constexpr char derived_key_hash_str[161] =
|
||||
"just imagine what would happen if we all decided to understand. you "
|
||||
"can't in the and by be or then before so just face it this text hurts "
|
||||
"to read? lokinet yolo!";
|
||||
|
@ -122,11 +122,11 @@ namespace llarp
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<PubKey> = true;
|
||||
inline constexpr bool IsToStringFormattable<PubKey> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<SecretKey> = true;
|
||||
inline constexpr bool IsToStringFormattable<SecretKey> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<PrivateKey> = true;
|
||||
inline constexpr bool IsToStringFormattable<PrivateKey> = true;
|
||||
|
||||
using ShortHash = AlignedBuffer<SHORTHASHSIZE>;
|
||||
using LongHash = AlignedBuffer<HASHSIZE>;
|
||||
|
@ -91,5 +91,5 @@ namespace llarp
|
||||
} // namespace dns
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<llarp::dns::Message> = true;
|
||||
inline constexpr bool IsToStringFormattable<llarp::dns::Message> = true;
|
||||
} // namespace llarp
|
||||
|
@ -57,4 +57,4 @@ namespace llarp::dns
|
||||
} // namespace llarp::dns
|
||||
|
||||
template <>
|
||||
constexpr inline bool llarp::IsToStringFormattable<llarp::dns::Question> = true;
|
||||
inline constexpr bool llarp::IsToStringFormattable<llarp::dns::Question> = true;
|
||||
|
@ -42,4 +42,4 @@ namespace llarp::dns
|
||||
} // namespace llarp::dns
|
||||
|
||||
template <>
|
||||
constexpr inline bool llarp::IsToStringFormattable<llarp::dns::ResourceRecord> = true;
|
||||
inline constexpr bool llarp::IsToStringFormattable<llarp::dns::ResourceRecord> = true;
|
||||
|
@ -1203,13 +1203,17 @@ namespace llarp
|
||||
log::info(link_cat, "PublishIntroMessage failed with error code: {}", payload);
|
||||
|
||||
if (payload == PublishIntroMessage::INVALID_INTROSET)
|
||||
{}
|
||||
{
|
||||
}
|
||||
else if (payload == PublishIntroMessage::EXPIRED)
|
||||
{}
|
||||
{
|
||||
}
|
||||
else if (payload == PublishIntroMessage::INSUFFICIENT)
|
||||
{}
|
||||
{
|
||||
}
|
||||
else if (payload == PublishIntroMessage::INVALID_ORDER)
|
||||
{}
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1705,7 +1709,8 @@ namespace llarp
|
||||
// see Path::HandleUpdateExitVerifyMessage
|
||||
}
|
||||
else
|
||||
{}
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ namespace llarp
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<Ip_address_deprecated> = true;
|
||||
inline constexpr bool IsToStringFormattable<Ip_address_deprecated> = true;
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace llarp
|
||||
return IP_range_deprecated{net::ExpandV4(ipaddr_ipv4_bits(a, b, c, d)), netmask_ipv6_bits(mask + 96)};
|
||||
}
|
||||
|
||||
static inline IP_range_deprecated FromIPv4(net::ipv4addr_t addr, net::ipv4addr_t netmask)
|
||||
inline static IP_range_deprecated FromIPv4(net::ipv4addr_t addr, net::ipv4addr_t netmask)
|
||||
{
|
||||
return IP_range_deprecated{
|
||||
net::ExpandV4(llarp::net::ToHost(addr)), netmask_ipv6_bits(bits::count_bits(netmask) + 96)};
|
||||
@ -150,7 +150,7 @@ namespace llarp
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<IP_range_deprecated> = true;
|
||||
inline constexpr bool IsToStringFormattable<IP_range_deprecated> = true;
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace llarp
|
||||
|
||||
// Initializes with upper and lower values
|
||||
constexpr uint128_t(uint64_t upper, uint64_t lower)
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
#ifdef __BIG_ENDIAN__
|
||||
: upper{upper}, lower{lower}
|
||||
#else
|
||||
@ -194,7 +194,8 @@ namespace llarp
|
||||
constexpr uint128_t& operator<<=(uint64_t shift)
|
||||
{
|
||||
if (shift == 0)
|
||||
{}
|
||||
{
|
||||
}
|
||||
else if (shift < 64)
|
||||
{
|
||||
upper = upper << shift | (lower >> (64 - shift));
|
||||
@ -226,7 +227,8 @@ namespace llarp
|
||||
constexpr uint128_t& operator>>=(uint64_t shift)
|
||||
{
|
||||
if (shift == 0)
|
||||
{}
|
||||
{
|
||||
}
|
||||
else if (shift < 64)
|
||||
{
|
||||
lower = lower >> shift | upper << (64 - shift);
|
||||
|
@ -15,11 +15,6 @@ namespace llarp
|
||||
{
|
||||
struct Router;
|
||||
|
||||
namespace routing
|
||||
{
|
||||
struct AbstractRoutingMessage;
|
||||
}
|
||||
|
||||
namespace path
|
||||
{
|
||||
std::string make_onion_payload(
|
||||
|
@ -9,9 +9,8 @@
|
||||
|
||||
namespace llarp::path
|
||||
{
|
||||
|
||||
Path::Path(Router& rtr, const std::vector<RemoteRC>& h, std::weak_ptr<PathHandler> pathset, std::string shortName)
|
||||
: path_set{std::move(pathset)}, _router{rtr}, _short_name{std::move(shortName)}
|
||||
: handler{std::move(pathset)}, _router{rtr}, _short_name{std::move(shortName)}
|
||||
{
|
||||
hops.resize(h.size());
|
||||
size_t hsz = h.size();
|
||||
@ -39,6 +38,33 @@ namespace llarp::path
|
||||
intro.path_id = hops[hsz - 1].txID;
|
||||
}
|
||||
|
||||
bool Path::operator<(const Path& other) const
|
||||
{
|
||||
auto& first_hop = hops[0];
|
||||
auto& other_first = other.hops[0];
|
||||
return std::tie(first_hop.txID, first_hop.rxID, first_hop.upstream)
|
||||
< std::tie(other_first.txID, other_first.rxID, other_first.upstream);
|
||||
}
|
||||
|
||||
bool Path::operator==(const Path& other) const
|
||||
{
|
||||
bool ret = true;
|
||||
size_t len = std::min(hops.size(), other.hops.size()), i = 0;
|
||||
|
||||
while (ret and i < len)
|
||||
{
|
||||
ret &= hops[i] == other.hops[i];
|
||||
++i;
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Path::operator!=(const Path& other) const
|
||||
{
|
||||
return not(*this == other);
|
||||
}
|
||||
|
||||
bool Path::obtain_exit(SecretKey sk, uint64_t flag, std::string tx_id, std::function<void(std::string)> func)
|
||||
{
|
||||
return send_path_control_message(
|
||||
@ -250,7 +276,7 @@ namespace llarp::path
|
||||
|
||||
void Path::rebuild()
|
||||
{
|
||||
if (auto parent = path_set.lock())
|
||||
if (auto parent = handler.lock())
|
||||
{
|
||||
std::vector<RemoteRC> new_hops;
|
||||
|
||||
@ -368,21 +394,6 @@ namespace llarp::path
|
||||
return fmt::format("TX={} RX={}", TXID(), RXID());
|
||||
}
|
||||
|
||||
/** Note: this is one of two places where AbstractRoutingMessage::bt_encode() is called, the
|
||||
other of which is llarp/path/transit_hop.cpp in TransitHop::SendRoutingMessage(). For now,
|
||||
we will default to the override of ::bt_encode() that returns an std::string. The role that
|
||||
llarp_buffer_t plays here is likely superfluous, and can be replaced with either a leaner
|
||||
llarp_buffer, or just handled using strings.
|
||||
|
||||
One important consideration is the frequency at which routing messages are sent, making
|
||||
superfluous copies important to optimize out here. We have to instantiate at least one
|
||||
std::string whether we pass a bt_dict_producer as a reference or create one within the
|
||||
::bt_encode() call.
|
||||
|
||||
If we decide to stay with std::strings, the function Path::HandleUpstream (along with the
|
||||
functions it calls and so on) will need to be modified to take an std::string that we can
|
||||
std::move around.
|
||||
*/
|
||||
/* TODO: replace this with sending an onion-ed data message
|
||||
bool Path::SendRoutingMessage(std::string payload, Router*)
|
||||
{
|
||||
|
@ -36,15 +36,12 @@ namespace llarp
|
||||
struct TransitHopInfo;
|
||||
struct PathHopConfig;
|
||||
|
||||
struct Endpoint_Hash;
|
||||
struct endpoint_comparator;
|
||||
|
||||
/// A path we made
|
||||
struct Path final : public AbstractHopHandler, public std::enable_shared_from_this<Path>
|
||||
{
|
||||
std::vector<PathHopConfig> hops;
|
||||
|
||||
std::weak_ptr<PathHandler> path_set;
|
||||
std::weak_ptr<PathHandler> handler;
|
||||
|
||||
service::Introduction intro;
|
||||
|
||||
@ -68,11 +65,6 @@ namespace llarp
|
||||
|
||||
StatusObject ExtractStatus() const;
|
||||
|
||||
bool operator<(const Path& other) const
|
||||
{
|
||||
return hops < other.hops;
|
||||
}
|
||||
|
||||
void MarkActive(llarp_time_t now)
|
||||
{
|
||||
last_recv_msg = std::max(now, last_recv_msg);
|
||||
@ -165,6 +157,12 @@ namespace llarp
|
||||
|
||||
std::string name() const;
|
||||
|
||||
bool operator<(const Path& other) const;
|
||||
|
||||
bool operator==(const Path& other) const;
|
||||
|
||||
bool operator!=(const Path& other) const;
|
||||
|
||||
private:
|
||||
std::string make_outer_payload(std::string payload);
|
||||
|
||||
@ -181,41 +179,23 @@ namespace llarp
|
||||
uint64_t last_latency_test_id = 0;
|
||||
const std::string _short_name;
|
||||
};
|
||||
|
||||
struct Hash
|
||||
{
|
||||
size_t operator()(const Path& p) const
|
||||
{
|
||||
const auto& tx = p.hops[0].txID;
|
||||
const auto& rx = p.hops[0].rxID;
|
||||
const auto& r = p.hops[0].upstream;
|
||||
const size_t rhash = std::accumulate(r.begin(), r.end(), 0, std::bit_xor{});
|
||||
return std::accumulate(
|
||||
rx.begin(),
|
||||
rx.begin(),
|
||||
std::accumulate(tx.begin(), tx.end(), rhash, std::bit_xor{}),
|
||||
std::bit_xor{});
|
||||
}
|
||||
};
|
||||
|
||||
/// hash for std::shared_ptr<Path> by path endpoint
|
||||
struct Endpoint_Hash
|
||||
{
|
||||
size_t operator()(const std::shared_ptr<Path>& p) const
|
||||
{
|
||||
if (p == nullptr)
|
||||
return 0;
|
||||
return std::hash<RouterID>{}(p->pivot_router_id());
|
||||
}
|
||||
};
|
||||
|
||||
/// comparision for equal endpoints
|
||||
struct endpoint_comparator
|
||||
{
|
||||
bool operator()(const std::shared_ptr<Path>& left, const std::shared_ptr<Path>& right) const
|
||||
{
|
||||
return left && right && left->pivot_router_id() == left->pivot_router_id();
|
||||
}
|
||||
};
|
||||
} // namespace path
|
||||
} // namespace llarp
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<llarp::path::Path>
|
||||
{
|
||||
size_t operator()(const llarp::path::Path& p) const
|
||||
{
|
||||
auto& first_hop = p.hops[0];
|
||||
llarp::AlignedBuffer<PUBKEYSIZE> b;
|
||||
std::memcpy(b.data(), first_hop.txID.data(), PATHIDSIZE);
|
||||
std::memcpy(&b[PATHIDSIZE], first_hop.txID.data(), PATHIDSIZE);
|
||||
|
||||
auto h = hash<llarp::AlignedBuffer<PUBKEYSIZE>>{}(b);
|
||||
return h ^ hash<llarp::RouterID>{}(first_hop.upstream);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
@ -41,13 +41,24 @@ namespace llarp
|
||||
llarp_time_t lifetime = DEFAULT_LIFETIME;
|
||||
|
||||
StatusObject ExtractStatus() const;
|
||||
};
|
||||
|
||||
inline bool operator<(const PathHopConfig& lhs, const PathHopConfig& rhs)
|
||||
{
|
||||
return std::tie(lhs.txID, lhs.rxID, lhs.rc, lhs.upstream, lhs.lifetime)
|
||||
< std::tie(rhs.txID, rhs.rxID, rhs.rc, rhs.upstream, rhs.lifetime);
|
||||
}
|
||||
bool operator<(const PathHopConfig& other) const
|
||||
{
|
||||
return std::tie(txID, rxID, rc, upstream, lifetime)
|
||||
< std::tie(other.txID, other.rxID, other.rc, other.upstream, other.lifetime);
|
||||
}
|
||||
|
||||
bool operator==(const PathHopConfig& other) const
|
||||
{
|
||||
return std::tie(txID, rxID, rc, upstream, lifetime)
|
||||
== std::tie(other.txID, other.rxID, other.rc, other.upstream, other.lifetime);
|
||||
}
|
||||
|
||||
bool operator!=(const PathHopConfig& other) const
|
||||
{
|
||||
return not(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
// milliseconds waiting between builds on a path per router
|
||||
static constexpr auto MIN_PATH_BUILD_INTERVAL = 500ms;
|
||||
|
@ -1,557 +0,0 @@
|
||||
#include "pathbuilder.hpp"
|
||||
|
||||
#include "path.hpp"
|
||||
#include "path_context.hpp"
|
||||
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/messages/path.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/path/pathset.hpp>
|
||||
#include <llarp/profiling.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace
|
||||
{
|
||||
auto path_cat = log::Cat("path");
|
||||
}
|
||||
|
||||
namespace path
|
||||
{
|
||||
bool BuildLimiter::Attempt(const RouterID& router)
|
||||
{
|
||||
return _edge_limiter.Insert(router);
|
||||
}
|
||||
|
||||
void BuildLimiter::Decay(llarp_time_t now)
|
||||
{
|
||||
_edge_limiter.Decay(now);
|
||||
}
|
||||
|
||||
bool BuildLimiter::Limited(const RouterID& router) const
|
||||
{
|
||||
return _edge_limiter.Contains(router);
|
||||
}
|
||||
|
||||
PathBuilder::PathBuilder(Router* p_router, size_t pathNum, size_t hops)
|
||||
: path::PathSet{pathNum}, _run{true}, router{p_router}, num_hops{hops}
|
||||
{}
|
||||
|
||||
/* - For each hop:
|
||||
* SetupHopKeys:
|
||||
* - Generate Ed keypair for the hop. ("commkey")
|
||||
* - Use that key and the hop's pubkey for DH key exchange (makes "hop.shared")
|
||||
* - Note: this *was* using hop's "enckey" but we're getting rid of that
|
||||
* - hop's "upstream" RouterID is next hop, or that hop's ID if it is terminal hop
|
||||
* - hop's chacha nonce is hash of symmetric key (hop.shared) from DH
|
||||
* - hop's "txID" and "rxID" are chosen before this step
|
||||
* - txID is the path ID for messages coming *from* the client/path origin
|
||||
* - rxID is the path ID for messages going *to* it.
|
||||
*
|
||||
* CreateHopInfoFrame:
|
||||
* - bt-encode "hop info":
|
||||
* - path lifetime
|
||||
* - protocol version
|
||||
* - txID
|
||||
* - rxID
|
||||
* - nonce
|
||||
* - upstream hop RouterID
|
||||
* - ephemeral public key (for DH)
|
||||
* - generate *second* ephemeral Ed keypair... ("framekey") TODO: why?
|
||||
* - generate DH symmetric key using "framekey" and hop's pubkey
|
||||
* - generate nonce for second encryption
|
||||
* - encrypt "hop info" using this symmetric key
|
||||
* - bt-encode nonce, "framekey" pubkey, encrypted "hop info"
|
||||
* - hash this bt-encoded string
|
||||
* - bt-encode hash and the frame in a dict, serialize
|
||||
*
|
||||
*
|
||||
* all of these "frames" go in a list, along with any needed dummy frames
|
||||
*/
|
||||
|
||||
void PathBuilder::setup_hop_keys(path::PathHopConfig& hop, const RouterID& nextHop)
|
||||
{
|
||||
// generate key
|
||||
crypto::encryption_keygen(hop.commkey);
|
||||
|
||||
hop.nonce.Randomize();
|
||||
// do key exchange
|
||||
if (!crypto::dh_client(hop.shared, hop.rc.router_id(), hop.commkey, hop.nonce))
|
||||
{
|
||||
auto err = fmt::format("{} failed to generate shared key for path build!", Name());
|
||||
log::error(path_cat, err);
|
||||
throw std::runtime_error{std::move(err)};
|
||||
}
|
||||
// generate nonceXOR value self->hop->pathKey
|
||||
ShortHash hash;
|
||||
crypto::shorthash(hash, hop.shared.data(), hop.shared.size());
|
||||
hop.nonceXOR = hash.data(); // nonceXOR is 24 bytes, ShortHash is 32; this will truncate
|
||||
|
||||
hop.upstream = nextHop;
|
||||
}
|
||||
|
||||
std::string PathBuilder::create_hop_info_frame(const path::PathHopConfig& hop)
|
||||
{
|
||||
std::string hop_info;
|
||||
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("COMMKEY", hop.commkey.toPublic().ToView());
|
||||
btdp.append("LIFETIME", path::DEFAULT_LIFETIME.count());
|
||||
btdp.append("NONCE", hop.nonce.ToView());
|
||||
btdp.append("RX", hop.rxID.ToView());
|
||||
btdp.append("TX", hop.txID.ToView());
|
||||
btdp.append("UPSTREAM", hop.upstream.ToView());
|
||||
|
||||
hop_info = std::move(btdp).str();
|
||||
}
|
||||
|
||||
SecretKey framekey;
|
||||
crypto::encryption_keygen(framekey);
|
||||
|
||||
SharedSecret shared;
|
||||
SymmNonce outer_nonce;
|
||||
outer_nonce.Randomize();
|
||||
|
||||
// derive (outer) shared key
|
||||
if (!crypto::dh_client(shared, hop.rc.router_id(), framekey, outer_nonce))
|
||||
{
|
||||
log::error(path_cat, "DH client failed during hop info encryption!");
|
||||
throw std::runtime_error{"DH failed during hop info encryption"};
|
||||
}
|
||||
|
||||
// encrypt hop_info (mutates in-place)
|
||||
if (!crypto::xchacha20(reinterpret_cast<uint8_t*>(hop_info.data()), hop_info.size(), shared, outer_nonce))
|
||||
{
|
||||
log::error(path_cat, "Hop info encryption failed!");
|
||||
throw std::runtime_error{"Hop info encrypttion failed"};
|
||||
}
|
||||
|
||||
std::string hashed_data;
|
||||
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("ENCRYPTED", hop_info);
|
||||
btdp.append("NONCE", outer_nonce.ToView());
|
||||
btdp.append("PUBKEY", framekey.toPublic().ToView());
|
||||
|
||||
hashed_data = std::move(btdp).str();
|
||||
}
|
||||
|
||||
std::string hash;
|
||||
hash.reserve(SHORTHASHSIZE);
|
||||
|
||||
if (!crypto::hmac(
|
||||
reinterpret_cast<uint8_t*>(hash.data()),
|
||||
reinterpret_cast<uint8_t*>(hashed_data.data()),
|
||||
hashed_data.size(),
|
||||
shared))
|
||||
{
|
||||
log::error(path_cat, "Failed to generate HMAC for hop info");
|
||||
throw std::runtime_error{"Failed to generate HMAC for hop info"};
|
||||
}
|
||||
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("FRAME", hashed_data);
|
||||
btdp.append("HASH", hash);
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
void PathBuilder::ResetInternalState()
|
||||
{
|
||||
build_interval_limit = PATH_BUILD_RATE;
|
||||
_last_build = 0s;
|
||||
}
|
||||
|
||||
void PathBuilder::Tick(llarp_time_t now)
|
||||
{
|
||||
PathSet::Tick(now);
|
||||
now = llarp::time_now_ms();
|
||||
router->pathbuild_limiter().Decay(now);
|
||||
|
||||
ExpirePaths(now, router);
|
||||
if (ShouldBuildMore(now))
|
||||
BuildOne();
|
||||
TickPaths(router);
|
||||
if (build_stats.attempts > 50)
|
||||
{
|
||||
if (build_stats.SuccessRatio() <= BuildStats::MinGoodRatio && now - last_warn_time > 5s)
|
||||
{
|
||||
LogWarn(Name(), " has a low path build success. ", build_stats);
|
||||
last_warn_time = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
util::StatusObject PathBuilder::ExtractStatus() const
|
||||
{
|
||||
util::StatusObject obj{
|
||||
{"buildStats", build_stats.ExtractStatus()},
|
||||
{"numHops", uint64_t{num_hops}},
|
||||
{"numPaths", uint64_t{num_paths_desired}}};
|
||||
std::transform(
|
||||
_paths.begin(),
|
||||
_paths.end(),
|
||||
std::back_inserter(obj["paths"]),
|
||||
[](const auto& item) -> util::StatusObject { return item.second->ExtractStatus(); });
|
||||
return obj;
|
||||
}
|
||||
|
||||
std::optional<RemoteRC> PathBuilder::SelectFirstHop(const std::set<RouterID>& exclude) const
|
||||
{
|
||||
std::optional<RemoteRC> found = std::nullopt;
|
||||
router->for_each_connection([&](link::Connection& conn) {
|
||||
RouterID rid{conn.conn->remote_key()};
|
||||
|
||||
#ifndef TESTNET
|
||||
if (router->is_bootstrap_node(rid))
|
||||
return;
|
||||
#endif
|
||||
if (exclude.count(rid))
|
||||
return;
|
||||
|
||||
if (BuildCooldownHit(rid))
|
||||
return;
|
||||
|
||||
if (router->router_profiling().IsBadForPath(rid))
|
||||
return;
|
||||
|
||||
found = router->node_db()->get_rc(rid);
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
std::optional<std::vector<RemoteRC>> PathBuilder::GetHopsForBuild()
|
||||
{
|
||||
auto filter = [r = router](const RemoteRC& rc) -> bool {
|
||||
return not r->router_profiling().IsBadForPath(rc.router_id(), 1);
|
||||
};
|
||||
|
||||
if (auto maybe = router->node_db()->get_random_rc_conditional(filter))
|
||||
return GetHopsAlignedToForBuild(maybe->router_id());
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool PathBuilder::Stop()
|
||||
{
|
||||
_run = false;
|
||||
// tell all our paths that they are to be ignored
|
||||
const auto now = Now();
|
||||
for (auto& item : _paths)
|
||||
{
|
||||
item.second->EnterState(PathStatus::IGNORE, now);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PathBuilder::IsStopped() const
|
||||
{
|
||||
return !_run.load();
|
||||
}
|
||||
|
||||
bool PathBuilder::ShouldRemove() const
|
||||
{
|
||||
return IsStopped() and NumInStatus(PathStatus::ESTABLISHED) == 0;
|
||||
}
|
||||
|
||||
bool PathBuilder::BuildCooldownHit(RouterID edge) const
|
||||
{
|
||||
return router->pathbuild_limiter().Limited(edge);
|
||||
}
|
||||
|
||||
bool PathBuilder::BuildCooldownHit(llarp_time_t now) const
|
||||
{
|
||||
return now < _last_build + build_interval_limit;
|
||||
}
|
||||
|
||||
bool PathBuilder::ShouldBuildMore(llarp_time_t now) const
|
||||
{
|
||||
if (IsStopped())
|
||||
return false;
|
||||
if (BuildCooldownHit(now))
|
||||
return false;
|
||||
return PathSet::ShouldBuildMore(now);
|
||||
}
|
||||
|
||||
void PathBuilder::BuildOne(PathRole roles)
|
||||
{
|
||||
if (const auto maybe = GetHopsForBuild())
|
||||
Build(*maybe, roles);
|
||||
}
|
||||
|
||||
bool PathBuilder::UrgentBuild(llarp_time_t) const
|
||||
{
|
||||
return build_interval_limit > MIN_PATH_BUILD_INTERVAL * 4;
|
||||
}
|
||||
|
||||
std::optional<std::vector<RemoteRC>> PathBuilder::GetHopsAlignedToForBuild(
|
||||
RouterID endpoint, const std::set<RouterID>& exclude)
|
||||
{
|
||||
const auto pathConfig = router->config()->paths;
|
||||
|
||||
std::vector<RemoteRC> hops;
|
||||
{
|
||||
const auto maybe = SelectFirstHop(exclude);
|
||||
if (not maybe.has_value())
|
||||
{
|
||||
log::warning(path_cat, "{} has no first hop candidate", Name());
|
||||
return std::nullopt;
|
||||
}
|
||||
hops.emplace_back(*maybe);
|
||||
};
|
||||
|
||||
RemoteRC endpointRC;
|
||||
if (const auto maybe = router->node_db()->get_rc(endpoint))
|
||||
{
|
||||
endpointRC = *maybe;
|
||||
}
|
||||
else
|
||||
return std::nullopt;
|
||||
|
||||
for (size_t idx = hops.size(); idx < num_hops; ++idx)
|
||||
{
|
||||
if (idx + 1 == num_hops)
|
||||
{
|
||||
hops.emplace_back(endpointRC);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto filter = [&hops, r = router, endpointRC, pathConfig, exclude](const RemoteRC& rc) -> bool {
|
||||
const auto& rid = rc.router_id();
|
||||
|
||||
if (exclude.count(rid))
|
||||
return false;
|
||||
|
||||
std::set<RemoteRC> hopsSet;
|
||||
hopsSet.insert(endpointRC);
|
||||
hopsSet.insert(hops.begin(), hops.end());
|
||||
|
||||
if (r->router_profiling().IsBadForPath(rid, 1))
|
||||
return false;
|
||||
|
||||
for (const auto& hop : hopsSet)
|
||||
{
|
||||
if (hop.router_id() == rid)
|
||||
return false;
|
||||
}
|
||||
|
||||
hopsSet.insert(rc);
|
||||
#ifndef TESTNET
|
||||
if (not pathConfig.check_rcs(hopsSet))
|
||||
return false;
|
||||
#endif
|
||||
return rc.router_id() != endpointRC.router_id();
|
||||
};
|
||||
|
||||
if (auto maybe = router->node_db()->get_random_rc_conditional(filter))
|
||||
hops.emplace_back(*maybe);
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
return hops;
|
||||
}
|
||||
|
||||
bool PathBuilder::BuildOneAlignedTo(const RouterID remote)
|
||||
{
|
||||
if (const auto maybe = GetHopsAlignedToForBuild(remote); maybe.has_value())
|
||||
{
|
||||
LogInfo(Name(), " building path to ", remote);
|
||||
Build(*maybe);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
llarp_time_t PathBuilder::Now() const
|
||||
{
|
||||
return router->now();
|
||||
}
|
||||
|
||||
void PathBuilder::Build(std::vector<RemoteRC> hops, PathRole roles)
|
||||
{
|
||||
if (IsStopped())
|
||||
{
|
||||
log::info(path_cat, "Path builder is stopped, aborting path build...");
|
||||
return;
|
||||
}
|
||||
|
||||
_last_build = llarp::time_now_ms();
|
||||
const auto& edge = hops[0].router_id();
|
||||
|
||||
if (not router->pathbuild_limiter().Attempt(edge))
|
||||
{
|
||||
log::warning(path_cat, "{} building too quickly to edge router {}", Name(), edge);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string path_shortName = "[path " + router->ShortName() + "-";
|
||||
path_shortName = path_shortName + std::to_string(router->NextPathBuildNumber()) + "]";
|
||||
|
||||
auto path = std::make_shared<path::Path>(router, hops, GetWeak(), roles, std::move(path_shortName));
|
||||
|
||||
log::info(path_cat, "{} building path -> {} : {}", Name(), path->short_name(), path->HopsString());
|
||||
|
||||
oxenc::bt_list_producer frames;
|
||||
std::vector<std::string> frame_str(path::MAX_LEN);
|
||||
auto& path_hops = path->hops;
|
||||
size_t n_hops = path_hops.size();
|
||||
size_t last_len{0};
|
||||
|
||||
// each hop will be able to read the outer part of its frame and decrypt
|
||||
// the inner part with that information. It will then do an onion step on the
|
||||
// remaining frames so the next hop can read the outer part of its frame,
|
||||
// and so on. As this de-onion happens from hop 1 to n, we create and onion
|
||||
// the frames from hop n downto 1 (i.e. reverse order). The first frame is
|
||||
// not onioned.
|
||||
//
|
||||
// Onion-ing the frames in this way will prevent relays controlled by
|
||||
// the same entity from knowing they are part of the same path
|
||||
// (unless they're adjacent in the path; nothing we can do about that obviously).
|
||||
|
||||
// i from n_hops downto 0
|
||||
size_t i = n_hops;
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
bool lastHop = (i == (n_hops - 1));
|
||||
|
||||
const auto& nextHop = lastHop ? path_hops[i].rc.router_id() : path_hops[i + 1].rc.router_id();
|
||||
|
||||
PathBuildMessage::setup_hop_keys(path_hops[i], nextHop);
|
||||
frame_str[i] = PathBuildMessage::serialize(path_hops[i]);
|
||||
|
||||
// all frames should be the same length...not sure what that is yet
|
||||
// it may vary if path lifetime is non-default, as that is encoded as an
|
||||
// integer in decimal, but it should be constant for a given path
|
||||
if (last_len != 0)
|
||||
assert(frame_str[i].size() == last_len);
|
||||
|
||||
last_len = frame_str[i].size();
|
||||
|
||||
// onion each previously-created frame using the established shared secret and
|
||||
// onion_nonce = path_hops[i].nonce ^ path_hops[i].nonceXOR, which the transit hop
|
||||
// will have recovered after decrypting its frame.
|
||||
// Note: final value passed to crypto::onion is xor factor, but that's for *after*
|
||||
// the onion round to compute the return value, so we don't care about it.
|
||||
for (size_t j = n_hops - 1; j > i; j--)
|
||||
{
|
||||
auto onion_nonce = path_hops[i].nonce ^ path_hops[i].nonceXOR;
|
||||
crypto::onion(
|
||||
reinterpret_cast<unsigned char*>(frame_str[j].data()),
|
||||
frame_str[j].size(),
|
||||
path_hops[i].shared,
|
||||
onion_nonce,
|
||||
onion_nonce);
|
||||
}
|
||||
}
|
||||
|
||||
std::string dummy;
|
||||
dummy.reserve(last_len);
|
||||
// append dummy frames; path build request must always have MAX_LEN frames
|
||||
for (i = n_hops; i < path::MAX_LEN; i++)
|
||||
{
|
||||
frame_str[i].resize(last_len);
|
||||
randombytes(reinterpret_cast<uint8_t*>(frame_str[i].data()), frame_str[i].size());
|
||||
}
|
||||
|
||||
for (auto& str : frame_str) // NOLINT
|
||||
{
|
||||
frames.append(std::move(str));
|
||||
}
|
||||
|
||||
router->path_context().AddOwnPath(GetSelf(), path);
|
||||
PathBuildStarted(path);
|
||||
|
||||
// TODO:
|
||||
// Path build fail and success are handled poorly at best and changing how we
|
||||
// handle these responses as well as how we store and use Paths as a whole might
|
||||
// be worth doing sooner rather than later. Leaving some TODOs below where fail
|
||||
// and success live.
|
||||
auto response_cb = [path](oxen::quic::message m) {
|
||||
if (m)
|
||||
{
|
||||
// TODO: inform success (what this means needs revisiting, badly)
|
||||
path->EnterState(path::PathStatus::ESTABLISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// TODO: inform failure (what this means needs revisiting, badly)
|
||||
if (m.timed_out)
|
||||
{
|
||||
log::warning(path_cat, "Path build request timed out!");
|
||||
path->EnterState(path::PathStatus::TIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
oxenc::bt_dict_consumer d{m.body()};
|
||||
auto status = d.require<std::string_view>(messages::STATUS_KEY);
|
||||
log::warning(path_cat, "Path build returned failure status: {}", status);
|
||||
path->EnterState(path::PathStatus::FAILED);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(path_cat, "Exception caught parsing path build response: {}", e.what());
|
||||
}
|
||||
};
|
||||
|
||||
if (not router->send_control_message(
|
||||
path->upstream(), "path_build", std::move(frames).str(), std::move(response_cb)))
|
||||
{
|
||||
log::warning(path_cat, "Error sending path_build control message");
|
||||
path->EnterState(path::PathStatus::FAILED, router->now());
|
||||
}
|
||||
}
|
||||
|
||||
void PathBuilder::HandlePathBuilt(std::shared_ptr<Path> p)
|
||||
{
|
||||
build_interval_limit = PATH_BUILD_RATE;
|
||||
router->router_profiling().MarkPathSuccess(p.get());
|
||||
|
||||
LogInfo(p->name(), " built latency=", to_string(p->intro.latency));
|
||||
build_stats.success++;
|
||||
}
|
||||
|
||||
void PathBuilder::HandlePathBuildFailedAt(std::shared_ptr<Path> p, RouterID edge)
|
||||
{
|
||||
PathSet::HandlePathBuildFailedAt(p, edge);
|
||||
DoPathBuildBackoff();
|
||||
}
|
||||
|
||||
void PathBuilder::DoPathBuildBackoff()
|
||||
{
|
||||
static constexpr std::chrono::milliseconds MaxBuildInterval = 30s;
|
||||
// linear backoff
|
||||
build_interval_limit = std::min(PATH_BUILD_RATE + build_interval_limit, MaxBuildInterval);
|
||||
LogWarn(Name(), " build interval is now ", to_string(build_interval_limit));
|
||||
}
|
||||
|
||||
void PathBuilder::HandlePathBuildTimeout(std::shared_ptr<Path> p)
|
||||
{
|
||||
router->router_profiling().MarkPathTimeout(p.get());
|
||||
PathSet::HandlePathBuildTimeout(p);
|
||||
DoPathBuildBackoff();
|
||||
}
|
||||
|
||||
void PathBuilder::ManualRebuild(size_t num, PathRole roles)
|
||||
{
|
||||
LogDebug(Name(), " manual rebuild ", num);
|
||||
while (num--)
|
||||
BuildOne(roles);
|
||||
}
|
||||
|
||||
} // namespace path
|
||||
} // namespace llarp
|
@ -247,6 +247,6 @@ namespace llarp
|
||||
} // namespace path
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<path::BuildStats> = true;
|
||||
inline constexpr bool IsToStringFormattable<path::BuildStats> = true;
|
||||
|
||||
} // namespace llarp
|
||||
|
@ -58,24 +58,9 @@ namespace llarp::path
|
||||
return started + lifetime;
|
||||
}
|
||||
|
||||
TransitHopInfo::TransitHopInfo(const RouterID& down) : downstream(down)
|
||||
TransitHopInfo::TransitHopInfo(RouterID down) : downstream{std::move(down)}
|
||||
{}
|
||||
|
||||
/** Note: this is one of two places where AbstractRoutingMessage::bt_encode() is called, the
|
||||
other of which is llarp/path/path.cpp in Path::SendRoutingMessage(). For now,
|
||||
we will default to the override of ::bt_encode() that returns an std::string. The role that
|
||||
llarp_buffer_t plays here is likely superfluous, and can be replaced with either a leaner
|
||||
llarp_buffer, or just handled using strings.
|
||||
|
||||
One important consideration is the frequency at which routing messages are sent, making
|
||||
superfluous copies important to optimize out here. We have to instantiate at least one
|
||||
std::string whether we pass a bt_dict_producer as a reference or create one within the
|
||||
::bt_encode() call.
|
||||
|
||||
If we decide to stay with std::strings, the function Path::HandleUpstream (along with the
|
||||
functions it calls and so on) will need to be modified to take an std::string that we can
|
||||
std::move around.
|
||||
*/
|
||||
/* TODO: replace this with layer of onion + send data message
|
||||
bool TransitHop::SendRoutingMessage(std::string payload, Router* r)
|
||||
{
|
||||
|
@ -14,32 +14,32 @@ namespace llarp
|
||||
struct TransitHopInfo
|
||||
{
|
||||
TransitHopInfo() = default;
|
||||
TransitHopInfo(const RouterID& down);
|
||||
TransitHopInfo(RouterID down);
|
||||
|
||||
HopID txID, rxID;
|
||||
RouterID upstream;
|
||||
RouterID downstream;
|
||||
|
||||
std::string to_string() const;
|
||||
|
||||
bool operator==(const TransitHopInfo& rhs) const
|
||||
{
|
||||
return std::tie(txID, rxID, upstream, downstream)
|
||||
== std::tie(rhs.txID, rhs.rxID, rhs.upstream, rhs.downstream);
|
||||
}
|
||||
|
||||
bool operator!=(const TransitHopInfo& rhs) const
|
||||
{
|
||||
return not(*this == rhs);
|
||||
}
|
||||
|
||||
bool operator<(const TransitHopInfo& rhs) const
|
||||
{
|
||||
return std::tie(txID, rxID, upstream, downstream)
|
||||
< std::tie(rhs.txID, rhs.rxID, rhs.upstream, rhs.downstream);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator==(const TransitHopInfo& lhs, const TransitHopInfo& rhs)
|
||||
{
|
||||
return std::tie(lhs.txID, lhs.rxID, lhs.upstream, lhs.downstream)
|
||||
== std::tie(rhs.txID, rhs.rxID, rhs.upstream, rhs.downstream);
|
||||
}
|
||||
|
||||
inline bool operator!=(const TransitHopInfo& lhs, const TransitHopInfo& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(const TransitHopInfo& lhs, const TransitHopInfo& rhs)
|
||||
{
|
||||
return std::tie(lhs.txID, lhs.rxID, lhs.upstream, lhs.downstream)
|
||||
< std::tie(rhs.txID, rhs.rxID, rhs.upstream, rhs.downstream);
|
||||
}
|
||||
|
||||
struct TransitHop : public AbstractHopHandler, std::enable_shared_from_this<TransitHop>
|
||||
{
|
||||
TransitHop();
|
||||
@ -125,9 +125,9 @@ namespace llarp
|
||||
} // namespace path
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<path::TransitHop> = true;
|
||||
inline constexpr bool IsToStringFormattable<path::TransitHop> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<path::TransitHopInfo> = true;
|
||||
inline constexpr bool IsToStringFormattable<path::TransitHopInfo> = true;
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
@ -136,7 +136,7 @@ namespace std
|
||||
template <>
|
||||
struct hash<llarp::path::TransitHopInfo>
|
||||
{
|
||||
std::size_t operator()(llarp::path::TransitHopInfo const& a) const
|
||||
std::size_t operator()(const llarp::path::TransitHopInfo& a) const
|
||||
{
|
||||
hash<llarp::RouterID> RHash{};
|
||||
hash<llarp::HopID> PHash{};
|
||||
|
@ -71,7 +71,7 @@ namespace llarp
|
||||
return (path_success * chances) > path_fail;
|
||||
}
|
||||
|
||||
static bool constexpr checkIsGood(uint64_t fails, uint64_t success, uint64_t chances)
|
||||
static constexpr bool checkIsGood(uint64_t fails, uint64_t success, uint64_t chances)
|
||||
{
|
||||
if (fails > 0 && (fails + success) >= chances)
|
||||
return (success / fails) > 1;
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
static inline constexpr size_t NETID_SIZE{8};
|
||||
inline static constexpr size_t NETID_SIZE{8};
|
||||
|
||||
/// On the wire we encode the data as a dict containing:
|
||||
/// "" -- the RC format version, which must be == RouterContact::Version for us to attempt to
|
||||
@ -45,11 +45,11 @@ namespace llarp
|
||||
static constexpr uint8_t RC_VERSION = 0;
|
||||
|
||||
/// Unit tests disable this to allow private IP ranges in RCs, which normally get rejected.
|
||||
static inline bool BLOCK_BOGONS = true;
|
||||
inline static bool BLOCK_BOGONS = true;
|
||||
|
||||
static inline std::string ACTIVE_NETID{LOKINET_DEFAULT_NETID};
|
||||
inline static std::string ACTIVE_NETID{LOKINET_DEFAULT_NETID};
|
||||
|
||||
static inline constexpr size_t MAX_RC_SIZE = 1024;
|
||||
inline static constexpr size_t MAX_RC_SIZE = 1024;
|
||||
|
||||
/// How long (from its signing time) before an RC is considered "stale". Relays republish
|
||||
/// their RCs slightly more frequently than this so that ideally this won't happen.
|
||||
@ -112,7 +112,7 @@ namespace llarp
|
||||
|
||||
public:
|
||||
/// should we serialize the exit info?
|
||||
const static bool serializeExit = true;
|
||||
static const bool serializeExit = true;
|
||||
|
||||
StatusObject extract_status() const;
|
||||
|
||||
@ -302,11 +302,11 @@ namespace llarp
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<RouterContact> = true;
|
||||
inline constexpr bool IsToStringFormattable<RouterContact> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<RemoteRC> = true;
|
||||
inline constexpr bool IsToStringFormattable<RemoteRC> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<LocalRC> = true;
|
||||
inline constexpr bool IsToStringFormattable<LocalRC> = true;
|
||||
|
||||
using RouterLookupHandler = std::function<void(const std::vector<RemoteRC>&)>;
|
||||
} // namespace llarp
|
||||
|
@ -48,7 +48,7 @@ namespace llarp
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<RouterID> = true;
|
||||
inline constexpr bool IsToStringFormattable<RouterID> = true;
|
||||
} // namespace llarp
|
||||
|
||||
namespace std
|
||||
|
@ -59,7 +59,7 @@ namespace llarp
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<RouterVersion> = true;
|
||||
inline constexpr bool IsToStringFormattable<RouterVersion> = true;
|
||||
|
||||
static constexpr int64_t INVALID_VERSION = -1;
|
||||
static const RouterVersion emptyRouterVersion({0, 0, 0}, INVALID_VERSION);
|
||||
|
@ -91,7 +91,7 @@ namespace llarp
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<service::Address> = true;
|
||||
inline constexpr bool IsToStringFormattable<service::Address> = true;
|
||||
} // namespace llarp
|
||||
|
||||
namespace std
|
||||
|
@ -549,7 +549,7 @@ namespace llarp::service
|
||||
|
||||
auto Endpoint::GetUniqueEndpointsForLookup() const
|
||||
{
|
||||
std::unordered_set<std::shared_ptr<path::Path>, path::Endpoint_Hash, path::endpoint_comparator> paths;
|
||||
std::unordered_set<std::shared_ptr<path::Path>> paths;
|
||||
|
||||
for_each_path([&paths](auto path) {
|
||||
if (path and path->IsReady())
|
||||
@ -561,7 +561,8 @@ namespace llarp::service
|
||||
|
||||
bool Endpoint::ReadyForNetwork() const
|
||||
{
|
||||
return is_ready() and ReadyToDoLookup(GetUniqueEndpointsForLookup().size());
|
||||
// return is_ready() and ReadyToDoLookup(GetUniqueEndpointsForLookup().size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Endpoint::ReadyToDoLookup(size_t num_paths) const
|
||||
|
@ -97,4 +97,4 @@ namespace llarp::service
|
||||
} // namespace llarp::service
|
||||
|
||||
template <>
|
||||
constexpr inline bool llarp::IsToStringFormattable<llarp::service::ServiceInfo> = true;
|
||||
inline constexpr bool llarp::IsToStringFormattable<llarp::service::ServiceInfo> = true;
|
||||
|
@ -81,7 +81,7 @@ namespace llarp::service
|
||||
} // namespace llarp::service
|
||||
|
||||
template <>
|
||||
constexpr inline bool llarp::IsToStringFormattable<llarp::service::Introduction> = true;
|
||||
inline constexpr bool llarp::IsToStringFormattable<llarp::service::Introduction> = true;
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
@ -171,6 +171,6 @@ namespace llarp::service
|
||||
} // namespace llarp::service
|
||||
|
||||
template <>
|
||||
constexpr inline bool llarp::IsToStringFormattable<llarp::service::IntroSet> = true;
|
||||
inline constexpr bool llarp::IsToStringFormattable<llarp::service::IntroSet> = true;
|
||||
template <>
|
||||
constexpr inline bool llarp::IsToStringFormattable<llarp::service::EncryptedIntroSet> = true;
|
||||
inline constexpr bool llarp::IsToStringFormattable<llarp::service::EncryptedIntroSet> = true;
|
||||
|
@ -81,40 +81,41 @@ namespace llarp
|
||||
std::set<SessionTag>& tags */);
|
||||
} // namespace util
|
||||
|
||||
template <typename Endpoint_t>
|
||||
static std::
|
||||
unordered_set<std::shared_ptr<path::Path>, path::Endpoint_Hash, path::endpoint_comparator>
|
||||
GetManyPathsWithUniqueEndpoints(
|
||||
/* Endpoint_t* ep,
|
||||
size_t N,
|
||||
std::optional<dht::Key_t> maybeLocation = std::nullopt,
|
||||
size_t tries = 10 */)
|
||||
{
|
||||
// std::unordered_set<RouterID> exclude;
|
||||
std::unordered_set<std::shared_ptr<path::Path>, path::Endpoint_Hash, path::endpoint_comparator> paths;
|
||||
// do
|
||||
// {
|
||||
// --tries;
|
||||
// std::shared_ptr<path::Path> path;
|
||||
// if (maybeLocation)
|
||||
// {
|
||||
// path = ep->GetEstablishedPathClosestTo(RouterID{maybeLocation->as_array()},
|
||||
// exclude);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// path = ep->PickRandomEstablishedPath();
|
||||
// }
|
||||
// if (path and path->IsReady())
|
||||
// {
|
||||
// paths.emplace(path);
|
||||
// exclude.insert(path->Endpoint());
|
||||
// }
|
||||
// } while (tries > 0 and paths.size() < N);
|
||||
return paths;
|
||||
}
|
||||
// template <typename Endpoint_t>
|
||||
// static std::
|
||||
// unordered_set<std::shared_ptr<path::Path>, path::Endpoint_Hash, path::endpoint_comparator>
|
||||
// GetManyPathsWithUniqueEndpoints(
|
||||
// /* Endpoint_t* ep,
|
||||
// size_t N,
|
||||
// std::optional<dht::Key_t> maybeLocation = std::nullopt,
|
||||
// size_t tries = 10 */)
|
||||
// {
|
||||
// // std::unordered_set<RouterID> exclude;
|
||||
// std::unordered_set<std::shared_ptr<path::Path>, path::Endpoint_Hash, path::endpoint_comparator>
|
||||
// paths;
|
||||
// // do
|
||||
// // {
|
||||
// // --tries;
|
||||
// // std::shared_ptr<path::Path> path;
|
||||
// // if (maybeLocation)
|
||||
// // {
|
||||
// // path = ep->GetEstablishedPathClosestTo(RouterID{maybeLocation->as_array()},
|
||||
// // exclude);
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // path = ep->PickRandomEstablishedPath();
|
||||
// // }
|
||||
// // if (path and path->IsReady())
|
||||
// // {
|
||||
// // paths.emplace(path);
|
||||
// // exclude.insert(path->Endpoint());
|
||||
// // }
|
||||
// // } while (tries > 0 and paths.size() < N);
|
||||
// return paths;
|
||||
// }
|
||||
} // namespace service
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<service::ProtocolType> = true;
|
||||
inline constexpr bool IsToStringFormattable<service::ProtocolType> = true;
|
||||
} // namespace llarp
|
||||
|
@ -282,7 +282,7 @@ namespace llarp
|
||||
} // namespace detail
|
||||
// True if T is or is derived from AlignedBuffer<N> for any N
|
||||
template <typename T>
|
||||
constexpr inline bool is_aligned_buffer = decltype(detail::is_aligned_buffer_impl(static_cast<T*>(nullptr)))::value;
|
||||
inline constexpr bool is_aligned_buffer = decltype(detail::is_aligned_buffer_impl(static_cast<T*>(nullptr)))::value;
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace llarp
|
||||
template <size_t... I>
|
||||
struct concat_args_fmt_impl<std::integer_sequence<size_t, I...>>
|
||||
{
|
||||
constexpr static std::array<char, sizeof...(I)> format{(I % 2 == 0 ? '{' : '}')...};
|
||||
static constexpr std::array<char, sizeof...(I)> format{(I % 2 == 0 ? '{' : '}')...};
|
||||
};
|
||||
template <size_t N>
|
||||
constexpr std::string_view concat_args_fmt()
|
||||
|
@ -54,5 +54,5 @@ namespace llarp
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<buffer_printer> = true;
|
||||
inline constexpr bool IsToStringFormattable<buffer_printer> = true;
|
||||
} // namespace llarp
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
constexpr static char whitespace[] = " \t\n\r\f\v";
|
||||
static constexpr char whitespace[] = " \t\n\r\f\v";
|
||||
|
||||
std::string_view TrimWhitespace(std::string_view str)
|
||||
{
|
||||
|
@ -14,9 +14,9 @@ namespace llarp
|
||||
return std::chrono::duration_cast<Res>(point.time_since_epoch());
|
||||
}
|
||||
|
||||
const static auto started_at_system = Clock_t::now();
|
||||
static const auto started_at_system = Clock_t::now();
|
||||
|
||||
const static auto started_at_steady = std::chrono::steady_clock::now();
|
||||
static const auto started_at_steady = std::chrono::steady_clock::now();
|
||||
} // namespace
|
||||
|
||||
std::chrono::steady_clock::time_point get_time()
|
||||
|
@ -266,7 +266,7 @@ namespace llarp::win32
|
||||
std::thread _recv_thread;
|
||||
std::thread _send_thread;
|
||||
|
||||
static inline constexpr size_t packet_queue_length = 1024;
|
||||
inline static constexpr size_t packet_queue_length = 1024;
|
||||
|
||||
public:
|
||||
WintunInterface(vpn::InterfaceInfo info, Router* router)
|
||||
|
Loading…
Reference in New Issue
Block a user