diff --git a/.clang-format b/.clang-format index 0632c3855..0806bf07e 100644 --- a/.clang-format +++ b/.clang-format @@ -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' diff --git a/.drone.jsonnet b/.drone.jsonnet index e69e53cbc..34602cea3 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -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', ], }], diff --git a/CMakeLists.txt b/CMakeLists.txt index cc7bb6a91..54badd636 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/contrib/format-version.sh b/contrib/format-version.sh index 8b9c8de9b..fc5d9afd1 100644 --- a/contrib/format-version.sh +++ b/contrib/format-version.sh @@ -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 diff --git a/daemon/lokinet.cpp b/daemon/lokinet.cpp index 4eaf201ca..0af1a25bd 100644 --- a/daemon/lokinet.cpp +++ b/daemon/lokinet.cpp @@ -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()); diff --git a/llarp/apple/vpn_interface.hpp b/llarp/apple/vpn_interface.hpp index 3be91503d..125df665b 100644 --- a/llarp/apple/vpn_interface.hpp +++ b/llarp/apple/vpn_interface.hpp @@ -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 _read_que{PacketQueueSize}; diff --git a/llarp/crypto/crypto.cpp b/llarp/crypto/crypto.cpp index 93a663942..16ec1135a 100644 --- a/llarp/crypto/crypto.cpp +++ b/llarp/crypto/crypto.cpp @@ -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!"; diff --git a/llarp/crypto/types.hpp b/llarp/crypto/types.hpp index 83bf663c0..1c08b8f9b 100644 --- a/llarp/crypto/types.hpp +++ b/llarp/crypto/types.hpp @@ -122,11 +122,11 @@ namespace llarp }; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; using ShortHash = AlignedBuffer; using LongHash = AlignedBuffer; diff --git a/llarp/dns/message.hpp b/llarp/dns/message.hpp index 907c8e2a4..28d883b86 100644 --- a/llarp/dns/message.hpp +++ b/llarp/dns/message.hpp @@ -91,5 +91,5 @@ namespace llarp } // namespace dns template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp diff --git a/llarp/dns/question.hpp b/llarp/dns/question.hpp index 1df3ca2eb..f81075c2f 100644 --- a/llarp/dns/question.hpp +++ b/llarp/dns/question.hpp @@ -57,4 +57,4 @@ namespace llarp::dns } // namespace llarp::dns template <> -constexpr inline bool llarp::IsToStringFormattable = true; +inline constexpr bool llarp::IsToStringFormattable = true; diff --git a/llarp/dns/rr.hpp b/llarp/dns/rr.hpp index dc34df1c7..c5ef4278f 100644 --- a/llarp/dns/rr.hpp +++ b/llarp/dns/rr.hpp @@ -42,4 +42,4 @@ namespace llarp::dns } // namespace llarp::dns template <> -constexpr inline bool llarp::IsToStringFormattable = true; +inline constexpr bool llarp::IsToStringFormattable = true; diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 3f6e3afc7..cce9b4c6e 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -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 - {} + { + } } } diff --git a/llarp/net/ip_address.hpp b/llarp/net/ip_address.hpp index 62c8c305b..955b6da3a 100644 --- a/llarp/net/ip_address.hpp +++ b/llarp/net/ip_address.hpp @@ -131,7 +131,7 @@ namespace llarp }; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp diff --git a/llarp/net/ip_range.hpp b/llarp/net/ip_range.hpp index 81a7488e0..29eb62c78 100644 --- a/llarp/net/ip_range.hpp +++ b/llarp/net/ip_range.hpp @@ -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 = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp diff --git a/llarp/net/uint128.hpp b/llarp/net/uint128.hpp index c5c2d18cd..78bea4aa3 100644 --- a/llarp/net/uint128.hpp +++ b/llarp/net/uint128.hpp @@ -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); diff --git a/llarp/path/abstracthophandler.hpp b/llarp/path/abstracthophandler.hpp index 0c5638df5..1fdfcbe93 100644 --- a/llarp/path/abstracthophandler.hpp +++ b/llarp/path/abstracthophandler.hpp @@ -15,11 +15,6 @@ namespace llarp { struct Router; - namespace routing - { - struct AbstractRoutingMessage; - } - namespace path { std::string make_onion_payload( diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index ed2bdb5a1..234b7380a 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -9,9 +9,8 @@ namespace llarp::path { - Path::Path(Router& rtr, const std::vector& h, std::weak_ptr 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 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 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*) { diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index 6e81e9bd9..2af5aa2a6 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -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 { std::vector hops; - std::weak_ptr path_set; + std::weak_ptr 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 by path endpoint - struct Endpoint_Hash - { - size_t operator()(const std::shared_ptr& p) const - { - if (p == nullptr) - return 0; - return std::hash{}(p->pivot_router_id()); - } - }; - - /// comparision for equal endpoints - struct endpoint_comparator - { - bool operator()(const std::shared_ptr& left, const std::shared_ptr& right) const - { - return left && right && left->pivot_router_id() == left->pivot_router_id(); - } - }; } // namespace path } // namespace llarp + +namespace std +{ + template <> + struct hash + { + size_t operator()(const llarp::path::Path& p) const + { + auto& first_hop = p.hops[0]; + llarp::AlignedBuffer b; + std::memcpy(b.data(), first_hop.txID.data(), PATHIDSIZE); + std::memcpy(&b[PATHIDSIZE], first_hop.txID.data(), PATHIDSIZE); + + auto h = hash>{}(b); + return h ^ hash{}(first_hop.upstream); + } + }; +} // namespace std diff --git a/llarp/path/path_types.hpp b/llarp/path/path_types.hpp index 9303bff1d..7d3fe1830 100644 --- a/llarp/path/path_types.hpp +++ b/llarp/path/path_types.hpp @@ -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; diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp deleted file mode 100644 index 8841cd4ff..000000000 --- a/llarp/path/pathbuilder.cpp +++ /dev/null @@ -1,557 +0,0 @@ -#include "pathbuilder.hpp" - -#include "path.hpp" -#include "path_context.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -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(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(hash.data()), - reinterpret_cast(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 PathBuilder::SelectFirstHop(const std::set& exclude) const - { - std::optional 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> 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> PathBuilder::GetHopsAlignedToForBuild( - RouterID endpoint, const std::set& exclude) - { - const auto pathConfig = router->config()->paths; - - std::vector 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 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 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(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 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(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(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(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 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 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 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 diff --git a/llarp/path/pathhandler.hpp b/llarp/path/pathhandler.hpp index 21fbc6cd3..a779ce661 100644 --- a/llarp/path/pathhandler.hpp +++ b/llarp/path/pathhandler.hpp @@ -247,6 +247,6 @@ namespace llarp } // namespace path template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 67a4ff3cc..37a98dad5 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -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) { diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 583851251..b411c9768 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -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(); @@ -125,9 +125,9 @@ namespace llarp } // namespace path template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp @@ -136,7 +136,7 @@ namespace std template <> struct hash { - std::size_t operator()(llarp::path::TransitHopInfo const& a) const + std::size_t operator()(const llarp::path::TransitHopInfo& a) const { hash RHash{}; hash PHash{}; diff --git a/llarp/profiling.cpp b/llarp/profiling.cpp index 1b8e569ad..574262568 100644 --- a/llarp/profiling.cpp +++ b/llarp/profiling.cpp @@ -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; diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index a698fd40d..d358e9249 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -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 = true; + inline constexpr bool IsToStringFormattable = true; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; using RouterLookupHandler = std::function&)>; } // namespace llarp diff --git a/llarp/router_id.hpp b/llarp/router_id.hpp index 03069f4dd..72af15081 100644 --- a/llarp/router_id.hpp +++ b/llarp/router_id.hpp @@ -48,7 +48,7 @@ namespace llarp } template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp namespace std diff --git a/llarp/router_version.hpp b/llarp/router_version.hpp index a888f0bc2..9ac934fb5 100644 --- a/llarp/router_version.hpp +++ b/llarp/router_version.hpp @@ -59,7 +59,7 @@ namespace llarp }; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; static constexpr int64_t INVALID_VERSION = -1; static const RouterVersion emptyRouterVersion({0, 0, 0}, INVALID_VERSION); diff --git a/llarp/service/address.hpp b/llarp/service/address.hpp index 4d51486c3..ade98b5d8 100644 --- a/llarp/service/address.hpp +++ b/llarp/service/address.hpp @@ -91,7 +91,7 @@ namespace llarp } template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp namespace std diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 65e5584b1..78273af33 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -549,7 +549,7 @@ namespace llarp::service auto Endpoint::GetUniqueEndpointsForLookup() const { - std::unordered_set, path::Endpoint_Hash, path::endpoint_comparator> paths; + std::unordered_set> 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 diff --git a/llarp/service/info.hpp b/llarp/service/info.hpp index a617476ec..0b74191fc 100644 --- a/llarp/service/info.hpp +++ b/llarp/service/info.hpp @@ -97,4 +97,4 @@ namespace llarp::service } // namespace llarp::service template <> -constexpr inline bool llarp::IsToStringFormattable = true; +inline constexpr bool llarp::IsToStringFormattable = true; diff --git a/llarp/service/intro.hpp b/llarp/service/intro.hpp index ee4377798..66ba8ba1c 100644 --- a/llarp/service/intro.hpp +++ b/llarp/service/intro.hpp @@ -81,7 +81,7 @@ namespace llarp::service } // namespace llarp::service template <> -constexpr inline bool llarp::IsToStringFormattable = true; +inline constexpr bool llarp::IsToStringFormattable = true; namespace std { diff --git a/llarp/service/intro_set.hpp b/llarp/service/intro_set.hpp index 0c0ea0dd5..4fb757cb8 100644 --- a/llarp/service/intro_set.hpp +++ b/llarp/service/intro_set.hpp @@ -171,6 +171,6 @@ namespace llarp::service } // namespace llarp::service template <> -constexpr inline bool llarp::IsToStringFormattable = true; +inline constexpr bool llarp::IsToStringFormattable = true; template <> -constexpr inline bool llarp::IsToStringFormattable = true; +inline constexpr bool llarp::IsToStringFormattable = true; diff --git a/llarp/service/types.hpp b/llarp/service/types.hpp index dd349b39e..cc649994b 100644 --- a/llarp/service/types.hpp +++ b/llarp/service/types.hpp @@ -81,40 +81,41 @@ namespace llarp std::set& tags */); } // namespace util - template - static std:: - unordered_set, path::Endpoint_Hash, path::endpoint_comparator> - GetManyPathsWithUniqueEndpoints( - /* Endpoint_t* ep, - size_t N, - std::optional maybeLocation = std::nullopt, - size_t tries = 10 */) - { - // std::unordered_set exclude; - std::unordered_set, path::Endpoint_Hash, path::endpoint_comparator> paths; - // do - // { - // --tries; - // std::shared_ptr 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 + // static std:: + // unordered_set, path::Endpoint_Hash, path::endpoint_comparator> + // GetManyPathsWithUniqueEndpoints( + // /* Endpoint_t* ep, + // size_t N, + // std::optional maybeLocation = std::nullopt, + // size_t tries = 10 */) + // { + // // std::unordered_set exclude; + // std::unordered_set, path::Endpoint_Hash, path::endpoint_comparator> + // paths; + // // do + // // { + // // --tries; + // // std::shared_ptr 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 = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp diff --git a/llarp/util/aligned.hpp b/llarp/util/aligned.hpp index 4b6d57a9f..052d6a404 100644 --- a/llarp/util/aligned.hpp +++ b/llarp/util/aligned.hpp @@ -282,7 +282,7 @@ namespace llarp } // namespace detail // True if T is or is derived from AlignedBuffer for any N template - constexpr inline bool is_aligned_buffer = decltype(detail::is_aligned_buffer_impl(static_cast(nullptr)))::value; + inline constexpr bool is_aligned_buffer = decltype(detail::is_aligned_buffer_impl(static_cast(nullptr)))::value; } // namespace llarp diff --git a/llarp/util/logging.hpp b/llarp/util/logging.hpp index 68823f361..2c70bfcd9 100644 --- a/llarp/util/logging.hpp +++ b/llarp/util/logging.hpp @@ -40,7 +40,7 @@ namespace llarp template struct concat_args_fmt_impl> { - constexpr static std::array format{(I % 2 == 0 ? '{' : '}')...}; + static constexpr std::array format{(I % 2 == 0 ? '{' : '}')...}; }; template constexpr std::string_view concat_args_fmt() diff --git a/llarp/util/logging/buffer.hpp b/llarp/util/logging/buffer.hpp index 2413ef318..61ded535c 100644 --- a/llarp/util/logging/buffer.hpp +++ b/llarp/util/logging/buffer.hpp @@ -54,5 +54,5 @@ namespace llarp }; template <> - constexpr inline bool IsToStringFormattable = true; + inline constexpr bool IsToStringFormattable = true; } // namespace llarp diff --git a/llarp/util/str.cpp b/llarp/util/str.cpp index 25aba3898..d112039f4 100644 --- a/llarp/util/str.cpp +++ b/llarp/util/str.cpp @@ -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) { diff --git a/llarp/util/time.cpp b/llarp/util/time.cpp index bc9433fbf..6f1729c01 100644 --- a/llarp/util/time.cpp +++ b/llarp/util/time.cpp @@ -14,9 +14,9 @@ namespace llarp return std::chrono::duration_cast(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() diff --git a/llarp/win32/wintun.cpp b/llarp/win32/wintun.cpp index bc56b60c9..49b7dc1ae 100644 --- a/llarp/win32/wintun.cpp +++ b/llarp/win32/wintun.cpp @@ -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)