mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-02 03:40:12 +00:00
following up before Tom meeting
This commit is contained in:
parent
f35f7fe3f2
commit
4ed6a01e02
@ -35,28 +35,11 @@ namespace llarp::routing
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "O");
|
||||
|
||||
{
|
||||
auto subdict = btdp.append_dict("B");
|
||||
|
||||
for (auto& b : blacklist_policy)
|
||||
b.bt_encode(subdict);
|
||||
}
|
||||
|
||||
btdp.append("E", flag);
|
||||
btdp.append("I", pubkey.ToView());
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
btdp.append("V", version);
|
||||
|
||||
{
|
||||
auto subdict = btdp.append_dict("B");
|
||||
|
||||
for (auto& w : whitelist_policy)
|
||||
w.bt_encode(subdict);
|
||||
}
|
||||
|
||||
btdp.append("X", address_lifetime);
|
||||
btdp.append("Z", sig.ToView());
|
||||
}
|
||||
@ -72,8 +55,6 @@ namespace llarp::routing
|
||||
ObtainExitMessage::decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictList("B", blacklist_policy, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("E", flag, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("I", pubkey, read, k, buf))
|
||||
@ -84,8 +65,6 @@ namespace llarp::routing
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("V", version, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictList("W", whitelist_policy, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("X", address_lifetime, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("Z", sig, read, k, buf))
|
||||
@ -106,7 +85,6 @@ namespace llarp::routing
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "G");
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
btdp.append("V", version);
|
||||
@ -174,16 +152,7 @@ namespace llarp::routing
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "J");
|
||||
btdp.append("B", backoff_time);
|
||||
|
||||
{
|
||||
auto subdict = btdp.append_dict("R");
|
||||
|
||||
for (auto& b : blacklist_policy)
|
||||
b.bt_encode(subdict);
|
||||
}
|
||||
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
btdp.append("V", version);
|
||||
@ -204,8 +173,6 @@ namespace llarp::routing
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictInt("B", backoff_time, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictList("R", blacklist_policy, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("S", sequence_number, read, k, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictInt("T", tx_id, read, k, buf))
|
||||
@ -255,7 +222,6 @@ namespace llarp::routing
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "V");
|
||||
btdp.append("P", path_id.ToView());
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
@ -322,7 +288,6 @@ namespace llarp::routing
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "V");
|
||||
btdp.append("S", sequence_number);
|
||||
btdp.append("T", tx_id);
|
||||
btdp.append("V", version);
|
||||
|
@ -10,11 +10,9 @@ namespace llarp::routing
|
||||
{
|
||||
struct ObtainExitMessage final : public AbstractRoutingMessage
|
||||
{
|
||||
std::vector<llarp::exit::Policy> blacklist_policy;
|
||||
uint64_t flag{0}; // 0 for snode, 1 for internet access
|
||||
llarp::PubKey pubkey;
|
||||
uint64_t tx_id{0};
|
||||
std::vector<llarp::exit::Policy> whitelist_policy;
|
||||
uint64_t address_lifetime{0};
|
||||
llarp::Signature sig;
|
||||
|
||||
@ -26,11 +24,9 @@ namespace llarp::routing
|
||||
void
|
||||
clear() override
|
||||
{
|
||||
blacklist_policy.clear();
|
||||
flag = 0;
|
||||
pubkey.Zero();
|
||||
tx_id = 0;
|
||||
whitelist_policy.clear();
|
||||
address_lifetime = 0;
|
||||
sig.Zero();
|
||||
}
|
||||
@ -88,7 +84,6 @@ namespace llarp::routing
|
||||
{
|
||||
using Nonce_t = llarp::AlignedBuffer<16>;
|
||||
uint64_t backoff_time;
|
||||
std::vector<llarp::exit::Policy> blacklist_policy;
|
||||
uint64_t tx_id;
|
||||
Nonce_t nonce;
|
||||
llarp::Signature sig;
|
||||
@ -97,7 +92,6 @@ namespace llarp::routing
|
||||
clear() override
|
||||
{
|
||||
backoff_time = 0;
|
||||
blacklist_policy.clear();
|
||||
tx_id = 0;
|
||||
nonce.Zero();
|
||||
sig.Zero();
|
||||
|
@ -159,14 +159,14 @@ namespace llarp::exit
|
||||
const static auto roles = llarp::path::ePathRoleExit | llarp::path::ePathRoleSVC;
|
||||
if (p->SupportsAnyRoles(roles))
|
||||
{
|
||||
llarp::LogInfo(p->Name(), " closing exit path");
|
||||
llarp::LogInfo(p->name(), " closing exit path");
|
||||
routing::CloseExitMessage msg;
|
||||
if (msg.Sign(m_ExitIdentity) && p->SendExitClose(msg, router))
|
||||
{
|
||||
p->ClearRoles(roles);
|
||||
}
|
||||
else
|
||||
llarp::LogWarn(p->Name(), " failed to send exit close message");
|
||||
llarp::LogWarn(p->name(), " failed to send exit close message");
|
||||
}
|
||||
};
|
||||
ForEachPath(sendExitClose);
|
||||
@ -180,10 +180,10 @@ namespace llarp::exit
|
||||
auto sendExitClose = [&](const path::Path_ptr p) {
|
||||
if (p->SupportsAnyRoles(path::ePathRoleExit))
|
||||
{
|
||||
LogInfo(p->Name(), " closing exit path");
|
||||
LogInfo(p->name(), " closing exit path");
|
||||
routing::CloseExitMessage msg;
|
||||
if (!(msg.Sign(m_ExitIdentity) && p->SendExitClose(msg, router)))
|
||||
LogWarn(p->Name(), " failed to send exit close message");
|
||||
LogWarn(p->name(), " failed to send exit close message");
|
||||
}
|
||||
};
|
||||
ForEachPath(sendExitClose);
|
||||
|
@ -210,7 +210,7 @@ namespace llarp
|
||||
std::string
|
||||
Name() const override;
|
||||
|
||||
virtual void
|
||||
void
|
||||
SendPacketToRemote(const llarp_buffer_t& pkt, service::ProtocolType t) override;
|
||||
|
||||
protected:
|
||||
@ -239,7 +239,7 @@ namespace llarp
|
||||
std::string
|
||||
Name() const override;
|
||||
|
||||
virtual void
|
||||
void
|
||||
SendPacketToRemote(const llarp_buffer_t& pkt, service::ProtocolType t) override;
|
||||
|
||||
protected:
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "contacts.hpp"
|
||||
|
||||
#include <llarp/messages/dht.hpp>
|
||||
#include <llarp/messages/exit.hpp>
|
||||
#include <llarp/messages/path.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/router/rc_lookup_handler.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
@ -198,6 +200,13 @@ namespace llarp
|
||||
};
|
||||
}
|
||||
|
||||
if (func)
|
||||
{
|
||||
func = [this, f = std::move(func)](oxen::quic::message m) mutable {
|
||||
router.loop()->call([func = std::move(f), msg = std::move(m)]() mutable { func(msg); });
|
||||
};
|
||||
}
|
||||
|
||||
return send_control_message_impl(remote, std::move(endpoint), std::move(body), std::move(func));
|
||||
}
|
||||
|
||||
@ -211,22 +220,14 @@ namespace llarp
|
||||
if (is_stopping)
|
||||
return false;
|
||||
|
||||
// DISCUSS: uncomment this if we want to excecute two callbacks
|
||||
// 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));
|
||||
return true;
|
||||
}
|
||||
|
||||
router.loop()->call([&]() {
|
||||
auto pending = PendingControlMessage(body, endpoint, func);
|
||||
router.loop()->call([this, remote, endpoint, body, f = std::move(func)]() {
|
||||
auto pending = PendingControlMessage(body, endpoint, f);
|
||||
|
||||
auto [itr, b] = pending_conn_msg_queue.emplace(remote, MessageQueue());
|
||||
itr->second.push_back(std::move(pending));
|
||||
@ -547,7 +548,7 @@ 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({{"NAME", maybe->ciphertext.c_str()}}));
|
||||
msg.respond(serialize_response({{"NAME", maybe->ciphertext}}));
|
||||
else
|
||||
msg.respond(serialize_response({{"STATUS", FindNameMessage::NOT_FOUND}}), true);
|
||||
});
|
||||
@ -600,14 +601,14 @@ namespace llarp
|
||||
LinkManager::handle_find_router(oxen::quic::message m)
|
||||
{
|
||||
std::string target_key;
|
||||
uint64_t is_exploratory, is_iterative;
|
||||
bool is_exploratory, is_iterative;
|
||||
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
|
||||
is_exploratory = btdc.require<uint64_t>("E");
|
||||
is_iterative = btdc.require<uint64_t>("I");
|
||||
is_exploratory = btdc.require<bool>("E");
|
||||
is_iterative = btdc.require<bool>("I");
|
||||
target_key = btdc.require<std::string>("K");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
@ -642,8 +643,7 @@ namespace llarp
|
||||
}
|
||||
|
||||
m.respond(
|
||||
serialize_response(
|
||||
{{"STATUS", FindRouterMessage::RETRY_EXP}, {"RECIPIENT", neighbors.c_str()}}),
|
||||
serialize_response({{"STATUS", FindRouterMessage::RETRY_EXP}, {"RECIPIENT", neighbors}}),
|
||||
true);
|
||||
}
|
||||
else
|
||||
@ -661,7 +661,7 @@ namespace llarp
|
||||
}
|
||||
else
|
||||
{
|
||||
m.respond(serialize_response({{"RC", closest_rc.ToString().c_str()}}));
|
||||
m.respond(serialize_response({{"RC", closest_rc.ToString()}}));
|
||||
}
|
||||
}
|
||||
else if (not is_iterative)
|
||||
@ -735,6 +735,7 @@ namespace llarp
|
||||
}
|
||||
|
||||
RouterID target{reinterpret_cast<uint8_t*>(payload.data())};
|
||||
|
||||
if (status == FindRouterMessage::RETRY_EXP)
|
||||
{
|
||||
log::critical(link_cat, "FindRouterMessage failed, retrying as exploratory!");
|
||||
@ -1034,6 +1035,36 @@ namespace llarp
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_build(oxen::quic::message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_build_response(oxen::quic::message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
// m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_confirm(oxen::quic::message m)
|
||||
{
|
||||
@ -1049,6 +1080,21 @@ namespace llarp
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_confirm_response(oxen::quic::message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
// m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_latency(oxen::quic::message m)
|
||||
{
|
||||
@ -1064,6 +1110,98 @@ namespace llarp
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_latency_response(oxen::quic::message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
// m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_transfer(oxen::quic::message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_transfer_response(oxen::quic::message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_obtain_exit(oxen::quic::message m)
|
||||
{
|
||||
// TODO: implement transit_hop things like nextseqno(), info.rxID, etc
|
||||
std::string copy{m.body_str()};
|
||||
ustring pubkey, signature;
|
||||
uint64_t flag, tx_id, seq_no;
|
||||
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{copy};
|
||||
|
||||
flag = btdc.require<uint64_t>("E");
|
||||
pubkey = btdc.require<ustring>("I");
|
||||
seq_no = btdc.require<uint64_t>("S");
|
||||
tx_id = btdc.require<uint64_t>("T");
|
||||
signature = btdc.require<ustring>("Z");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response({{"STATUS", ObtainExit::EXCEPTION}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
RouterID target{pubkey.data()};
|
||||
|
||||
if (CryptoManager::instance()->verify(
|
||||
pubkey.data(), reinterpret_cast<uint8_t*>(copy.data()), copy.size(), signature.data()))
|
||||
{}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_obtain_exit_response(oxen::quic::message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_update_exit(oxen::quic::message m)
|
||||
{
|
||||
@ -1080,20 +1218,11 @@ namespace llarp
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_obtain_exit(oxen::quic::message m)
|
||||
LinkManager::handle_update_exit_response(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{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");
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@ -1101,11 +1230,6 @@ namespace llarp
|
||||
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
|
||||
RouterID target;
|
||||
target.FromString(pubkey);
|
||||
|
||||
// auto handler = router.path_context().GetByDownstream(target, tx_id);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1124,6 +1248,17 @@ namespace llarp
|
||||
}
|
||||
|
||||
void
|
||||
LinkManager::handle_path_build(oxen::quic::message)
|
||||
{}
|
||||
LinkManager::handle_close_exit_response(oxen::quic::message m)
|
||||
{
|
||||
try
|
||||
{
|
||||
oxenc::bt_dict_consumer btdc{m.body()};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
log::warning(link_cat, "Exception: {}", e.what());
|
||||
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // namespace llarp
|
||||
|
@ -289,10 +289,11 @@ namespace llarp
|
||||
|
||||
// Path messages
|
||||
void handle_path_build(oxen::quic::message); // relay
|
||||
void handle_relay_status(oxen::quic::message); // relay
|
||||
void handle_path_confirm(oxen::quic::message); // relay
|
||||
void handle_path_latency(oxen::quic::message); // relay
|
||||
void handle_path_transfer(oxen::quic::message); // relay
|
||||
void handle_relay_commit(oxen::quic::message); // relay
|
||||
void handle_relay_status(oxen::quic::message); // relay
|
||||
|
||||
// Exit messages
|
||||
void handle_obtain_exit(oxen::quic::message); // relay
|
||||
@ -319,6 +320,7 @@ namespace llarp
|
||||
|
||||
// Path responses
|
||||
void handle_path_build_response(oxen::quic::message);
|
||||
void handle_relay_commit_response(oxen::quic::message);
|
||||
void handle_relay_status_response(oxen::quic::message);
|
||||
void handle_path_confirm_response(oxen::quic::message);
|
||||
void handle_path_latency_response(oxen::quic::message);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/dht/key.hpp>
|
||||
#include <llarp/path/path_types.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
@ -6,10 +6,10 @@ namespace llarp
|
||||
{
|
||||
namespace FindRouterMessage
|
||||
{
|
||||
inline const char* EXCEPTION = "EXCEPTION";
|
||||
inline const char* RETRY_EXP = "RETRY AS EXPLORATORY";
|
||||
inline const char* RETRY_ITER = "RETRY AS ITERATIVE";
|
||||
inline const char* RETRY_NEW = "RETRY WITH NEW RECIPIENT";
|
||||
inline auto EXCEPTION = "EXCEPTION"sv;
|
||||
inline auto RETRY_EXP = "RETRY AS EXPLORATORY"sv;
|
||||
inline auto RETRY_ITER = "RETRY AS ITERATIVE"sv;
|
||||
inline auto RETRY_NEW = "RETRY WITH NEW RECIPIENT"sv;
|
||||
|
||||
inline static std::string
|
||||
serialize(const RouterID& rid, bool is_iterative, bool is_exploratory, uint64_t tx_id)
|
||||
@ -18,7 +18,6 @@ namespace llarp
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "R");
|
||||
btdp.append("E", is_exploratory);
|
||||
btdp.append("I", is_iterative);
|
||||
btdp.append("K", rid.ToView());
|
||||
@ -35,10 +34,10 @@ namespace llarp
|
||||
|
||||
namespace FindIntroMessage
|
||||
{
|
||||
inline const char* EXCEPTION = "EXCEPTION";
|
||||
inline const char* NOT_FOUND = "NOT FOUND";
|
||||
inline const char* INVALID_ORDER = "INVALID ORDER";
|
||||
inline const char* INSUFFICIENT_NODES = "INSUFFICIENT NODES";
|
||||
inline auto EXCEPTION = "EXCEPTION"sv;
|
||||
inline auto NOT_FOUND = "NOT FOUND"sv;
|
||||
inline auto INVALID_ORDER = "INVALID ORDER"sv;
|
||||
inline auto INSUFFICIENT_NODES = "INSUFFICIENT NODES"sv;
|
||||
|
||||
inline static std::string
|
||||
serialize(
|
||||
@ -48,7 +47,6 @@ namespace llarp
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "F");
|
||||
btdp.append("N", tag);
|
||||
btdp.append("O", order);
|
||||
btdp.append("R", is_relayed ? 1 : 0);
|
||||
@ -66,8 +64,8 @@ namespace llarp
|
||||
|
||||
namespace FindNameMessage
|
||||
{
|
||||
inline const char* EXCEPTION = "EXCEPTION";
|
||||
inline const char* NOT_FOUND = "NOT FOUND";
|
||||
inline auto EXCEPTION = "EXCEPTION"sv;
|
||||
inline auto NOT_FOUND = "NOT FOUND"sv;
|
||||
|
||||
inline static std::string
|
||||
serialize([[maybe_unused]] const dht::Key_t& from, dht::Key_t name_hash, uint64_t tx_id)
|
||||
@ -76,7 +74,6 @@ namespace llarp
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "N");
|
||||
btdp.append("H", name_hash.ToView());
|
||||
btdp.append("T", tx_id);
|
||||
}
|
||||
@ -91,11 +88,11 @@ namespace llarp
|
||||
|
||||
namespace PublishIntroMessage
|
||||
{
|
||||
inline const char* EXCEPTION = "EXCEPTION";
|
||||
inline const char* INVALID_INTROSET = "INVALID INTROSET";
|
||||
inline const char* EXPIRED = "EXPIRED INTROSET";
|
||||
inline const char* INSUFFICIENT = "INSUFFICIENT NODES";
|
||||
inline const char* INVALID_ORDER = "INVALID ORDER";
|
||||
inline auto EXCEPTION = "EXCEPTION"sv;
|
||||
inline auto INVALID_INTROSET = "INVALID INTROSET"sv;
|
||||
inline auto EXPIRED = "EXPIRED INTROSET"sv;
|
||||
inline auto INSUFFICIENT = "INSUFFICIENT NODES"sv;
|
||||
inline auto INVALID_ORDER = "INVALID ORDER"sv;
|
||||
|
||||
inline static std::string
|
||||
serialize(std::string introset, uint64_t relay_order, uint64_t is_relayed, uint64_t tx_id)
|
||||
@ -104,7 +101,6 @@ namespace llarp
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("A", "I");
|
||||
btdp.append("I", introset);
|
||||
btdp.append("O", relay_order);
|
||||
btdp.append("R", is_relayed);
|
||||
|
25
llarp/messages/exit.hpp
Normal file
25
llarp/messages/exit.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace ObtainExit
|
||||
{
|
||||
inline auto EXCEPTION = "EXCEPTION"sv;
|
||||
|
||||
}
|
||||
|
||||
namespace UpdateExit
|
||||
{
|
||||
inline auto EXCEPTION = "EXCEPTION"sv;
|
||||
|
||||
}
|
||||
|
||||
namespace CloseExit
|
||||
{
|
||||
inline auto EXCEPTION = "EXCEPTION"sv;
|
||||
|
||||
}
|
||||
|
||||
} // namespace llarp
|
@ -4,22 +4,119 @@
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct PathMessage : public AbstractSerializable
|
||||
{};
|
||||
namespace PathBuildMessage
|
||||
{
|
||||
inline static void
|
||||
setup_hop_keys(path::PathHopConfig& hop, const RouterID& nextHop)
|
||||
{
|
||||
auto crypto = CryptoManager::instance();
|
||||
|
||||
struct RelayCommitMessage : public PathMessage
|
||||
{};
|
||||
// generate key
|
||||
crypto->encryption_keygen(hop.commkey);
|
||||
|
||||
struct RelayStatusMessage : public PathMessage
|
||||
{};
|
||||
hop.nonce.Randomize();
|
||||
// do key exchange
|
||||
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::error(path_cat, err);
|
||||
throw std::runtime_error{std::move(err)};
|
||||
}
|
||||
// generate nonceXOR value self->hop->pathKey
|
||||
crypto->shorthash(hop.nonceXOR, hop.shared.data(), hop.shared.size());
|
||||
|
||||
struct PathConfirmMessage : public PathMessage
|
||||
{};
|
||||
hop.upstream = nextHop;
|
||||
}
|
||||
|
||||
struct PathLatencyMessage : public PathMessage
|
||||
{};
|
||||
inline static std::string
|
||||
serialize(const path::PathHopConfig& hop)
|
||||
{
|
||||
auto crypto = CryptoManager::instance();
|
||||
|
||||
struct PathTransferMessage : public PathMessage
|
||||
{};
|
||||
std::string hop_info;
|
||||
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("lifetime", path::DEFAULT_LIFETIME.count());
|
||||
btdp.append("txid", hop.txID.ToView());
|
||||
btdp.append("rxid", hop.rxID.ToView());
|
||||
btdp.append("nonce", hop.nonce.ToView());
|
||||
btdp.append("next", hop.upstream.ToView());
|
||||
btdp.append("commkey", hop.commkey.toPublic().ToView());
|
||||
|
||||
hop_info = std::move(btdp).str();
|
||||
}
|
||||
|
||||
SecretKey framekey;
|
||||
crypto->encryption_keygen(framekey);
|
||||
|
||||
SharedSecret shared;
|
||||
TunnelNonce outer_nonce;
|
||||
outer_nonce.Randomize();
|
||||
|
||||
// derive (outer) shared key
|
||||
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"};
|
||||
}
|
||||
|
||||
// encrypt hop_info (mutates in-place)
|
||||
if (!crypto->xchacha20(
|
||||
reinterpret_cast<uint8_t*>(hop_info.data()), hop_info.size(), shared, outer_nonce))
|
||||
{
|
||||
log::error(path_cat, "Hop info encryption failed!");
|
||||
throw std::runtime_error{"Hop info encrypttion failed"};
|
||||
}
|
||||
|
||||
std::string hashed_data;
|
||||
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("encrypted", hop_info);
|
||||
btdp.append("pubkey", framekey.toPublic().ToView());
|
||||
btdp.append("nonce", outer_nonce.ToView());
|
||||
|
||||
hashed_data = std::move(btdp).str();
|
||||
}
|
||||
|
||||
std::string hash;
|
||||
hash.reserve(SHORTHASHSIZE);
|
||||
|
||||
if (!crypto->hmac(
|
||||
reinterpret_cast<uint8_t*>(hash.data()),
|
||||
reinterpret_cast<uint8_t*>(hashed_data.data()),
|
||||
hashed_data.size(),
|
||||
shared))
|
||||
{
|
||||
log::error(path_cat, "Failed to generate HMAC for hop info");
|
||||
throw std::runtime_error{"Failed to generate HMAC for hop info"};
|
||||
}
|
||||
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("hash", hash);
|
||||
btdp.append("frame", hashed_data);
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
} // namespace PathBuildMessage
|
||||
|
||||
namespace RelayCommitMessage
|
||||
{}
|
||||
|
||||
namespace RelayStatusMessage
|
||||
{}
|
||||
|
||||
namespace PathConfirmMessage
|
||||
{}
|
||||
|
||||
namespace PathLatencyMessage
|
||||
{}
|
||||
|
||||
namespace PathTransferMessage
|
||||
{}
|
||||
|
||||
} // namespace llarp
|
||||
|
@ -308,9 +308,9 @@ namespace llarp
|
||||
}
|
||||
// persist sessions to upstream and downstream routers until the commit
|
||||
// ends
|
||||
self->context->router()->PersistSessionUntil(
|
||||
self->context->router()->persist_connection_until(
|
||||
self->hop->info.downstream, self->hop->ExpireTime() + 10s);
|
||||
self->context->router()->PersistSessionUntil(
|
||||
self->context->router()->persist_connection_until(
|
||||
self->hop->info.upstream, self->hop->ExpireTime() + 10s);
|
||||
// put hop
|
||||
self->context->PutTransitHop(self->hop);
|
||||
@ -345,7 +345,7 @@ namespace llarp
|
||||
else
|
||||
{
|
||||
// persist session to downstream until path expiration
|
||||
self->context->router()->PersistSessionUntil(
|
||||
self->context->router()->persist_connection_until(
|
||||
self->hop->info.downstream, self->hop->ExpireTime() + 10s);
|
||||
// put hop
|
||||
self->context->PutTransitHop(self->hop);
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "path.hpp"
|
||||
|
||||
#include <llarp/dht/context.hpp>
|
||||
#include <llarp/exit/exit_messages.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/messages/discard.hpp>
|
||||
@ -114,13 +113,13 @@ namespace llarp::path
|
||||
}
|
||||
|
||||
bool
|
||||
Path::IsEndpoint(const RouterID& r, const PathID_t& id) const
|
||||
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;
|
||||
}
|
||||
|
||||
RouterID
|
||||
Path::Upstream() const
|
||||
Path::upstream() const
|
||||
{
|
||||
return hops[0].rc.pubkey;
|
||||
}
|
||||
@ -206,7 +205,7 @@ namespace llarp::path
|
||||
{
|
||||
r->notify_router_event<tooling::PathBuildRejectedEvent>(Endpoint(), RXID(), *failedAt);
|
||||
LogWarn(
|
||||
Name(),
|
||||
name(),
|
||||
" build failed at ",
|
||||
*failedAt,
|
||||
" status=",
|
||||
@ -302,16 +301,16 @@ namespace llarp::path
|
||||
}
|
||||
else if (st == ePathBuilding)
|
||||
{
|
||||
LogInfo("path ", Name(), " is building");
|
||||
LogInfo("path ", name(), " is building");
|
||||
buildStarted = now;
|
||||
}
|
||||
else if (st == ePathEstablished && _status == ePathBuilding)
|
||||
{
|
||||
LogInfo("path ", Name(), " is built, took ", ToString(now - buildStarted));
|
||||
LogInfo("path ", name(), " is built, took ", ToString(now - buildStarted));
|
||||
}
|
||||
else if (st == ePathTimeout && _status == ePathEstablished)
|
||||
{
|
||||
LogInfo("path ", Name(), " died");
|
||||
LogInfo("path ", name(), " died");
|
||||
_status = st;
|
||||
if (auto parent = m_PathSet.lock())
|
||||
{
|
||||
@ -320,11 +319,11 @@ namespace llarp::path
|
||||
}
|
||||
else if (st == ePathEstablished && _status == ePathTimeout)
|
||||
{
|
||||
LogInfo("path ", Name(), " reanimated");
|
||||
LogInfo("path ", name(), " reanimated");
|
||||
}
|
||||
else if (st == ePathIgnore)
|
||||
{
|
||||
LogInfo("path ", Name(), " ignored");
|
||||
LogInfo("path ", name(), " ignored");
|
||||
}
|
||||
_status = st;
|
||||
}
|
||||
@ -404,7 +403,7 @@ namespace llarp::path
|
||||
std::vector<RouterContact> newHops;
|
||||
for (const auto& hop : hops)
|
||||
newHops.emplace_back(hop.rc);
|
||||
LogInfo(Name(), " rebuilding on ", ShortName());
|
||||
LogInfo(name(), " rebuilding on ", ShortName());
|
||||
parent->Build(newHops);
|
||||
}
|
||||
}
|
||||
@ -419,7 +418,7 @@ namespace llarp::path
|
||||
latency.sequence_number = NextSeqNo();
|
||||
m_LastLatencyTestID = latency.sent_time;
|
||||
m_LastLatencyTestTime = now;
|
||||
LogDebug(Name(), " send latency test id=", latency.sent_time);
|
||||
LogDebug(name(), " send latency test id=", latency.sent_time);
|
||||
if (not SendRoutingMessage(latency, r))
|
||||
return false;
|
||||
FlushUpstream(r);
|
||||
@ -447,7 +446,7 @@ namespace llarp::path
|
||||
const auto dlt = now - buildStarted;
|
||||
if (dlt >= path::BUILD_TIMEOUT)
|
||||
{
|
||||
LogWarn(Name(), " waited for ", ToString(dlt), " and no path was built");
|
||||
LogWarn(name(), " waited for ", ToString(dlt), " and no path was built");
|
||||
r->router_profiling().MarkPathFail(this);
|
||||
EnterState(ePathExpired, now);
|
||||
return;
|
||||
@ -471,7 +470,7 @@ namespace llarp::path
|
||||
dlt = now - m_LastRecvMessage;
|
||||
if (dlt >= path::ALIVE_TIMEOUT)
|
||||
{
|
||||
LogWarn(Name(), " waited for ", ToString(dlt), " and path looks dead");
|
||||
LogWarn(name(), " waited for ", ToString(dlt), " and path looks dead");
|
||||
r->router_profiling().MarkPathFail(this);
|
||||
EnterState(ePathTimeout, now);
|
||||
}
|
||||
@ -488,13 +487,13 @@ namespace llarp::path
|
||||
{
|
||||
for (const auto& msg : msgs)
|
||||
{
|
||||
if (r->send_data_message(Upstream(), msg))
|
||||
if (r->send_data_message(upstream(), msg))
|
||||
{
|
||||
m_TXRate += msg.enc.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDebug("failed to send upstream to ", Upstream());
|
||||
LogDebug("failed to send upstream to ", upstream());
|
||||
}
|
||||
}
|
||||
r->TriggerPump();
|
||||
@ -572,7 +571,7 @@ namespace llarp::path
|
||||
}
|
||||
|
||||
std::string
|
||||
Path::Name() const
|
||||
Path::name() const
|
||||
{
|
||||
return fmt::format("TX={} RX={}", TXID(), RXID());
|
||||
}
|
||||
@ -725,7 +724,7 @@ namespace llarp::path
|
||||
r->router_profiling().MarkPathSuccess(this);
|
||||
|
||||
// persist session with upstream router until the path is done
|
||||
r->PersistSessionUntil(Upstream(), intro.expiry);
|
||||
r->persist_connection_until(upstream(), intro.expiry);
|
||||
MarkActive(now);
|
||||
return SendLatencyMessage(r);
|
||||
}
|
||||
@ -808,22 +807,22 @@ namespace llarp::path
|
||||
{
|
||||
if (msg.Verify(EndpointPubKey()))
|
||||
{
|
||||
LogInfo(Name(), " had its exit closed");
|
||||
LogInfo(name(), " had its exit closed");
|
||||
_role &= ~ePathRoleExit;
|
||||
return true;
|
||||
}
|
||||
|
||||
LogError(Name(), " CXM from exit with bad signature");
|
||||
LogError(name(), " CXM from exit with bad signature");
|
||||
}
|
||||
else
|
||||
LogError(Name(), " unwarranted CXM");
|
||||
LogError(name(), " unwarranted CXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Path::SendExitRequest(const routing::ObtainExitMessage& msg, Router* r)
|
||||
{
|
||||
LogInfo(Name(), " sending exit request to ", Endpoint());
|
||||
LogInfo(name(), " sending exit request to ", Endpoint());
|
||||
m_ExitObtainTX = msg.tx_id;
|
||||
return SendRoutingMessage(msg, r);
|
||||
}
|
||||
@ -831,7 +830,7 @@ namespace llarp::path
|
||||
bool
|
||||
Path::SendExitClose(const routing::CloseExitMessage& msg, Router* r)
|
||||
{
|
||||
LogInfo(Name(), " closing exit to ", Endpoint());
|
||||
LogInfo(name(), " closing exit to ", Endpoint());
|
||||
// mark as not exit anymore
|
||||
_role &= ~ePathRoleExit;
|
||||
return SendRoutingMessage(msg, r);
|
||||
@ -842,7 +841,7 @@ namespace llarp::path
|
||||
{
|
||||
(void)msg;
|
||||
(void)r;
|
||||
LogError(Name(), " got unwarranted OXM");
|
||||
LogError(name(), " got unwarranted OXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -851,7 +850,7 @@ namespace llarp::path
|
||||
{
|
||||
(void)msg;
|
||||
(void)r;
|
||||
LogError(Name(), " got unwarranted UXM");
|
||||
LogError(name(), " got unwarranted UXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -862,14 +861,14 @@ namespace llarp::path
|
||||
{
|
||||
if (!msg.Verify(EndpointPubKey()))
|
||||
{
|
||||
LogError(Name(), "RXM invalid signature");
|
||||
LogError(name(), "RXM invalid signature");
|
||||
return false;
|
||||
}
|
||||
LogInfo(Name(), " ", Endpoint(), " Rejected exit");
|
||||
LogInfo(name(), " ", Endpoint(), " Rejected exit");
|
||||
MarkActive(r->now());
|
||||
return InformExitResult(llarp_time_t(msg.backoff_time));
|
||||
}
|
||||
LogError(Name(), " got unwarranted RXM");
|
||||
LogError(name(), " got unwarranted RXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -880,16 +879,16 @@ namespace llarp::path
|
||||
{
|
||||
if (!msg.Verify(EndpointPubKey()))
|
||||
{
|
||||
LogError(Name(), " GXM signature failed");
|
||||
LogError(name(), " GXM signature failed");
|
||||
return false;
|
||||
}
|
||||
// we now can send exit traffic
|
||||
_role |= ePathRoleExit;
|
||||
LogInfo(Name(), " ", Endpoint(), " Granted exit");
|
||||
LogInfo(name(), " ", Endpoint(), " Granted exit");
|
||||
MarkActive(r->now());
|
||||
return InformExitResult(0s);
|
||||
}
|
||||
LogError(Name(), " got unwarranted GXM");
|
||||
LogError(name(), " got unwarranted GXM");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -34,16 +34,10 @@ namespace llarp
|
||||
{
|
||||
struct TransitHop;
|
||||
struct TransitHopInfo;
|
||||
struct PathHopConfig;
|
||||
|
||||
using TransitHop_ptr = std::shared_ptr<TransitHop>;
|
||||
|
||||
inline bool
|
||||
operator<(const PathHopConfig& lhs, const PathHopConfig& rhs)
|
||||
{
|
||||
return std::tie(lhs.txID, lhs.rxID, lhs.rc, lhs.upstream, lhs.lifetime)
|
||||
< std::tie(rhs.txID, rhs.rxID, rhs.rc, rhs.upstream, rhs.lifetime);
|
||||
}
|
||||
|
||||
/// A path we made
|
||||
struct Path final : public AbstractHopHandler,
|
||||
public routing::AbstractRoutingMessageHandler,
|
||||
@ -330,16 +324,16 @@ namespace llarp
|
||||
EndpointPubKey() const;
|
||||
|
||||
bool
|
||||
IsEndpoint(const RouterID& router, const PathID_t& path) const;
|
||||
is_endpoint(const RouterID& router, const PathID_t& path) const;
|
||||
|
||||
PathID_t
|
||||
RXID() const override;
|
||||
|
||||
RouterID
|
||||
Upstream() const;
|
||||
upstream() const;
|
||||
|
||||
std::string
|
||||
Name() const;
|
||||
name() const;
|
||||
|
||||
void
|
||||
AddObtainExitHandler(ObtainedExitHandler handler)
|
||||
|
@ -1,7 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/constants/path.hpp>
|
||||
#include <llarp/crypto/constants.hpp>
|
||||
#include <llarp/util/aligned.hpp>
|
||||
#include <llarp/crypto/types.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
static auto path_cat = llarp::log::Cat("lokinet.path");
|
||||
} // namespace
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
@ -10,6 +18,43 @@ namespace llarp
|
||||
using AlignedBuffer<PATHIDSIZE>::AlignedBuffer;
|
||||
};
|
||||
|
||||
namespace path
|
||||
{
|
||||
/// configuration for a single hop when building a path
|
||||
struct PathHopConfig
|
||||
{
|
||||
/// path id
|
||||
PathID_t txID, rxID;
|
||||
// router contact of router
|
||||
RouterContact rc;
|
||||
// temp public encryption key
|
||||
SecretKey commkey;
|
||||
/// shared secret at this hop
|
||||
SharedSecret shared;
|
||||
/// hash of shared secret used for nonce mutation
|
||||
ShortHash nonceXOR;
|
||||
/// next hop's router id
|
||||
RouterID upstream;
|
||||
/// nonce for key exchange
|
||||
TunnelNonce nonce;
|
||||
// lifetime
|
||||
llarp_time_t lifetime = DEFAULT_LIFETIME;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const;
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator<(const PathHopConfig& lhs, const PathHopConfig& rhs)
|
||||
{
|
||||
return std::tie(lhs.txID, lhs.rxID, lhs.rc, lhs.upstream, lhs.lifetime)
|
||||
< std::tie(rhs.txID, rhs.rxID, rhs.rc, rhs.upstream, rhs.lifetime);
|
||||
}
|
||||
|
||||
// milliseconds waiting between builds on a path per router
|
||||
static constexpr auto MIN_PATH_BUILD_INTERVAL = 500ms;
|
||||
static constexpr auto PATH_BUILD_RATE = 100ms;
|
||||
} // namespace path
|
||||
} // namespace llarp
|
||||
|
||||
namespace std
|
||||
|
@ -2,15 +2,16 @@
|
||||
#include "path_context.hpp"
|
||||
|
||||
#include <llarp/crypto/crypto.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/messages/path.hpp>
|
||||
#include <llarp/messages/relay_commit.hpp>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
#include <llarp/profiling.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/router/rc_lookup_handler.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/tooling/path_event.hpp>
|
||||
#include <llarp/link/link_manager.hpp>
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/logging.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
@ -78,7 +79,7 @@ namespace llarp
|
||||
*/
|
||||
|
||||
void
|
||||
Builder::SetupHopKeys(path::PathHopConfig& hop, const RouterID& nextHop)
|
||||
Builder::setup_hop_keys(path::PathHopConfig& hop, const RouterID& nextHop)
|
||||
{
|
||||
auto crypto = CryptoManager::instance();
|
||||
|
||||
@ -89,41 +90,47 @@ namespace llarp
|
||||
// do key exchange
|
||||
if (!crypto->dh_client(hop.shared, hop.rc.pubkey, hop.commkey, hop.nonce))
|
||||
{
|
||||
LogError(Name(), " Failed to generate shared key for path build");
|
||||
throw std::runtime_error{"Failed to generate shared key for path build"};
|
||||
auto err = fmt::format("{} failed to generate shared key for path build!", Name());
|
||||
log::error(path_cat, err);
|
||||
throw std::runtime_error{std::move(err)};
|
||||
}
|
||||
// generate nonceXOR value self->hop->pathKey
|
||||
crypto->shorthash(hop.nonceXOR, llarp_buffer_t(hop.shared));
|
||||
crypto->shorthash(hop.nonceXOR, hop.shared.data(), hop.shared.size());
|
||||
|
||||
hop.upstream = nextHop;
|
||||
}
|
||||
|
||||
// FIXME: this is definitely not optimal using bt_dict instead of bt_dict_producer, among other
|
||||
// things
|
||||
std::string
|
||||
Builder::CreateHopInfoFrame(const path::PathHopConfig& hop)
|
||||
Builder::create_hop_info_frame(const path::PathHopConfig& hop)
|
||||
{
|
||||
auto crypto = CryptoManager::instance();
|
||||
|
||||
oxenc::bt_dict hop_info_dict;
|
||||
hop_info_dict["lifetime"] = path::DEFAULT_LIFETIME.count(); // milliseconds
|
||||
hop_info_dict["txid"] = hop.txID;
|
||||
hop_info_dict["rxid"] = hop.rxID;
|
||||
hop_info_dict["nonce"] = hop.nonce;
|
||||
hop_info_dict["next"] = hop.upstream;
|
||||
hop_info_dict["commkey"] = hop.commkey.toPublic(); // pubkey of ephemeral Ed key for DH
|
||||
std::string hop_info;
|
||||
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("lifetime", path::DEFAULT_LIFETIME.count());
|
||||
btdp.append("txid", hop.txID.ToView());
|
||||
btdp.append("rxid", hop.rxID.ToView());
|
||||
btdp.append("nonce", hop.nonce.ToView());
|
||||
btdp.append("next", hop.upstream.ToView());
|
||||
btdp.append("commkey", hop.commkey.toPublic().ToView());
|
||||
|
||||
hop_info = std::move(btdp).str();
|
||||
}
|
||||
|
||||
auto hop_info = oxenc::bt_serialize(hop_info_dict);
|
||||
SecretKey framekey;
|
||||
crypto->encryption_keygen(framekey);
|
||||
|
||||
SharedSecret shared;
|
||||
TunnelNonce outer_nonce;
|
||||
outer_nonce.Randomize();
|
||||
|
||||
// derive (outer) shared key
|
||||
if (!crypto->dh_client(shared, hop.rc.pubkey, framekey, outer_nonce))
|
||||
{
|
||||
llarp::LogError("DH failed during hop info encryption");
|
||||
log::error(path_cat, "DH client failed during hop info encryption!");
|
||||
throw std::runtime_error{"DH failed during hop info encryption"};
|
||||
}
|
||||
|
||||
@ -131,31 +138,41 @@ namespace llarp
|
||||
if (!crypto->xchacha20(
|
||||
reinterpret_cast<uint8_t*>(hop_info.data()), hop_info.size(), shared, outer_nonce))
|
||||
{
|
||||
llarp::LogError("hop info encrypt failed");
|
||||
throw std::runtime_error{"hop info encrypt failed"};
|
||||
log::error(path_cat, "Hop info encryption failed!");
|
||||
throw std::runtime_error{"Hop info encrypttion failed"};
|
||||
}
|
||||
oxenc::bt_dict hashed_dict;
|
||||
hashed_dict["encrypted"] = hop_info;
|
||||
hashed_dict["pubkey"] = framekey.toPublic();
|
||||
hashed_dict["nonce"] = nonce;
|
||||
auto hashed_data = oxenc::bt_serialize(hashed_dict);
|
||||
|
||||
std::basic_string<uint8_t> hash{SHORTHASHSIZE, '\0'};
|
||||
std::string hashed_data;
|
||||
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
btdp.append("encrypted", hop_info);
|
||||
btdp.append("pubkey", framekey.toPublic().ToView());
|
||||
btdp.append("nonce", outer_nonce.ToView());
|
||||
|
||||
hashed_data = std::move(btdp).str();
|
||||
}
|
||||
|
||||
std::string hash;
|
||||
hash.reserve(SHORTHASHSIZE);
|
||||
|
||||
if (!crypto->hmac(
|
||||
hash.data(),
|
||||
reinterpret_cast<uint8_t*>(hash.data()),
|
||||
reinterpret_cast<uint8_t*>(hashed_data.data()),
|
||||
hashed_data.size(),
|
||||
shared))
|
||||
{
|
||||
llarp::LogError("Failed to generate HMAC for hop info");
|
||||
log::error(path_cat, "Failed to generate HMAC for hop info");
|
||||
throw std::runtime_error{"Failed to generate HMAC for hop info"};
|
||||
}
|
||||
|
||||
oxenc::bt_dict final_frame;
|
||||
final_frame["hash"] = hash;
|
||||
final_frame["frame"] = hashed_data;
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
return oxenc::bt_serialize(final_frame);
|
||||
btdp.append("hash", hash);
|
||||
btdp.append("frame", hashed_data);
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
void
|
||||
@ -386,63 +403,83 @@ namespace llarp
|
||||
Builder::Build(std::vector<RouterContact> hops, PathRole roles)
|
||||
{
|
||||
if (IsStopped())
|
||||
{
|
||||
log::info(path_cat, "Path builder is stopped, aborting path build...");
|
||||
return;
|
||||
lastBuild = Now();
|
||||
}
|
||||
|
||||
lastBuild = llarp::time_now_ms();
|
||||
const RouterID edge{hops[0].pubkey};
|
||||
|
||||
if (not router->pathbuild_limiter().Attempt(edge))
|
||||
{
|
||||
LogWarn(Name(), " building too fast to edge router ", edge);
|
||||
log::warning(path_cat, "{} building too quickly to edge router {}", Name(), edge);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string path_shortName = "[path " + router->ShortName() + "-";
|
||||
path_shortName = path_shortName + std::to_string(router->NextPathBuildNumber()) + "]";
|
||||
auto path = std::make_shared<path::Path>(hops, GetWeak(), roles, std::move(path_shortName));
|
||||
LogInfo(Name(), " build ", path->ShortName(), ": ", path->HopsString());
|
||||
|
||||
log::info(
|
||||
path_cat, "{} building path -> {} : {}", Name(), path->ShortName(), path->HopsString());
|
||||
|
||||
oxenc::bt_list_producer frames;
|
||||
|
||||
auto& path_hops = path->hops;
|
||||
size_t n_hops = path_hops.size();
|
||||
size_t last_len{0};
|
||||
for (size_t i = 0; i < path_hops.size(); i++)
|
||||
|
||||
for (size_t i = 0; i < n_hops; i++)
|
||||
{
|
||||
bool lastHop = (i == (path_hops.size() - 1));
|
||||
bool lastHop = (i == (n_hops - 1));
|
||||
|
||||
const auto& nextHop = lastHop ? path_hops[i].rc.pubkey : path_hops[i + 1].rc.pubkey;
|
||||
SetupHopKeys(path_hops[i], nextHop);
|
||||
auto frame_str = CreateHopInfoFrame(path_hops[i]);
|
||||
|
||||
// TODO: talk to Tom about what he thinks about this
|
||||
PathBuildMessage::setup_hop_keys(path_hops[i], nextHop);
|
||||
auto frame_str = PathBuildMessage::serialize(path_hops[i]);
|
||||
|
||||
// all frames should be the same length...not sure what that is yet
|
||||
if (last_len != 0)
|
||||
assert(
|
||||
frame_str.size()
|
||||
== last_len); // all frames should be the same length...not sure what that is yet
|
||||
assert(frame_str.size() == last_len);
|
||||
|
||||
last_len = frame_str.size();
|
||||
frames.append(frame_str);
|
||||
frames.append(std::move(frame_str));
|
||||
}
|
||||
|
||||
std::string dummy{last_len, '\0'};
|
||||
std::string dummy;
|
||||
dummy.reserve(last_len);
|
||||
|
||||
// append dummy frames; path build request must always have MAX_LEN frames
|
||||
for (size_t i = 0; i < path::MAX_LEN - path_hops.size(); i++)
|
||||
for (size_t i = 0; i < path::MAX_LEN - n_hops; i++)
|
||||
{
|
||||
randombytes(reinterpret_cast<uint8_t*>(dummy.data()), dummy.size());
|
||||
frames.append(dummy);
|
||||
}
|
||||
|
||||
m_router->notify_router_event<tooling::PathAttemptEvent>(m_router->pubkey(), path);
|
||||
// TODO: talk to Tom about whether we do still this or not
|
||||
// router->notify_router_event<tooling::PathAttemptEvent>(router->pubkey(), path);
|
||||
|
||||
auto self = GetSelf();
|
||||
m_router->path_context().AddOwnPath(self, path);
|
||||
router->path_context().AddOwnPath(self, path);
|
||||
PathBuildStarted(path);
|
||||
|
||||
auto response_cb = [self](oxen::quic::message m) {
|
||||
auto response_cb = [self](oxen::quic::message) {
|
||||
// TODO: this (replaces handling LRSM, which also needs replacing)
|
||||
|
||||
// TODO: Talk to Tom about why are we using it as a response callback?
|
||||
// Do you mean TransitHop::HandleLRSM?
|
||||
};
|
||||
|
||||
if (not m_router->send_control_message(
|
||||
path->Upstream(), "path_build", std::move(frames.str()), std::move(response_cb)))
|
||||
if (not router->send_control_message(
|
||||
path->upstream(), "path_build", std::move(frames).str(), std::move(response_cb)))
|
||||
{
|
||||
log::warning(log_path, "Error sending path_build control message");
|
||||
path->EnterState(path::ePathFailed, m_router->now());
|
||||
path->EnterState(path::ePathFailed, router->now());
|
||||
}
|
||||
|
||||
m_router->PersistSessionUntil(path->Upstream(), path->ExpireTime());
|
||||
router->persist_connection_until(path->upstream(), path->ExpireTime());
|
||||
}
|
||||
|
||||
void
|
||||
@ -451,7 +488,7 @@ namespace llarp
|
||||
buildIntervalLimit = PATH_BUILD_RATE;
|
||||
router->router_profiling().MarkPathSuccess(p.get());
|
||||
|
||||
LogInfo(p->Name(), " built latency=", ToString(p->intro.latency));
|
||||
LogInfo(p->name(), " built latency=", ToString(p->intro.latency));
|
||||
m_BuildStats.success++;
|
||||
}
|
||||
|
||||
@ -479,24 +516,25 @@ namespace llarp
|
||||
DoPathBuildBackoff();
|
||||
for (const auto& hop : p->hops)
|
||||
{
|
||||
const RouterID router{hop.rc.pubkey};
|
||||
const RouterID rid{hop.rc.pubkey};
|
||||
// look up router and see if it's still on the network
|
||||
router->loop()->call_soon([router, r = router]() {
|
||||
LogInfo("looking up ", router, " because of path build timeout");
|
||||
router->loop()->call_soon([rid, r = router]() {
|
||||
log::info(path_cat, "Looking up RouterID {} due to path build timeout", rid);
|
||||
r->rc_lookup_handler().get_rc(
|
||||
router,
|
||||
[r](const auto& router, const auto* rc, auto result) {
|
||||
rid,
|
||||
[r](const auto& rid, const auto* rc, auto result) {
|
||||
if (result == RCRequestResult::Success && rc != nullptr)
|
||||
{
|
||||
LogInfo("refreshed rc for ", router);
|
||||
log::info(path_cat, "Refreshed RouterContact for {}", rid);
|
||||
;
|
||||
r->node_db()->PutIfNewer(*rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove all connections to this router as it's probably not registered anymore
|
||||
LogWarn("removing router ", router, " because of path build timeout");
|
||||
r->link_manager().deregister_peer(router);
|
||||
r->node_db()->Remove(router);
|
||||
log::warning(path_cat, "Removing router {} due to path build timeout", rid);
|
||||
r->link_manager().deregister_peer(rid);
|
||||
r->node_db()->Remove(rid);
|
||||
}
|
||||
},
|
||||
true);
|
||||
|
@ -10,35 +10,6 @@
|
||||
|
||||
namespace llarp::path
|
||||
{
|
||||
|
||||
/// configuration for a single hop when building a path
|
||||
struct PathHopConfig
|
||||
{
|
||||
/// path id
|
||||
PathID_t txID, rxID;
|
||||
// router contact of router
|
||||
RouterContact rc;
|
||||
// temp public encryption key
|
||||
SecretKey commkey;
|
||||
/// shared secret at this hop
|
||||
SharedSecret shared;
|
||||
/// hash of shared secret used for nonce mutation
|
||||
ShortHash nonceXOR;
|
||||
/// next hop's router id
|
||||
RouterID upstream;
|
||||
/// nonce for key exchange
|
||||
TunnelNonce nonce;
|
||||
// lifetime
|
||||
llarp_time_t lifetime = DEFAULT_LIFETIME;
|
||||
|
||||
util::StatusObject
|
||||
ExtractStatus() const;
|
||||
};
|
||||
|
||||
// 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
|
||||
@ -81,10 +52,10 @@ namespace llarp::path
|
||||
DoPathBuildBackoff();
|
||||
|
||||
void
|
||||
SetupHopKeys(path::PathHopConfig& hop, const RouterID& nextHop);
|
||||
setup_hop_keys(path::PathHopConfig& hop, const RouterID& nextHop);
|
||||
|
||||
std::string
|
||||
CreateHopInfoFrame(const path::PathHopConfig& hop);
|
||||
create_hop_info_frame(const path::PathHopConfig& hop);
|
||||
|
||||
public:
|
||||
Router* const router;
|
||||
|
@ -233,7 +233,7 @@ namespace llarp::path
|
||||
auto itr = m_Paths.begin();
|
||||
while (itr != m_Paths.end())
|
||||
{
|
||||
if (itr->second->IsEndpoint(ep, id))
|
||||
if (itr->second->is_endpoint(ep, id))
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
@ -290,7 +290,7 @@ namespace llarp::path
|
||||
PathSet::AddPath(Path_ptr path)
|
||||
{
|
||||
Lock_t l(m_PathsMutex);
|
||||
const auto upstream = path->Upstream(); // RouterID
|
||||
const auto upstream = path->upstream(); // RouterID
|
||||
const auto RXID = path->RXID(); // PathID
|
||||
if (not m_Paths.emplace(std::make_pair(upstream, RXID), path).second)
|
||||
{
|
||||
|
@ -90,25 +90,20 @@ namespace llarp::path
|
||||
if (!IsEndpoint(r->pubkey()))
|
||||
return false;
|
||||
|
||||
std::array<byte_t, MAX_LINK_MSG_SIZE - 128> tmp;
|
||||
llarp_buffer_t buf(tmp);
|
||||
|
||||
auto bte = msg.bt_encode();
|
||||
buf.write(bte.begin(), bte.end());
|
||||
auto buf = msg.bt_encode();
|
||||
|
||||
TunnelNonce N;
|
||||
N.Randomize();
|
||||
buf.sz = buf.cur - buf.base;
|
||||
// pad to nearest MESSAGE_PAD_SIZE bytes
|
||||
auto dlt = buf.sz % PAD_SIZE;
|
||||
auto dlt = buf.size() % PAD_SIZE;
|
||||
|
||||
if (dlt)
|
||||
{
|
||||
dlt = PAD_SIZE - dlt;
|
||||
// randomize padding
|
||||
CryptoManager::instance()->randbytes(buf.cur, dlt);
|
||||
buf.sz += dlt;
|
||||
CryptoManager::instance()->randbytes(reinterpret_cast<uint8_t*>(buf.data()), dlt);
|
||||
}
|
||||
buf.cur = buf.base;
|
||||
|
||||
return HandleDownstream(buf, N, r);
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ namespace llarp
|
||||
}
|
||||
|
||||
void
|
||||
Router::PersistSessionUntil(const RouterID& remote, llarp_time_t until)
|
||||
Router::persist_connection_until(const RouterID& remote, llarp_time_t until)
|
||||
{
|
||||
_link_manager.set_conn_persist(remote, until);
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ namespace llarp
|
||||
StopLinks();
|
||||
|
||||
void
|
||||
PersistSessionUntil(const RouterID& remote, llarp_time_t until);
|
||||
persist_connection_until(const RouterID& remote, llarp_time_t until);
|
||||
|
||||
bool
|
||||
EnsureIdentity();
|
||||
|
@ -711,7 +711,7 @@ namespace llarp
|
||||
{
|
||||
for (size_t i = 0; i < INTROSET_REQS_PER_RELAY; ++i)
|
||||
{
|
||||
router()->send_control_message(path->Upstream(), "publish_intro", introset.bt_encode());
|
||||
router()->send_control_message(path->upstream(), "publish_intro", introset.bt_encode());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ namespace llarp::service
|
||||
llarp_time_t expiry = 0s;
|
||||
uint64_t version = llarp::constants::proto_version;
|
||||
|
||||
Introduction() = default;
|
||||
Introduction(std::string buf);
|
||||
|
||||
util::StatusObject
|
||||
|
@ -32,7 +32,7 @@ namespace llarp::service
|
||||
path::Path_ptr path, PathID_t from, std::shared_ptr<ProtocolMessage> self)
|
||||
{
|
||||
if (!self->handler->HandleDataMessage(path, from, self))
|
||||
LogWarn("failed to handle data message from ", path->Name());
|
||||
LogWarn("failed to handle data message from ", path->name());
|
||||
}
|
||||
|
||||
bool
|
||||
|
Loading…
Reference in New Issue
Block a user