mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-15 12:13:24 +00:00
RC refactor layout
- Local and Remote RC's now implemented with discrete functionalities and uses
This commit is contained in:
parent
431490fb8b
commit
632f4ee70b
@ -41,7 +41,7 @@ if(APPLE)
|
||||
set(LOKINET_APPLE_BUILD 5)
|
||||
endif()
|
||||
|
||||
set(RELEASE_MOTTO "Our Lord And Savior" CACHE STRING "Release motto")
|
||||
set(LOKINET_RELEASE_MOTTO "Anonymous, decentralized, IP-based overlay network" CACHE STRING "Release motto")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||
|
||||
|
@ -86,7 +86,7 @@ main(int argc, char* argv[])
|
||||
#else
|
||||
cpr::Get(
|
||||
cpr::Url{bootstrap_url},
|
||||
cpr::Header{{"User-Agent", std::string{llarp::VERSION_FULL}}},
|
||||
cpr::Header{{"User-Agent", std::string{llarp::LOKINET_VERSION_FULL}}},
|
||||
cpr::Ssl(cpr::ssl::CaPath{X509_get_default_cert_dir()}));
|
||||
#endif
|
||||
if (resp.status_code != 200)
|
||||
|
@ -403,7 +403,7 @@ namespace
|
||||
{
|
||||
if (options.version)
|
||||
{
|
||||
std::cout << llarp::VERSION_FULL << std::endl;
|
||||
std::cout << llarp::LOKINET_VERSION_FULL << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -548,7 +548,8 @@ namespace
|
||||
static void
|
||||
run_main_context(std::optional<fs::path> confFile, const llarp::RuntimeOptions opts)
|
||||
{
|
||||
llarp::LogInfo(fmt::format("starting up {} {}", llarp::VERSION_FULL, llarp::RELEASE_MOTTO));
|
||||
llarp::LogInfo(fmt::format(
|
||||
"starting up {} {}", llarp::LOKINET_VERSION_FULL, llarp::LOKINET_RELEASE_MOTTO));
|
||||
try
|
||||
{
|
||||
std::shared_ptr<llarp::Config> conf;
|
||||
|
@ -99,6 +99,8 @@ lokinet_add_library(lokinet-time-place
|
||||
net/net_int.cpp
|
||||
net/sock_addr.cpp
|
||||
router_contact.cpp
|
||||
router_contact_local.cpp
|
||||
router_contact_remote.cpp
|
||||
router_id.cpp
|
||||
router_version.cpp # to be deleted shortly
|
||||
service/address.cpp
|
||||
|
@ -60,7 +60,7 @@ namespace llarp
|
||||
else
|
||||
{
|
||||
RouterContact rc;
|
||||
if (not rc.Read(fpath))
|
||||
if (not rc.read(fpath))
|
||||
{
|
||||
throw std::runtime_error{
|
||||
fmt::format("failed to decode bootstrap RC, file='{}', rc={}", fpath, rc)};
|
||||
|
@ -58,9 +58,10 @@ namespace llarp
|
||||
conf.defineOption<std::string>(
|
||||
"router",
|
||||
"netid",
|
||||
Default{llarp::DEFAULT_NETID},
|
||||
Default{llarp::LOKINET_DEFAULT_NETID},
|
||||
Comment{
|
||||
"Network ID; this is '"s + llarp::DEFAULT_NETID + "' for mainnet, 'gamma' for testnet.",
|
||||
"Network ID; this is '"s + llarp::LOKINET_DEFAULT_NETID
|
||||
+ "' for mainnet, 'gamma' for testnet.",
|
||||
},
|
||||
[this](std::string arg) {
|
||||
if (arg.size() > NetID::size())
|
||||
@ -1329,7 +1330,7 @@ namespace llarp
|
||||
std::set<IPRange> seenRanges;
|
||||
for (const auto& hop : rcs)
|
||||
{
|
||||
const auto network_addr = net::In6ToHUInt(hop.addr.in6().sin6_addr) & netmask;
|
||||
const auto network_addr = net::In6ToHUInt(hop.addr6()->in6().sin6_addr) & netmask;
|
||||
if (auto [it, inserted] = seenRanges.emplace(network_addr, netmask); not inserted)
|
||||
{
|
||||
return false;
|
||||
@ -1444,7 +1445,7 @@ namespace llarp
|
||||
{
|
||||
try
|
||||
{
|
||||
ini = util::slurp_file(*fname);
|
||||
ini = util::file_to_string(*fname);
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ namespace llarp
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Data = util::slurp_file(fname);
|
||||
m_Data = util::file_to_string(fname);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ namespace llarp
|
||||
m_transportKeyPath = deriveFile(our_transport_key_filename, config.router.m_transportKeyFile);
|
||||
|
||||
RouterContact rc;
|
||||
bool exists = rc.Read(m_rcPath);
|
||||
bool exists = rc.read(m_rcPath);
|
||||
if (not exists and not genIfAbsent)
|
||||
{
|
||||
LogError("Could not read RouterContact at path ", m_rcPath);
|
||||
@ -61,7 +61,7 @@ namespace llarp
|
||||
|
||||
// we need to back up keys if our self.signed doesn't appear to have a
|
||||
// valid signature
|
||||
m_needBackup = (isSNode and not rc.VerifySignature());
|
||||
m_needBackup = (isSNode and not rc.verify_signature());
|
||||
|
||||
// if our RC file can't be verified, assume it is out of date (e.g. uses
|
||||
// older encryption) and needs to be regenerated. before doing so, backup
|
||||
|
@ -4,12 +4,11 @@
|
||||
namespace llarp
|
||||
{
|
||||
// clang-format off
|
||||
const std::array<uint16_t, 3> VERSION{{@lokinet_VERSION_MAJOR@, @lokinet_VERSION_MINOR@, @lokinet_VERSION_PATCH@}};
|
||||
const std::array<uint64_t, 4> ROUTER_VERSION{{llarp::constants::proto_version, @lokinet_VERSION_MAJOR@, @lokinet_VERSION_MINOR@, @lokinet_VERSION_PATCH@}};
|
||||
const char* const VERSION_TAG = "@VERSIONTAG@";
|
||||
const char* const VERSION_FULL = "lokinet-@lokinet_VERSION_MAJOR@.@lokinet_VERSION_MINOR@.@lokinet_VERSION_PATCH@-@VERSIONTAG@";
|
||||
const std::array<uint16_t, 3> LOKINET_VERSION{{@lokinet_VERSION_MAJOR@, @lokinet_VERSION_MINOR@, @lokinet_VERSION_PATCH@}};
|
||||
const char* const LOKINET_VERSION_TAG = "@VERSIONTAG@";
|
||||
const char* const LOKINET_VERSION_FULL = "lokinet-@lokinet_VERSION_MAJOR@.@lokinet_VERSION_MINOR@.@lokinet_VERSION_PATCH@-@LOKINET_VERSION_TAG@";
|
||||
|
||||
const char* const RELEASE_MOTTO = "@RELEASE_MOTTO@";
|
||||
const char* const DEFAULT_NETID = "lokinet";
|
||||
const char* const LOKINET_RELEASE_MOTTO = "@RELEASE_MOTTO@";
|
||||
const char* const LOKINET_DEFAULT_NETID = "lokinet";
|
||||
// clang-format on
|
||||
} // namespace llarp
|
||||
|
@ -6,11 +6,10 @@
|
||||
namespace llarp
|
||||
{
|
||||
// Given a full lokinet version of: lokinet-1.2.3-abc these are:
|
||||
extern const std::array<uint16_t, 3> VERSION; // [1, 2, 3]
|
||||
extern const std::array<uint64_t, 4> ROUTER_VERSION; // [proto, 1, 2, 3]
|
||||
extern const char* const VERSION_TAG; // "abc"
|
||||
extern const char* const VERSION_FULL; // "lokinet-1.2.3-abc"
|
||||
extern const std::array<uint16_t, 3> LOKINET_VERSION;
|
||||
extern const char* const LOKINET_VERSION_TAG;
|
||||
extern const char* const LOKINET_VERSION_FULL;
|
||||
|
||||
extern const char* const RELEASE_MOTTO;
|
||||
extern const char* const DEFAULT_NETID;
|
||||
extern const char* const LOKINET_RELEASE_MOTTO;
|
||||
extern const char* const LOKINET_DEFAULT_NETID;
|
||||
} // namespace llarp
|
||||
|
@ -59,7 +59,8 @@ namespace llarp
|
||||
throw std::runtime_error("Cannot call Setup() on context without a Config");
|
||||
|
||||
if (opts.showBanner)
|
||||
llarp::LogInfo(fmt::format("{} {}", llarp::VERSION_FULL, llarp::RELEASE_MOTTO));
|
||||
llarp::LogInfo(
|
||||
fmt::format("{} {}", llarp::LOKINET_VERSION_FULL, llarp::LOKINET_RELEASE_MOTTO));
|
||||
|
||||
if (!loop)
|
||||
{
|
||||
|
@ -273,6 +273,14 @@ namespace llarp
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
crypto::verify(const PubKey& pub, ustring_view data, ustring_view sig)
|
||||
{
|
||||
return (pub.size() == 32 && sig.size() == 64)
|
||||
? crypto_sign_verify_detached(sig.data(), data.data(), data.size(), pub.data()) != -1
|
||||
: false;
|
||||
}
|
||||
|
||||
bool
|
||||
crypto::verify(const PubKey& pub, uint8_t* buf, size_t size, const Signature& sig)
|
||||
{
|
||||
@ -428,11 +436,6 @@ namespace llarp
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
crypto::seed_to_secretkey(llarp::SecretKey& secret, const llarp::IdentitySecret& seed)
|
||||
{
|
||||
return crypto_sign_ed25519_seed_keypair(secret.data() + 32, secret.data(), seed.data()) != -1;
|
||||
}
|
||||
void
|
||||
crypto::randomize(uint8_t* buf, size_t len)
|
||||
{
|
||||
@ -517,19 +520,19 @@ namespace llarp
|
||||
#endif
|
||||
|
||||
const byte_t*
|
||||
seckey_topublic(const SecretKey& sec)
|
||||
seckey_to_pubkey(const SecretKey& sec)
|
||||
{
|
||||
return sec.data() + 32;
|
||||
}
|
||||
|
||||
const byte_t*
|
||||
pq_keypair_to_public(const PQKeyPair& k)
|
||||
pq_keypair_to_pubkey(const PQKeyPair& k)
|
||||
{
|
||||
return k.data() + PQ_SECRETKEYSIZE;
|
||||
}
|
||||
|
||||
const byte_t*
|
||||
pq_keypair_to_secret(const PQKeyPair& k)
|
||||
pq_keypair_to_seckey(const PQKeyPair& k)
|
||||
{
|
||||
return k.data();
|
||||
}
|
||||
|
@ -64,8 +64,11 @@ namespace llarp
|
||||
sign(Signature&, const PrivateKey&, uint8_t* buf, size_t size);
|
||||
/// ed25519 verify
|
||||
bool
|
||||
verify(const PubKey&, ustring_view, ustring_view);
|
||||
bool
|
||||
verify(const PubKey&, uint8_t*, size_t, const Signature&);
|
||||
bool verify(ustring_view, ustring_view, ustring_view);
|
||||
bool
|
||||
verify(ustring_view, ustring_view, ustring_view);
|
||||
bool
|
||||
verify(uint8_t*, uint8_t*, size_t, uint8_t*);
|
||||
|
||||
@ -87,9 +90,6 @@ namespace llarp
|
||||
uint64_t key_n,
|
||||
const AlignedBuffer<32>* hash = nullptr);
|
||||
|
||||
/// seed to secretkey
|
||||
bool
|
||||
seed_to_secretkey(llarp::SecretKey&, const llarp::IdentitySecret&);
|
||||
/// randomize buffer
|
||||
void
|
||||
randomize(uint8_t* buf, size_t len);
|
||||
@ -124,13 +124,13 @@ namespace llarp
|
||||
randint();
|
||||
|
||||
const byte_t*
|
||||
seckey_topublic(const SecretKey& secret);
|
||||
seckey_to_pubkey(const SecretKey& secret);
|
||||
|
||||
const byte_t*
|
||||
pq_keypair_to_public(const PQKeyPair& keypair);
|
||||
pq_keypair_to_pubkey(const PQKeyPair& keypair);
|
||||
|
||||
const byte_t*
|
||||
pq_keypair_to_secret(const PQKeyPair& keypair);
|
||||
pq_keypair_to_seckey(const PQKeyPair& keypair);
|
||||
|
||||
/// rng type that uses llarp::randint(), which is cryptographically secure
|
||||
struct CSRNG
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "types.hpp"
|
||||
|
||||
#include <llarp/router_id.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/file.hpp>
|
||||
|
||||
@ -32,6 +33,36 @@ namespace llarp
|
||||
return oxenc::to_hex(begin(), end());
|
||||
}
|
||||
|
||||
PubKey::operator RouterID() const
|
||||
{
|
||||
return {as_array()};
|
||||
}
|
||||
|
||||
PubKey&
|
||||
PubKey::operator=(const byte_t* ptr)
|
||||
{
|
||||
std::copy(ptr, ptr + SIZE, begin());
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const PubKey& lhs, const PubKey& rhs)
|
||||
{
|
||||
return lhs.as_array() == rhs.as_array();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const PubKey& lhs, const RouterID& rhs)
|
||||
{
|
||||
return lhs.as_array() == rhs.as_array();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const RouterID& lhs, const PubKey& rhs)
|
||||
{
|
||||
return lhs.as_array() == rhs.as_array();
|
||||
}
|
||||
|
||||
bool
|
||||
SecretKey::LoadFromFile(const fs::path& fname)
|
||||
{
|
||||
@ -39,7 +70,7 @@ namespace llarp
|
||||
std::array<byte_t, 128> tmp;
|
||||
try
|
||||
{
|
||||
sz = util::slurp_file(fname, tmp.data(), tmp.size());
|
||||
sz = util::file_to_buffer(fname, tmp.data(), tmp.size());
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
@ -107,53 +138,7 @@ namespace llarp
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IdentitySecret::LoadFromFile(const fs::path& fname)
|
||||
{
|
||||
std::array<byte_t, SIZE> buf;
|
||||
size_t sz;
|
||||
try
|
||||
{
|
||||
sz = util::slurp_file(fname, buf.data(), buf.size());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
llarp::LogError("failed to load service node seed: ", e.what());
|
||||
return false;
|
||||
}
|
||||
if (sz != SIZE)
|
||||
{
|
||||
llarp::LogError("service node seed size invalid: ", sz, " != ", SIZE);
|
||||
return false;
|
||||
}
|
||||
std::copy(buf.begin(), buf.end(), begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
byte_t*
|
||||
Signature::Lo()
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
const byte_t*
|
||||
Signature::Lo() const
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
byte_t*
|
||||
Signature::Hi()
|
||||
{
|
||||
return data() + 32;
|
||||
}
|
||||
|
||||
const byte_t*
|
||||
Signature::Hi() const
|
||||
{
|
||||
return data() + 32;
|
||||
}
|
||||
} // namespace llarp
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include "constants.hpp"
|
||||
|
||||
#include <llarp/router_id.hpp>
|
||||
#include <llarp/util/aligned.hpp>
|
||||
#include <llarp/util/fs.hpp>
|
||||
#include <llarp/util/types.hpp>
|
||||
@ -15,7 +14,9 @@ namespace llarp
|
||||
using SharedSecret = AlignedBuffer<SHAREDKEYSIZE>;
|
||||
using KeyExchangeNonce = AlignedBuffer<32>;
|
||||
|
||||
struct PubKey final : public AlignedBuffer<PUBKEYSIZE>
|
||||
struct RouterID;
|
||||
|
||||
struct PubKey : public AlignedBuffer<PUBKEYSIZE>
|
||||
{
|
||||
PubKey() = default;
|
||||
|
||||
@ -37,36 +38,20 @@ namespace llarp
|
||||
static PubKey
|
||||
from_string(const std::string& s);
|
||||
|
||||
operator RouterID() const
|
||||
{
|
||||
return {as_array()};
|
||||
}
|
||||
operator RouterID() const;
|
||||
|
||||
PubKey&
|
||||
operator=(const byte_t* ptr)
|
||||
{
|
||||
std::copy(ptr, ptr + SIZE, begin());
|
||||
return *this;
|
||||
}
|
||||
operator=(const byte_t* ptr);
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const PubKey& lhs, const PubKey& rhs)
|
||||
{
|
||||
return lhs.as_array() == rhs.as_array();
|
||||
}
|
||||
bool
|
||||
operator==(const PubKey& lhs, const PubKey& rhs);
|
||||
|
||||
inline bool
|
||||
operator==(const PubKey& lhs, const RouterID& rhs)
|
||||
{
|
||||
return lhs.as_array() == rhs.as_array();
|
||||
}
|
||||
bool
|
||||
operator==(const PubKey& lhs, const RouterID& rhs);
|
||||
|
||||
inline bool
|
||||
operator==(const RouterID& lhs, const PubKey& rhs)
|
||||
{
|
||||
return lhs.as_array() == rhs.as_array();
|
||||
}
|
||||
bool
|
||||
operator==(const RouterID& lhs, const PubKey& rhs);
|
||||
|
||||
struct PrivateKey;
|
||||
|
||||
@ -161,58 +146,24 @@ namespace llarp
|
||||
toPublic(PubKey& pubkey) const;
|
||||
};
|
||||
|
||||
/// IdentitySecret is a secret key from a service node secret seed
|
||||
struct IdentitySecret final : public AlignedBuffer<32>
|
||||
{
|
||||
IdentitySecret() : AlignedBuffer<32>()
|
||||
{}
|
||||
|
||||
/// no copy constructor
|
||||
explicit IdentitySecret(const IdentitySecret&) = delete;
|
||||
// no byte data constructor
|
||||
explicit IdentitySecret(const byte_t*) = delete;
|
||||
|
||||
/// load service node seed from file
|
||||
bool
|
||||
LoadFromFile(const fs::path& fname);
|
||||
|
||||
std::string_view
|
||||
ToString() const
|
||||
{
|
||||
return "[IdentitySecret]";
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<PubKey> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<SecretKey> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<PrivateKey> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<IdentitySecret> = true;
|
||||
|
||||
using ShortHash = AlignedBuffer<SHORTHASHSIZE>;
|
||||
using LongHash = AlignedBuffer<HASHSIZE>;
|
||||
|
||||
struct Signature final : public AlignedBuffer<SIGSIZE>
|
||||
{
|
||||
byte_t*
|
||||
Hi();
|
||||
|
||||
const byte_t*
|
||||
Hi() const;
|
||||
|
||||
byte_t*
|
||||
Lo();
|
||||
|
||||
const byte_t*
|
||||
Lo() const;
|
||||
//
|
||||
};
|
||||
|
||||
using TunnelNonce = AlignedBuffer<TUNNONCESIZE>;
|
||||
using SymmNonce = AlignedBuffer<NONCESIZE>;
|
||||
using SymmKey = AlignedBuffer<32>;
|
||||
using SymmKey = AlignedBuffer<32>; // not used
|
||||
|
||||
using PQCipherBlock = AlignedBuffer<PQ_CIPHERTEXTSIZE + 1>;
|
||||
using PQPubKey = AlignedBuffer<PQ_PUBKEYSIZE>;
|
||||
|
@ -22,7 +22,7 @@ namespace llarp::dht
|
||||
bool
|
||||
operator()(const RouterContact& left, const RouterContact& right) const
|
||||
{
|
||||
return (left.pubkey ^ us) < (right.pubkey ^ us);
|
||||
return (left.router_id() ^ us) < (right.router_id() ^ us);
|
||||
}
|
||||
};
|
||||
} // namespace llarp::dht
|
||||
|
@ -19,19 +19,19 @@ namespace llarp::dht
|
||||
ID.Zero();
|
||||
}
|
||||
|
||||
RCNode(const RouterContact& other) : rc(other), ID(other.pubkey)
|
||||
RCNode(const RouterContact& other) : rc(other), ID(other.router_id())
|
||||
{}
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const
|
||||
{
|
||||
return rc.ExtractStatus();
|
||||
return rc.extract_status();
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const RCNode& other) const
|
||||
{
|
||||
return rc.last_updated < other.rc.last_updated;
|
||||
return rc.timestamp() < other.rc.timestamp();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -580,25 +580,29 @@ namespace llarp::handlers
|
||||
{
|
||||
router->modify_rc(
|
||||
[srvRecords = SRVRecords()](RouterContact rc) -> std::optional<RouterContact> {
|
||||
// TODO: update this RouterContact handling
|
||||
|
||||
// check if there are any new srv records
|
||||
bool shouldUpdate = false;
|
||||
// bool shouldUpdate = false;
|
||||
|
||||
for (const auto& rcSrv : rc.srvRecords)
|
||||
{
|
||||
if (srvRecords.count(rcSrv) == 0)
|
||||
shouldUpdate = true;
|
||||
}
|
||||
// for (const auto& rcSrv : rc.srvRecords)
|
||||
// {
|
||||
// if (srvRecords.count(rcSrv) == 0)
|
||||
// shouldUpdate = true;
|
||||
// }
|
||||
|
||||
// no new records so don't modify
|
||||
if (not shouldUpdate)
|
||||
return std::nullopt;
|
||||
// // no new records so don't modify
|
||||
// if (not shouldUpdate)
|
||||
// return std::nullopt;
|
||||
|
||||
// we got new entries so we clear the whole vector on the rc and recreate it
|
||||
rc.srvRecords.clear();
|
||||
for (auto& record : srvRecords)
|
||||
rc.srvRecords.emplace_back(record);
|
||||
// set the verssion to 1 because we have srv records
|
||||
rc.version = 1;
|
||||
// // we got new entries so we clear the whole vector on the rc and recreate it
|
||||
// rc.srvRecords.clear();
|
||||
|
||||
// for (auto& record : srvRecords)
|
||||
// rc.srvRecords.emplace_back(record);
|
||||
|
||||
// // set the verssion to 1 because we have srv records
|
||||
// rc.version = 1;
|
||||
return rc;
|
||||
});
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ namespace llarp
|
||||
|
||||
while (itr != nodes.end())
|
||||
{
|
||||
if (itr->second.rc.IsExpired(now))
|
||||
if (itr->second.rc.is_expired(now))
|
||||
itr = nodes.erase(itr);
|
||||
else
|
||||
++itr;
|
||||
|
@ -20,7 +20,7 @@ namespace llarp
|
||||
std::shared_ptr<link::Connection>
|
||||
Endpoint::get_conn(const RouterContact& rc) const
|
||||
{
|
||||
if (auto itr = conns.find(rc.pubkey); itr != conns.end())
|
||||
if (auto itr = conns.find(rc.router_id()); itr != conns.end())
|
||||
return itr->second;
|
||||
|
||||
return nullptr;
|
||||
@ -303,14 +303,14 @@ namespace llarp
|
||||
void
|
||||
LinkManager::connect_to(const RouterContact& rc)
|
||||
{
|
||||
if (auto conn = ep.get_conn(rc.pubkey); conn)
|
||||
if (auto conn = ep.get_conn(rc.router_id()); conn)
|
||||
{
|
||||
// TODO: should implement some connection failed logic, but not the same logic that
|
||||
// would be executed for another failure case
|
||||
return;
|
||||
}
|
||||
|
||||
auto& remote_addr = rc.addr;
|
||||
const auto& remote_addr = rc.addr();
|
||||
|
||||
// TODO: confirm remote end is using the expected pubkey (RouterID).
|
||||
// TODO: ALPN for "client" vs "relay" (could just be set on endpoint creation)
|
||||
@ -491,9 +491,9 @@ namespace llarp
|
||||
|
||||
if (auto maybe_other = node_db->GetRandom(filter))
|
||||
{
|
||||
exclude.insert(maybe_other->pubkey);
|
||||
exclude.insert(maybe_other->router_id());
|
||||
|
||||
if (not rc_lookup->is_session_allowed(maybe_other->pubkey))
|
||||
if (not rc_lookup->is_session_allowed(maybe_other->router_id()))
|
||||
continue;
|
||||
|
||||
connect_to(*maybe_other);
|
||||
@ -609,23 +609,25 @@ namespace llarp
|
||||
target_rid.FromString(target_key);
|
||||
|
||||
const auto target_addr = dht::Key_t{reinterpret_cast<uint8_t*>(target_key.data())};
|
||||
const auto& local_rid = _router.rc().pubkey;
|
||||
const auto& local_rid = _router.rc().router_id();
|
||||
const auto local_key = dht::Key_t{local_rid};
|
||||
|
||||
if (is_exploratory)
|
||||
{
|
||||
std::string neighbors{};
|
||||
|
||||
const auto closest_rcs =
|
||||
_router.node_db()->find_many_closest_to(target_addr, RC_LOOKUP_STORAGE_REDUNDANCY);
|
||||
|
||||
for (const auto& rc : closest_rcs)
|
||||
{
|
||||
const auto& rid = rc.pubkey;
|
||||
const auto& rid = rc.router_id();
|
||||
if (_router.router_profiling().IsBadForConnect(rid) || target_rid == rid
|
||||
|| local_rid == rid)
|
||||
continue;
|
||||
|
||||
neighbors += rid.bt_encode();
|
||||
neighbors +=
|
||||
rid.bt_encode(); // TODO: refactor to use reference to bt_dict_producer subdict
|
||||
}
|
||||
|
||||
m.respond(
|
||||
@ -635,12 +637,12 @@ namespace llarp
|
||||
else
|
||||
{
|
||||
const auto closest_rc = _router.node_db()->find_closest_to(target_addr);
|
||||
const auto& closest_rid = closest_rc.pubkey;
|
||||
const auto& closest_rid = closest_rc.router_id();
|
||||
const auto closest_key = dht::Key_t{closest_rid};
|
||||
|
||||
if (target_addr == closest_key)
|
||||
{
|
||||
if (closest_rc.ExpiresSoon(llarp::time_now_ms()))
|
||||
if (closest_rc.expires_within_delta(llarp::time_now_ms()))
|
||||
{
|
||||
send_control_message(
|
||||
target_rid,
|
||||
@ -837,7 +839,7 @@ namespace llarp
|
||||
|
||||
const auto now = _router.now();
|
||||
const auto addr = dht::Key_t{reinterpret_cast<uint8_t*>(derived_signing_key.data())};
|
||||
const auto local_key = _router.rc().pubkey;
|
||||
const auto local_key = _router.rc().router_id();
|
||||
|
||||
if (not service::EncryptedIntroSet::verify(introset, derived_signing_key, sig))
|
||||
{
|
||||
@ -878,7 +880,7 @@ namespace llarp
|
||||
log::info(link_cat, "Relaying PublishIntroMessage for {}", addr);
|
||||
|
||||
const auto& peer_rc = closest_rcs[relay_order];
|
||||
const auto& peer_key = peer_rc.pubkey;
|
||||
const auto& peer_key = peer_rc.router_id();
|
||||
|
||||
if (peer_key == local_key)
|
||||
{
|
||||
@ -908,7 +910,7 @@ namespace llarp
|
||||
|
||||
for (const auto& rc : closest_rcs)
|
||||
{
|
||||
if (rc.pubkey == local_key)
|
||||
if (rc.router_id() == local_key)
|
||||
{
|
||||
rc_index = index;
|
||||
break;
|
||||
@ -1024,7 +1026,7 @@ namespace llarp
|
||||
log::info(link_cat, "Relaying FindIntroMessage for {}", addr);
|
||||
|
||||
const auto& peer_rc = closest_rcs[relay_order];
|
||||
const auto& peer_key = peer_rc.pubkey;
|
||||
const auto& peer_key = peer_rc.router_id();
|
||||
|
||||
send_control_message(
|
||||
peer_key,
|
||||
|
@ -372,8 +372,8 @@ namespace llarp
|
||||
endpoint->connect(remote, link_manager.tls_creds, std::forward<Opt>(opts)...);
|
||||
|
||||
// emplace immediately for connection open callback to find scid
|
||||
connid_map.emplace(conn_interface->scid(), rc.pubkey);
|
||||
auto [itr, b] = conns.emplace(rc.pubkey, nullptr);
|
||||
connid_map.emplace(conn_interface->scid(), rc.router_id());
|
||||
auto [itr, b] = conns.emplace(rc.router_id(), nullptr);
|
||||
|
||||
auto control_stream =
|
||||
conn_interface->template get_new_stream<oxen::quic::BTRequestStream>();
|
||||
|
@ -22,7 +22,7 @@ namespace llarp
|
||||
|
||||
hop.nonce.Randomize();
|
||||
// do key exchange
|
||||
if (!crypto::dh_client(hop.shared, hop.rc.pubkey, hop.commkey, hop.nonce))
|
||||
if (!crypto::dh_client(hop.shared, hop.rc._pubkey, hop.commkey, hop.nonce))
|
||||
{
|
||||
auto err = fmt::format("Failed to generate shared key for path build!");
|
||||
log::warning(path_cat, err);
|
||||
@ -60,7 +60,7 @@ namespace llarp
|
||||
outer_nonce.Randomize();
|
||||
|
||||
// derive (outer) shared key
|
||||
if (!crypto::dh_client(shared, hop.rc.pubkey, framekey, outer_nonce))
|
||||
if (!crypto::dh_client(shared, hop.rc._pubkey, framekey, outer_nonce))
|
||||
{
|
||||
log::warning(path_cat, "DH client failed during hop info encryption!");
|
||||
throw std::runtime_error{"DH failed during hop info encryption"};
|
||||
|
@ -54,7 +54,7 @@ namespace llarp
|
||||
bool
|
||||
RelayUpstreamMessage::handle_message(Router* r) const
|
||||
{
|
||||
auto path = r->path_context().GetByDownstream(conn->remote_rc.pubkey, pathid);
|
||||
auto path = r->path_context().GetByDownstream(conn->remote_rc._pubkey, pathid);
|
||||
if (path)
|
||||
{
|
||||
return path->HandleUpstream(llarp_buffer_t(enc), nonce, r);
|
||||
@ -110,7 +110,7 @@ namespace llarp
|
||||
bool
|
||||
RelayDownstreamMessage::handle_message(Router* r) const
|
||||
{
|
||||
auto path = r->path_context().GetByUpstream(conn->remote_rc.pubkey, pathid);
|
||||
auto path = r->path_context().GetByUpstream(conn->remote_rc._pubkey, pathid);
|
||||
if (path)
|
||||
{
|
||||
return path->HandleDownstream(llarp_buffer_t(enc), nonce, r);
|
||||
|
@ -14,8 +14,6 @@ static const std::string RC_FILE_EXT = ".signed";
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
static auto logcat = log::Cat("nodedb");
|
||||
|
||||
NodeDB::Entry::Entry(RouterContact value) : rc(std::move(value)), insertedAt(llarp::time_now_ms())
|
||||
{}
|
||||
|
||||
@ -79,7 +77,7 @@ namespace llarp
|
||||
// TODO: split this up? idk maybe some day...
|
||||
disk([this, data = std::move(copy)]() {
|
||||
for (const auto& rc : data)
|
||||
rc.Write(get_path_by_pubkey(rc.pubkey));
|
||||
rc.write(get_path_by_pubkey(rc.router_id()));
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -123,20 +121,14 @@ namespace llarp
|
||||
|
||||
RouterContact rc{};
|
||||
|
||||
if (not rc.Read(f))
|
||||
if (not rc.read(f))
|
||||
{
|
||||
// try loading it, purge it if it is junk
|
||||
purge.emplace(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (not rc.FromOurNetwork())
|
||||
{
|
||||
// skip entries that are not from our network
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rc.IsExpired(time_now_ms()))
|
||||
if (rc.is_expired(time_now_ms()))
|
||||
{
|
||||
// rc expired dont load it and purge it later
|
||||
purge.emplace(f);
|
||||
@ -145,8 +137,8 @@ namespace llarp
|
||||
|
||||
// validate signature and purge entries with invalid signatures
|
||||
// load ones with valid signatures
|
||||
if (rc.VerifySignature())
|
||||
entries.emplace(rc.pubkey, rc);
|
||||
if (rc.verify_signature()) // TODO: fix this after RouterContact -> RemoteRC
|
||||
entries.emplace(rc.router_id(), rc);
|
||||
else
|
||||
purge.emplace(f);
|
||||
|
||||
@ -172,7 +164,7 @@ namespace llarp
|
||||
|
||||
router.loop()->call([this]() {
|
||||
for (const auto& item : entries)
|
||||
item.second.rc.Write(get_path_by_pubkey(item.first));
|
||||
item.second.rc.write(get_path_by_pubkey(item.first));
|
||||
});
|
||||
}
|
||||
|
||||
@ -213,9 +205,9 @@ namespace llarp
|
||||
auto itr = entries.begin();
|
||||
while (itr != entries.end())
|
||||
{
|
||||
if (itr->second.insertedAt < cutoff and keep.count(itr->second.rc.pubkey) == 0)
|
||||
if (itr->second.insertedAt < cutoff and keep.count(itr->second.rc.router_id()) == 0)
|
||||
{
|
||||
removed.insert(itr->second.rc.pubkey);
|
||||
removed.insert(itr->second.rc.router_id());
|
||||
itr = entries.erase(itr);
|
||||
}
|
||||
else
|
||||
@ -230,8 +222,8 @@ namespace llarp
|
||||
NodeDB::put_rc(RouterContact rc)
|
||||
{
|
||||
router.loop()->call([this, rc]() {
|
||||
entries.erase(rc.pubkey);
|
||||
entries.emplace(rc.pubkey, rc);
|
||||
entries.erase(rc.router_id());
|
||||
entries.emplace(rc.router_id(), rc);
|
||||
});
|
||||
}
|
||||
|
||||
@ -245,14 +237,14 @@ namespace llarp
|
||||
NodeDB::put_rc_if_newer(RouterContact rc)
|
||||
{
|
||||
router.loop()->call([this, rc]() {
|
||||
auto itr = entries.find(rc.pubkey);
|
||||
if (itr == entries.end() or itr->second.rc.OtherIsNewer(rc))
|
||||
auto itr = entries.find(rc.router_id());
|
||||
if (itr == entries.end() or itr->second.rc.other_is_newer(rc))
|
||||
{
|
||||
// delete if existing
|
||||
if (itr != entries.end())
|
||||
entries.erase(itr);
|
||||
// add new entry
|
||||
entries.emplace(rc.pubkey, rc);
|
||||
entries.emplace(rc.router_id(), rc);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -282,14 +274,14 @@ namespace llarp
|
||||
llarp::RouterContact rc;
|
||||
const llarp::dht::XorMetric compare(location);
|
||||
VisitAll([&rc, compare](const auto& otherRC) {
|
||||
if (rc.pubkey.IsZero())
|
||||
if (rc.router_id().IsZero())
|
||||
{
|
||||
rc = otherRC;
|
||||
return;
|
||||
}
|
||||
if (compare(
|
||||
llarp::dht::Key_t{otherRC.pubkey.as_array()},
|
||||
llarp::dht::Key_t{rc.pubkey.as_array()}))
|
||||
llarp::dht::Key_t{rc.router_id().as_array()}))
|
||||
rc = otherRC;
|
||||
});
|
||||
return rc;
|
||||
|
@ -150,7 +150,7 @@ namespace llarp
|
||||
{
|
||||
if (visit(itr->second.rc))
|
||||
{
|
||||
removed.insert(itr->second.rc.pubkey);
|
||||
removed.insert(itr->second.rc.router_id());
|
||||
itr = entries.erase(itr);
|
||||
}
|
||||
else
|
||||
|
@ -40,7 +40,7 @@ namespace llarp::path
|
||||
hops[idx].txID = hops[idx + 1].rxID;
|
||||
}
|
||||
// initialize parts of the introduction
|
||||
intro.router = hops[hsz - 1].rc.pubkey;
|
||||
intro.router = hops[hsz - 1].rc._router_id;
|
||||
intro.path_id = hops[hsz - 1].txID;
|
||||
if (auto parent = m_PathSet.lock())
|
||||
EnterState(ePathBuilding, parent->Now());
|
||||
@ -152,13 +152,13 @@ namespace llarp::path
|
||||
RouterID
|
||||
Path::Endpoint() const
|
||||
{
|
||||
return hops[hops.size() - 1].rc.pubkey;
|
||||
return hops[hops.size() - 1].rc._router_id;
|
||||
}
|
||||
|
||||
PubKey
|
||||
Path::EndpointPubKey() const
|
||||
{
|
||||
return hops[hops.size() - 1].rc.pubkey;
|
||||
return hops[hops.size() - 1].rc._router_id;
|
||||
}
|
||||
|
||||
PathID_t
|
||||
@ -184,13 +184,13 @@ namespace llarp::path
|
||||
bool
|
||||
Path::is_endpoint(const RouterID& r, const PathID_t& id) const
|
||||
{
|
||||
return hops[hops.size() - 1].rc.pubkey == r && hops[hops.size() - 1].txID == id;
|
||||
return hops[hops.size() - 1].rc._router_id == r && hops[hops.size() - 1].txID == id;
|
||||
}
|
||||
|
||||
RouterID
|
||||
Path::upstream() const
|
||||
{
|
||||
return hops[0].rc.pubkey;
|
||||
return hops[0].rc._router_id;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
@ -208,7 +208,7 @@ namespace llarp::path
|
||||
{
|
||||
if (!hops.empty())
|
||||
hops_str += " -> ";
|
||||
hops_str += RouterID(hop.rc.pubkey).ToString();
|
||||
hops_str += RouterID(hop.rc._router_id).ToString();
|
||||
}
|
||||
return hops_str;
|
||||
}
|
||||
@ -262,9 +262,9 @@ namespace llarp::path
|
||||
PathHopConfig::ExtractStatus() const
|
||||
{
|
||||
util::StatusObject obj{
|
||||
{"ip", rc.addr.to_string()},
|
||||
{"ip", rc._addr.to_string()},
|
||||
{"lifetime", to_json(lifetime)},
|
||||
{"router", rc.pubkey.ToHex()},
|
||||
{"router", rc._router_id.ToHex()},
|
||||
{"txid", txID.ToHex()},
|
||||
{"rxid", rxID.ToHex()}};
|
||||
return obj;
|
||||
|
@ -83,7 +83,7 @@ namespace llarp
|
||||
|
||||
hop.nonce.Randomize();
|
||||
// do key exchange
|
||||
if (!crypto::dh_client(hop.shared, hop.rc.pubkey, hop.commkey, hop.nonce))
|
||||
if (!crypto::dh_client(hop.shared, hop.rc._pubkey, hop.commkey, hop.nonce))
|
||||
{
|
||||
auto err = fmt::format("{} failed to generate shared key for path build!", Name());
|
||||
log::error(path_cat, err);
|
||||
@ -121,7 +121,7 @@ namespace llarp
|
||||
outer_nonce.Randomize();
|
||||
|
||||
// derive (outer) shared key
|
||||
if (!crypto::dh_client(shared, hop.rc.pubkey, framekey, outer_nonce))
|
||||
if (!crypto::dh_client(shared, hop.rc._pubkey, framekey, outer_nonce))
|
||||
{
|
||||
log::error(path_cat, "DH client failed during hop info encryption!");
|
||||
throw std::runtime_error{"DH failed during hop info encryption"};
|
||||
@ -218,16 +218,16 @@ namespace llarp
|
||||
router->for_each_connection([&](link::Connection& conn) {
|
||||
const auto& rc = conn.remote_rc;
|
||||
#ifndef TESTNET
|
||||
if (router->IsBootstrapNode(rc.pubkey))
|
||||
if (router->IsBootstrapNode(rc._pubkey))
|
||||
return;
|
||||
#endif
|
||||
if (exclude.count(rc.pubkey))
|
||||
if (exclude.count(rc._pubkey))
|
||||
return;
|
||||
|
||||
if (BuildCooldownHit(rc.pubkey))
|
||||
if (BuildCooldownHit(rc._pubkey))
|
||||
return;
|
||||
|
||||
if (router->router_profiling().IsBadForPath(rc.pubkey))
|
||||
if (router->router_profiling().IsBadForPath(rc._pubkey))
|
||||
return;
|
||||
|
||||
found = rc;
|
||||
@ -243,7 +243,7 @@ namespace llarp
|
||||
};
|
||||
if (const auto maybe = router->node_db()->GetRandom(filter))
|
||||
{
|
||||
return GetHopsAlignedToForBuild(maybe->pubkey);
|
||||
return GetHopsAlignedToForBuild(maybe->_pubkey);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
@ -353,7 +353,7 @@ namespace llarp
|
||||
return false;
|
||||
for (const auto& hop : hopsSet)
|
||||
{
|
||||
if (hop.pubkey == rc.pubkey)
|
||||
if (hop._pubkey == rc.pubkey)
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -362,7 +362,7 @@ namespace llarp
|
||||
if (not pathConfig.Acceptable(hopsSet))
|
||||
return false;
|
||||
#endif
|
||||
return rc.pubkey != endpointRC.pubkey;
|
||||
return rc.pubkey != endpointRC._pubkey;
|
||||
};
|
||||
|
||||
if (const auto maybe = router->node_db()->GetRandom(filter))
|
||||
@ -402,7 +402,7 @@ namespace llarp
|
||||
}
|
||||
|
||||
lastBuild = llarp::time_now_ms();
|
||||
const RouterID edge{hops[0].pubkey};
|
||||
const RouterID edge{hops[0]._pubkey};
|
||||
|
||||
if (not router->pathbuild_limiter().Attempt(edge))
|
||||
{
|
||||
@ -429,7 +429,7 @@ namespace llarp
|
||||
{
|
||||
bool lastHop = (i == (n_hops - 1));
|
||||
|
||||
const auto& nextHop = lastHop ? path_hops[i].rc.pubkey : path_hops[i + 1].rc.pubkey;
|
||||
const auto& nextHop = lastHop ? path_hops[i].rc._pubkey : path_hops[i + 1].rc._pubkey;
|
||||
|
||||
PathBuildMessage::setup_hop_keys(path_hops[i], nextHop);
|
||||
auto frame_str = PathBuildMessage::serialize(path_hops[i]);
|
||||
@ -533,7 +533,7 @@ namespace llarp
|
||||
DoPathBuildBackoff();
|
||||
for (const auto& hop : p->hops)
|
||||
{
|
||||
const RouterID target{hop.rc.pubkey};
|
||||
const RouterID target{hop.rc._pubkey};
|
||||
// look up router and see if it's still on the network
|
||||
log::info(path_cat, "Looking up RouterID {} due to path build timeout", target);
|
||||
|
||||
|
@ -10,8 +10,6 @@ using oxenc::bt_dict_producer;
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
static auto logcat = log::Cat("profiling");
|
||||
|
||||
RouterProfile::RouterProfile(bt_dict_consumer dict)
|
||||
{
|
||||
BDecode(std::move(dict));
|
||||
@ -204,7 +202,7 @@ namespace llarp
|
||||
first = false;
|
||||
else
|
||||
{
|
||||
auto& profile = m_Profiles[hop.rc.pubkey];
|
||||
auto& profile = m_Profiles[hop.rc.router_id()];
|
||||
profile.pathFailCount += 1;
|
||||
profile.lastUpdated = llarp::time_now_ms();
|
||||
}
|
||||
@ -217,7 +215,7 @@ namespace llarp
|
||||
util::Lock lock{m_ProfilesMutex};
|
||||
for (const auto& hop : p->hops)
|
||||
{
|
||||
auto& profile = m_Profiles[hop.rc.pubkey];
|
||||
auto& profile = m_Profiles[hop.rc.router_id()];
|
||||
profile.pathTimeoutCount += 1;
|
||||
profile.lastUpdated = llarp::time_now_ms();
|
||||
}
|
||||
@ -230,7 +228,7 @@ namespace llarp
|
||||
const auto sz = p->hops.size();
|
||||
for (const auto& hop : p->hops)
|
||||
{
|
||||
auto& profile = m_Profiles[hop.rc.pubkey];
|
||||
auto& profile = m_Profiles[hop.rc.router_id()];
|
||||
// redeem previous fails by halfing the fail count and setting timeout to zero
|
||||
profile.pathFailCount /= 2;
|
||||
profile.pathTimeoutCount = 0;
|
||||
@ -299,7 +297,7 @@ namespace llarp
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string data = util::slurp_file(fname);
|
||||
std::string data = util::file_to_string(fname);
|
||||
util::Lock lock{m_ProfilesMutex};
|
||||
BDecode(bt_dict_consumer{data});
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace llarp
|
||||
bool
|
||||
RCGossiper::IsOurRC(const RouterContact& rc) const
|
||||
{
|
||||
return rc.pubkey == rid;
|
||||
return rc.router_id() == rid;
|
||||
}
|
||||
|
||||
void
|
||||
@ -67,11 +67,11 @@ namespace llarp
|
||||
RCGossiper::GossipRC(const RouterContact& rc)
|
||||
{
|
||||
// only distribute public routers
|
||||
if (not rc.IsPublicRouter())
|
||||
if (not rc.is_public_router())
|
||||
return false;
|
||||
if (link_manager == nullptr)
|
||||
return false;
|
||||
const RouterID pubkey(rc.pubkey);
|
||||
const RouterID pubkey(rc.router_id());
|
||||
// filter check
|
||||
if (filter.Contains(pubkey))
|
||||
return false;
|
||||
|
@ -101,6 +101,7 @@ namespace llarp
|
||||
throw;
|
||||
}
|
||||
|
||||
// TODO: replace this with construction of RemoteRC
|
||||
RouterContact result{std::move(payload)};
|
||||
|
||||
if (callback)
|
||||
@ -204,22 +205,22 @@ namespace llarp
|
||||
bool
|
||||
RCLookupHandler::check_rc(const RouterContact& rc) const
|
||||
{
|
||||
if (not is_session_allowed(rc.pubkey))
|
||||
if (not is_session_allowed(rc.router_id()))
|
||||
{
|
||||
contacts->delete_rc_node_async(dht::Key_t{rc.pubkey});
|
||||
contacts->delete_rc_node_async(dht::Key_t{rc.router_id()});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not rc.Verify(llarp::time_now_ms()))
|
||||
if (not rc.verify(llarp::time_now_ms())) // TODO: fix this call after RouterContact -> RemoteRC
|
||||
{
|
||||
LogWarn("RC for ", RouterID(rc.pubkey), " is invalid");
|
||||
LogWarn("RC for ", RouterID(rc.router_id()), " is invalid");
|
||||
return false;
|
||||
}
|
||||
|
||||
// update nodedb if required
|
||||
if (rc.IsPublicRouter())
|
||||
if (rc.is_public_router())
|
||||
{
|
||||
LogDebug("Adding or updating RC for ", RouterID(rc.pubkey), " to nodedb and dht.");
|
||||
LogDebug("Adding or updating RC for ", RouterID(rc.router_id()), " to nodedb and dht.");
|
||||
node_db->put_rc_if_newer(rc);
|
||||
contacts->put_rc_node_async(rc);
|
||||
}
|
||||
@ -252,17 +253,17 @@ namespace llarp
|
||||
RCLookupHandler::check_renegotiate_valid(RouterContact newrc, RouterContact oldrc)
|
||||
{
|
||||
// mismatch of identity ?
|
||||
if (newrc.pubkey != oldrc.pubkey)
|
||||
if (newrc.router_id() != oldrc.router_id())
|
||||
return false;
|
||||
|
||||
if (!is_session_allowed(newrc.pubkey))
|
||||
if (!is_session_allowed(newrc.router_id()))
|
||||
return false;
|
||||
|
||||
auto func = [this, newrc] { check_rc(newrc); };
|
||||
work_func(func);
|
||||
|
||||
// update dht if required
|
||||
if (contacts->rc_nodes()->HasNode(dht::Key_t{newrc.pubkey}))
|
||||
if (contacts->rc_nodes()->HasNode(dht::Key_t{newrc.router_id()}))
|
||||
{
|
||||
contacts->rc_nodes()->PutNode(newrc);
|
||||
}
|
||||
@ -278,15 +279,15 @@ namespace llarp
|
||||
std::unordered_set<RouterID> routersToLookUp;
|
||||
|
||||
node_db->VisitInsertedBefore(
|
||||
[&](const RouterContact& rc) { routersToLookUp.insert(rc.pubkey); },
|
||||
now - RouterContact::UpdateInterval);
|
||||
[&](const RouterContact& rc) { routersToLookUp.insert(rc.router_id()); },
|
||||
now - RouterContact::REPUBLISH);
|
||||
|
||||
for (const auto& router : routersToLookUp)
|
||||
{
|
||||
get_rc(router, nullptr, true);
|
||||
}
|
||||
|
||||
node_db->remove_stale_rcs(boostrap_rid_list, now - RouterContact::StaleInsertionAge);
|
||||
node_db->remove_stale_rcs(boostrap_rid_list, now - RouterContact::STALE);
|
||||
}
|
||||
|
||||
void
|
||||
@ -301,7 +302,7 @@ namespace llarp
|
||||
{
|
||||
for (const auto& rc : bootstrap_rc_list)
|
||||
{
|
||||
log::info(link_cat, "Doing explore via bootstrap node: {}", RouterID(rc.pubkey));
|
||||
log::info(link_cat, "Doing explore via bootstrap node: {}", RouterID(rc.router_id()));
|
||||
|
||||
// TODO: replace this concept
|
||||
// dht->ExploreNetworkVia(dht::Key_t{rc.pubkey});
|
||||
@ -383,7 +384,7 @@ namespace llarp
|
||||
|
||||
for (const auto& rc : bootstrap_rc_list)
|
||||
{
|
||||
boostrap_rid_list.insert(rc.pubkey);
|
||||
boostrap_rid_list.insert(rc.router_id());
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,7 +393,7 @@ namespace llarp
|
||||
{
|
||||
for (const auto& rc : bootstrap_rc_list)
|
||||
{
|
||||
if (rc.pubkey == remote)
|
||||
if (rc.router_id() == remote)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -6,8 +6,6 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
static auto logcat = log::Cat("route-poker");
|
||||
|
||||
void
|
||||
RoutePoker::add_route(oxen::quic::Address ip)
|
||||
{
|
||||
@ -221,7 +219,7 @@ namespace llarp
|
||||
|
||||
// explicit route pokes for first hops
|
||||
router.for_each_connection(
|
||||
[this](link::Connection conn) { add_route(conn.remote_rc.addr); });
|
||||
[this](link::Connection conn) { add_route(conn.remote_rc.addr()); });
|
||||
|
||||
add_route(router.link_manager().local());
|
||||
// add default route
|
||||
@ -240,7 +238,7 @@ namespace llarp
|
||||
{
|
||||
// unpoke routes for first hops
|
||||
router.for_each_connection(
|
||||
[this](link::Connection conn) { delete_route(conn.remote_rc.addr); });
|
||||
[this](link::Connection conn) { delete_route(conn.remote_rc.addr()); });
|
||||
if (is_enabled() and is_up)
|
||||
{
|
||||
vpn::AbstractRouteManager& route = router.vpn_platform()->RouteManager();
|
||||
|
@ -36,8 +36,6 @@ static constexpr std::chrono::milliseconds ROUTER_TICK_INTERVAL = 250ms;
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
static auto logcat = log::Cat("router");
|
||||
|
||||
Router::Router(EventLoop_ptr loop, std::shared_ptr<vpn::Platform> vpnPlatform)
|
||||
: _route_poker{std::make_shared<RoutePoker>(*this)}
|
||||
, _lmq{std::make_shared<oxenmq::OxenMQ>()}
|
||||
@ -178,7 +176,7 @@ namespace llarp
|
||||
|
||||
util::StatusObject stats{
|
||||
{"running", true},
|
||||
{"version", llarp::VERSION_FULL},
|
||||
{"version", llarp::LOKINET_VERSION_FULL},
|
||||
{"uptime", to_json(Uptime())},
|
||||
{"numPathsBuilt", pathsCount},
|
||||
{"numPeersConnected", peers},
|
||||
@ -216,8 +214,9 @@ namespace llarp
|
||||
|
||||
std::unordered_set<RouterID> peer_pubkeys;
|
||||
|
||||
for_each_connection(
|
||||
[&peer_pubkeys](link::Connection& conn) { peer_pubkeys.emplace(conn.remote_rc.pubkey); });
|
||||
for_each_connection([&peer_pubkeys](link::Connection& conn) {
|
||||
peer_pubkeys.emplace(conn.remote_rc.router_id());
|
||||
});
|
||||
|
||||
loop()->call([this, &peer_pubkeys]() {
|
||||
for (auto& pk : peer_pubkeys)
|
||||
@ -253,7 +252,7 @@ namespace llarp
|
||||
|
||||
if (auto maybe = node_db()->GetRandom([](const auto&) -> bool { return true; }))
|
||||
{
|
||||
router = maybe->pubkey;
|
||||
router = maybe->router_id();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -444,16 +443,16 @@ namespace llarp
|
||||
Router::HandleSaveRC() const
|
||||
{
|
||||
std::string fname = our_rc_file.string();
|
||||
router_contact.Write(fname.c_str());
|
||||
router_contact.write(fname.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
Router::SaveRC()
|
||||
{
|
||||
LogDebug("verify RC signature");
|
||||
if (!router_contact.Verify(now()))
|
||||
if (!router_contact.verify(now())) // TODO: RouterContact -> RemoteRC
|
||||
{
|
||||
Dump<MAX_RC_SIZE>(rc());
|
||||
Dump<RouterContact::MAX_RC_SIZE>(rc());
|
||||
LogError("RC is invalid, not saving");
|
||||
return false;
|
||||
}
|
||||
@ -569,9 +568,7 @@ namespace llarp
|
||||
{
|
||||
SecretKey nextOnionKey;
|
||||
RouterContact nextRC = router_contact;
|
||||
if (!nextRC.Sign(identity()))
|
||||
return false;
|
||||
if (!nextRC.Verify(time_now_ms(), false))
|
||||
if (!nextRC.sign(identity())) // TODO: RouterContact -> LocalRC
|
||||
return false;
|
||||
router_contact = std::move(nextRC);
|
||||
if (IsServiceNode())
|
||||
@ -585,20 +582,17 @@ namespace llarp
|
||||
// Set netid before anything else
|
||||
log::debug(logcat, "Network ID set to {}", conf.router.m_netId);
|
||||
if (!conf.router.m_netId.empty()
|
||||
&& strcmp(conf.router.m_netId.c_str(), llarp::DEFAULT_NETID) != 0)
|
||||
&& strcmp(conf.router.m_netId.c_str(), llarp::LOKINET_DEFAULT_NETID) != 0)
|
||||
{
|
||||
const auto& netid = conf.router.m_netId;
|
||||
llarp::LogWarn(
|
||||
"!!!! you have manually set netid to be '",
|
||||
netid,
|
||||
"' which does not equal '",
|
||||
llarp::DEFAULT_NETID,
|
||||
llarp::LOKINET_DEFAULT_NETID,
|
||||
"' you will run as a different network, good luck "
|
||||
"and don't forget: something something MUH traffic "
|
||||
"shape correlation !!!!");
|
||||
NetID::DefaultValue() = NetID(reinterpret_cast<const byte_t*>(netid.c_str()));
|
||||
// reset netid in our rc
|
||||
router_contact.netID = llarp::NetID();
|
||||
}
|
||||
|
||||
// Router config
|
||||
@ -628,7 +622,7 @@ namespace llarp
|
||||
else
|
||||
log::debug(logcat, "No explicit public address given; will auto-detect during link setup");
|
||||
|
||||
RouterContact::BlockBogons = conf.router.m_blockBogons;
|
||||
RouterContact::BLOCK_BOGONS = conf.router.m_blockBogons;
|
||||
|
||||
auto& networkConfig = conf.network;
|
||||
|
||||
@ -679,10 +673,10 @@ namespace llarp
|
||||
auto clearBadRCs = [this]() {
|
||||
for (auto it = bootstrap_rc_list.begin(); it != bootstrap_rc_list.end();)
|
||||
{
|
||||
if (it->IsObsoleteBootstrap())
|
||||
log::warning(logcat, "ignoring obsolete boostrap RC: {}", RouterID{it->pubkey});
|
||||
else if (not it->Verify(now()))
|
||||
log::warning(logcat, "ignoring invalid bootstrap RC: {}", RouterID{it->pubkey});
|
||||
if (it->is_obsolete_bootstrap())
|
||||
log::warning(logcat, "ignoring obsolete boostrap RC: {}", RouterID{it->router_id()});
|
||||
else if (not it->verify(now())) // TODO: RouterContact -> RemoteRC
|
||||
log::warning(logcat, "ignoring invalid bootstrap RC: {}", RouterID{it->router_id()});
|
||||
else
|
||||
{
|
||||
++it;
|
||||
@ -785,7 +779,7 @@ namespace llarp
|
||||
return std::count_if(
|
||||
bootstrap_rc_list.begin(),
|
||||
bootstrap_rc_list.end(),
|
||||
[r](const RouterContact& rc) -> bool { return rc.pubkey == r; })
|
||||
[r](const RouterContact& rc) -> bool { return rc.router_id() == r; })
|
||||
> 0;
|
||||
}
|
||||
|
||||
@ -806,8 +800,8 @@ namespace llarp
|
||||
if (IsServiceNode())
|
||||
{
|
||||
LogInfo(NumberOfConnectedClients(), " client connections");
|
||||
LogInfo(ToString(router_contact.Age(now)), " since we last updated our RC");
|
||||
LogInfo(ToString(router_contact.TimeUntilExpires(now)), " until our RC expires");
|
||||
LogInfo(ToString(router_contact.age(now)), " since we last updated our RC");
|
||||
LogInfo(ToString(router_contact.time_to_expiry(now)), " until our RC expires");
|
||||
}
|
||||
if (_last_stats_report > 0s)
|
||||
LogInfo(ToString(now - _last_stats_report), " last reported stats");
|
||||
@ -819,7 +813,7 @@ namespace llarp
|
||||
{
|
||||
std::string status;
|
||||
auto out = std::back_inserter(status);
|
||||
fmt::format_to(out, "v{}", fmt::join(llarp::VERSION, "."));
|
||||
fmt::format_to(out, "v{}", fmt::join(llarp::LOKINET_VERSION, "."));
|
||||
if (IsServiceNode())
|
||||
{
|
||||
fmt::format_to(
|
||||
@ -901,7 +895,8 @@ namespace llarp
|
||||
bool should_gossip = appears_funded();
|
||||
|
||||
if (is_snode
|
||||
and (router_contact.ExpiresSoon(now, std::chrono::milliseconds(randint() % 10000)) or (now - router_contact.last_updated) > rc_regen_interval))
|
||||
and (router_contact.expires_within_delta(now, std::chrono::milliseconds(randint() % 10000))
|
||||
or (now - router_contact.timestamp().time_since_epoch()) > rc_regen_interval))
|
||||
{
|
||||
LogInfo("regenerating RC");
|
||||
if (update_rc())
|
||||
@ -923,22 +918,22 @@ namespace llarp
|
||||
// remove RCs for nodes that are no longer allowed by network policy
|
||||
node_db()->RemoveIf([&](const RouterContact& rc) -> bool {
|
||||
// don't purge bootstrap nodes from nodedb
|
||||
if (IsBootstrapNode(rc.pubkey))
|
||||
if (IsBootstrapNode(rc.router_id()))
|
||||
{
|
||||
log::trace(logcat, "Not removing {}: is bootstrap node", rc.pubkey);
|
||||
log::trace(logcat, "Not removing {}: is bootstrap node", rc.router_id());
|
||||
return false;
|
||||
}
|
||||
// if for some reason we stored an RC that isn't a valid router
|
||||
// purge this entry
|
||||
if (not rc.IsPublicRouter())
|
||||
if (not rc.is_public_router())
|
||||
{
|
||||
log::debug(logcat, "Removing {}: not a valid router", rc.pubkey);
|
||||
log::debug(logcat, "Removing {}: not a valid router", rc.router_id());
|
||||
return true;
|
||||
}
|
||||
/// clear out a fully expired RC
|
||||
if (rc.IsExpired(now))
|
||||
if (rc.is_expired(now))
|
||||
{
|
||||
log::debug(logcat, "Removing {}: RC is expired", rc.pubkey);
|
||||
log::debug(logcat, "Removing {}: RC is expired", rc.router_id());
|
||||
return true;
|
||||
}
|
||||
// clients have no notion of a whilelist
|
||||
@ -946,23 +941,23 @@ namespace llarp
|
||||
// routers that are not whitelisted for first hops
|
||||
if (not is_snode)
|
||||
{
|
||||
log::trace(logcat, "Not removing {}: we are a client and it looks fine", rc.pubkey);
|
||||
log::trace(logcat, "Not removing {}: we are a client and it looks fine", rc.router_id());
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we don't have the whitelist yet don't remove the entry
|
||||
if (not has_whitelist)
|
||||
{
|
||||
log::debug(logcat, "Skipping check on {}: don't have whitelist yet", rc.pubkey);
|
||||
log::debug(logcat, "Skipping check on {}: don't have whitelist yet", rc.router_id());
|
||||
return false;
|
||||
}
|
||||
// if we have no whitelist enabled or we have
|
||||
// the whitelist enabled and we got the whitelist
|
||||
// check against the whitelist and remove if it's not
|
||||
// in the whitelist OR if there is no whitelist don't remove
|
||||
if (has_whitelist and not _rc_lookup_handler.is_session_allowed(rc.pubkey))
|
||||
if (has_whitelist and not _rc_lookup_handler.is_session_allowed(rc.router_id()))
|
||||
{
|
||||
log::debug(logcat, "Removing {}: not a valid router", rc.pubkey);
|
||||
log::debug(logcat, "Removing {}: not a valid router", rc.router_id());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -971,10 +966,10 @@ namespace llarp
|
||||
if (not is_snode or not has_whitelist)
|
||||
{
|
||||
// find all deregistered relays
|
||||
std::unordered_set<PubKey> close_peers;
|
||||
std::unordered_set<RouterID> close_peers;
|
||||
|
||||
for_each_connection([this, &close_peers](link::Connection& conn) {
|
||||
const auto& pk = conn.remote_rc.pubkey;
|
||||
const auto& pk = conn.remote_rc.router_id();
|
||||
|
||||
if (conn.remote_is_relay and not _rc_lookup_handler.is_session_allowed(pk))
|
||||
close_peers.insert(pk);
|
||||
@ -1051,7 +1046,7 @@ namespace llarp
|
||||
std::set<dht::Key_t> peer_keys;
|
||||
|
||||
for_each_connection(
|
||||
[&peer_keys](link::Connection& conn) { peer_keys.emplace(conn.remote_rc.pubkey); });
|
||||
[&peer_keys](link::Connection& conn) { peer_keys.emplace(conn.remote_rc.router_id()); });
|
||||
|
||||
_contacts->rc_nodes()->RemoveIf(
|
||||
[&peer_keys](const dht::Key_t& k) -> bool { return peer_keys.count(k) == 0; });
|
||||
@ -1112,15 +1107,18 @@ namespace llarp
|
||||
if (is_running || is_stopping)
|
||||
return false;
|
||||
|
||||
// set public signing key
|
||||
router_contact.pubkey = seckey_topublic(identity());
|
||||
// TODO: replace all this logic with construction of LocalRC
|
||||
|
||||
/* // set public signing key
|
||||
router_contact._router_id = seckey_topublic(identity());
|
||||
// set router version if service node
|
||||
if (IsServiceNode())
|
||||
{
|
||||
router_contact.routerVersion = RouterVersion(llarp::VERSION, llarp::constants::proto_version);
|
||||
router_contact.routerVersion =
|
||||
RouterVersion(llarp::LOKINET_VERSION, llarp::constants::proto_version);
|
||||
}
|
||||
|
||||
if (IsServiceNode() and not router_contact.IsPublicRouter())
|
||||
if (IsServiceNode() and not router_contact.is_public_router())
|
||||
{
|
||||
LogError("we are configured as relay but have no reachable addresses");
|
||||
return false;
|
||||
@ -1130,7 +1128,7 @@ namespace llarp
|
||||
router_contact.enckey = seckey_topublic(encryption());
|
||||
|
||||
LogInfo("Signing rc...");
|
||||
if (!router_contact.Sign(identity()))
|
||||
if (!router_contact.sign(identity()))
|
||||
{
|
||||
LogError("failed to sign rc");
|
||||
return false;
|
||||
@ -1166,14 +1164,14 @@ namespace llarp
|
||||
// regenerate keys and resign rc before everything else
|
||||
crypto::identity_keygen(_identity);
|
||||
crypto::encryption_keygen(_encryption);
|
||||
router_contact.pubkey = seckey_topublic(identity());
|
||||
router_contact._router_id = seckey_topublic(identity());
|
||||
router_contact.enckey = seckey_topublic(encryption());
|
||||
if (!router_contact.Sign(identity()))
|
||||
if (!router_contact.sign(identity()))
|
||||
{
|
||||
LogError("failed to regenerate keys and sign RC");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
LogInfo("starting hidden service context...");
|
||||
if (!hidden_service_context().StartAll())
|
||||
@ -1193,7 +1191,7 @@ namespace llarp
|
||||
{
|
||||
node_db()->put_rc(rc);
|
||||
_contacts->rc_nodes()->PutNode(rc);
|
||||
LogInfo("added bootstrap node ", RouterID{rc.pubkey});
|
||||
LogInfo("added bootstrap node ", RouterID{rc.router_id()});
|
||||
}
|
||||
|
||||
LogInfo("have ", _node_db->num_loaded(), " routers");
|
||||
|
@ -465,7 +465,7 @@ namespace llarp
|
||||
const byte_t*
|
||||
pubkey() const
|
||||
{
|
||||
return seckey_topublic(_identity);
|
||||
return seckey_to_pubkey(_identity);
|
||||
}
|
||||
|
||||
/// send to remote router or queue for sending
|
||||
|
@ -12,407 +12,276 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
static auto logcat = log::Cat("RC");
|
||||
|
||||
NetID&
|
||||
NetID::DefaultValue()
|
||||
{
|
||||
static NetID defaultID(reinterpret_cast<const byte_t*>(llarp::DEFAULT_NETID));
|
||||
return defaultID;
|
||||
}
|
||||
// RouterContact::RouterContact(std::string buf)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// oxenc::bt_list_consumer btlc{buf};
|
||||
|
||||
bool RouterContact::BlockBogons = true;
|
||||
// // signature.from_string(btlc.consume_string());
|
||||
// signed_bt_dict = btlc.consume_string();
|
||||
|
||||
/// 1 day rc lifespan
|
||||
constexpr auto rc_lifetime = 24h;
|
||||
/// an RC inserted long enough ago (4 hrs) is considered stale and is removed
|
||||
constexpr auto rc_stale_age = 4h;
|
||||
/// window of time in which a router wil try to update their RC before it is marked stale
|
||||
constexpr auto rc_update_window = 5min;
|
||||
/// update RCs shortly before they are about to expire
|
||||
constexpr auto rc_update_interval = rc_stale_age - rc_update_window;
|
||||
|
||||
llarp_time_t RouterContact::Lifetime = rc_lifetime;
|
||||
llarp_time_t RouterContact::StaleInsertionAge = rc_stale_age;
|
||||
llarp_time_t RouterContact::UpdateInterval = rc_update_interval;
|
||||
|
||||
/// how many rc lifetime intervals should we wait until purging an rc
|
||||
constexpr auto expiration_lifetime_generations = 10;
|
||||
/// the max age of an rc before we want to expire it
|
||||
constexpr auto rc_expire_age = rc_lifetime * expiration_lifetime_generations;
|
||||
|
||||
NetID::NetID(const byte_t* val)
|
||||
{
|
||||
const size_t len = strnlen(reinterpret_cast<const char*>(val), size());
|
||||
std::copy(val, val + len, begin());
|
||||
}
|
||||
|
||||
NetID::NetID() : NetID(DefaultValue().data())
|
||||
{}
|
||||
|
||||
bool
|
||||
NetID::operator==(const NetID& other) const
|
||||
{
|
||||
return ToString() == other.ToString();
|
||||
}
|
||||
|
||||
std::string
|
||||
NetID::ToString() const
|
||||
{
|
||||
return {begin(), std::find(begin(), end(), '\0')};
|
||||
}
|
||||
|
||||
bool
|
||||
NetID::BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
Zero();
|
||||
llarp_buffer_t strbuf;
|
||||
if (!bencode_read_string(buf, &strbuf))
|
||||
return false;
|
||||
|
||||
if (strbuf.sz > size())
|
||||
return false;
|
||||
|
||||
std::copy(strbuf.base, strbuf.base + strbuf.sz, begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NetID::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
auto term = std::find(begin(), end(), '\0');
|
||||
return bencode_write_bytestring(buf, data(), std::distance(begin(), term));
|
||||
}
|
||||
|
||||
RouterContact::RouterContact(std::string buf)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_list_consumer btlc{buf};
|
||||
|
||||
signature.from_string(btlc.consume_string());
|
||||
signed_bt_dict = btlc.consume_string();
|
||||
|
||||
// TODO: parse bt dict
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::warning(llarp_cat, "Error: RouterContact failed to populate bt encoded contents!");
|
||||
}
|
||||
}
|
||||
// // TODO: parse bt dict
|
||||
// }
|
||||
// catch (...)
|
||||
// {
|
||||
// log::warning(llarp_cat, "Error: RouterContact failed to populate bt encoded contents!");
|
||||
// }
|
||||
// }
|
||||
|
||||
std::string
|
||||
RouterContact::bt_encode() const
|
||||
{
|
||||
oxenc::bt_list_producer btlp;
|
||||
|
||||
try
|
||||
{
|
||||
btlp.append(signature.ToView());
|
||||
btlp.append(signed_bt_dict);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::warning(llarp_cat, "Error: RouterContact failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btlp).str();
|
||||
}
|
||||
|
||||
void
|
||||
RouterContact::bt_encode_subdict(oxenc::bt_list_producer& btlp) const
|
||||
{
|
||||
btlp.append(signature.ToView());
|
||||
btlp.append(signed_bt_dict);
|
||||
}
|
||||
|
||||
std::string
|
||||
RouterContact::ToTXTRecord() const
|
||||
{
|
||||
std::string result;
|
||||
auto out = std::back_inserter(result);
|
||||
fmt::format_to(out, "addr={}; pk={}", addr.to_string(), pubkey);
|
||||
fmt::format_to(out, "updated={}; onion_pk={}; ", last_updated.count(), enckey.ToHex());
|
||||
if (routerVersion.has_value())
|
||||
fmt::format_to(out, "router_version={}; ", *routerVersion);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::FromOurNetwork() const
|
||||
{
|
||||
return netID == NetID::DefaultValue();
|
||||
}
|
||||
|
||||
std::string
|
||||
RouterContact::bencode_signed_section() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("a", addr.to_string());
|
||||
btdp.append("i", netID.ToView());
|
||||
btdp.append("k", pubkey.bt_encode());
|
||||
btdp.append("p", enckey.ToView());
|
||||
btdp.append("r", routerVersion->ToString());
|
||||
|
||||
if (not srvRecords.empty())
|
||||
{
|
||||
auto sublist = btdp.append_list("s");
|
||||
|
||||
for (auto& s : srvRecords)
|
||||
sublist.append(s.bt_encode());
|
||||
}
|
||||
|
||||
btdp.append("u", last_updated.count());
|
||||
|
||||
bt_encode(btdp);
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
void
|
||||
RouterContact::Clear()
|
||||
RouterContact::bt_load(oxenc::bt_dict_consumer& data)
|
||||
{
|
||||
signature.Zero();
|
||||
enckey.Zero();
|
||||
pubkey.Zero();
|
||||
routerVersion = std::optional<RouterVersion>{};
|
||||
last_updated = 0s;
|
||||
srvRecords.clear();
|
||||
version = llarp::constants::proto_version;
|
||||
if (int rc_ver = data.require<uint8_t>(""); rc_ver != RC_VERSION)
|
||||
throw std::runtime_error{"Invalid RC: do not know how to parse v{} RCs"_format(rc_ver)};
|
||||
|
||||
auto ipv4_port = data.require<std::string_view>("4");
|
||||
|
||||
if (ipv4_port.size() != 6)
|
||||
throw std::runtime_error{
|
||||
"Invalid RC address: expected 6-byte IPv4 IP/port, got {}"_format(ipv4_port.size())};
|
||||
|
||||
sockaddr_in s4;
|
||||
s4.sin_family = AF_INET;
|
||||
|
||||
std::memcpy(&s4.sin_addr.s_addr, ipv4_port.data(), 4);
|
||||
std::memcpy(&s4.sin_port, ipv4_port.data() + 4, 2);
|
||||
|
||||
_addr = oxen::quic::Address{&s4};
|
||||
|
||||
if (!_addr.is_public())
|
||||
throw std::runtime_error{"Invalid RC: IPv4 address is not a publicly routable IP"};
|
||||
|
||||
if (auto ipv6_port = data.maybe<std::string_view>("6"))
|
||||
{
|
||||
if (ipv6_port->size() != 18)
|
||||
throw std::runtime_error{
|
||||
"Invalid RC address: expected 18-byte IPv6 IP/port, got {}"_format(ipv6_port->size())};
|
||||
|
||||
sockaddr_in6 s6{};
|
||||
s6.sin6_family = AF_INET6;
|
||||
|
||||
std::memcpy(&s6.sin6_addr.s6_addr, ipv6_port->data(), 16);
|
||||
std::memcpy(&s6.sin6_port, ipv6_port->data() + 16, 2);
|
||||
|
||||
_addr6.emplace(&s6);
|
||||
if (!_addr6->is_public())
|
||||
throw std::runtime_error{"Invalid RC: IPv6 address is not a publicly routable IP"};
|
||||
}
|
||||
else
|
||||
{
|
||||
_addr6.reset();
|
||||
}
|
||||
|
||||
auto netid = data.maybe<std::string_view>("i").value_or(llarp::LOKINET_DEFAULT_NETID);
|
||||
if (netid != ACTIVE_NETID)
|
||||
throw std::runtime_error{
|
||||
"Invalid RC netid: expected {}, got {}; this is an RC for a different network!"_format(
|
||||
ACTIVE_NETID, netid)};
|
||||
|
||||
auto pk = data.require<std::string_view>("p");
|
||||
|
||||
if (pk.size() != RouterID::SIZE)
|
||||
throw std::runtime_error{"Invalid RC: router id has invalid size {}"_format(pk.size())};
|
||||
|
||||
std::memcpy(_router_id.data(), pk.data(), RouterID::SIZE);
|
||||
|
||||
_timestamp = rc_time{std::chrono::seconds{data.require<int64_t>("t")}};
|
||||
|
||||
auto ver = data.require<ustring_view>("v");
|
||||
|
||||
if (ver.size() != 3)
|
||||
throw std::runtime_error{
|
||||
"Invalid RC router version: received {} bytes (!= 3)"_format(ver.size())};
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
_router_version[i] = ver[i];
|
||||
}
|
||||
|
||||
// std::string
|
||||
// RouterContact::bencode_signed_section() const
|
||||
// {
|
||||
// oxenc::bt_dict_producer btdp;
|
||||
|
||||
// btdp.append("4", _addr.to_string());
|
||||
|
||||
// if (_addr6)
|
||||
// btdp.append("6", _addr6->to_string());
|
||||
|
||||
// if (ACTIVE_NETID != llarp::LOKINET_DEFAULT_NETID)
|
||||
// btdp.append("i", ACTIVE_NETID);
|
||||
|
||||
// btdp.append("p", _router_id.bt_encode());
|
||||
// btdp.append("t", _timestamp.time_since_epoch().count());
|
||||
// btdp.append("v", _router_version.data());
|
||||
|
||||
// return std::move(btdp).str();
|
||||
// }
|
||||
|
||||
util::StatusObject
|
||||
RouterContact::ExtractStatus() const
|
||||
RouterContact::extract_status() const
|
||||
{
|
||||
util::StatusObject obj{
|
||||
{"lastUpdated", last_updated.count()},
|
||||
{"publicRouter", IsPublicRouter()},
|
||||
{"identity", pubkey.ToString()},
|
||||
{"address", addr.to_string()}};
|
||||
{"lastUpdated", _timestamp.time_since_epoch().count()},
|
||||
{"publicRouter", is_public_router()},
|
||||
{"identity", _router_id.ToString()},
|
||||
{"address", _addr.to_string()}};
|
||||
|
||||
// if (routerVersion)
|
||||
// {
|
||||
// obj["routerVersion"] = routerVersion->ToString();
|
||||
// }
|
||||
// std::vector<util::StatusObject> srv;
|
||||
// for (const auto& record : srvRecords)
|
||||
// {
|
||||
// srv.emplace_back(record.ExtractStatus());
|
||||
// }
|
||||
// obj["srvRecords"] = srv;
|
||||
|
||||
if (routerVersion)
|
||||
{
|
||||
obj["routerVersion"] = routerVersion->ToString();
|
||||
}
|
||||
std::vector<util::StatusObject> srv;
|
||||
for (const auto& record : srvRecords)
|
||||
{
|
||||
srv.emplace_back(record.ExtractStatus());
|
||||
}
|
||||
obj["srvRecords"] = srv;
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
Clear();
|
||||
// TODO: unfuck all of this
|
||||
|
||||
if (*buf->cur == 'd') // old format
|
||||
{
|
||||
return DecodeVersion_0(buf);
|
||||
}
|
||||
else if (*buf->cur != 'l') // if not dict, should be new format and start with list
|
||||
{
|
||||
return false;
|
||||
}
|
||||
(void)buf;
|
||||
|
||||
try
|
||||
{
|
||||
std::string_view buf_view(reinterpret_cast<char*>(buf->cur), buf->size_left());
|
||||
oxenc::bt_list_consumer btlist(buf_view);
|
||||
// clear();
|
||||
|
||||
uint64_t outer_version = btlist.consume_integer<uint64_t>();
|
||||
// if (*buf->cur == 'd') // old format
|
||||
// {
|
||||
// return DecodeVersion_0(buf);
|
||||
// }
|
||||
// else if (*buf->cur != 'l') // if not dict, should be new format and start with list
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (outer_version == 1)
|
||||
{
|
||||
bool decode_result = DecodeVersion_1(btlist);
|
||||
// try
|
||||
// {
|
||||
// std::string_view buf_view(reinterpret_cast<char*>(buf->cur), buf->size_left());
|
||||
// oxenc::bt_list_consumer btlist(buf_view);
|
||||
|
||||
// advance the llarp_buffer_t since lokimq serialization is unaware of it.
|
||||
// FIXME: this is broken (current_buffer got dropped), but the whole thing is getting
|
||||
// replaced.
|
||||
// buf->cur += btlist.
|
||||
// current_buffer().data() - buf_view.data() + 1;
|
||||
// uint64_t outer_version = btlist.consume_integer<uint64_t>();
|
||||
|
||||
return decode_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
log::warning(logcat, "Received RouterContact with unkown version ({})", outer_version);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::debug(logcat, "RouterContact::BDecode failed: {}", e.what());
|
||||
}
|
||||
// if (outer_version == 1)
|
||||
// {
|
||||
// bool decode_result = DecodeVersion_1(btlist);
|
||||
|
||||
// // advance the llarp_buffer_t since lokimq serialization is unaware of it.
|
||||
// // FIXME: this is broken (current_buffer got dropped), but the whole thing is getting
|
||||
// // replaced.
|
||||
// // buf->cur += btlist.
|
||||
// // current_buffer().data() - buf_view.data() + 1;
|
||||
|
||||
// return decode_result;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// log::warning(logcat, "Received RouterContact with unkown version ({})", outer_version);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// catch (const std::exception& e)
|
||||
// {
|
||||
// log::debug(logcat, "RouterContact::BDecode failed: {}", e.what());
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::DecodeVersion_0(llarp_buffer_t* buf)
|
||||
{
|
||||
return bencode_decode_dict(*this, buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::DecodeVersion_1(oxenc::bt_list_consumer& btlist)
|
||||
{
|
||||
auto signature_string = btlist.consume_string_view();
|
||||
signed_bt_dict = btlist.consume_dict_data();
|
||||
|
||||
if (not btlist.is_finished())
|
||||
{
|
||||
log::debug(logcat, "RouterContact serialized list too long for specified version.");
|
||||
return false;
|
||||
}
|
||||
|
||||
llarp_buffer_t sigbuf(signature_string.data(), signature_string.size());
|
||||
if (not signature.FromBytestring(&sigbuf))
|
||||
{
|
||||
log::debug(logcat, "RouterContact serialized signature had invalid length.");
|
||||
return false;
|
||||
}
|
||||
|
||||
llarp_buffer_t data_dict_buf(signed_bt_dict.data(), signed_bt_dict.size());
|
||||
return bencode_decode_dict(*this, &data_dict_buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
(void)key;
|
||||
|
||||
// TOFIX: fuck everything about llarp_buffer_t
|
||||
|
||||
// if (!BEncodeMaybeReadDictEntry("a", addr, read, key, buf))
|
||||
// return false;
|
||||
|
||||
if (!BEncodeMaybeReadDictEntry("i", netID, read, key, buf))
|
||||
return false;
|
||||
// if (!BEncodeMaybeReadDictEntry("i", netID, read, key, buf))
|
||||
// return false;
|
||||
|
||||
if (!BEncodeMaybeReadDictEntry("k", pubkey, read, key, buf))
|
||||
return false;
|
||||
// if (!BEncodeMaybeReadDictEntry("k", _router_id, read, key, buf))
|
||||
// return false;
|
||||
|
||||
if (key.startswith("r"))
|
||||
{
|
||||
RouterVersion r;
|
||||
if (not r.BDecode(buf))
|
||||
return false;
|
||||
routerVersion = r;
|
||||
return true;
|
||||
}
|
||||
// if (key.startswith("r"))
|
||||
// {
|
||||
// RouterVersion r;
|
||||
// if (not r.BDecode(buf))
|
||||
// return false;
|
||||
// routerVersion = r;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (not BEncodeMaybeReadDictList("s", srvRecords, read, key, buf))
|
||||
return false;
|
||||
// if (not BEncodeMaybeReadDictList("s", srvRecords, read, key, buf))
|
||||
// return false;
|
||||
|
||||
if (!BEncodeMaybeReadDictEntry("p", enckey, read, key, buf))
|
||||
return false;
|
||||
// if (!BEncodeMaybeReadDictEntry("p", enckey, read, key, buf))
|
||||
// return false;
|
||||
|
||||
if (!BEncodeMaybeReadDictInt("u", last_updated, read, key, buf))
|
||||
return false;
|
||||
// if (!BEncodeMaybeReadDictInt("u", _timestamp, read, key, buf))
|
||||
// return false;
|
||||
|
||||
if (!BEncodeMaybeReadDictInt("v", version, read, key, buf))
|
||||
return false;
|
||||
// if (!BEncodeMaybeReadDictInt("v", version, read, key, buf))
|
||||
// return false;
|
||||
|
||||
if (key.startswith("x") and serializeExit)
|
||||
{
|
||||
return bencode_discard(buf);
|
||||
}
|
||||
// if (key.startswith("x") and serializeExit)
|
||||
// {
|
||||
// return bencode_discard(buf);
|
||||
// }
|
||||
|
||||
if (!BEncodeMaybeReadDictEntry("z", signature, read, key, buf))
|
||||
return false;
|
||||
// if (!BEncodeMaybeReadDictEntry("z", signature, read, key, buf))
|
||||
// return false;
|
||||
|
||||
return read or bencode_discard(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::IsPublicRouter() const
|
||||
RouterContact::is_public_router() const
|
||||
{
|
||||
if (not routerVersion)
|
||||
if (_router_version.empty())
|
||||
return false;
|
||||
return addr.is_addressable();
|
||||
return _addr.is_addressable();
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::IsExpired(llarp_time_t now) const
|
||||
RouterContact::is_expired(llarp_time_t now) const
|
||||
{
|
||||
return Age(now) >= rc_expire_age;
|
||||
return age(now) >= _timestamp.time_since_epoch() + LIFETIME;
|
||||
}
|
||||
|
||||
llarp_time_t
|
||||
RouterContact::TimeUntilExpires(llarp_time_t now) const
|
||||
RouterContact::time_to_expiry(llarp_time_t now) const
|
||||
{
|
||||
const auto expiresAt = last_updated + Lifetime;
|
||||
return now < expiresAt ? expiresAt - now : 0s;
|
||||
const auto expiry = _timestamp.time_since_epoch() + LIFETIME;
|
||||
return now < expiry ? expiry - now : 0s;
|
||||
}
|
||||
|
||||
llarp_time_t
|
||||
RouterContact::Age(llarp_time_t now) const
|
||||
RouterContact::age(llarp_time_t now) const
|
||||
{
|
||||
return now > last_updated ? now - last_updated : 0s;
|
||||
auto delta = now - _timestamp.time_since_epoch();
|
||||
return delta > 0s ? delta : 0s;
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const
|
||||
RouterContact::expires_within_delta(llarp_time_t now, llarp_time_t dlt) const
|
||||
{
|
||||
return TimeUntilExpires(now) <= dlt;
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::Sign(const SecretKey& secretkey)
|
||||
{
|
||||
pubkey = llarp::seckey_topublic(secretkey);
|
||||
signature.Zero();
|
||||
last_updated = time_now_ms();
|
||||
|
||||
signed_bt_dict = bencode_signed_section();
|
||||
|
||||
return crypto::sign(
|
||||
signature,
|
||||
secretkey,
|
||||
reinterpret_cast<uint8_t*>(signed_bt_dict.data()),
|
||||
signed_bt_dict.size());
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::Verify(llarp_time_t now, bool allowExpired) const
|
||||
{
|
||||
if (netID != NetID::DefaultValue())
|
||||
{
|
||||
log::error(
|
||||
logcat, "netid mismatch: '{}' (theirs) != '{}' (ours)", netID, NetID::DefaultValue());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsExpired(now) and not allowExpired)
|
||||
return false;
|
||||
|
||||
// TODO: make net* overridable
|
||||
const auto* net = net::Platform::Default_ptr();
|
||||
|
||||
if (net->IsBogon(addr.in4()) && BlockBogons)
|
||||
{
|
||||
log::error(logcat, "invalid address info: {}", addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!VerifySignature())
|
||||
{
|
||||
log::error(logcat, "invalid signature: {}", *this);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::VerifySignature() const
|
||||
{
|
||||
RouterContact copy;
|
||||
copy = *this;
|
||||
copy.signature.Zero();
|
||||
|
||||
auto bte = copy.bt_encode();
|
||||
return crypto::verify(pubkey, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), signature);
|
||||
return time_to_expiry(now) <= dlt;
|
||||
}
|
||||
|
||||
static constexpr std::array obsolete_bootstraps = {
|
||||
@ -421,18 +290,18 @@ namespace llarp
|
||||
};
|
||||
|
||||
bool
|
||||
RouterContact::IsObsoleteBootstrap() const
|
||||
RouterContact::is_obsolete_bootstrap() const
|
||||
{
|
||||
for (const auto& k : obsolete_bootstraps)
|
||||
{
|
||||
if (pubkey.ToHex() == k)
|
||||
if (_router_id.ToHex() == k)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::Write(const fs::path& fname) const
|
||||
RouterContact::write(const fs::path& fname) const
|
||||
{
|
||||
std::array<byte_t, MAX_RC_SIZE> tmp;
|
||||
llarp_buffer_t buf(tmp);
|
||||
@ -453,13 +322,13 @@ namespace llarp
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::Read(const fs::path& fname)
|
||||
RouterContact::read(const fs::path& fname)
|
||||
{
|
||||
std::array<byte_t, MAX_RC_SIZE> tmp;
|
||||
llarp_buffer_t buf(tmp);
|
||||
try
|
||||
{
|
||||
util::slurp_file(fname, tmp.data(), tmp.size());
|
||||
util::file_to_buffer(fname, tmp.data(), tmp.size());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@ -468,19 +337,4 @@ namespace llarp
|
||||
}
|
||||
return BDecode(&buf);
|
||||
}
|
||||
|
||||
std::string
|
||||
RouterContact::ToString() const
|
||||
{
|
||||
return fmt::format(
|
||||
"[RC k={} updated={} netid={} v={} ai={{{}}} e={} z={}]",
|
||||
pubkey,
|
||||
last_updated.count(),
|
||||
netID,
|
||||
version,
|
||||
fmt::format("{}", addr),
|
||||
enckey,
|
||||
signature);
|
||||
}
|
||||
|
||||
} // namespace llarp
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "router_id.hpp"
|
||||
#include "router_version.hpp"
|
||||
|
||||
#include <llarp/constants/version.hpp>
|
||||
@ -17,128 +18,169 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#define MAX_RC_SIZE (1024)
|
||||
|
||||
namespace oxenc
|
||||
{
|
||||
class bt_list_consumer;
|
||||
} // namespace oxenc
|
||||
|
||||
/*
|
||||
- figure out where we do bt_encoding of RC's
|
||||
- maybe dump secret key from bt_encode
|
||||
- it's weird to pass the secret key contextually
|
||||
- suspicion we will need optional signature as an optional(?) string with serialized data
|
||||
- resetting signature would be string::clear() instead
|
||||
- ::sign() will cache serialized value
|
||||
- do timestamp stuff
|
||||
- bt_encode that takes bt_dict_producer requires reference to subdict
|
||||
- presumably to be done in endpoints
|
||||
- will be used for get_multi_rc endpoint
|
||||
*/
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// NetID
|
||||
struct NetID final : public AlignedBuffer<8>
|
||||
{
|
||||
static NetID&
|
||||
DefaultValue();
|
||||
static auto logcat = log::Cat("RC");
|
||||
|
||||
NetID();
|
||||
|
||||
explicit NetID(const byte_t* val);
|
||||
|
||||
NetID(const NetID& other) = default;
|
||||
NetID&
|
||||
operator=(const NetID& other) = default;
|
||||
|
||||
bool
|
||||
operator==(const NetID& other) const;
|
||||
|
||||
bool
|
||||
operator!=(const NetID& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
std::string
|
||||
ToString() const;
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t* buf);
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const;
|
||||
};
|
||||
using rc_time = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>;
|
||||
|
||||
/// RouterContact
|
||||
struct RouterContact
|
||||
{
|
||||
/// for unit tests
|
||||
static bool BlockBogons;
|
||||
static constexpr uint8_t RC_VERSION = 0;
|
||||
|
||||
static llarp_time_t Lifetime;
|
||||
static llarp_time_t UpdateInterval;
|
||||
static llarp_time_t StaleInsertionAge;
|
||||
|
||||
RouterContact()
|
||||
/// Constructs an empty RC
|
||||
RouterContact() = default;
|
||||
RouterContact(std::string)
|
||||
{
|
||||
Clear();
|
||||
log::error(logcat, "ERROR: SUPPLANT THIS CONSTRUCTOR");
|
||||
}
|
||||
|
||||
RouterContact(std::string buf);
|
||||
// RouterContact(std::string buf);
|
||||
|
||||
/// RC version that we support; we fail to load RCs that don't have the same version as that
|
||||
/// means they are incompatible with us.
|
||||
// static constexpr uint8_t VERSION = 0;
|
||||
|
||||
/// Unit tests disable this to allow private IP ranges in RCs, which normally get rejected.
|
||||
static inline bool BLOCK_BOGONS = true;
|
||||
|
||||
static inline std::string ACTIVE_NETID{LOKINET_DEFAULT_NETID};
|
||||
|
||||
static inline constexpr size_t MAX_RC_SIZE = 1024;
|
||||
|
||||
/// Timespans for RCs:
|
||||
|
||||
/// How long (relative to its timestamp) before an RC becomes stale. Stale records are used
|
||||
/// (e.g. for path building) only if there are no non-stale records available, such as might be
|
||||
/// the case when a client has been turned off for a while.
|
||||
static constexpr auto STALE = 12h;
|
||||
|
||||
/// How long before an RC becomes invalid (and thus deleted).
|
||||
static constexpr auto LIFETIME = 30 * 24h;
|
||||
|
||||
/// How long before a relay updates and re-publish its RC to the network. (Relays can
|
||||
/// re-publish more frequently than this if needed; this is meant to apply only if there are no
|
||||
/// changes i.e. just to push out a new confirmation of the details).
|
||||
static constexpr auto REPUBLISH = STALE / 2 - 5min;
|
||||
|
||||
/// Getters for private attributes
|
||||
const oxen::quic::Address&
|
||||
addr() const
|
||||
{
|
||||
return _addr;
|
||||
}
|
||||
|
||||
const std::optional<oxen::quic::Address>&
|
||||
addr6() const
|
||||
{
|
||||
return _addr6;
|
||||
}
|
||||
|
||||
const RouterID&
|
||||
router_id() const
|
||||
{
|
||||
return _router_id;
|
||||
}
|
||||
|
||||
const rc_time&
|
||||
timestamp() const
|
||||
{
|
||||
return _timestamp;
|
||||
}
|
||||
|
||||
protected:
|
||||
// advertised addresses
|
||||
oxen::quic::Address addr;
|
||||
// network identifier
|
||||
NetID netID;
|
||||
// public encryption public key
|
||||
llarp::PubKey enckey;
|
||||
oxen::quic::Address _addr; // refactor all 15 uses to use addr() method
|
||||
std::optional<oxen::quic::Address> _addr6; // optional ipv6
|
||||
// public signing public key
|
||||
llarp::PubKey pubkey;
|
||||
// signature
|
||||
llarp::Signature signature;
|
||||
RouterID _router_id; // refactor all 103 uses to use router_id() method
|
||||
|
||||
llarp_time_t last_updated = 0s;
|
||||
uint64_t version = llarp::constants::proto_version;
|
||||
std::optional<RouterVersion> routerVersion;
|
||||
rc_time _timestamp{};
|
||||
|
||||
// Lokinet version at the time the RC was produced
|
||||
std::array<uint8_t, 3> _router_version;
|
||||
|
||||
public:
|
||||
/// should we serialize the exit info?
|
||||
const static bool serializeExit = true;
|
||||
|
||||
std::string signed_bt_dict;
|
||||
|
||||
std::vector<dns::SRVData> srvRecords;
|
||||
ustring _signed_payload;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const;
|
||||
|
||||
RouterID
|
||||
router_id() const
|
||||
{
|
||||
return pubkey;
|
||||
}
|
||||
extract_status() const;
|
||||
|
||||
nlohmann::json
|
||||
ToJson() const
|
||||
to_json() const
|
||||
{
|
||||
return ExtractStatus();
|
||||
return extract_status();
|
||||
}
|
||||
|
||||
std::string
|
||||
ToString() const;
|
||||
virtual std::string
|
||||
to_string() const
|
||||
{
|
||||
return fmt::format(
|
||||
"[RC k={} updated={} v={} addr={}]",
|
||||
_router_id,
|
||||
_timestamp,
|
||||
RC_VERSION,
|
||||
_addr.to_string());
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// parse the reset of the fields. (Future versions might have backwards-compat support
|
||||
/// for lower versions).
|
||||
/// "4" -- 6 byte packed IPv4 address & port: 4 bytes of IPv4 address followed by 2 bytes of
|
||||
/// port, both encoded in network (i.e. big-endian) order.
|
||||
/// "6" -- optional 18 byte IPv6 address & port: 16 byte raw IPv6 address followed by 2 bytes
|
||||
/// of port in network order.
|
||||
/// "i" -- optional network ID string of up to 8 bytes; this is omitted for the default network
|
||||
/// ID ("lokinet") but included for others (such as "gamma" for testnet).
|
||||
/// "p" -- 32-byte router pubkey
|
||||
/// "t" -- timestamp when this RC record was created (which also implicitly determines when it
|
||||
/// goes stale and when it expires).
|
||||
/// "v" -- lokinet version of the router; this is a three-byte packed value of
|
||||
/// MAJOR, MINOR, PATCH, e.g. \x00\x0a\x03 for 0.10.3.
|
||||
/// "~" -- signature of all of the previous serialized data, signed by "p"
|
||||
std::string
|
||||
bt_encode() const;
|
||||
|
||||
void
|
||||
bt_encode_subdict(oxenc::bt_list_producer& btlp) const;
|
||||
|
||||
std::string
|
||||
bencode_signed_section() const;
|
||||
|
||||
std::string
|
||||
ToTXTRecord() const;
|
||||
virtual void
|
||||
bt_encode(oxenc::bt_dict_producer& btdp) const
|
||||
{
|
||||
(void)btdp;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const RouterContact& other) const
|
||||
{
|
||||
return addr == other.addr && enckey == other.enckey && pubkey == other.pubkey
|
||||
&& signature == other.signature && last_updated == other.last_updated
|
||||
&& netID == other.netID;
|
||||
return _router_id == other._router_id and _addr == other._addr and _addr6 == other._addr6
|
||||
and _timestamp == other._timestamp and _router_version == other._router_version;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const RouterContact& other) const
|
||||
{
|
||||
return pubkey < other.pubkey;
|
||||
return _router_id < other._router_id;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -147,14 +189,9 @@ namespace llarp
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
bool
|
||||
IsExit() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void
|
||||
clear()
|
||||
{}
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t* buf);
|
||||
@ -163,64 +200,170 @@ namespace llarp
|
||||
decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf);
|
||||
|
||||
bool
|
||||
IsPublicRouter() const;
|
||||
|
||||
bool
|
||||
Verify(llarp_time_t now, bool allowExpired = true) const;
|
||||
|
||||
bool
|
||||
Sign(const llarp::SecretKey& secret);
|
||||
is_public_router() const;
|
||||
|
||||
/// does this RC expire soon? default delta is 1 minute
|
||||
bool
|
||||
ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 1min) const;
|
||||
expires_within_delta(llarp_time_t now, llarp_time_t dlt = 1min) const;
|
||||
|
||||
/// returns true if this RC is expired and should be removed
|
||||
bool
|
||||
IsExpired(llarp_time_t now) const;
|
||||
is_expired(llarp_time_t now) const;
|
||||
|
||||
/// returns time in ms until we expire or 0 if we have expired
|
||||
llarp_time_t
|
||||
TimeUntilExpires(llarp_time_t now) const;
|
||||
time_to_expiry(llarp_time_t now) const;
|
||||
|
||||
/// get the age of this RC in ms
|
||||
llarp_time_t
|
||||
Age(llarp_time_t now) const;
|
||||
age(llarp_time_t now) const;
|
||||
|
||||
bool
|
||||
OtherIsNewer(const RouterContact& other) const
|
||||
other_is_newer(const RouterContact& other) const
|
||||
{
|
||||
return last_updated < other.last_updated;
|
||||
return _timestamp < other._timestamp;
|
||||
}
|
||||
|
||||
bool
|
||||
Read(const fs::path& fname);
|
||||
read(const fs::path& fname);
|
||||
|
||||
bool
|
||||
Write(const fs::path& fname) const;
|
||||
write(const fs::path& fname) const;
|
||||
|
||||
bool
|
||||
VerifySignature() const;
|
||||
is_obsolete_bootstrap() const;
|
||||
|
||||
/// return true if the netid in this rc is for the network id we are using
|
||||
bool
|
||||
FromOurNetwork() const;
|
||||
void
|
||||
bt_load(oxenc::bt_dict_consumer& data);
|
||||
|
||||
bool
|
||||
IsObsoleteBootstrap() const;
|
||||
};
|
||||
|
||||
|
||||
/// Extension of RouterContact used to store a local "RC," and inserts a RouterContact by
|
||||
/// re-parsing and sending it out. This sub-class contains a pubkey and all the other attributes
|
||||
/// required for signing and serialization
|
||||
///
|
||||
/// Note: this class may be entirely superfluous, so it is used here as a placeholder until its
|
||||
/// marginal utility is determined. It may end up as a free-floating method that reads in
|
||||
/// parameters and outputs a bt-serialized string
|
||||
struct LocalRC : public RouterContact
|
||||
{
|
||||
private:
|
||||
bool
|
||||
DecodeVersion_0(llarp_buffer_t* buf);
|
||||
ustring _signature;
|
||||
|
||||
const SecretKey _secret_key;
|
||||
|
||||
void
|
||||
bt_sign(oxenc::bt_dict_consumer& btdc);
|
||||
|
||||
void
|
||||
resign();
|
||||
|
||||
public:
|
||||
LocalRC(std::string payload, const SecretKey sk);
|
||||
|
||||
void
|
||||
bt_encode(oxenc::bt_dict_producer& btdp) const override;
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
_addr = {};
|
||||
_addr6.reset();
|
||||
_router_id.Zero();
|
||||
_timestamp = {};
|
||||
_router_version.fill(0);
|
||||
_signature.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
DecodeVersion_1(oxenc::bt_list_consumer& btlist);
|
||||
operator==(const LocalRC& other) const
|
||||
{
|
||||
return _router_id == other._router_id and _addr == other._addr and _addr6 == other._addr6
|
||||
and _timestamp == other._timestamp and _router_version == other._router_version
|
||||
and _signature == other._signature;
|
||||
}
|
||||
|
||||
/// Mutators for the private member attributes. Calling on the mutators
|
||||
/// will clear the current signature and re-sign the RC
|
||||
void
|
||||
set_addr(oxen::quic::Address new_addr)
|
||||
{
|
||||
resign();
|
||||
_addr = std::move(new_addr);
|
||||
}
|
||||
|
||||
void
|
||||
set_addr6(oxen::quic::Address new_addr)
|
||||
{
|
||||
resign();
|
||||
_addr6 = std::move(new_addr);
|
||||
}
|
||||
|
||||
void
|
||||
set_router_id(RouterID rid)
|
||||
{
|
||||
resign();
|
||||
_router_id = std::move(rid);
|
||||
}
|
||||
|
||||
void
|
||||
set_timestamp(llarp_time_t ts)
|
||||
{
|
||||
set_timestamp(rc_time{std::chrono::duration_cast<std::chrono::seconds>(ts)});
|
||||
}
|
||||
|
||||
void
|
||||
set_timestamp(rc_time ts)
|
||||
{
|
||||
_timestamp = ts;
|
||||
}
|
||||
|
||||
/// Sets RC timestamp to current system clock time
|
||||
void
|
||||
set_systime_timestamp()
|
||||
{
|
||||
set_timestamp(
|
||||
std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Extension of RouterContact used in a "read-only" fashion. Parses the incoming RC to query
|
||||
/// the data in the constructor, eliminating the need for a ::verify method/
|
||||
struct RemoteRC : public RouterContact
|
||||
{
|
||||
private:
|
||||
//
|
||||
|
||||
void
|
||||
bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired = false);
|
||||
|
||||
public:
|
||||
RemoteRC(std::string payload);
|
||||
|
||||
// TODO: this method could use oxenc's append_encoded
|
||||
void
|
||||
bt_encode(oxenc::bt_dict_producer& btdp) const override;
|
||||
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
_addr = {};
|
||||
_addr6.reset();
|
||||
_router_id.Zero();
|
||||
_timestamp = {};
|
||||
_router_version.fill(0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<NetID> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<RouterContact> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<RemoteRC> = true;
|
||||
template <>
|
||||
constexpr inline bool IsToStringFormattable<LocalRC> = true;
|
||||
|
||||
using RouterLookupHandler = std::function<void(const std::vector<RouterContact>&)>;
|
||||
} // namespace llarp
|
||||
@ -233,7 +376,7 @@ namespace std
|
||||
size_t
|
||||
operator()(const llarp::RouterContact& r) const
|
||||
{
|
||||
return std::hash<llarp::PubKey>{}(r.pubkey);
|
||||
return std::hash<llarp::PubKey>{}(r.router_id());
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
108
llarp/router_contact_local.cpp
Normal file
108
llarp/router_contact_local.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include "constants/version.hpp"
|
||||
#include "crypto/crypto.hpp"
|
||||
#include "net/net.hpp"
|
||||
#include "router_contact.hpp"
|
||||
#include "util/bencode.hpp"
|
||||
#include "util/buffer.hpp"
|
||||
#include "util/file.hpp"
|
||||
#include "util/time.hpp"
|
||||
|
||||
#include <oxenc/bt_serialize.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
LocalRC::LocalRC(std::string payload, const SecretKey sk) :
|
||||
_secret_key{std::move(sk)}
|
||||
{
|
||||
_router_id = llarp::seckey_to_pubkey(_secret_key);
|
||||
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{payload};
|
||||
bt_load(btdc);
|
||||
bt_sign(btdc);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(logcat, "Failed to parse LocalRC: {}", e.what());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LocalRC::bt_sign(oxenc::bt_dict_consumer& btdc)
|
||||
{
|
||||
_signature.clear();
|
||||
|
||||
btdc.require_signature("~", [&](ustring_view msg, ustring_view s) {
|
||||
if (!crypto::sign(const_cast<unsigned char*>(s.data()), _secret_key, msg))
|
||||
throw std::runtime_error{"Failed to sign RC"};
|
||||
|
||||
_signature = s;
|
||||
_signed_payload = msg;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
LocalRC::bt_encode(oxenc::bt_dict_producer& btdp) const
|
||||
{
|
||||
btdp.append("", RC_VERSION);
|
||||
|
||||
std::array<unsigned char, 18> buf;
|
||||
|
||||
{
|
||||
if (not _addr.is_ipv4())
|
||||
throw std::runtime_error{"Unable to encode RC: addr is not IPv4"};
|
||||
|
||||
auto in4 = _addr.in4();
|
||||
|
||||
std::memcpy(buf.data(), &in4.sin_addr.s_addr, 4);
|
||||
std::memcpy(buf.data() + 4, &in4.sin_port, 2);
|
||||
|
||||
btdp.append("4", ustring_view{buf.data(), 6});
|
||||
}
|
||||
|
||||
if (_addr6)
|
||||
{
|
||||
if (not _addr.is_ipv6())
|
||||
throw std::runtime_error{"Unable to encode RC: addr6 is set but is not IPv6"};
|
||||
|
||||
auto in6 = _addr.in6();
|
||||
|
||||
std::memcpy(buf.data(), &in6.sin6_addr.s6_addr, 16);
|
||||
std::memcpy(buf.data() + 16, &in6.sin6_port, 2);
|
||||
|
||||
btdp.append("6", ustring_view{buf.data(), 18});
|
||||
}
|
||||
|
||||
if (ACTIVE_NETID != llarp::LOKINET_DEFAULT_NETID)
|
||||
btdp.append("i", ACTIVE_NETID);
|
||||
|
||||
btdp.append("p", _router_id.ToView());
|
||||
|
||||
btdp.append("t", _timestamp.time_since_epoch().count());
|
||||
|
||||
static_assert(llarp::LOKINET_VERSION.size() == 3);
|
||||
btdp.append(
|
||||
"v", std::string_view{reinterpret_cast<const char*>(llarp::LOKINET_VERSION.data()), 3});
|
||||
|
||||
btdp.append_signature("~", [&](ustring_view to_sign) {
|
||||
std::array<unsigned char, 64> sig;
|
||||
|
||||
if (!crypto::sign(sig.data(), _secret_key, to_sign))
|
||||
throw std::runtime_error{"Failed to sign LocalRC"};
|
||||
|
||||
return sig;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
LocalRC::resign()
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{_signed_payload};
|
||||
bt_sign(btdc);
|
||||
|
||||
// DISCUSS: should we also update the timestamp when we re-sign?
|
||||
// -> Is the timestamp referring to signing time or time the RC was originally created?
|
||||
}
|
||||
} // namespace llarp
|
69
llarp/router_contact_remote.cpp
Normal file
69
llarp/router_contact_remote.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "constants/version.hpp"
|
||||
#include "crypto/crypto.hpp"
|
||||
#include "net/net.hpp"
|
||||
#include "router_contact.hpp"
|
||||
#include "util/bencode.hpp"
|
||||
#include "util/buffer.hpp"
|
||||
#include "util/file.hpp"
|
||||
#include "util/time.hpp"
|
||||
|
||||
#include <oxenc/bt_serialize.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
RemoteRC::RemoteRC(std::string payload)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{payload};
|
||||
bt_load(btdc);
|
||||
bt_verify(btdc);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(logcat, "Failed to parse RemoteRC: {}", e.what());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RemoteRC::bt_encode(oxenc::bt_dict_producer& btdp) const
|
||||
{
|
||||
(void)btdp;
|
||||
|
||||
// TODO: implement append_encoded in oxenc so we can finish this implementation.
|
||||
// It is almost identical to the implementation of LocalRC::bt_encode, except the
|
||||
// call to append_signature is append_encoded.
|
||||
//
|
||||
// When that is done, we can take the common logic and move it into the base class
|
||||
// ::bt_encode, and then have each derived class call into a different virtual method
|
||||
// that calls append_signature in the LocalRC and append_encoded in the RemoteRC
|
||||
}
|
||||
|
||||
void
|
||||
RemoteRC::bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired)
|
||||
{
|
||||
data.require_signature("~", [this, reject_expired](ustring_view msg, ustring_view sig) {
|
||||
if (sig.size() != 64)
|
||||
throw std::runtime_error{"Invalid signature: not 64 bytes"};
|
||||
|
||||
if (is_expired(time_now_ms()) and reject_expired)
|
||||
throw std::runtime_error{"Unable to verify expired RemoteRC!"};
|
||||
|
||||
// TODO: revisit if this is needed; detail from previous implementation
|
||||
const auto* net = net::Platform::Default_ptr();
|
||||
|
||||
if (net->IsBogon(addr().in4()) and BLOCK_BOGONS)
|
||||
{
|
||||
auto err = "Unable to verify expired RemoteRC!";
|
||||
log::info(logcat, err);
|
||||
throw std::runtime_error{err};
|
||||
}
|
||||
|
||||
if (not crypto::verify(router_id(), msg, sig))
|
||||
throw std::runtime_error{"Failed to verify RemoteRC"};
|
||||
|
||||
_signed_payload = msg;
|
||||
});
|
||||
}
|
||||
} // namespace llarp
|
@ -3,9 +3,11 @@
|
||||
#include "util/aligned.hpp"
|
||||
#include "util/status.hpp"
|
||||
|
||||
#include <llarp/crypto/types.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct RouterID : public AlignedBuffer<32>
|
||||
struct RouterID : public PubKey
|
||||
{
|
||||
static constexpr size_t SIZE = 32;
|
||||
|
||||
@ -13,10 +15,10 @@ namespace llarp
|
||||
|
||||
RouterID() = default;
|
||||
|
||||
RouterID(const byte_t* buf) : AlignedBuffer<SIZE>(buf)
|
||||
RouterID(const byte_t* buf) : PubKey(buf)
|
||||
{}
|
||||
|
||||
RouterID(const Data& data) : AlignedBuffer<SIZE>(data)
|
||||
RouterID(const Data& data) : PubKey(data)
|
||||
{}
|
||||
|
||||
util::StatusObject
|
||||
|
@ -181,7 +181,7 @@ namespace llarp::rpc
|
||||
|
||||
nlohmann::json payload = {
|
||||
{"pubkey_ed25519", oxenc::to_hex(pk.begin(), pk.end())},
|
||||
{"version", {VERSION[0], VERSION[1], VERSION[2]}}};
|
||||
{"version", {LOKINET_VERSION[0], LOKINET_VERSION[1], LOKINET_VERSION[2]}}};
|
||||
|
||||
if (auto err = r->OxendErrorState())
|
||||
payload["error"] = *err;
|
||||
|
@ -154,7 +154,7 @@ namespace llarp::rpc
|
||||
RPCServer::invoke(Version& version)
|
||||
{
|
||||
util::StatusObject result{
|
||||
{"version", llarp::VERSION_FULL}, {"uptime", to_json(m_Router.Uptime())}};
|
||||
{"version", llarp::LOKINET_VERSION_FULL}, {"uptime", to_json(m_Router.Uptime())}};
|
||||
|
||||
SetJSONResponse(result, version.response);
|
||||
}
|
||||
|
@ -223,10 +223,12 @@ namespace llarp::service
|
||||
// handles when we resolved a .snode
|
||||
auto handleResolvedSNodeName = [resultHandler, nodedb = router()->node_db()](auto router_id) {
|
||||
std::vector<dns::SRVData> result{};
|
||||
|
||||
if (auto maybe_rc = nodedb->get_rc(router_id))
|
||||
{
|
||||
result = maybe_rc->srvRecords;
|
||||
result = maybe_rc->srvRecords; // TODO: RouterContact has no SRV records
|
||||
}
|
||||
|
||||
resultHandler(std::move(result));
|
||||
};
|
||||
|
||||
@ -766,7 +768,7 @@ namespace llarp::service
|
||||
});
|
||||
if (not maybe.has_value())
|
||||
return std::nullopt;
|
||||
return GetHopsForBuildWithEndpoint(maybe->pubkey);
|
||||
return GetHopsForBuildWithEndpoint(maybe->router_id());
|
||||
}
|
||||
|
||||
std::optional<std::vector<RouterContact>>
|
||||
|
@ -44,7 +44,7 @@ namespace llarp::service
|
||||
{
|
||||
crypto::identity_keygen(signkey);
|
||||
crypto::encryption_keygen(enckey);
|
||||
pub.Update(seckey_topublic(signkey), seckey_topublic(enckey));
|
||||
pub.Update(seckey_to_pubkey(signkey), seckey_to_pubkey(enckey));
|
||||
crypto::pqe_keygen(pq);
|
||||
if (not crypto::derive_subkey_private(derivedSignKey, signkey, 1))
|
||||
{
|
||||
@ -114,7 +114,7 @@ namespace llarp::service
|
||||
// read file
|
||||
try
|
||||
{
|
||||
util::slurp_file(fname, tmp.data(), tmp.size());
|
||||
util::file_to_buffer(fname, tmp.data(), tmp.size());
|
||||
}
|
||||
catch (const std::length_error&)
|
||||
{
|
||||
@ -139,7 +139,7 @@ namespace llarp::service
|
||||
if (!vanity.IsZero())
|
||||
van = vanity;
|
||||
// update pubkeys
|
||||
pub.Update(seckey_topublic(signkey), seckey_topublic(enckey), van);
|
||||
pub.Update(seckey_to_pubkey(signkey), seckey_to_pubkey(enckey), van);
|
||||
if (not crypto::derive_subkey_private(derivedSignKey, signkey, 1))
|
||||
{
|
||||
throw std::runtime_error("failed to derive subkey");
|
||||
@ -163,7 +163,7 @@ namespace llarp::service
|
||||
// set service info
|
||||
i.address_keys = pub;
|
||||
// set public encryption key
|
||||
i.sntru_pubkey = pq_keypair_to_public(pq);
|
||||
i.sntru_pubkey = pq_keypair_to_pubkey(pq);
|
||||
|
||||
auto bte = i.bt_encode();
|
||||
|
||||
|
@ -256,7 +256,7 @@ namespace llarp::service
|
||||
// copy
|
||||
ProtocolFrameMessage frame(self->frame);
|
||||
if (!crypto::pqe_decrypt(
|
||||
self->frame.cipher, K, pq_keypair_to_secret(self->m_LocalIdentity.pq)))
|
||||
self->frame.cipher, K, pq_keypair_to_seckey(self->m_LocalIdentity.pq)))
|
||||
{
|
||||
LogError("pqke failed C=", self->frame.cipher);
|
||||
self->msg.reset();
|
||||
|
@ -365,7 +365,7 @@ namespace llarp
|
||||
std::string content;
|
||||
try
|
||||
{
|
||||
content = util::slurp_file(fpath);
|
||||
content = util::file_to_string(fpath);
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
|
@ -19,7 +19,7 @@
|
||||
namespace llarp::util
|
||||
{
|
||||
static std::streampos
|
||||
slurp_file_open(const fs::path& filename, fs::ifstream& in)
|
||||
file_reader_impl(const fs::path& filename, fs::ifstream& in)
|
||||
{
|
||||
in.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
in.open(filename, std::ios::binary | std::ios::in);
|
||||
@ -30,21 +30,21 @@ namespace llarp::util
|
||||
}
|
||||
|
||||
std::string
|
||||
slurp_file(const fs::path& filename)
|
||||
file_to_string(const fs::path& filename)
|
||||
{
|
||||
fs::ifstream in;
|
||||
std::string contents;
|
||||
auto size = slurp_file_open(filename, in);
|
||||
auto size = file_reader_impl(filename, in);
|
||||
contents.resize(size);
|
||||
in.read(contents.data(), size);
|
||||
return contents;
|
||||
}
|
||||
|
||||
size_t
|
||||
slurp_file(const fs::path& filename, char* buffer, size_t buffer_size)
|
||||
file_to_buffer(const fs::path& filename, char* buffer, size_t buffer_size)
|
||||
{
|
||||
fs::ifstream in;
|
||||
auto size = slurp_file_open(filename, in);
|
||||
auto size = file_reader_impl(filename, in);
|
||||
if (static_cast<size_t>(size) > buffer_size)
|
||||
throw std::length_error{"file is too large for buffer"};
|
||||
in.read(buffer, size);
|
||||
|
@ -14,21 +14,21 @@ namespace llarp::util
|
||||
{
|
||||
/// Reads a binary file from disk into a string. Throws on error.
|
||||
std::string
|
||||
slurp_file(const fs::path& filename);
|
||||
file_to_string(const fs::path& filename);
|
||||
|
||||
/// Reads a binary file from disk directly into a buffer. Throws a std::length_error if the
|
||||
/// file is bigger than the buffer. Returns the bytes copied on success.
|
||||
size_t
|
||||
slurp_file(const fs::path& filename, char* buffer, size_t buffer_size);
|
||||
file_to_buffer(const fs::path& filename, char* buffer, size_t buffer_size);
|
||||
|
||||
/// Same, but for some non-char but single-byte char type (e.g. byte_t, std::byte, unsigned char).
|
||||
template <
|
||||
typename Char,
|
||||
std::enable_if_t<sizeof(Char) == 1 and not std::is_same_v<Char, char>, int> = 1>
|
||||
inline size_t
|
||||
slurp_file(const fs::path& filename, Char* buffer, size_t buffer_size)
|
||||
file_to_buffer(const fs::path& filename, Char* buffer, size_t buffer_size)
|
||||
{
|
||||
return slurp_file(filename, reinterpret_cast<char*>(buffer), buffer_size);
|
||||
return file_to_buffer(filename, reinterpret_cast<char*>(buffer), buffer_size);
|
||||
}
|
||||
|
||||
/// Dumps binary string contents to disk. The file is overwritten if it already exists. Throws
|
||||
|
Loading…
Reference in New Issue
Block a user