mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-02 03:40:12 +00:00
Message method implementation continued
- tons of surrounding stupid refactoring required
This commit is contained in:
parent
ad007ff832
commit
1a9f977208
@ -149,19 +149,18 @@ add_library(lokinet-consensus
|
||||
# lokinet-dht holds all logic related to interacting with and participating in the DHT hashring
|
||||
add_library(lokinet-dht
|
||||
STATIC
|
||||
dht/dht.cpp
|
||||
dht/explorenetworkjob.cpp
|
||||
dht/localtaglookup.cpp
|
||||
dht/localrouterlookup.cpp
|
||||
dht/localserviceaddresslookup.cpp
|
||||
dht/message.cpp
|
||||
dht/messages/findintro.cpp
|
||||
dht/messages/findrouter.cpp
|
||||
dht/messages/gotintro.cpp
|
||||
dht/messages/gotrouter.cpp
|
||||
dht/messages/pubintro.cpp
|
||||
dht/messages/findname.cpp
|
||||
dht/messages/gotname.cpp
|
||||
# dht/messages/findintro.cpp
|
||||
# dht/messages/findrouter.cpp
|
||||
# dht/messages/gotintro.cpp
|
||||
# dht/messages/gotrouter.cpp
|
||||
# dht/messages/pubintro.cpp
|
||||
# dht/messages/findname.cpp
|
||||
# dht/messages/gotname.cpp
|
||||
dht/publishservicejob.cpp
|
||||
dht/recursiverouterlookup.cpp
|
||||
dht/serviceaddresslookup.cpp
|
||||
@ -197,6 +196,7 @@ add_library(lokinet-layer-onion
|
||||
add_library(lokinet-layer-link
|
||||
STATIC
|
||||
link/connection.cpp
|
||||
link/contacts.cpp
|
||||
link/link_manager.cpp
|
||||
messages/link_intro.cpp
|
||||
)
|
||||
@ -220,7 +220,6 @@ add_library(lokinet-context
|
||||
STATIC
|
||||
context.cpp
|
||||
link/link_manager.cpp
|
||||
router/outbound_message_handler.cpp
|
||||
router/rc_lookup_handler.cpp
|
||||
router/rc_gossiper.cpp
|
||||
router/router.cpp
|
||||
|
@ -3,8 +3,7 @@
|
||||
#include "constants/evloop.hpp"
|
||||
|
||||
#include "config/config.hpp"
|
||||
#include "crypto/crypto_libsodium.hpp"
|
||||
#include "dht/context.hpp"
|
||||
#include "crypto/crypto.hpp"
|
||||
#include "ev/ev.hpp"
|
||||
#include <memory>
|
||||
#include "nodedb.hpp"
|
||||
@ -75,7 +74,7 @@ namespace llarp
|
||||
loop = EventLoop::create(jobQueueSize);
|
||||
}
|
||||
|
||||
crypto = std::make_shared<sodium::CryptoLibSodium>();
|
||||
crypto = std::make_shared<Crypto>();
|
||||
cryptoManager = std::make_shared<CryptoManager>(crypto.get());
|
||||
|
||||
router = makeRouter(loop);
|
||||
|
@ -22,6 +22,14 @@ namespace llarp
|
||||
return true;
|
||||
}
|
||||
|
||||
PubKey
|
||||
PubKey::from_string(const std::string& s)
|
||||
{
|
||||
PubKey p;
|
||||
oxenc::from_hex(s.begin(), s.end(), p.begin());
|
||||
return p;
|
||||
}
|
||||
|
||||
std::string
|
||||
PubKey::ToString() const
|
||||
{
|
||||
|
@ -33,6 +33,9 @@ namespace llarp
|
||||
bool
|
||||
FromString(const std::string& str);
|
||||
|
||||
static PubKey
|
||||
from_string(const std::string& s);
|
||||
|
||||
operator RouterID() const
|
||||
{
|
||||
return {as_array()};
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "dht.h"
|
||||
#include "key.hpp"
|
||||
#include <llarp/messages/link_message.hpp>
|
||||
#include <llarp/path/path_types.hpp>
|
||||
@ -39,16 +38,6 @@ namespace llarp::dht
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* val) = 0;
|
||||
|
||||
// methods we do not want to inherit onwards from AbstractSerializable
|
||||
void
|
||||
bt_encode(oxenc::bt_list_producer&) const final
|
||||
{
|
||||
throw std::runtime_error{"Error: DHT messages should encode directly to a bt dict producer!"};
|
||||
}
|
||||
void
|
||||
bt_encode(llarp_buffer&) const final
|
||||
{
|
||||
throw std::runtime_error{"Error: DHT messages should encode directly to a bt dict producer!"};
|
||||
}
|
||||
std::string
|
||||
bt_encode() const final
|
||||
{
|
||||
|
105
llarp/link/contacts.cpp
Normal file
105
llarp/link/contacts.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
#include "contacts.hpp"
|
||||
|
||||
#include <llarp/messages/dht.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
Contacts::Contacts(const dht::Key_t& k, Router& r) : _local_key{k}, _router{r}
|
||||
{
|
||||
timer_keepalive = std::make_shared<int>(0);
|
||||
_router.loop()->call_every(1s, timer_keepalive, [this]() { on_clean_contacts(); });
|
||||
|
||||
_rc_nodes = std::make_unique<dht::Bucket<dht::RCNode>>(_local_key, llarp::randint);
|
||||
_introset_nodes = std::make_unique<dht::Bucket<dht::ISNode>>(_local_key, llarp::randint);
|
||||
}
|
||||
|
||||
std::optional<service::EncryptedIntroSet>
|
||||
Contacts::get_introset_by_location(const dht::Key_t& key) const
|
||||
{
|
||||
auto& introsets = _introset_nodes->nodes;
|
||||
|
||||
if (auto itr = introsets.find(key); itr != introsets.end())
|
||||
return itr->second.introset;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void
|
||||
Contacts::on_clean_contacts()
|
||||
{
|
||||
const auto now = llarp::time_now_ms();
|
||||
|
||||
if (_rc_nodes)
|
||||
{
|
||||
auto& nodes = _rc_nodes->nodes;
|
||||
auto itr = nodes.begin();
|
||||
|
||||
while (itr != nodes.end())
|
||||
{
|
||||
if (itr->second.rc.IsExpired(now))
|
||||
itr = nodes.erase(itr);
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
if (_introset_nodes)
|
||||
{
|
||||
auto& svcs = _introset_nodes->nodes;
|
||||
auto itr = svcs.begin();
|
||||
|
||||
while (itr != svcs.end())
|
||||
{
|
||||
if (itr->second.introset.IsExpired(now))
|
||||
itr = svcs.erase(itr);
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
util::StatusObject
|
||||
Contacts::extract_status() const
|
||||
{
|
||||
util::StatusObject obj{
|
||||
{"nodes", _rc_nodes->ExtractStatus()},
|
||||
{"services", _introset_nodes->ExtractStatus()},
|
||||
{"local_key", _local_key.ToHex()}};
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool
|
||||
Contacts::lookup_router(
|
||||
const RouterID& rid, std::function<void(const std::vector<RouterContact>&)> func)
|
||||
{
|
||||
dht::Key_t ask_peer;
|
||||
|
||||
if (not _rc_nodes->FindClosest(dht::Key_t{rid}, ask_peer))
|
||||
return false;
|
||||
|
||||
_router.loop()->call([this, rid, func]() {
|
||||
pending_lookups[rid] = [](const std::vector<RouterContact>&) {
|
||||
// TODO: combine this concept with service::Endpoint introset lookups?
|
||||
};
|
||||
|
||||
_router.send_control_message(
|
||||
rid, "find_router", FindRouterMessage::serialize(rid, false, false, 0));
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Contacts::put_rc_node_async(const dht::RCNode& val)
|
||||
{
|
||||
_router.loop()->call([this, val]() { _rc_nodes->PutNode(val); });
|
||||
}
|
||||
|
||||
void
|
||||
Contacts::delete_rc_node_async(const dht::Key_t& val)
|
||||
{
|
||||
_router.loop()->call([this, val]() { _rc_nodes->DelNode(val); });
|
||||
}
|
||||
|
||||
} // namespace llarp
|
78
llarp/link/contacts.hpp
Normal file
78
llarp/link/contacts.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/dht/bucket.hpp>
|
||||
#include <llarp/dht/node.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct Router;
|
||||
|
||||
/// This class mediates storage, retrieval, and functionality for the various types
|
||||
/// of contact information that needs to be stored locally by the link manager and
|
||||
/// router, like RouterContacts and introsets for example
|
||||
struct Contacts
|
||||
{
|
||||
private:
|
||||
// TODO: why was this a shared ptr in the original implementation? revisit this
|
||||
std::shared_ptr<int> timer_keepalive;
|
||||
const dht::Key_t& _local_key;
|
||||
Router& _router;
|
||||
std::atomic<bool> transit_allowed{false};
|
||||
|
||||
// holds router contacts
|
||||
std::unique_ptr<dht::Bucket<dht::RCNode>> _rc_nodes;
|
||||
// holds introsets for remote services
|
||||
std::unique_ptr<dht::Bucket<dht::ISNode>> _introset_nodes;
|
||||
|
||||
public:
|
||||
Contacts(const dht::Key_t& local, Router& r);
|
||||
|
||||
/// Sets the value of transit_allowed to the value of `b`. Returns false if the
|
||||
/// value was already b, true otherwise
|
||||
bool
|
||||
set_transit_allowed(bool b)
|
||||
{
|
||||
return not transit_allowed.exchange(b) == b;
|
||||
}
|
||||
|
||||
std::unordered_map<RouterID, std::function<void(const std::vector<RouterContact>&)>>
|
||||
pending_lookups;
|
||||
|
||||
void
|
||||
on_clean_contacts();
|
||||
|
||||
std::optional<service::EncryptedIntroSet>
|
||||
get_introset_by_location(const dht::Key_t& key) const;
|
||||
|
||||
util::StatusObject
|
||||
extract_status() const;
|
||||
|
||||
bool
|
||||
lookup_router(const RouterID&, std::function<void(const std::vector<RouterContact>&)>);
|
||||
|
||||
void
|
||||
put_rc_node_async(const dht::RCNode& val);
|
||||
|
||||
void
|
||||
delete_rc_node_async(const dht::Key_t& val);
|
||||
|
||||
dht::Bucket<dht::RCNode>*
|
||||
rc_nodes() const
|
||||
{
|
||||
return _rc_nodes.get();
|
||||
}
|
||||
|
||||
dht::Bucket<dht::ISNode>*
|
||||
services() const
|
||||
{
|
||||
return _introset_nodes.get();
|
||||
}
|
||||
|
||||
Router*
|
||||
router() const
|
||||
{
|
||||
return &_router;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace llarp
|
@ -1,4 +0,0 @@
|
||||
#include "link_endpoints.hpp"
|
||||
|
||||
namespace llarp
|
||||
{} // namespace llarp
|
@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace llarp
|
||||
{} // namespace llarp
|
@ -1,5 +1,6 @@
|
||||
#include "link_manager.hpp"
|
||||
#include "connection.hpp"
|
||||
#include "contacts.hpp"
|
||||
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/router/rc_lookup_handler.hpp>
|
||||
@ -150,24 +151,27 @@ namespace llarp
|
||||
- stream constructor callback
|
||||
- will return a BTRequestStream on the first call to get_new_stream<BTRequestStream>
|
||||
*/
|
||||
return quic->endpoint(
|
||||
auto ep = quic->endpoint(
|
||||
router.public_ip(),
|
||||
[this](oxen::quic::connection_interface& ci) { return on_conn_open(ci); },
|
||||
[this](oxen::quic::connection_interface& ci, uint64_t ec) {
|
||||
return on_conn_closed(ci, ec);
|
||||
},
|
||||
[this](oxen::quic::dgram_interface& di, bstring dgram) { recv_data_message(di, dgram); },
|
||||
[this](oxen::quic::dgram_interface& di, bstring dgram) { recv_data_message(di, dgram); });
|
||||
ep->listen(
|
||||
tls_creds,
|
||||
[&](oxen::quic::Connection& c,
|
||||
oxen::quic::Endpoint& e,
|
||||
std::optional<int64_t> id) -> std::shared_ptr<oxen::quic::Stream> {
|
||||
if (id && id == 0)
|
||||
{
|
||||
auto s = std::make_shared<oxen::quic::BTRequestStream>();
|
||||
auto s = std::make_shared<oxen::quic::BTRequestStream>(c, e);
|
||||
register_commands(s);
|
||||
return s;
|
||||
}
|
||||
return std::make_shared<oxen::quic::Stream>(c, e);
|
||||
});
|
||||
return ep;
|
||||
}
|
||||
|
||||
LinkManager::LinkManager(Router& r)
|
||||
@ -185,10 +189,37 @@ namespace llarp
|
||||
std::string endpoint,
|
||||
std::string body,
|
||||
std::function<void(oxen::quic::message m)> func)
|
||||
{
|
||||
if (func)
|
||||
return send_control_message_impl(
|
||||
remote, std::move(endpoint), std::move(body), std::move(func));
|
||||
|
||||
if (auto itr = rpc_responses.find(endpoint); itr != rpc_responses.end())
|
||||
return send_control_message_impl(
|
||||
remote, std::move(endpoint), std::move(body), [&](oxen::quic::message m) {
|
||||
return std::invoke(itr->second, this, std::move(m));
|
||||
});
|
||||
|
||||
return send_control_message_impl(remote, std::move(endpoint), std::move(body));
|
||||
}
|
||||
|
||||
bool
|
||||
LinkManager::send_control_message_impl(
|
||||
const RouterID& remote,
|
||||
std::string endpoint,
|
||||
std::string body,
|
||||
std::function<void(oxen::quic::message m)> func)
|
||||
{
|
||||
if (is_stopping)
|
||||
return false;
|
||||
|
||||
auto cb = [this, f = std::move(func), endpoint](oxen::quic::message m) {
|
||||
f(m);
|
||||
|
||||
if (auto itr = rpc_responses.find(endpoint); itr != rpc_responses.end())
|
||||
std::invoke(itr->second, this, std::move(m));
|
||||
};
|
||||
|
||||
if (auto conn = ep.get_conn(remote); conn)
|
||||
{
|
||||
conn->control_stream->command(endpoint, body, std::move(func));
|
||||
@ -290,7 +321,7 @@ namespace llarp
|
||||
|
||||
// TODO: confirm remote end is using the expected pubkey (RouterID).
|
||||
// TODO: ALPN for "client" vs "relay" (could just be set on endpoint creation)
|
||||
if (auto rv = ep.establish_connection(remote_addr, rc, tls_creds); rv)
|
||||
if (auto rv = ep.establish_connection(remote_addr, rc); rv)
|
||||
{
|
||||
log::info(quic_cat, "Connection to {} successfully established!", remote_addr);
|
||||
return;
|
||||
@ -493,14 +524,14 @@ namespace llarp
|
||||
LinkManager::handle_find_name(oxen::quic::message m)
|
||||
{
|
||||
std::string name_hash;
|
||||
uint64_t tx_id;
|
||||
[[maybe_unused]] uint64_t tx_id;
|
||||
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdp{m.body()};
|
||||
|
||||
safe_fetch_value(btdp, "H", name_hash);
|
||||
safe_fetch_value(btdp, "T", tx_id);
|
||||
name_hash = btdp.require<std::string>("H");
|
||||
tx_id = btdp.require<uint64_t>("T");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@ -510,11 +541,10 @@ namespace llarp
|
||||
|
||||
router.rpc_client()->lookup_ons_hash(
|
||||
name_hash, [this, msg = std::move(m)](std::optional<service::EncryptedName> maybe) mutable {
|
||||
|
||||
if (maybe.has_value())
|
||||
msg.respond(serialize_response(true, {"NAME", maybe->ciphertext.c_str()}));
|
||||
msg.respond(serialize_response(true, {{"NAME", maybe->ciphertext.c_str()}}));
|
||||
else
|
||||
msg.respond(serialize_response(false, {"STATUS", "NOT FOUND"}), true);
|
||||
msg.respond(serialize_response(false, {{"STATUS", "NOT FOUND"}}), true);
|
||||
});
|
||||
}
|
||||
|
||||
@ -527,24 +557,21 @@ namespace llarp
|
||||
void
|
||||
LinkManager::handle_find_router(oxen::quic::message m)
|
||||
{
|
||||
ustring target_key;
|
||||
uint64_t is_exploratory, is_iterative, tx_id;
|
||||
std::string target_key;
|
||||
uint64_t is_exploratory, is_iterative;
|
||||
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
|
||||
|
||||
|
||||
safe_fetch_value(btdc, "E", is_exploratory);
|
||||
safe_fetch_value(btdc, "I", is_iterative);
|
||||
safe_fetch_value(btdc, "K", target_key);
|
||||
safe_fetch_value(btdc, "T", tx_id);
|
||||
is_exploratory = btdc.require<uint64_t>("E");
|
||||
is_iterative = btdc.require<uint64_t>("I");
|
||||
target_key = btdc.require<std::string>("E");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -552,15 +579,82 @@ namespace llarp
|
||||
|
||||
// TODO: do we need a replacement for dht.pendingIntroSetLookups() etc here?
|
||||
|
||||
const auto target_addr = dht::Key_t{};
|
||||
RouterID target_rid;
|
||||
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_key = dht::Key_t{local_rid};
|
||||
|
||||
|
||||
if (is_exploratory)
|
||||
{
|
||||
std::string neighbors{};
|
||||
const auto closest_rcs =
|
||||
router.node_db()->FindManyClosestTo(target_addr, RC_LOOKUP_STORAGE_REDUNDANCY);
|
||||
|
||||
for (const auto& rc : closest_rcs)
|
||||
{
|
||||
const auto& rid = rc.pubkey;
|
||||
if (router.router_profiling().IsBadForConnect(rid) || target_rid == rid || local_rid == rid)
|
||||
continue;
|
||||
|
||||
neighbors += oxenc::bt_serialize(rid.ToString());
|
||||
}
|
||||
|
||||
m.respond(
|
||||
serialize_response(
|
||||
false, {{"STATUS", "RETRY EXPLORATORY"}, {"ROUTERS", neighbors.c_str()}}),
|
||||
true);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto closest_rc = router.node_db()->FindClosestTo(target_addr);
|
||||
const auto& closest_rid = closest_rc.pubkey;
|
||||
const auto closest_key = dht::Key_t{closest_rid};
|
||||
|
||||
if (target_addr == closest_key)
|
||||
{
|
||||
if (closest_rc.ExpiresSoon(llarp::time_now_ms()))
|
||||
{
|
||||
send_control_message_impl(
|
||||
target_rid, "find_router", m.body_str(), [this](oxen::quic::message m) {
|
||||
return handle_find_router_response(std::move(m));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
m.respond(serialize_response(true, {{"RC", closest_rc.ToString().c_str()}}));
|
||||
}
|
||||
}
|
||||
else if (not is_iterative)
|
||||
{
|
||||
if ((closest_key ^ target_addr) < (local_key ^ target_addr))
|
||||
{
|
||||
send_control_message_impl(
|
||||
closest_rc.pubkey, "find_router", m.body_str(), [this](oxen::quic::message m) {
|
||||
return handle_find_router_response(std::move(m));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
m.respond(serialize_response(false, {{"STATUS", "RETRY ITERATIVE"}}), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.respond(
|
||||
serialize_response(
|
||||
false,
|
||||
{{"STATUS", "RETRY NEW RECIPIENT"},
|
||||
{"RECIPIENT", reinterpret_cast<const char*>(closest_rid.data())}}),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_publish_intro(oxen::quic::message m)
|
||||
{
|
||||
std::string introset, derived_signing_key, sig;
|
||||
std::string introset, derived_signing_key, payload, sig, nonce;
|
||||
uint64_t is_relayed, relay_order, tx_id;
|
||||
std::chrono::milliseconds signed_at;
|
||||
|
||||
@ -568,21 +662,23 @@ namespace llarp
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc_a{m.body()};
|
||||
|
||||
safe_fetch_value(btdc_a, "I", introset);
|
||||
safe_fetch_value(btdc_a, "O", relay_order);
|
||||
safe_fetch_value(btdc_a, "R", is_relayed);
|
||||
safe_fetch_value(btdc_a, "T", tx_id);
|
||||
introset = btdc_a.require<std::string>("I");
|
||||
relay_order = btdc_a.require<uint64_t>("O");
|
||||
is_relayed = btdc_a.require<uint64_t>("R");
|
||||
tx_id = btdc_a.require<uint64_t>("T");
|
||||
|
||||
oxenc::bt_dict_consumer btdc_b{introset};
|
||||
oxenc::bt_dict_consumer btdc_b{introset.data()};
|
||||
|
||||
safe_fetch_value(btdc_b, "d", derived_signing_key);
|
||||
safe_fetch_value(btdc_b, "s", signed_at);
|
||||
safe_fetch_value(btdc_b, "z", sig);
|
||||
derived_signing_key = btdc_b.require<std::string>("d");
|
||||
nonce = btdc_b.require<std::string>("n");
|
||||
signed_at = std::chrono::milliseconds{btdc_b.require<uint64_t>("s")};
|
||||
payload = btdc_b.require<std::string>("x");
|
||||
sig = btdc_b.require<std::string>("z");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -593,14 +689,14 @@ namespace llarp
|
||||
if (not service::EncryptedIntroSet::verify(introset, derived_signing_key, sig))
|
||||
{
|
||||
log::error(link_cat, "Received PublishIntroMessage with invalid introset: {}", introset);
|
||||
m.respond(serialize_response(false, {"STATUS", "INVALID INTROSET"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "INVALID INTROSET"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (now + service::MAX_INTROSET_TIME_DELTA > signed_at + path::DEFAULT_LIFETIME)
|
||||
{
|
||||
log::error(link_cat, "Received PublishIntroMessage with expired introset: {}", introset);
|
||||
m.respond(serialize_response(false, {"STATUS", "EXPIRED INTROSET"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXPIRED INTROSET"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -610,17 +706,19 @@ namespace llarp
|
||||
{
|
||||
log::error(
|
||||
link_cat, "Received PublishIntroMessage but only know {} nodes", closest_rcs.size());
|
||||
m.respond(serialize_response(false, {"STATUS", "INSUFFICIENT NODES"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "INSUFFICIENT NODES"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
service::EncryptedIntroSet enc{derived_signing_key, signed_at, payload, nonce, sig};
|
||||
|
||||
if (is_relayed)
|
||||
{
|
||||
if (relay_order >= INTROSET_STORAGE_REDUNDANCY)
|
||||
{
|
||||
log::error(
|
||||
link_cat, "Received PublishIntroMessage with invalide relay order: {}", relay_order);
|
||||
m.respond(serialize_response(false, {"STATUS", "INVALID ORDER"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "INVALID ORDER"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -636,8 +734,7 @@ namespace llarp
|
||||
"Received PublishIntroMessage in which we are peer index {}.. storing introset",
|
||||
relay_order);
|
||||
|
||||
// TODO: replace this concept
|
||||
// dht->services()->PutNode(introset);
|
||||
router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)});
|
||||
m.respond(serialize_response(true));
|
||||
}
|
||||
else
|
||||
@ -645,7 +742,7 @@ namespace llarp
|
||||
log::info(
|
||||
link_cat, "Received PublishIntroMessage; propagating to peer index {}", relay_order);
|
||||
|
||||
send_control_message(
|
||||
send_control_message_impl(
|
||||
peer_key, "publish_intro", m.body_str(), [this](oxen::quic::message m) {
|
||||
return handle_publish_intro_response(std::move(m));
|
||||
});
|
||||
@ -669,8 +766,8 @@ namespace llarp
|
||||
if (rc_index >= 0)
|
||||
{
|
||||
log::info(link_cat, "Received PublishIntroMessage for {} (TXID: {}); we are candidate {}");
|
||||
// TODO: replace this concept
|
||||
// dht->services()->PutNode(introset);
|
||||
|
||||
router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)});
|
||||
m.respond(serialize_response(true));
|
||||
}
|
||||
else
|
||||
@ -690,17 +787,16 @@ namespace llarp
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
|
||||
safe_fetch_value(btdc, "N", tag_name);
|
||||
safe_fetch_value(btdc, "O", relay_order);
|
||||
safe_fetch_value(btdc, "R", is_relayed);
|
||||
safe_fetch_value(btdc, "S", location);
|
||||
safe_fetch_value(btdc, "T", tx_id);
|
||||
safe_fetch_value(btdc, "N", tag_name);
|
||||
tag_name = btdc.require<std::string>("N");
|
||||
relay_order = btdc.require<uint64_t>("O");
|
||||
is_relayed = btdc.require<uint64_t>("R");
|
||||
location = btdc.require<std::string>("S");
|
||||
tx_id = btdc.require<uint64_t>("T");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -714,7 +810,7 @@ namespace llarp
|
||||
{
|
||||
log::warning(
|
||||
link_cat, "Received FindIntroMessage with invalid relay order: {}", relay_order);
|
||||
m.respond(serialize_response(false, {"STATUS", "INVALID ORDER"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "INVALID ORDER"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -724,7 +820,7 @@ namespace llarp
|
||||
{
|
||||
log::error(
|
||||
link_cat, "Received FindIntroMessage but only know {} nodes", closest_rcs.size());
|
||||
m.respond(serialize_response(false, {"STATUS", "INSUFFICIENT NODES"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "INSUFFICIENT NODES"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -733,15 +829,16 @@ namespace llarp
|
||||
const auto& peer_rc = closest_rcs[relay_order];
|
||||
const auto& peer_key = peer_rc.pubkey;
|
||||
|
||||
send_control_message(peer_key, "find_intro", m.body_str(), [this](oxen::quic::message m) {
|
||||
return handle_find_intro_response(std::move(m));
|
||||
});
|
||||
send_control_message_impl(
|
||||
peer_key, "find_intro", m.body_str(), [this](oxen::quic::message m) {
|
||||
return handle_find_intro_response(std::move(m));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: replace this concept and add it to the response
|
||||
// const auto maybe = dht.GetIntroSetByLocation(location);
|
||||
m.respond(serialize_response(true, {"INTROSET", ""}));
|
||||
m.respond(serialize_response(true, {{"INTROSET", ""}}));
|
||||
}
|
||||
|
||||
void
|
||||
@ -754,7 +851,7 @@ namespace llarp
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -769,7 +866,7 @@ namespace llarp
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -784,7 +881,7 @@ namespace llarp
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -792,16 +889,30 @@ namespace llarp
|
||||
void
|
||||
LinkManager::handle_obtain_exit(oxen::quic::message m)
|
||||
{
|
||||
// TODO: implement transit_hop things like nextseqno(), info.rxID, etc
|
||||
std::string payload{m.body_str()}, pubkey;
|
||||
[[maybe_unused]] uint64_t flag, tx_id, seq_no;
|
||||
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
oxenc::bt_dict_consumer btdc{payload};
|
||||
|
||||
flag = btdc.require<uint64_t>("E");
|
||||
pubkey = btdc.require<std::string>("I");
|
||||
seq_no = btdc.require<uint64_t>("S");
|
||||
tx_id = btdc.require<uint64_t>("T");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
RouterID target;
|
||||
target.FromString(pubkey);
|
||||
|
||||
// auto handler = router.path_context().GetByDownstream(target, tx_id);
|
||||
}
|
||||
|
||||
void
|
||||
@ -814,7 +925,7 @@ namespace llarp
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -829,7 +940,7 @@ namespace llarp
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -844,7 +955,7 @@ namespace llarp
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -859,7 +970,7 @@ namespace llarp
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -874,8 +985,10 @@ namespace llarp
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response(false, {"STATUS", "EXCEPTION"}), true);
|
||||
m.respond(serialize_response(false, {{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if we have any pending intro lookups in contacts
|
||||
}
|
||||
} // namespace llarp
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "connection.hpp"
|
||||
#include "link_endpoints.hpp"
|
||||
|
||||
#include <llarp/router/rc_lookup_handler.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
@ -140,7 +139,6 @@ namespace llarp
|
||||
public:
|
||||
explicit LinkManager(Router& r);
|
||||
|
||||
// set is_request to true for RPC requests, false for RPC commands
|
||||
bool
|
||||
send_control_message(
|
||||
const RouterID& remote,
|
||||
@ -152,6 +150,13 @@ namespace llarp
|
||||
send_data_message(const RouterID& remote, std::string data);
|
||||
|
||||
private:
|
||||
bool
|
||||
send_control_message_impl(
|
||||
const RouterID& remote,
|
||||
std::string endpoint,
|
||||
std::string body,
|
||||
std::function<void(oxen::quic::message)> = nullptr);
|
||||
|
||||
friend struct link::Endpoint;
|
||||
|
||||
std::atomic<bool> is_stopping;
|
||||
@ -302,34 +307,20 @@ namespace llarp
|
||||
{"obtain_exit", &LinkManager::handle_obtain_exit},
|
||||
{"close_exit", &LinkManager::handle_close_exit}};
|
||||
|
||||
std::unordered_map<std::string, void (LinkManager::*)(oxen::quic::message)> rpc_responses = {
|
||||
{"find_name", &LinkManager::handle_find_name_response},
|
||||
{"find_router", &LinkManager::handle_find_router_response},
|
||||
{"publish_intro", &LinkManager::handle_publish_intro_response},
|
||||
{"find_intro", &LinkManager::handle_find_intro_response}};
|
||||
|
||||
// response handling functions
|
||||
void handle_publish_intro_response(oxen::quic::message);
|
||||
void handle_find_name_response(oxen::quic::message); // not used?
|
||||
void handle_find_name_response(oxen::quic::message); // not used?
|
||||
void handle_find_router_response(oxen::quic::message);
|
||||
void handle_find_intro_response(oxen::quic::message);
|
||||
|
||||
std::string
|
||||
serialize_response(bool success, oxenc::bt_dict supplement = {});
|
||||
|
||||
/** Searches the bt dict held by a dict consumer for a specific key `k`, setting
|
||||
the value at `dest` and throwing if not found. This is equivalent to calling:
|
||||
|
||||
if (not bdca.skip_until(k))
|
||||
throw std::invalid_argument{"..."};
|
||||
dest = btdc.consume_integer<int_type>() OR btdc.consume_string();
|
||||
*/
|
||||
template <typename T>
|
||||
void
|
||||
safe_fetch_value(oxenc::bt_dict_consumer& btdc, const char* k, T& dest)
|
||||
{
|
||||
if (not btdc.skip_until(k))
|
||||
throw std::invalid_argument{""};
|
||||
|
||||
if constexpr (std::is_integral_v<T>)
|
||||
dest = btdc.consume_integer<T>();
|
||||
else
|
||||
dest = btdc.consume_string();
|
||||
}
|
||||
};
|
||||
|
||||
namespace link
|
||||
@ -346,11 +337,11 @@ namespace llarp
|
||||
|
||||
// emplace immediately for connection open callback to find scid
|
||||
connid_map.emplace(conn_interface->scid(), rc.pubkey);
|
||||
auto [itr, b] = conns.emplace(rc.pubkey);
|
||||
auto [itr, b] = conns.emplace(rc.pubkey, nullptr);
|
||||
|
||||
auto control_stream =
|
||||
conn_interface->template get_new_stream<oxen::quic::BTRequestStream>();
|
||||
itr->second = std::make_shared<link::Connection>(conn_interface, rc, control_stream);
|
||||
itr->second = std::make_shared<link::Connection>(conn_interface, control_stream, rc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -18,11 +18,7 @@ namespace llarp
|
||||
virtual std::string
|
||||
bt_encode() const = 0;
|
||||
virtual void
|
||||
bt_encode(llarp_buffer& b) const = 0;
|
||||
virtual void
|
||||
bt_encode(oxenc::bt_dict_producer& btdp) const = 0;
|
||||
virtual void
|
||||
bt_encode(oxenc::bt_list_producer& btlp) const = 0;
|
||||
};
|
||||
|
||||
struct AbstractMessageHandler
|
||||
|
72
llarp/messages/dht.hpp
Normal file
72
llarp/messages/dht.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <llarp/dht/key.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
#include <llarp/util/bencode.hpp>
|
||||
#include <llarp/path/path_types.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct DHTMessage : public AbstractSerializable
|
||||
{};
|
||||
|
||||
struct FindRouterMessage : public DHTMessage
|
||||
{
|
||||
private:
|
||||
RouterID target;
|
||||
bool is_iterative{false};
|
||||
bool is_exploratory{false};
|
||||
uint64_t tx_id{0};
|
||||
|
||||
public:
|
||||
explicit FindRouterMessage(const RouterID& rid, bool is_itr, bool is_exp, uint64_t tx)
|
||||
: target{rid}, is_iterative{is_itr}, is_exploratory{is_exp}, tx_id{tx}
|
||||
{}
|
||||
|
||||
std::string
|
||||
bt_encode() const override
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "R");
|
||||
btdp.append("E", is_exploratory ? 1 : 0);
|
||||
btdp.append("I", is_iterative ? 1 : 0);
|
||||
btdp.append("K", target.ToView());
|
||||
btdp.append("T", tx_id);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::error(link_cat, "Error: FindRouterMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
static std::string
|
||||
serialize(const RouterID& rid, bool is_itr, bool is_exp, uint64_t tx)
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "R");
|
||||
btdp.append("E", is_exp ? 1 : 0);
|
||||
btdp.append("I", is_itr ? 1 : 0);
|
||||
btdp.append("K", rid.ToView());
|
||||
btdp.append("T", tx);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::error(link_cat, "Error: FindRouterMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
};
|
||||
} // namespace llarp
|
@ -95,7 +95,8 @@ namespace llarp
|
||||
{
|
||||
if (!verify())
|
||||
return false;
|
||||
return conn->GotLIM(this);
|
||||
return true;
|
||||
// return conn->GotLIM(this);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -54,22 +54,11 @@ namespace llarp
|
||||
|
||||
// methods we do not want to inherit onwards from AbstractSerializable
|
||||
void
|
||||
bt_encode(llarp_buffer&) const final
|
||||
{
|
||||
throw std::runtime_error{"Error: Link messages should not encode directly to a buffer!"};
|
||||
}
|
||||
void
|
||||
bt_encode(oxenc::bt_dict_producer&) const final
|
||||
{
|
||||
throw std::runtime_error{
|
||||
"Error: Link messages should not encode directly to a bt list producer!"};
|
||||
}
|
||||
void
|
||||
bt_encode(oxenc::bt_list_producer&) const final
|
||||
{
|
||||
throw std::runtime_error{
|
||||
"Error: Link messages should not encode directly to a bt list producer!"};
|
||||
}
|
||||
};
|
||||
|
||||
struct AbstractDataMessage : public AbstractLinkMessage
|
||||
|
@ -193,16 +193,16 @@ namespace llarp
|
||||
// the actual hop
|
||||
std::shared_ptr<Hop> hop;
|
||||
|
||||
const std::optional<IpAddress> fromAddr;
|
||||
oxen::quic::Address from_addr;
|
||||
|
||||
LRCMFrameDecrypt(Context* ctx, Decrypter_ptr dec, const LR_CommitMessage* commit)
|
||||
: decrypter(std::move(dec))
|
||||
, frames(commit->frames)
|
||||
, context(ctx)
|
||||
, hop(std::make_shared<Hop>())
|
||||
, fromAddr(
|
||||
commit->conn->remote_rc.IsPublicRouter() ? std::optional<oxen::quic::Address>{}
|
||||
: commit->conn->remote_rc.addr)
|
||||
, from_addr{
|
||||
commit->conn->remote_rc.IsPublicRouter() ? oxen::quic::Address{}
|
||||
: commit->conn->remote_rc.addr}
|
||||
{
|
||||
hop->info.downstream = commit->conn->remote_rc.pubkey;
|
||||
}
|
||||
@ -268,14 +268,14 @@ namespace llarp
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->fromAddr)
|
||||
if (self->from_addr.is_addressable())
|
||||
{
|
||||
// only do ip limiting from non service nodes
|
||||
#ifndef LOKINET_HIVE
|
||||
if (self->context->CheckPathLimitHitByIP(*self->fromAddr))
|
||||
if (self->context->CheckPathLimitHitByIP(self->from_addr.to_string()))
|
||||
{
|
||||
// we hit a limit so tell it to slow tf down
|
||||
llarp::LogError("client path build hit limit ", *self->fromAddr);
|
||||
llarp::LogError("client path build hit limit ", self->from_addr);
|
||||
OnForwardLRCMResult(
|
||||
self->context->router(),
|
||||
self->hop,
|
||||
@ -413,7 +413,7 @@ namespace llarp
|
||||
return;
|
||||
}
|
||||
// generate hash of hop key for nonce mutation
|
||||
crypto->shorthash(self->hop->nonceXOR, llarp_buffer_t(self->hop->pathKey));
|
||||
crypto->shorthash(self->hop->nonceXOR, self->hop->pathKey.data(), self->hop->pathKey.size());
|
||||
if (self->record.work && self->record.work->IsValid(now))
|
||||
{
|
||||
llarp::LogDebug(
|
||||
|
@ -249,8 +249,10 @@ namespace llarp
|
||||
|
||||
// send the status message to previous hop
|
||||
// if it fails we are hitting a failure case we can't cope with so ... drop.
|
||||
if (not router->SendToOrQueue(nextHop, *msg, resultCallback))
|
||||
resultCallback(SendStatus::Congestion);
|
||||
|
||||
// TODO: replace with new message serialization
|
||||
// if (not router->SendToOrQueue(nextHop, *msg, resultCallback))
|
||||
// resultCallback(SendStatus::Congestion);
|
||||
|
||||
// trigger idempotent pump to make sure stuff gets sent
|
||||
router->TriggerPump();
|
||||
|
@ -78,11 +78,6 @@ namespace llarp
|
||||
fromString(addr, false);
|
||||
}
|
||||
|
||||
SockAddr::SockAddr(const AddressInfo& info) : SockAddr{info.ip}
|
||||
{
|
||||
setPort(huint16_t{info.port});
|
||||
}
|
||||
|
||||
SockAddr::SockAddr(const SockAddr& other)
|
||||
{
|
||||
*this = other;
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct AddressInfo;
|
||||
|
||||
/// A simple SockAddr wrapper which provides a sockaddr_in (IPv4). Memory management is handled
|
||||
/// in constructor and destructor (if needed) and copying is disabled.
|
||||
struct SockAddr
|
||||
@ -39,8 +37,6 @@ namespace llarp
|
||||
SockAddr(std::string_view addr);
|
||||
SockAddr(std::string_view addr, huint16_t port); // port is in native (host) order
|
||||
|
||||
SockAddr(const AddressInfo&);
|
||||
|
||||
SockAddr(const SockAddr&);
|
||||
SockAddr&
|
||||
operator=(const SockAddr&);
|
||||
|
@ -10,7 +10,7 @@ namespace llarp::path
|
||||
static constexpr auto DefaultPathBuildLimit = 500ms;
|
||||
|
||||
PathContext::PathContext(Router* router)
|
||||
: _router(router), m_AllowTransit(false), m_PathLimits(DefaultPathBuildLimit)
|
||||
: _router(router), m_AllowTransit(false), path_limits(DefaultPathBuildLimit)
|
||||
{}
|
||||
|
||||
void
|
||||
@ -36,7 +36,22 @@ namespace llarp::path
|
||||
remote.setPort(0);
|
||||
// try inserting remote address by ip into decaying hash set
|
||||
// if it cannot insert it has hit a limit
|
||||
return not m_PathLimits.Insert(remote);
|
||||
return not path_limits.Insert(remote);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PathContext::CheckPathLimitHitByIP(const std::string& ip)
|
||||
{
|
||||
#ifdef TESTNET
|
||||
return false;
|
||||
#else
|
||||
IpAddress remote{ip};
|
||||
// null out the port -- we don't care about it for path limiting purposes
|
||||
remote.setPort(0);
|
||||
// try inserting remote address by ip into decaying hash set
|
||||
// if it cannot insert it has hit a limit
|
||||
return not path_limits.Insert(remote);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -85,7 +100,9 @@ namespace llarp::path
|
||||
|
||||
LogDebug("forwarding LRCM to ", nextHop);
|
||||
|
||||
return _router->SendToOrQueue(nextHop, msg, handler);
|
||||
// TODO: replace with new message serialization for LRCM
|
||||
// return _router->SendToOrQueue(nextHop, msg, handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <
|
||||
@ -340,7 +357,7 @@ namespace llarp::path
|
||||
PathContext::ExpirePaths(llarp_time_t now)
|
||||
{
|
||||
// decay limits
|
||||
m_PathLimits.Decay(now);
|
||||
path_limits.Decay(now);
|
||||
|
||||
{
|
||||
SyncTransitMap_t::Lock_t lock(m_TransitPaths.first);
|
||||
@ -350,7 +367,8 @@ namespace llarp::path
|
||||
{
|
||||
if (itr->second->Expired(now))
|
||||
{
|
||||
_router->outboundMessageHandler().RemovePath(itr->first);
|
||||
// TODO: this
|
||||
// _router->outboundMessageHandler().RemovePath(itr->first);
|
||||
itr = map.erase(itr);
|
||||
}
|
||||
else
|
||||
|
@ -53,6 +53,9 @@ namespace llarp
|
||||
bool
|
||||
CheckPathLimitHitByIP(const IpAddress& ip);
|
||||
|
||||
bool
|
||||
CheckPathLimitHitByIP(const std::string& ip);
|
||||
|
||||
bool
|
||||
AllowingTransit() const;
|
||||
|
||||
@ -185,7 +188,7 @@ namespace llarp
|
||||
SyncTransitMap_t m_TransitPaths;
|
||||
SyncOwnedPathsMap_t m_OurPaths;
|
||||
bool m_AllowTransit;
|
||||
util::DecayingHashSet<IpAddress> m_PathLimits;
|
||||
util::DecayingHashSet<IpAddress> path_limits;
|
||||
};
|
||||
} // namespace path
|
||||
} // namespace llarp
|
||||
|
@ -57,7 +57,7 @@ namespace llarp
|
||||
return;
|
||||
}
|
||||
// generate nonceXOR valueself->hop->pathKey
|
||||
crypto->shorthash(hop.nonceXOR, llarp_buffer_t(hop.shared));
|
||||
crypto->shorthash(hop.nonceXOR, hop.shared.data(), hop.shared.size());
|
||||
++idx;
|
||||
|
||||
bool isFarthestHop = idx == path->hops.size();
|
||||
|
@ -7,149 +7,145 @@
|
||||
#include <atomic>
|
||||
#include <set>
|
||||
|
||||
namespace llarp
|
||||
namespace llarp::path
|
||||
{
|
||||
namespace path
|
||||
// milliseconds waiting between builds on a path per router
|
||||
static constexpr auto MIN_PATH_BUILD_INTERVAL = 500ms;
|
||||
static constexpr auto PATH_BUILD_RATE = 100ms;
|
||||
|
||||
/// limiter for path builds
|
||||
/// prevents overload and such
|
||||
class BuildLimiter
|
||||
{
|
||||
// milliseconds waiting between builds on a path per router
|
||||
static constexpr auto MIN_PATH_BUILD_INTERVAL = 500ms;
|
||||
static constexpr auto PATH_BUILD_RATE = 100ms;
|
||||
util::DecayingHashSet<RouterID> m_EdgeLimiter;
|
||||
|
||||
/// limiter for path builds
|
||||
/// prevents overload and such
|
||||
class BuildLimiter
|
||||
public:
|
||||
/// attempt a build
|
||||
/// return true if we are allowed to continue
|
||||
bool
|
||||
Attempt(const RouterID& router);
|
||||
|
||||
/// decay limit entries
|
||||
void
|
||||
Decay(llarp_time_t now);
|
||||
|
||||
/// return true if this router is currently limited
|
||||
bool
|
||||
Limited(const RouterID& router) const;
|
||||
};
|
||||
|
||||
struct Builder : public PathSet
|
||||
{
|
||||
private:
|
||||
llarp_time_t m_LastWarn = 0s;
|
||||
|
||||
protected:
|
||||
/// flag for PathSet::Stop()
|
||||
std::atomic<bool> _run;
|
||||
|
||||
virtual bool
|
||||
UrgentBuild(llarp_time_t now) const;
|
||||
|
||||
/// return true if we hit our soft limit for building paths too fast on a first hop
|
||||
bool
|
||||
BuildCooldownHit(RouterID edge) const;
|
||||
|
||||
private:
|
||||
void
|
||||
DoPathBuildBackoff();
|
||||
|
||||
public:
|
||||
Router* const m_router;
|
||||
SecretKey enckey;
|
||||
size_t numHops;
|
||||
llarp_time_t lastBuild = 0s;
|
||||
llarp_time_t buildIntervalLimit = MIN_PATH_BUILD_INTERVAL;
|
||||
|
||||
/// construct
|
||||
Builder(Router* p_router, size_t numDesiredPaths, size_t numHops);
|
||||
|
||||
virtual ~Builder() = default;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const;
|
||||
|
||||
bool
|
||||
ShouldBuildMore(llarp_time_t now) const override;
|
||||
|
||||
/// should we bundle RCs in builds?
|
||||
virtual bool
|
||||
ShouldBundleRC() const = 0;
|
||||
|
||||
void
|
||||
ResetInternalState() override;
|
||||
|
||||
/// return true if we hit our soft limit for building paths too fast
|
||||
bool
|
||||
BuildCooldownHit(llarp_time_t now) const;
|
||||
|
||||
/// get roles for this path builder
|
||||
virtual PathRole
|
||||
GetRoles() const
|
||||
{
|
||||
util::DecayingHashSet<RouterID> m_EdgeLimiter;
|
||||
return ePathRoleAny;
|
||||
}
|
||||
|
||||
public:
|
||||
/// attempt a build
|
||||
/// return true if we are allowed to continue
|
||||
bool
|
||||
Attempt(const RouterID& router);
|
||||
|
||||
/// decay limit entries
|
||||
void
|
||||
Decay(llarp_time_t now);
|
||||
|
||||
/// return true if this router is currently limited
|
||||
bool
|
||||
Limited(const RouterID& router) const;
|
||||
};
|
||||
|
||||
struct Builder : public PathSet
|
||||
BuildStats
|
||||
CurrentBuildStats() const
|
||||
{
|
||||
private:
|
||||
llarp_time_t m_LastWarn = 0s;
|
||||
return m_BuildStats;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// flag for PathSet::Stop()
|
||||
std::atomic<bool> _run;
|
||||
bool
|
||||
Stop() override;
|
||||
|
||||
virtual bool
|
||||
UrgentBuild(llarp_time_t now) const;
|
||||
bool
|
||||
IsStopped() const override;
|
||||
|
||||
/// return true if we hit our soft limit for building paths too fast on a first hop
|
||||
bool
|
||||
BuildCooldownHit(RouterID edge) const;
|
||||
bool
|
||||
ShouldRemove() const override;
|
||||
|
||||
private:
|
||||
void
|
||||
DoPathBuildBackoff();
|
||||
llarp_time_t
|
||||
Now() const override;
|
||||
|
||||
public:
|
||||
Router* const m_router;
|
||||
SecretKey enckey;
|
||||
size_t numHops;
|
||||
llarp_time_t lastBuild = 0s;
|
||||
llarp_time_t buildIntervalLimit = MIN_PATH_BUILD_INTERVAL;
|
||||
void
|
||||
Tick(llarp_time_t now) override;
|
||||
|
||||
/// construct
|
||||
Builder(Router* p_router, size_t numDesiredPaths, size_t numHops);
|
||||
void
|
||||
BuildOne(PathRole roles = ePathRoleAny) override;
|
||||
|
||||
virtual ~Builder() = default;
|
||||
bool
|
||||
BuildOneAlignedTo(const RouterID endpoint) override;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const;
|
||||
std::optional<std::vector<RouterContact>>
|
||||
GetHopsAlignedToForBuild(RouterID endpoint, const std::set<RouterID>& exclude = {});
|
||||
|
||||
bool
|
||||
ShouldBuildMore(llarp_time_t now) const override;
|
||||
void
|
||||
Build(std::vector<RouterContact> hops, PathRole roles = ePathRoleAny) override;
|
||||
|
||||
/// should we bundle RCs in builds?
|
||||
virtual bool
|
||||
ShouldBundleRC() const = 0;
|
||||
/// pick a first hop
|
||||
std::optional<RouterContact>
|
||||
SelectFirstHop(const std::set<RouterID>& exclude = {}) const;
|
||||
|
||||
void
|
||||
ResetInternalState() override;
|
||||
std::optional<std::vector<RouterContact>>
|
||||
GetHopsForBuild() override;
|
||||
|
||||
/// return true if we hit our soft limit for building paths too fast
|
||||
bool
|
||||
BuildCooldownHit(llarp_time_t now) const;
|
||||
void
|
||||
ManualRebuild(size_t N, PathRole roles = ePathRoleAny);
|
||||
|
||||
/// get roles for this path builder
|
||||
virtual PathRole
|
||||
GetRoles() const
|
||||
{
|
||||
return ePathRoleAny;
|
||||
}
|
||||
const SecretKey&
|
||||
GetTunnelEncryptionSecretKey() const;
|
||||
|
||||
BuildStats
|
||||
CurrentBuildStats() const
|
||||
{
|
||||
return m_BuildStats;
|
||||
}
|
||||
void
|
||||
HandlePathBuilt(Path_ptr p) override;
|
||||
|
||||
bool
|
||||
Stop() override;
|
||||
void
|
||||
HandlePathBuildTimeout(Path_ptr p) override;
|
||||
|
||||
bool
|
||||
IsStopped() const override;
|
||||
void
|
||||
HandlePathBuildFailedAt(Path_ptr p, RouterID hop) override;
|
||||
};
|
||||
|
||||
bool
|
||||
ShouldRemove() const override;
|
||||
using Builder_ptr = std::shared_ptr<Builder>;
|
||||
|
||||
llarp_time_t
|
||||
Now() const override;
|
||||
|
||||
virtual void
|
||||
Tick(llarp_time_t now) override;
|
||||
|
||||
void
|
||||
BuildOne(PathRole roles = ePathRoleAny) override;
|
||||
|
||||
bool
|
||||
BuildOneAlignedTo(const RouterID endpoint) override;
|
||||
|
||||
std::optional<std::vector<RouterContact>>
|
||||
GetHopsAlignedToForBuild(RouterID endpoint, const std::set<RouterID>& exclude = {});
|
||||
|
||||
void
|
||||
Build(std::vector<RouterContact> hops, PathRole roles = ePathRoleAny) override;
|
||||
|
||||
/// pick a first hop
|
||||
std::optional<RouterContact>
|
||||
SelectFirstHop(const std::set<RouterID>& exclude = {}) const;
|
||||
|
||||
virtual std::optional<std::vector<RouterContact>>
|
||||
GetHopsForBuild() override;
|
||||
|
||||
void
|
||||
ManualRebuild(size_t N, PathRole roles = ePathRoleAny);
|
||||
|
||||
virtual const SecretKey&
|
||||
GetTunnelEncryptionSecretKey() const;
|
||||
|
||||
virtual void
|
||||
HandlePathBuilt(Path_ptr p) override;
|
||||
|
||||
virtual void
|
||||
HandlePathBuildTimeout(Path_ptr p) override;
|
||||
|
||||
virtual void
|
||||
HandlePathBuildFailedAt(Path_ptr p, RouterID hop) override;
|
||||
};
|
||||
|
||||
using Builder_ptr = std::shared_ptr<Builder>;
|
||||
|
||||
} // namespace path
|
||||
|
||||
} // namespace llarp
|
||||
} // namespace llarp::path
|
||||
|
@ -92,7 +92,7 @@ namespace llarp::path
|
||||
}
|
||||
|
||||
void
|
||||
PathSet::ExpirePaths(llarp_time_t now, Router* router)
|
||||
PathSet::ExpirePaths(llarp_time_t now, [[maybe_unused]] Router* router)
|
||||
{
|
||||
Lock_t l(m_PathsMutex);
|
||||
if (m_Paths.size() == 0)
|
||||
@ -102,10 +102,11 @@ namespace llarp::path
|
||||
{
|
||||
if (itr->second->Expired(now))
|
||||
{
|
||||
// TODO: this
|
||||
PathID_t txid = itr->second->TXID();
|
||||
router->outboundMessageHandler().RemovePath(std::move(txid));
|
||||
// router->outboundMessageHandler().RemovePath(std::move(txid));
|
||||
PathID_t rxid = itr->second->RXID();
|
||||
router->outboundMessageHandler().RemovePath(std::move(rxid));
|
||||
// router->outboundMessageHandler().RemovePath(std::move(rxid));
|
||||
itr = m_Paths.erase(itr);
|
||||
}
|
||||
else
|
||||
|
@ -29,19 +29,11 @@ namespace llarp
|
||||
return false;
|
||||
|
||||
ShortHash digest;
|
||||
std::array<byte_t, MaxSize> tmp;
|
||||
llarp_buffer_t buf(tmp);
|
||||
auto buf = bt_encode();
|
||||
|
||||
auto bte = bt_encode();
|
||||
|
||||
if (auto b = buf.write(bte.begin(), bte.end()); not b)
|
||||
return false;
|
||||
|
||||
// rewind
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// hash
|
||||
if (!CryptoManager::instance()->shorthash(digest, buf))
|
||||
if (!CryptoManager::instance()->shorthash(
|
||||
digest, reinterpret_cast<uint8_t*>(buf.data()), buf.size()))
|
||||
return false;
|
||||
// check bytes required
|
||||
uint32_t required = std::floor(std::log(extendedLifetime.count()));
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <chrono>
|
||||
#include "rc_lookup_handler.hpp"
|
||||
|
||||
#include <llarp/link/contacts.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/service/context.hpp>
|
||||
@ -8,7 +9,6 @@
|
||||
#include <llarp/util/types.hpp>
|
||||
#include <llarp/util/thread/threading.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/dht/context.hpp>
|
||||
#include "router.hpp"
|
||||
|
||||
#include <iterator>
|
||||
@ -113,7 +113,7 @@ namespace llarp
|
||||
LogWarn("cannot lookup ", router, " anonymously");
|
||||
}
|
||||
|
||||
if (!dht->LookupRouter(router, fn))
|
||||
if (not contacts->lookup_router(router, fn))
|
||||
{
|
||||
finalize_request(router, nullptr, RCRequestResult::RouterNotFound);
|
||||
}
|
||||
@ -195,11 +195,11 @@ namespace llarp
|
||||
{
|
||||
if (not is_session_allowed(rc.pubkey))
|
||||
{
|
||||
dht->DelRCNodeAsync(dht::Key_t{rc.pubkey});
|
||||
contacts->delete_rc_node_async(dht::Key_t{rc.pubkey});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not rc.Verify(dht->Now()))
|
||||
if (not rc.Verify(llarp::time_now_ms()))
|
||||
{
|
||||
LogWarn("RC for ", RouterID(rc.pubkey), " is invalid");
|
||||
return false;
|
||||
@ -210,7 +210,7 @@ namespace llarp
|
||||
{
|
||||
LogDebug("Adding or updating RC for ", RouterID(rc.pubkey), " to nodedb and dht.");
|
||||
loop->call([rc, n = node_db] { n->PutIfNewer(rc); });
|
||||
dht->PutRCNodeAsync(rc);
|
||||
contacts->put_rc_node_async(rc);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -251,9 +251,9 @@ namespace llarp
|
||||
work_func(func);
|
||||
|
||||
// update dht if required
|
||||
if (dht->Nodes()->HasNode(dht::Key_t{newrc.pubkey}))
|
||||
if (contacts->rc_nodes()->HasNode(dht::Key_t{newrc.pubkey}))
|
||||
{
|
||||
dht->Nodes()->PutNode(newrc);
|
||||
contacts->rc_nodes()->PutNode(newrc);
|
||||
}
|
||||
|
||||
// TODO: check for other places that need updating the RC
|
||||
@ -295,7 +295,8 @@ namespace llarp
|
||||
for (const auto& rc : bootstrap_rc_list)
|
||||
{
|
||||
LogInfo("Doing explore via bootstrap node: ", RouterID(rc.pubkey));
|
||||
dht->ExploreNetworkVia(dht::Key_t{rc.pubkey});
|
||||
// TODO: replace this concept
|
||||
// dht->ExploreNetworkVia(dht::Key_t{rc.pubkey});
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,7 +333,7 @@ namespace llarp
|
||||
return;
|
||||
}
|
||||
// service nodes gossip, not explore
|
||||
if (dht->GetRouter()->IsServiceNode())
|
||||
if (contacts->router()->IsServiceNode())
|
||||
return;
|
||||
|
||||
// explore via every connected peer
|
||||
@ -356,7 +357,7 @@ namespace llarp
|
||||
|
||||
void
|
||||
RCLookupHandler::init(
|
||||
std::shared_ptr<dht::AbstractDHTMessageHandler> d,
|
||||
std::shared_ptr<Contacts> c,
|
||||
std::shared_ptr<NodeDB> nodedb,
|
||||
EventLoop_ptr l,
|
||||
worker_func dowork,
|
||||
@ -367,7 +368,7 @@ namespace llarp
|
||||
bool useWhitelist_arg,
|
||||
bool isServiceNode_arg)
|
||||
{
|
||||
dht = d;
|
||||
contacts = c;
|
||||
node_db = std::move(nodedb);
|
||||
loop = std::move(l);
|
||||
work_func = std::move(dowork);
|
||||
|
@ -24,9 +24,9 @@ namespace llarp
|
||||
namespace service
|
||||
{
|
||||
struct Context;
|
||||
|
||||
} // namespace service
|
||||
|
||||
struct Contacts;
|
||||
struct LinkManager;
|
||||
struct RouterContact;
|
||||
|
||||
@ -109,7 +109,7 @@ namespace llarp
|
||||
|
||||
void
|
||||
init(
|
||||
std::shared_ptr<dht::AbstractDHTMessageHandler> dht,
|
||||
std::shared_ptr<Contacts> contacts,
|
||||
std::shared_ptr<NodeDB> nodedb,
|
||||
std::shared_ptr<EventLoop> loop,
|
||||
worker_func dowork,
|
||||
@ -143,7 +143,7 @@ namespace llarp
|
||||
|
||||
mutable util::Mutex _mutex; // protects pendingCallbacks, whitelistRouters
|
||||
|
||||
std::shared_ptr<dht::AbstractDHTMessageHandler> dht = nullptr;
|
||||
std::shared_ptr<Contacts> contacts = nullptr;
|
||||
std::shared_ptr<NodeDB> node_db;
|
||||
std::shared_ptr<EventLoop> loop;
|
||||
worker_func work_func = nullptr;
|
||||
|
@ -5,10 +5,9 @@
|
||||
#include <llarp/constants/proto.hpp>
|
||||
#include <llarp/constants/files.hpp>
|
||||
#include <llarp/constants/time.hpp>
|
||||
#include <llarp/crypto/crypto_libsodium.hpp>
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/dht/context.hpp>
|
||||
#include <llarp/dht/node.hpp>
|
||||
#include <llarp/link/contacts.hpp>
|
||||
#include <llarp/messages/link_message.hpp>
|
||||
#include <llarp/net/net.hpp>
|
||||
#include <stdexcept>
|
||||
@ -46,16 +45,16 @@ 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)}
|
||||
: _route_poker{std::make_shared<RoutePoker>(*this)}
|
||||
, _lmq{std::make_shared<oxenmq::OxenMQ>()}
|
||||
, _loop{std::move(loop)}
|
||||
, _vpn{std::move(vpnPlatform)}
|
||||
, paths{this}
|
||||
, _exit_context{this}
|
||||
, _dht{dht::make_handler()}
|
||||
, _disk_thread{_lmq->add_tagged_thread("disk")}
|
||||
, _rpc_server{nullptr}
|
||||
, _randomStartDelay{platform::is_simulation ? std::chrono::milliseconds{(llarp::randint() % 1250) + 2000} : 0s}
|
||||
, _link_manager{*this}
|
||||
, _hidden_service_context{this}
|
||||
{
|
||||
_key_manager = std::make_shared<KeyManager>();
|
||||
@ -70,7 +69,7 @@ namespace llarp
|
||||
|
||||
Router::~Router()
|
||||
{
|
||||
_dht.reset();
|
||||
_contacts.reset();
|
||||
}
|
||||
|
||||
// TODO: investigate changes needed for libquic integration
|
||||
@ -97,7 +96,7 @@ namespace llarp
|
||||
return util::StatusObject{
|
||||
{"running", true},
|
||||
{"numNodesKnown", _node_db->NumLoaded()},
|
||||
{"dht", _dht->ExtractStatus()},
|
||||
{"contacts", _contacts->extract_status()},
|
||||
{"services", _hidden_service_context.ExtractStatus()},
|
||||
{"exit", _exit_context.ExtractStatus()},
|
||||
{"links", _link_manager.extract_status()},
|
||||
@ -238,9 +237,6 @@ namespace llarp
|
||||
void
|
||||
Router::GossipRCIfNeeded(const RouterContact rc)
|
||||
{
|
||||
if (disableGossipingRC_TestingOnly())
|
||||
return;
|
||||
|
||||
/// if we are not a service node forget about gossip
|
||||
if (not IsServiceNode())
|
||||
return;
|
||||
@ -272,23 +268,21 @@ namespace llarp
|
||||
loop_wakeup->Trigger();
|
||||
}
|
||||
|
||||
bool
|
||||
Router::SendToOrQueue(
|
||||
const RouterID& remote, const AbstractLinkMessage& msg, SendStatusHandler handler)
|
||||
{
|
||||
return _outboundMessageHandler.QueueMessage(remote, msg, handler);
|
||||
}
|
||||
|
||||
bool
|
||||
Router::send_data_message(const RouterID& remote, const AbstractDataMessage& msg)
|
||||
{
|
||||
return _link_manager.send_or_queue_data(remote, msg.bt_encode());
|
||||
return _link_manager.send_data_message(remote, msg.bt_encode());
|
||||
}
|
||||
|
||||
bool
|
||||
Router::send_control_message(const RouterID& remote, const AbstractLinkMessage& msg)
|
||||
Router::send_control_message(
|
||||
const RouterID& remote,
|
||||
std::string ep,
|
||||
std::string body,
|
||||
std::function<void(oxen::quic::message m)> func)
|
||||
{
|
||||
return _link_manager.send_or_queue_data(remote, msg.bt_encode());
|
||||
return _link_manager.send_control_message(
|
||||
remote, std::move(ep), std::move(body), std::move(func));
|
||||
}
|
||||
|
||||
void
|
||||
@ -754,10 +748,9 @@ namespace llarp
|
||||
LogInfo("Loaded ", bootstrap_rc_list.size(), " bootstrap routers");
|
||||
|
||||
// Init components after relevant config settings loaded
|
||||
_outboundMessageHandler.Init(this);
|
||||
_link_manager.init(&_rc_lookup_handler);
|
||||
_rc_lookup_handler.init(
|
||||
_dht,
|
||||
_contacts,
|
||||
_node_db,
|
||||
_loop,
|
||||
util::memFn(&Router::queue_work, this),
|
||||
@ -832,7 +825,7 @@ namespace llarp
|
||||
void
|
||||
Router::report_stats()
|
||||
{
|
||||
const auto now = now();
|
||||
const auto now = llarp::time_now_ms();
|
||||
LogInfo(node_db()->NumLoaded(), " RCs loaded");
|
||||
LogInfo(bootstrap_rc_list.size(), " bootstrap peers");
|
||||
LogInfo(NumberOfConnectedRouters(), " router connections");
|
||||
@ -905,7 +898,7 @@ namespace llarp
|
||||
if (is_stopping)
|
||||
return;
|
||||
// LogDebug("tick router");
|
||||
const auto now = now();
|
||||
const auto now = llarp::time_now_ms();
|
||||
if (const auto delta = now - _last_tick; _last_tick != 0s and delta > TimeskipDetectedDuration)
|
||||
{
|
||||
// we detected a time skip into the futre, thaw the network
|
||||
@ -1111,7 +1104,7 @@ namespace llarp
|
||||
for_each_connection(
|
||||
[&peer_keys](link::Connection& conn) { peer_keys.emplace(conn.remote_rc.pubkey); });
|
||||
|
||||
dht()->Nodes()->RemoveIf(
|
||||
_contacts->rc_nodes()->RemoveIf(
|
||||
[&peer_keys](const dht::Key_t& k) -> bool { return peer_keys.count(k) == 0; });
|
||||
|
||||
paths.ExpirePaths(now);
|
||||
@ -1120,12 +1113,6 @@ namespace llarp
|
||||
_last_tick = llarp::time_now_ms();
|
||||
}
|
||||
|
||||
bool
|
||||
Router::Sign(Signature& sig, const llarp_buffer_t& buf) const
|
||||
{
|
||||
return CryptoManager::instance()->sign(sig, identity(), buf);
|
||||
}
|
||||
|
||||
void
|
||||
Router::modify_rc(std::function<std::optional<RouterContact>(RouterContact)> modify)
|
||||
{
|
||||
@ -1271,12 +1258,12 @@ namespace llarp
|
||||
_node_db->LoadFromDisk();
|
||||
}
|
||||
|
||||
_dht->Init(llarp::dht::Key_t(pubkey()), this);
|
||||
_contacts = std::make_shared<Contacts>(llarp::dht::Key_t(pubkey()), *this);
|
||||
|
||||
for (const auto& rc : bootstrap_rc_list)
|
||||
{
|
||||
node_db()->Put(rc);
|
||||
_dht->Nodes()->PutNode(rc);
|
||||
_contacts->rc_nodes()->PutNode(rc);
|
||||
LogInfo("added bootstrap node ", RouterID{rc.pubkey});
|
||||
}
|
||||
|
||||
@ -1494,7 +1481,7 @@ namespace llarp
|
||||
{
|
||||
LogInfo("accepting transit traffic");
|
||||
paths.AllowTransit();
|
||||
_dht->AllowTransit() = true;
|
||||
_contacts->set_transit_allowed(true);
|
||||
_exit_context.AddExitEndpoint("default", _config->network, _config->dns);
|
||||
return true;
|
||||
}
|
||||
@ -1549,63 +1536,63 @@ namespace llarp
|
||||
void
|
||||
Router::InitInboundLinks()
|
||||
{
|
||||
auto addrs = _config->links.InboundListenAddrs;
|
||||
if (is_service_node and addrs.empty())
|
||||
{
|
||||
LogInfo("Inferring Public Address");
|
||||
// auto addrs = _config->links.InboundListenAddrs;
|
||||
// if (is_service_node and addrs.empty())
|
||||
// {
|
||||
// LogInfo("Inferring Public Address");
|
||||
|
||||
auto maybe_port = _config->links.PublicPort;
|
||||
if (_config->router.PublicPort and not maybe_port)
|
||||
maybe_port = _config->router.PublicPort;
|
||||
if (not maybe_port)
|
||||
maybe_port = net::port_t::from_host(constants::DefaultInboundIWPPort);
|
||||
// auto maybe_port = _config->links.PublicPort;
|
||||
// if (_config->router.PublicPort and not maybe_port)
|
||||
// maybe_port = _config->router.PublicPort;
|
||||
// if (not maybe_port)
|
||||
// maybe_port = net::port_t::from_host(constants::DefaultInboundIWPPort);
|
||||
|
||||
if (auto maybe_addr = net().MaybeInferPublicAddr(*maybe_port))
|
||||
{
|
||||
LogInfo("Public Address looks to be ", *maybe_addr);
|
||||
addrs.emplace_back(std::move(*maybe_addr));
|
||||
}
|
||||
}
|
||||
if (is_service_node and addrs.empty())
|
||||
throw std::runtime_error{"we are a service node and we have no inbound links configured"};
|
||||
// if (auto maybe_addr = net().MaybeInferPublicAddr(*maybe_port))
|
||||
// {
|
||||
// LogInfo("Public Address looks to be ", *maybe_addr);
|
||||
// addrs.emplace_back(std::move(*maybe_addr));
|
||||
// }
|
||||
// }
|
||||
// if (is_service_node and addrs.empty())
|
||||
// throw std::runtime_error{"we are a service node and we have no inbound links configured"};
|
||||
|
||||
// create inbound links, if we are a service node
|
||||
for (auto bind_addr : addrs)
|
||||
{
|
||||
if (bind_addr.getPort() == 0)
|
||||
throw std::invalid_argument{"inbound link cannot use port 0"};
|
||||
// // create inbound links, if we are a service node
|
||||
// for (auto bind_addr : addrs)
|
||||
// {
|
||||
// if (bind_addr.getPort() == 0)
|
||||
// throw std::invalid_argument{"inbound link cannot use port 0"};
|
||||
|
||||
if (net().IsWildcardAddress(bind_addr.getIP()))
|
||||
{
|
||||
if (auto maybe_ip = public_ip())
|
||||
bind_addr.setIP(*maybe_ip);
|
||||
else
|
||||
throw std::runtime_error{"no public ip provided for inbound socket"};
|
||||
}
|
||||
// if (net().IsWildcardAddress(bind_addr.getIP()))
|
||||
// {
|
||||
// if (auto maybe_ip = public_ip())
|
||||
// bind_addr.setIP(public_ip().host());
|
||||
// else
|
||||
// throw std::runtime_error{"no public ip provided for inbound socket"};
|
||||
// }
|
||||
|
||||
AddressInfo ai;
|
||||
ai.fromSockAddr(bind_addr);
|
||||
// AddressInfo ai;
|
||||
// ai.fromSockAddr(bind_addr);
|
||||
|
||||
_link_manager.connect_to({ai.IPString(), ai.port}, true);
|
||||
// _link_manager.connect_to({ai.IPString(), ai.port}, true);
|
||||
|
||||
ai.pubkey = llarp::seckey_topublic(_identity);
|
||||
ai.dialect = "quicinet"; // FIXME: constant, also better name?
|
||||
ai.rank = 2; // FIXME: hardcoded from the beginning...keep?
|
||||
AddAddressToRC(ai);
|
||||
}
|
||||
// ai.pubkey = llarp::seckey_topublic(_identity);
|
||||
// ai.dialect = "quicinet"; // FIXME: constant, also better name?
|
||||
// ai.rank = 2; // FIXME: hardcoded from the beginning...keep?
|
||||
// AddAddressToRC(ai);
|
||||
// }
|
||||
}
|
||||
|
||||
void
|
||||
Router::InitOutboundLinks()
|
||||
{
|
||||
auto addrs = config()->links.OutboundLinks;
|
||||
if (addrs.empty())
|
||||
addrs.emplace_back(net().Wildcard());
|
||||
// auto addrs = config()->links.OutboundLinks;
|
||||
// if (addrs.empty())
|
||||
// addrs.emplace_back(net().Wildcard());
|
||||
|
||||
for (auto& bind_addr : addrs)
|
||||
{
|
||||
_link_manager.connect_to({bind_addr.ToString()}, false);
|
||||
}
|
||||
// for (auto& bind_addr : addrs)
|
||||
// {
|
||||
// _link_manager.connect_to({bind_addr.ToString()}, false);
|
||||
// }
|
||||
}
|
||||
|
||||
const llarp::net::Platform&
|
||||
|
@ -64,6 +64,10 @@ namespace llarp
|
||||
static constexpr size_t INTROSET_STORAGE_REDUNDANCY =
|
||||
(INTROSET_RELAY_REDUNDANCY * INTROSET_REQS_PER_RELAY);
|
||||
|
||||
static constexpr size_t RC_LOOKUP_STORAGE_REDUNDANCY{4};
|
||||
|
||||
struct Contacts;
|
||||
|
||||
class RouteManager final /* : public Router */
|
||||
{
|
||||
public:
|
||||
@ -118,7 +122,8 @@ namespace llarp
|
||||
exit::Context _exit_context;
|
||||
SecretKey _identity;
|
||||
SecretKey _encryption;
|
||||
std::shared_ptr<dht::AbstractDHTMessageHandler> _dht;
|
||||
std::shared_ptr<dht::AbstractDHTMessageHandler> _dh_t;
|
||||
std::shared_ptr<Contacts> _contacts;
|
||||
std::shared_ptr<NodeDB> _node_db;
|
||||
llarp_time_t _started_at;
|
||||
const oxenmq::TaggedThreadID _disk_thread;
|
||||
@ -140,7 +145,6 @@ namespace llarp
|
||||
oxenmq::address rpc_addr;
|
||||
Profiling _router_profiling;
|
||||
fs::path _profile_file;
|
||||
OutboundMessageHandler _outboundMessageHandler;
|
||||
LinkManager _link_manager{*this};
|
||||
RCLookupHandler _rc_lookup_handler;
|
||||
RCGossiper _rcGossiper;
|
||||
@ -178,16 +182,16 @@ namespace llarp
|
||||
void
|
||||
handle_router_event(std::unique_ptr<tooling::RouterEvent> event) const;
|
||||
|
||||
virtual bool
|
||||
disableGossipingRC_TestingOnly()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
public:
|
||||
void
|
||||
for_each_connection(std::function<void(link::Connection&)> func);
|
||||
|
||||
Contacts*
|
||||
contacts() const
|
||||
{
|
||||
return _contacts.get();
|
||||
}
|
||||
|
||||
std::shared_ptr<Config>
|
||||
config() const
|
||||
{
|
||||
@ -215,22 +219,6 @@ namespace llarp
|
||||
return _rpc_client;
|
||||
}
|
||||
|
||||
std::shared_ptr<dht::AbstractDHTMessageHandler>
|
||||
dht() const
|
||||
{
|
||||
return _dht;
|
||||
}
|
||||
|
||||
/** TOFIX: this
|
||||
- refactor path types (path_context, pathset) to use unified ID type, not PathID_t
|
||||
- refactor all callers to use new implementation of remove_path
|
||||
*/
|
||||
OutboundMessageHandler&
|
||||
outboundMessageHandler()
|
||||
{
|
||||
return _outboundMessageHandler;
|
||||
}
|
||||
|
||||
LinkManager&
|
||||
link_manager()
|
||||
{
|
||||
@ -376,9 +364,6 @@ namespace llarp
|
||||
llarp_time_t
|
||||
Uptime() const;
|
||||
|
||||
bool
|
||||
Sign(Signature& sig, const llarp_buffer_t& buf) const;
|
||||
|
||||
service::Context&
|
||||
hidden_service_context()
|
||||
{
|
||||
@ -530,7 +515,11 @@ namespace llarp
|
||||
send_data_message(const RouterID& remote, const AbstractDataMessage& msg);
|
||||
|
||||
bool
|
||||
send_control_message(const RouterID& remote, const AbstractLinkMessage& msg);
|
||||
send_control_message(
|
||||
const RouterID& remote,
|
||||
std::string endpoint,
|
||||
std::string body,
|
||||
std::function<void(oxen::quic::message m)> func = nullptr);
|
||||
|
||||
bool IsBootstrapNode(RouterID) const;
|
||||
|
||||
|
@ -136,95 +136,33 @@ namespace llarp
|
||||
return netID == NetID::DefaultValue();
|
||||
}
|
||||
|
||||
bool
|
||||
RouterContact::BEncodeSignedSection(llarp_buffer_t* buf) const
|
||||
std::string
|
||||
RouterContact::bencode_signed_section() const
|
||||
{
|
||||
/* write dict begin */
|
||||
if (!bencode_start_dict(buf))
|
||||
return false;
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
/* write ai if they exist */
|
||||
if (!bencode_write_bytestring(buf, "a", 1))
|
||||
return false;
|
||||
if (!BEncodeWriteList(addrs.begin(), addrs.end(), buf))
|
||||
return false;
|
||||
btdp.append("a", addr.to_string());
|
||||
btdp.append("i", netID.ToView());
|
||||
btdp.append("k", pubkey.bt_encode());
|
||||
|
||||
/* write netid */
|
||||
if (!bencode_write_bytestring(buf, "i", 1))
|
||||
return false;
|
||||
if (!netID.BEncode(buf))
|
||||
return false;
|
||||
/* write signing pubkey */
|
||||
if (!bencode_write_bytestring(buf, "k", 1))
|
||||
return false;
|
||||
if (!pubkey.bt_encode(buf))
|
||||
return false;
|
||||
auto n = Nick();
|
||||
if (not n.empty())
|
||||
btdp.append("n", n);
|
||||
|
||||
std::string nick = Nick();
|
||||
if (!nick.empty())
|
||||
btdp.append("p", enckey.ToView());
|
||||
btdp.append("r", routerVersion);
|
||||
|
||||
if (not srvRecords.empty())
|
||||
{
|
||||
/* write nickname */
|
||||
if (!bencode_write_bytestring(buf, "n", 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!bencode_write_bytestring(buf, nick.c_str(), nick.size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto sublist = btdp.append_list("s");
|
||||
|
||||
for (auto& s : srvRecords)
|
||||
sublist.append(s.bt_encode());
|
||||
}
|
||||
|
||||
/* write encryption pubkey */
|
||||
if (!bencode_write_bytestring(buf, "p", 1))
|
||||
return false;
|
||||
if (!enckey.bt_encode(buf))
|
||||
return false;
|
||||
btdp.append("u", last_updated.count());
|
||||
|
||||
// write router version if present
|
||||
if (routerVersion)
|
||||
{
|
||||
if (not BEncodeWriteDictEntry("r", *routerVersion, buf))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version > 0)
|
||||
{
|
||||
// srv records if present
|
||||
if (not BEncodeWriteDictList("s", srvRecords, buf))
|
||||
return false;
|
||||
}
|
||||
/* write last updated */
|
||||
if (!bencode_write_bytestring(buf, "u", 1))
|
||||
return false;
|
||||
if (!bencode_write_uint64(buf, last_updated.count()))
|
||||
return false;
|
||||
|
||||
/* write versions */
|
||||
if (!bencode_write_uint64_entry(buf, "v", 1, version))
|
||||
return false;
|
||||
|
||||
// D We can delete this?
|
||||
if (serializeExit)
|
||||
{
|
||||
/* write xi if they exist */
|
||||
if (!bencode_write_bytestring(buf, "x", 1))
|
||||
return false;
|
||||
/* no exits anymore in RCs */
|
||||
const std::vector<AlignedBuffer<8>> exits{};
|
||||
if (!BEncodeWriteList(exits.begin(), exits.end(), buf))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
/* write signature */
|
||||
if (!bencode_write_bytestring(buf, "z", 1))
|
||||
return false;
|
||||
if (!signature.bt_encode(buf))
|
||||
return false;
|
||||
}
|
||||
|
||||
return bencode_end(buf);
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
void
|
||||
@ -458,26 +396,16 @@ namespace llarp
|
||||
RouterContact::Sign(const SecretKey& secretkey)
|
||||
{
|
||||
pubkey = llarp::seckey_topublic(secretkey);
|
||||
std::array<byte_t, MAX_RC_SIZE> tmp;
|
||||
llarp_buffer_t buf(tmp);
|
||||
signature.Zero();
|
||||
last_updated = time_now_ms();
|
||||
|
||||
if (!BEncodeSignedSection(&buf))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
signed_bt_dict = bencode_signed_section();
|
||||
|
||||
signed_bt_dict = std::string(reinterpret_cast<char*>(buf.base), buf.sz);
|
||||
|
||||
if (version == 0 or version == 1)
|
||||
{
|
||||
return CryptoManager::instance()->sign(signature, secretkey, buf);
|
||||
}
|
||||
|
||||
return false;
|
||||
return CryptoManager::instance()->sign(
|
||||
signature,
|
||||
secretkey,
|
||||
reinterpret_cast<uint8_t*>(signed_bt_dict.data()),
|
||||
signed_bt_dict.size());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -116,8 +116,8 @@ namespace llarp
|
||||
void
|
||||
bt_encode_subdict(oxenc::bt_list_producer& btlp) const;
|
||||
|
||||
bool
|
||||
BEncodeSignedSection(llarp_buffer_t* buf) const;
|
||||
std::string
|
||||
bencode_signed_section() const;
|
||||
|
||||
std::string
|
||||
ToTXTRecord() const;
|
||||
|
@ -42,17 +42,6 @@ namespace llarp
|
||||
|
||||
// methods we do not want to inherit onwards from AbstractSerializable
|
||||
void
|
||||
bt_encode(oxenc::bt_list_producer&) const final
|
||||
{
|
||||
throw std::runtime_error{
|
||||
"Error: Routing messages should not encode directly to a bt list producer!"};
|
||||
}
|
||||
void
|
||||
bt_encode(llarp_buffer&) const final
|
||||
{
|
||||
throw std::runtime_error{"Error: Routing messages should not encode directly to a buffer!"};
|
||||
}
|
||||
void
|
||||
bt_encode(oxenc::bt_dict_producer&) const final
|
||||
{
|
||||
throw std::runtime_error{
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "endpoint.hpp"
|
||||
#include "endpoint_state.hpp"
|
||||
#include "endpoint_util.hpp"
|
||||
#include "hidden_service_address_lookup.hpp"
|
||||
#include "auth.hpp"
|
||||
#include "llarp/util/logging.hpp"
|
||||
#include "outbound_context.hpp"
|
||||
@ -11,7 +10,6 @@
|
||||
|
||||
#include <llarp/net/ip.hpp>
|
||||
#include <llarp/net/ip_range.hpp>
|
||||
#include <llarp/dht/context.hpp>
|
||||
#include <llarp/dht/key.hpp>
|
||||
#include <llarp/dht/messages/findintro.hpp>
|
||||
#include <llarp/dht/messages/findname.hpp>
|
||||
@ -408,7 +406,7 @@ namespace llarp
|
||||
std::set<EncryptedIntroSet> remote;
|
||||
for (const auto& introset : msg->found)
|
||||
{
|
||||
if (not introset.Verify(Now()))
|
||||
if (not introset.verify(Now()))
|
||||
{
|
||||
LogError(Name(), " got invalid introset");
|
||||
return false;
|
||||
@ -425,7 +423,7 @@ namespace llarp
|
||||
}
|
||||
std::unique_ptr<IServiceLookup> lookup = std::move(itr->second);
|
||||
lookups.erase(itr);
|
||||
lookup->HandleIntrosetResponse(remote);
|
||||
// lookup->HandleIntrosetResponse(remote);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -716,43 +714,31 @@ namespace llarp
|
||||
auto* r = router();
|
||||
|
||||
const auto paths = GetManyPathsWithUniqueEndpoints(
|
||||
this,
|
||||
llarp::dht::INTROSET_RELAY_REDUNDANCY,
|
||||
dht::Key_t{introset.derivedSigningKey.as_array()});
|
||||
this, INTROSET_RELAY_REDUNDANCY, dht::Key_t{introset.derivedSigningKey.as_array()});
|
||||
|
||||
if (paths.size() != llarp::dht::INTROSET_RELAY_REDUNDANCY)
|
||||
if (paths.size() != INTROSET_RELAY_REDUNDANCY)
|
||||
{
|
||||
LogWarn(
|
||||
"Cannot publish intro set because we only have ",
|
||||
paths.size(),
|
||||
" paths, but need ",
|
||||
llarp::dht::INTROSET_RELAY_REDUNDANCY);
|
||||
INTROSET_RELAY_REDUNDANCY);
|
||||
return false;
|
||||
}
|
||||
|
||||
// do publishing for each path selected
|
||||
size_t published = 0;
|
||||
|
||||
for (const auto& path : paths)
|
||||
{
|
||||
for (size_t i = 0; i < llarp::dht::INTROSET_REQS_PER_RELAY; ++i)
|
||||
for (size_t i = 0; i < INTROSET_REQS_PER_RELAY; ++i)
|
||||
{
|
||||
r->notify_router_event<tooling::PubIntroSentEvent>(
|
||||
r->pubkey(),
|
||||
llarp::dht::Key_t{introset.derivedSigningKey.as_array()},
|
||||
RouterID(path->hops[path->hops.size() - 1].rc.pubkey),
|
||||
published);
|
||||
if (PublishIntroSetVia(introset, r, path, published))
|
||||
published++;
|
||||
RouterID(path->hops[path->hops.size() - 1].rc.pubkey));
|
||||
|
||||
m_router->send_control_message(path->Upstream(), "publish_intro", introset.bt_encode());
|
||||
}
|
||||
}
|
||||
if (published != llarp::dht::INTROSET_STORAGE_REDUNDANCY)
|
||||
LogWarn(
|
||||
"Publish introset failed: could only publish ",
|
||||
published,
|
||||
" copies but wanted ",
|
||||
llarp::dht::INTROSET_STORAGE_REDUNDANCY);
|
||||
return published == llarp::dht::INTROSET_STORAGE_REDUNDANCY;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct PublishIntroSetJob : public IServiceLookup
|
||||
|
@ -6,6 +6,19 @@
|
||||
|
||||
namespace llarp::service
|
||||
{
|
||||
EncryptedIntroSet::EncryptedIntroSet(
|
||||
std::string signing_key,
|
||||
std::chrono::milliseconds signed_at,
|
||||
std::string enc_payload,
|
||||
std::string nonce,
|
||||
std::string s)
|
||||
: signedAt{signed_at}, nounce{reinterpret_cast<uint8_t*>(nonce.data())}
|
||||
{
|
||||
derivedSigningKey = PubKey::from_string(signing_key);
|
||||
introsetPayload = oxenc::bt_deserialize<std::vector<uint8_t>>(enc_payload);
|
||||
sig.from_string(std::move(s));
|
||||
}
|
||||
|
||||
util::StatusObject
|
||||
EncryptedIntroSet::ExtractStatus() const
|
||||
{
|
||||
@ -132,6 +145,12 @@ namespace llarp::service
|
||||
derivedSigningKey, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), sig);
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedIntroSet::verify(uint8_t* introset, size_t introset_size, uint8_t* key, uint8_t* sig)
|
||||
{
|
||||
return CryptoManager::instance()->verify(key, introset, introset_size, sig);
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedIntroSet::verify(std::string introset, std::string key, std::string sig)
|
||||
{
|
||||
|
@ -139,6 +139,15 @@ namespace llarp::service
|
||||
std::optional<Tag> topic;
|
||||
Signature sig;
|
||||
|
||||
EncryptedIntroSet() = default;
|
||||
|
||||
explicit EncryptedIntroSet(
|
||||
std::string signing_key,
|
||||
std::chrono::milliseconds signed_at,
|
||||
std::string enc_payload,
|
||||
std::string nonce,
|
||||
std::string sig);
|
||||
|
||||
bool
|
||||
Sign(const PrivateKey& k);
|
||||
|
||||
@ -164,6 +173,9 @@ namespace llarp::service
|
||||
bool
|
||||
verify(llarp_time_t now) const;
|
||||
|
||||
static bool
|
||||
verify(uint8_t* introset, size_t introset_size, uint8_t* key, uint8_t* sig);
|
||||
|
||||
static bool
|
||||
verify(std::string introset, std::string key, std::string sig);
|
||||
|
||||
|
@ -56,13 +56,13 @@ namespace llarp
|
||||
|
||||
explicit AlignedBuffer(const std::array<byte_t, SIZE>& buf)
|
||||
{
|
||||
m_data = buf;
|
||||
_data = buf;
|
||||
}
|
||||
|
||||
AlignedBuffer&
|
||||
operator=(const byte_t* data)
|
||||
{
|
||||
std::memcpy(m_data.data(), data, sz);
|
||||
std::memcpy(_data.data(), data, sz);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -79,37 +79,37 @@ namespace llarp
|
||||
bool
|
||||
operator==(const AlignedBuffer& other) const
|
||||
{
|
||||
return m_data == other.m_data;
|
||||
return _data == other._data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const AlignedBuffer& other) const
|
||||
{
|
||||
return m_data != other.m_data;
|
||||
return _data != other._data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const AlignedBuffer& other) const
|
||||
{
|
||||
return m_data < other.m_data;
|
||||
return _data < other._data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator>(const AlignedBuffer& other) const
|
||||
{
|
||||
return m_data > other.m_data;
|
||||
return _data > other._data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<=(const AlignedBuffer& other) const
|
||||
{
|
||||
return m_data <= other.m_data;
|
||||
return _data <= other._data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator>=(const AlignedBuffer& other) const
|
||||
{
|
||||
return m_data >= other.m_data;
|
||||
return _data >= other._data;
|
||||
}
|
||||
|
||||
AlignedBuffer
|
||||
@ -126,7 +126,7 @@ namespace llarp
|
||||
// Mutate in place instead.
|
||||
for (size_t i = 0; i < sz; ++i)
|
||||
{
|
||||
m_data[i] ^= other.m_data[i];
|
||||
_data[i] ^= other._data[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -135,14 +135,14 @@ namespace llarp
|
||||
operator[](size_t idx)
|
||||
{
|
||||
assert(idx < SIZE);
|
||||
return m_data[idx];
|
||||
return _data[idx];
|
||||
}
|
||||
|
||||
const byte_t&
|
||||
operator[](size_t idx) const
|
||||
{
|
||||
assert(idx < SIZE);
|
||||
return m_data[idx];
|
||||
return _data[idx];
|
||||
}
|
||||
|
||||
static constexpr size_t
|
||||
@ -154,31 +154,31 @@ namespace llarp
|
||||
void
|
||||
Fill(byte_t f)
|
||||
{
|
||||
m_data.fill(f);
|
||||
_data.fill(f);
|
||||
}
|
||||
|
||||
std::array<byte_t, SIZE>&
|
||||
as_array()
|
||||
{
|
||||
return m_data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
const std::array<byte_t, SIZE>&
|
||||
as_array() const
|
||||
{
|
||||
return m_data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
byte_t*
|
||||
data()
|
||||
{
|
||||
return m_data.data();
|
||||
return _data.data();
|
||||
}
|
||||
|
||||
const byte_t*
|
||||
data() const
|
||||
{
|
||||
return m_data.data();
|
||||
return _data.data();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -196,7 +196,7 @@ namespace llarp
|
||||
void
|
||||
Zero()
|
||||
{
|
||||
m_data.fill(0);
|
||||
_data.fill(0);
|
||||
}
|
||||
|
||||
virtual void
|
||||
@ -208,25 +208,25 @@ namespace llarp
|
||||
typename std::array<byte_t, SIZE>::iterator
|
||||
begin()
|
||||
{
|
||||
return m_data.begin();
|
||||
return _data.begin();
|
||||
}
|
||||
|
||||
typename std::array<byte_t, SIZE>::iterator
|
||||
end()
|
||||
{
|
||||
return m_data.end();
|
||||
return _data.end();
|
||||
}
|
||||
|
||||
typename std::array<byte_t, SIZE>::const_iterator
|
||||
begin() const
|
||||
{
|
||||
return m_data.cbegin();
|
||||
return _data.cbegin();
|
||||
}
|
||||
|
||||
typename std::array<byte_t, SIZE>::const_iterator
|
||||
end() const
|
||||
{
|
||||
return m_data.cend();
|
||||
return _data.cend();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -241,6 +241,19 @@ namespace llarp
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
from_string(std::string b)
|
||||
{
|
||||
if (b.size() != sz)
|
||||
{
|
||||
log::error(util_cat, "Error: buffer size mismatch in aligned buffer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memcpy(_data.data(), b.data(), b.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
bt_encode(llarp_buffer_t* buf) const
|
||||
{
|
||||
@ -292,7 +305,7 @@ namespace llarp
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<byte_t, SIZE> m_data;
|
||||
std::array<byte_t, SIZE> _data;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
|
@ -15,6 +15,11 @@ namespace llarp
|
||||
namespace log = oxen::log;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
static auto util_cat = llarp::log::Cat("lokinet.util");
|
||||
} // namespace
|
||||
|
||||
// Not ready to pollute these deprecation warnings everywhere yet
|
||||
#if 0
|
||||
#define LOKINET_LOG_DEPRECATED(Meth) \
|
||||
|
Loading…
Reference in New Issue
Block a user