path control message response status changes

change path control message inner message response to take just a
string, which will be a bt-encoded response with an early key for
status.  If there is a timeout we pass a bt dict that only has that as
the status, else the response we de-onioned should have either an OK
status or some other error.

change messages to use new status key

correctly call Path::EnterState on path build response
pull/2216/head
Thomas Winget 7 months ago
parent e7632d0a30
commit abb2f63ec6

@ -124,6 +124,8 @@ namespace llarp
} // namespace link } // namespace link
using messages::serialize_response;
void void
LinkManager::for_each_connection(std::function<void(link::Connection&)> func) LinkManager::for_each_connection(std::function<void(link::Connection&)> func)
{ {
@ -534,7 +536,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
respond(serialize_response({{"STATUS", FindNameMessage::EXCEPTION}})); respond(serialize_response({{messages::STATUS_KEY, FindNameMessage::EXCEPTION}}));
} }
_router.rpc_client()->lookup_ons_hash( _router.rpc_client()->lookup_ons_hash(
@ -544,7 +546,7 @@ namespace llarp
if (maybe) if (maybe)
respond(serialize_response({{"NAME", maybe->ciphertext}})); respond(serialize_response({{"NAME", maybe->ciphertext}}));
else else
respond(serialize_response({{"STATUS", FindNameMessage::NOT_FOUND}})); respond(serialize_response({{messages::STATUS_KEY, FindNameMessage::NOT_FOUND}}));
}); });
} }
@ -562,7 +564,7 @@ namespace llarp
try try
{ {
oxenc::bt_dict_consumer btdc{m.body()}; oxenc::bt_dict_consumer btdc{m.body()};
payload = btdc.require<std::string>(m ? "NAME" : "STATUS"); payload = btdc.require<std::string>(m ? "NAME" : messages::STATUS_KEY);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
@ -609,7 +611,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
respond(serialize_response({{"STATUS", FindRouterMessage::EXCEPTION}, {"TARGET", ""}})); respond(serialize_response({{messages::STATUS_KEY, FindRouterMessage::EXCEPTION}, {"TARGET", ""}}));
return; return;
} }
@ -640,7 +642,7 @@ namespace llarp
} }
respond( respond(
serialize_response({{"STATUS", FindRouterMessage::RETRY_EXP}, {"TARGET", neighbors}})); serialize_response({{messages::STATUS_KEY, FindRouterMessage::RETRY_EXP}, {"TARGET", neighbors}}));
} }
else else
{ {
@ -680,14 +682,14 @@ namespace llarp
else else
{ {
respond(serialize_response( respond(serialize_response(
{{"STATUS", FindRouterMessage::RETRY_ITER}, {{messages::STATUS_KEY, FindRouterMessage::RETRY_ITER},
{"TARGET", reinterpret_cast<const char*>(target_addr.data())}})); {"TARGET", reinterpret_cast<const char*>(target_addr.data())}}));
} }
} }
else else
{ {
respond(serialize_response( respond(serialize_response(
{{"STATUS", FindRouterMessage::RETRY_NEW}, {{messages::STATUS_KEY, FindRouterMessage::RETRY_NEW},
{"TARGET", reinterpret_cast<const char*>(closest_rid.data())}})); {"TARGET", reinterpret_cast<const char*>(closest_rid.data())}}));
} }
} }
@ -837,7 +839,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
respond(serialize_response({{"STATUS", PublishIntroMessage::EXCEPTION}})); respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::EXCEPTION}}));
return; return;
} }
@ -848,14 +850,14 @@ namespace llarp
if (not service::EncryptedIntroSet::verify(introset, derived_signing_key, sig)) if (not service::EncryptedIntroSet::verify(introset, derived_signing_key, sig))
{ {
log::error(link_cat, "Received PublishIntroMessage with invalid introset: {}", introset); log::error(link_cat, "Received PublishIntroMessage with invalid introset: {}", introset);
respond(serialize_response({{"STATUS", PublishIntroMessage::INVALID_INTROSET}})); respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::INVALID_INTROSET}}));
return; return;
} }
if (now + service::MAX_INTROSET_TIME_DELTA > signed_at + path::DEFAULT_LIFETIME) if (now + service::MAX_INTROSET_TIME_DELTA > signed_at + path::DEFAULT_LIFETIME)
{ {
log::error(link_cat, "Received PublishIntroMessage with expired introset: {}", introset); log::error(link_cat, "Received PublishIntroMessage with expired introset: {}", introset);
respond(serialize_response({{"STATUS", PublishIntroMessage::EXPIRED}})); respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::EXPIRED}}));
return; return;
} }
@ -865,7 +867,7 @@ namespace llarp
{ {
log::error( log::error(
link_cat, "Received PublishIntroMessage but only know {} nodes", closest_rcs.size()); link_cat, "Received PublishIntroMessage but only know {} nodes", closest_rcs.size());
respond(serialize_response({{"STATUS", PublishIntroMessage::INSUFFICIENT}})); respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::INSUFFICIENT}}));
return; return;
} }
@ -877,7 +879,7 @@ namespace llarp
{ {
log::error( log::error(
link_cat, "Received PublishIntroMessage with invalide relay order: {}", relay_order); link_cat, "Received PublishIntroMessage with invalide relay order: {}", relay_order);
respond(serialize_response({{"STATUS", PublishIntroMessage::INVALID_ORDER}})); respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::INVALID_ORDER}}));
return; return;
} }
@ -894,7 +896,7 @@ namespace llarp
relay_order); relay_order);
_router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)}); _router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)});
respond(serialize_response({{"STATUS", ""}})); respond(serialize_response({{messages::STATUS_KEY, ""}}));
} }
else else
{ {
@ -932,7 +934,7 @@ namespace llarp
log::info(link_cat, "Received PublishIntroMessage for {} (TXID: {}); we are candidate {}"); log::info(link_cat, "Received PublishIntroMessage for {} (TXID: {}); we are candidate {}");
_router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)}); _router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)});
respond(serialize_response({{"STATUS", ""}})); respond(serialize_response({{messages::STATUS_KEY, ""}}));
} }
else else
log::warning( log::warning(
@ -955,7 +957,7 @@ namespace llarp
try try
{ {
oxenc::bt_dict_consumer btdc{m.body()}; oxenc::bt_dict_consumer btdc{m.body()};
payload = btdc.require<std::string>("STATUS"); payload = btdc.require<std::string>(messages::STATUS_KEY);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
@ -1006,7 +1008,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
respond(serialize_response({{"STATUS", FindIntroMessage::EXCEPTION}})); respond(serialize_response({{messages::STATUS_KEY, FindIntroMessage::EXCEPTION}}));
return; return;
} }
@ -1018,7 +1020,7 @@ namespace llarp
{ {
log::warning( log::warning(
link_cat, "Received FindIntroMessage with invalid relay order: {}", relay_order); link_cat, "Received FindIntroMessage with invalid relay order: {}", relay_order);
respond(serialize_response({{"STATUS", FindIntroMessage::INVALID_ORDER}})); respond(serialize_response({{messages::STATUS_KEY, FindIntroMessage::INVALID_ORDER}}));
return; return;
} }
@ -1028,7 +1030,7 @@ namespace llarp
{ {
log::error( log::error(
link_cat, "Received FindIntroMessage but only know {} nodes", closest_rcs.size()); link_cat, "Received FindIntroMessage but only know {} nodes", closest_rcs.size());
respond(serialize_response({{"STATUS", FindIntroMessage::INSUFFICIENT_NODES}})); respond(serialize_response({{messages::STATUS_KEY, FindIntroMessage::INSUFFICIENT_NODES}}));
return; return;
} }
@ -1066,7 +1068,7 @@ namespace llarp
log::warning( log::warning(
link_cat, link_cat,
"Received FindIntroMessage with relayed == false and no local introset entry"); "Received FindIntroMessage with relayed == false and no local introset entry");
respond(serialize_response({{"STATUS", FindIntroMessage::NOT_FOUND}})); respond(serialize_response({{messages::STATUS_KEY, FindIntroMessage::NOT_FOUND}}));
} }
} }
} }
@ -1085,7 +1087,7 @@ namespace llarp
try try
{ {
oxenc::bt_dict_consumer btdc{m.body()}; oxenc::bt_dict_consumer btdc{m.body()};
payload = btdc.require<std::string>((m) ? "INTROSET" : "STATUS"); payload = btdc.require<std::string>((m) ? "INTROSET" : messages::STATUS_KEY);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
@ -1112,7 +1114,7 @@ namespace llarp
if (!_router.path_context().AllowingTransit()) if (!_router.path_context().AllowingTransit())
{ {
log::warning(link_cat, "got path build request when not permitting transit"); log::warning(link_cat, "got path build request when not permitting transit");
m.respond(serialize_response({{"STATUS", PathBuildMessage::NO_TRANSIT}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::NO_TRANSIT}}), true);
return; return;
} }
try try
@ -1142,7 +1144,7 @@ namespace llarp
shared.data(), other_pubkey.data(), _router.pubkey(), inner_nonce.data())) shared.data(), other_pubkey.data(), _router.pubkey(), inner_nonce.data()))
{ {
log::info(link_cat, "DH server initialization failed during path build"); log::info(link_cat, "DH server initialization failed during path build");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true);
return; return;
} }
@ -1155,14 +1157,14 @@ namespace llarp
shared)) shared))
{ {
log::error(link_cat, "HMAC failed on path build request"); log::error(link_cat, "HMAC failed on path build request");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true);
return; return;
} }
if (!std::equal( if (!std::equal(
digest.begin(), digest.end(), reinterpret_cast<const unsigned char*>(hash.data()))) digest.begin(), digest.end(), reinterpret_cast<const unsigned char*>(hash.data())))
{ {
log::info(link_cat, "HMAC mismatch on path build request"); log::info(link_cat, "HMAC mismatch on path build request");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true);
return; return;
} }
@ -1174,7 +1176,7 @@ namespace llarp
outer_nonce.data())) outer_nonce.data()))
{ {
log::info(link_cat, "Decrypt failed on path build request"); log::info(link_cat, "Decrypt failed on path build request");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true);
return; return;
} }
@ -1195,7 +1197,7 @@ namespace llarp
if (frame.empty()) if (frame.empty())
{ {
log::info(link_cat, "Path build request received invalid frame"); log::info(link_cat, "Path build request received invalid frame");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_FRAMES}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_FRAMES}}), true);
return; return;
} }
@ -1212,7 +1214,7 @@ namespace llarp
if (hop_info.txID.IsZero() || hop_info.rxID.IsZero()) if (hop_info.txID.IsZero() || hop_info.rxID.IsZero())
{ {
log::warning(link_cat, "Invalid PathID; PathIDs must be non-zero"); log::warning(link_cat, "Invalid PathID; PathIDs must be non-zero");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_PATHID}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_PATHID}}), true);
return; return;
} }
@ -1221,7 +1223,7 @@ namespace llarp
if (_router.path_context().HasTransitHop(hop_info)) if (_router.path_context().HasTransitHop(hop_info))
{ {
log::warning(link_cat, "Invalid PathID; PathIDs must be unique"); log::warning(link_cat, "Invalid PathID; PathIDs must be unique");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_PATHID}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_PATHID}}), true);
return; return;
} }
@ -1229,7 +1231,7 @@ namespace llarp
hop->pathKey.data(), other_pubkey.data(), _router.pubkey(), inner_nonce.data())) hop->pathKey.data(), other_pubkey.data(), _router.pubkey(), inner_nonce.data()))
{ {
log::warning(link_cat, "DH failed during path build."); log::warning(link_cat, "DH failed during path build.");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true);
return; return;
} }
// generate hash of hop key for nonce mutation // generate hash of hop key for nonce mutation
@ -1241,7 +1243,7 @@ namespace llarp
if (hop->lifetime >= path::DEFAULT_LIFETIME) if (hop->lifetime >= path::DEFAULT_LIFETIME)
{ {
log::warning(link_cat, "Path build attempt with too long of a lifetime."); log::warning(link_cat, "Path build attempt with too long of a lifetime.");
m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_LIFETIME}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_LIFETIME}}), true);
return; return;
} }
@ -1253,7 +1255,7 @@ namespace llarp
hop->terminal_hop = true; hop->terminal_hop = true;
// we are terminal hop and everything is okay // we are terminal hop and everything is okay
_router.path_context().PutTransitHop(hop); _router.path_context().PutTransitHop(hop);
m.respond(serialize_response({{"STATUS", PathBuildMessage::OK}}), false); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::OK}}), false);
return; return;
} }
@ -1285,7 +1287,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
m.respond(serialize_response({{"STATUS", PathBuildMessage::EXCEPTION}}), true); m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::EXCEPTION}}), true);
return; return;
} }
} }
@ -1300,7 +1302,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
// m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); // m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true);
return; return;
} }
} }
@ -1315,7 +1317,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true);
return; return;
} }
} }
@ -1330,7 +1332,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
// m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); // m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true);
return; return;
} }
} }
@ -1345,7 +1347,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true);
return; return;
} }
} }
@ -1360,7 +1362,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
// m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); // m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true);
return; return;
} }
} }
@ -1375,7 +1377,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true);
return; return;
} }
} }
@ -1390,7 +1392,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true);
return; return;
} }
} }
@ -1429,7 +1431,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
m.respond(serialize_response({{"STATUS", ObtainExitMessage::EXCEPTION}}), true); m.respond(serialize_response({{messages::STATUS_KEY, ObtainExitMessage::EXCEPTION}}), true);
throw; throw;
} }
} }
@ -1497,7 +1499,7 @@ namespace llarp
{ {
(exit_ep->UpdateLocalPath(transit_hop->info.rxID)) (exit_ep->UpdateLocalPath(transit_hop->info.rxID))
? m.respond(UpdateExitMessage::sign_and_serialize_response(_router.identity(), tx_id)) ? m.respond(UpdateExitMessage::sign_and_serialize_response(_router.identity(), tx_id))
: m.respond(serialize_response({{"STATUS", UpdateExitMessage::UPDATE_FAILED}}), true); : m.respond(serialize_response({{messages::STATUS_KEY, UpdateExitMessage::UPDATE_FAILED}}), true);
} }
// If we fail to verify the message, no-op // If we fail to verify the message, no-op
} }
@ -1505,7 +1507,7 @@ namespace llarp
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
m.respond(serialize_response({{"STATUS", UpdateExitMessage::EXCEPTION}}), true); m.respond(serialize_response({{messages::STATUS_KEY, UpdateExitMessage::EXCEPTION}}), true);
return; return;
} }
} }
@ -1584,12 +1586,12 @@ namespace llarp
} }
} }
m.respond(serialize_response({{"STATUS", CloseExitMessage::UPDATE_FAILED}}), true); m.respond(serialize_response({{messages::STATUS_KEY, CloseExitMessage::UPDATE_FAILED}}), true);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(link_cat, "Exception: {}", e.what()); log::warning(link_cat, "Exception: {}", e.what());
m.respond(serialize_response({{"STATUS", CloseExitMessage::EXCEPTION}}), true); m.respond(serialize_response({{messages::STATUS_KEY, CloseExitMessage::EXCEPTION}}), true);
return; return;
} }
} }

@ -4,6 +4,7 @@
#include <llarp/constants/path.hpp> #include <llarp/constants/path.hpp>
#include <llarp/crypto/crypto.hpp> #include <llarp/crypto/crypto.hpp>
#include <llarp/messages/common.hpp>
#include <llarp/path/transit_hop.hpp> #include <llarp/path/transit_hop.hpp>
#include <llarp/router/rc_lookup_handler.hpp> #include <llarp/router/rc_lookup_handler.hpp>
#include <llarp/router_contact.hpp> #include <llarp/router_contact.hpp>
@ -27,12 +28,6 @@ namespace llarp
{ {
struct LinkManager; struct LinkManager;
inline std::string
serialize_response(oxenc::bt_dict supplement = {})
{
return oxenc::bt_serialize(supplement);
}
namespace link namespace link
{ {
struct Connection; struct Connection;

@ -18,6 +18,24 @@ namespace
namespace llarp namespace llarp
{ {
namespace messages
{
inline std::string
serialize_response(oxenc::bt_dict supplement = {})
{
return oxenc::bt_serialize(supplement);
}
// ideally STATUS is the first key in a bt-dict, so use a single, early ascii char
inline auto STATUS_KEY = "!"s;
inline auto STATUS_OK = "OK"sv;
inline auto STATUS_TIMEOUT = "TIMEOUT"sv;
inline auto STATUS_ERROR = "ERROR"sv; // generic, unknown error (e.g. onion decrypt throw)
inline auto TIMEOUT_BT_DICT = serialize_response({{STATUS_KEY, STATUS_TIMEOUT}});
inline auto ERROR_BT_DICT = serialize_response({{STATUS_KEY, STATUS_ERROR}});
} // namespace llarp::messages
/// abstract base class for serialized messages /// abstract base class for serialized messages
struct AbstractSerializable struct AbstractSerializable
{ {

@ -59,7 +59,7 @@ namespace llarp
/// a timeout flag (if set, response string will be empty) /// a timeout flag (if set, response string will be empty)
virtual bool virtual bool
send_path_control_message( send_path_control_message(
std::string method, std::string body, std::function<void(std::string, bool)> func) = 0; std::string method, std::string body, std::function<void(std::string)> func) = 0;
/// send routing message and increment sequence number /// send routing message and increment sequence number
virtual bool virtual bool

@ -49,7 +49,7 @@ namespace llarp::path
bool bool
Path::obtain_exit( Path::obtain_exit(
SecretKey sk, uint64_t flag, std::string tx_id, std::function<void(std::string, bool)> func) SecretKey sk, uint64_t flag, std::string tx_id, std::function<void(std::string)> func)
{ {
return send_path_control_message( return send_path_control_message(
"obtain_exit", "obtain_exit",
@ -58,7 +58,7 @@ namespace llarp::path
} }
bool bool
Path::close_exit(SecretKey sk, std::string tx_id, std::function<void(std::string, bool)> func) Path::close_exit(SecretKey sk, std::string tx_id, std::function<void(std::string)> func)
{ {
return send_path_control_message( return send_path_control_message(
"close_exit", CloseExitMessage::sign_and_serialize(sk, std::move(tx_id)), std::move(func)); "close_exit", CloseExitMessage::sign_and_serialize(sk, std::move(tx_id)), std::move(func));
@ -69,21 +69,21 @@ namespace llarp::path
const dht::Key_t& location, const dht::Key_t& location,
bool is_relayed, bool is_relayed,
uint64_t order, uint64_t order,
std::function<void(std::string, bool)> func) std::function<void(std::string)> func)
{ {
return send_path_control_message( return send_path_control_message(
"find_intro", FindIntroMessage::serialize(location, is_relayed, order), std::move(func)); "find_intro", FindIntroMessage::serialize(location, is_relayed, order), std::move(func));
} }
bool bool
Path::find_name(std::string name, std::function<void(std::string, bool)> func) Path::find_name(std::string name, std::function<void(std::string)> func)
{ {
return send_path_control_message( return send_path_control_message(
"find_name", FindNameMessage::serialize(std::move(name)), std::move(func)); "find_name", FindNameMessage::serialize(std::move(name)), std::move(func));
} }
bool bool
Path::find_router(std::string rid, std::function<void(std::string, bool)> func) Path::find_router(std::string rid, std::function<void(std::string)> func)
{ {
return send_path_control_message( return send_path_control_message(
"find_router", FindRouterMessage::serialize(std::move(rid), false, false), std::move(func)); "find_router", FindRouterMessage::serialize(std::move(rid), false, false), std::move(func));
@ -91,7 +91,7 @@ namespace llarp::path
bool bool
Path::send_path_control_message( Path::send_path_control_message(
std::string method, std::string body, std::function<void(std::string, bool)> func) std::string method, std::string body, std::function<void(std::string)> func)
{ {
oxenc::bt_dict_producer btdp; oxenc::bt_dict_producer btdp;
btdp.append("BODY", body); btdp.append("BODY", body);
@ -121,13 +121,16 @@ namespace llarp::path
std::move(outer_payload), std::move(outer_payload),
[response_cb = std::move(func), weak = weak_from_this()](oxen::quic::message m) { [response_cb = std::move(func), weak = weak_from_this()](oxen::quic::message m) {
auto self = weak.lock(); auto self = weak.lock();
if (not self) // TODO: do we want to allow empty callback here?
if ((not self) or (not response_cb))
return; return;
if (m.timed_out) if (m.timed_out)
{ {
response_cb(""s, true); response_cb(messages::TIMEOUT_BT_DICT);
return; return;
} }
TunnelNonce nonce{}; TunnelNonce nonce{};
std::string payload; std::string payload;
try try
@ -139,9 +142,11 @@ namespace llarp::path
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(path_cat, "Error parsing onion response: {}", e.what()); log::warning(path_cat, "Error parsing path control message response: {}", e.what());
response_cb(messages::ERROR_BT_DICT);
return; return;
} }
for (const auto& hop : self->hops) for (const auto& hop : self->hops)
{ {
nonce = crypto::onion( nonce = crypto::onion(
@ -155,7 +160,7 @@ namespace llarp::path
// TODO: should we do anything (even really simple) here to check if the decrypted // TODO: should we do anything (even really simple) here to check if the decrypted
// response is sensible (e.g. is a bt dict)? Parsing and handling of the // response is sensible (e.g. is a bt dict)? Parsing and handling of the
// contents (errors or otherwise) is the currently responsibility of the callback. // contents (errors or otherwise) is the currently responsibility of the callback.
response_cb(payload, false); response_cb(payload);
}); });
} }
@ -242,6 +247,8 @@ namespace llarp::path
void void
Path::EnterState(PathStatus st, llarp_time_t now) Path::EnterState(PathStatus st, llarp_time_t now)
{ {
if (now == 0s) now = router.now();
if (st == ePathFailed) if (st == ePathFailed)
{ {
_status = st; _status = st;

@ -143,7 +143,7 @@ namespace llarp
} }
void void
EnterState(PathStatus st, llarp_time_t now); EnterState(PathStatus st, llarp_time_t now = 0s);
llarp_time_t llarp_time_t
ExpireTime() const ExpireTime() const
@ -186,28 +186,28 @@ namespace llarp
Tick(llarp_time_t now, Router* r); Tick(llarp_time_t now, Router* r);
bool bool
find_name(std::string name, std::function<void(std::string, bool)> func = nullptr); find_name(std::string name, std::function<void(std::string)> func = nullptr);
bool bool
find_router(std::string rid, std::function<void(std::string, bool)> func = nullptr); find_router(std::string rid, std::function<void(std::string)> func = nullptr);
bool bool
find_intro( find_intro(
const dht::Key_t& location, const dht::Key_t& location,
bool is_relayed = false, bool is_relayed = false,
uint64_t order = 0, uint64_t order = 0,
std::function<void(std::string, bool)> func = nullptr); std::function<void(std::string)> func = nullptr);
bool bool
close_exit( close_exit(
SecretKey sk, std::string tx_id, std::function<void(std::string, bool)> func = nullptr); SecretKey sk, std::string tx_id, std::function<void(std::string)> func = nullptr);
bool bool
obtain_exit( obtain_exit(
SecretKey sk, SecretKey sk,
uint64_t flag, uint64_t flag,
std::string tx_id, std::string tx_id,
std::function<void(std::string, bool)> func = nullptr); std::function<void(std::string)> func = nullptr);
/// sends a control request along a path /// sends a control request along a path
/// ///
@ -221,7 +221,7 @@ namespace llarp
send_path_control_message( send_path_control_message(
std::string method, std::string method,
std::string body, std::string body,
std::function<void(std::string, bool)> func = nullptr) override; std::function<void(std::string)> func = nullptr) override;
bool bool
SendRoutingMessage(std::string payload, Router* r) override; SendRoutingMessage(std::string payload, Router* r) override;

@ -1,5 +1,6 @@
#include "pathbuilder.hpp" #include "pathbuilder.hpp"
#include "llarp/path/pathset.hpp"
#include "path.hpp" #include "path.hpp"
#include "path_context.hpp" #include "path_context.hpp"
@ -462,8 +463,7 @@ namespace llarp
frames.append(dummy); frames.append(dummy);
} }
auto self = GetSelf(); router->path_context().AddOwnPath(GetSelf(), path);
router->path_context().AddOwnPath(self, path);
PathBuildStarted(path); PathBuildStarted(path);
// TODO: // TODO:
@ -471,32 +471,33 @@ namespace llarp
// handle these responses as well as how we store and use Paths as a whole might // handle these responses as well as how we store and use Paths as a whole might
// be worth doing sooner rather than later. Leaving some TODOs below where fail // be worth doing sooner rather than later. Leaving some TODOs below where fail
// and success live. // and success live.
auto response_cb = [self](oxen::quic::message m) { auto response_cb = [path](oxen::quic::message m) {
try try
{ {
if (not m) if (m)
{ {
if (m.timed_out) // TODO: inform success (what this means needs revisiting, badly)
{ path->EnterState(path::ePathEstablished);
log::warning(path_cat, "Path build timed out");
}
else
{
oxenc::bt_dict_consumer d{m.body()};
auto status = d.require<std::string_view>("STATUS");
log::warning(path_cat, "Path build returned failure status: {}", status);
}
// TODO: inform failure (what this means needs revisiting, badly)
return; return;
} }
if (m.timed_out)
// TODO: inform success (what this means needs revisiting, badly) {
log::warning(path_cat, "Path build timed out");
}
else
{
oxenc::bt_dict_consumer d{m.body()};
auto status = d.require<std::string_view>(messages::STATUS_KEY);
log::warning(path_cat, "Path build returned failure status: {}", status);
}
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
log::warning(path_cat, "Failed parsing path build response."); log::warning(path_cat, "Failed parsing path build response.");
// TODO: inform failure (what this means needs revisiting, badly)
} }
// TODO: inform failure (what this means needs revisiting, badly)
path->EnterState(path::ePathFailed);
}; };
if (not router->send_control_message( if (not router->send_control_message(

@ -53,7 +53,7 @@ namespace llarp::path
bool bool
TransitHop::send_path_control_message( TransitHop::send_path_control_message(
std::string, std::string, std::function<void(std::string, bool)>) std::string, std::string, std::function<void(std::string)>)
{ {
return true; return true;
} }

@ -140,7 +140,7 @@ namespace llarp
send_path_control_message( send_path_control_message(
std::string method, std::string method,
std::string body, std::string body,
std::function<void(std::string, bool)> func) override; std::function<void(std::string)> func) override;
// send routing message when end of path // send routing message when end of path
bool bool

@ -202,20 +202,20 @@ namespace llarp::service
// If we fail along the way (e.g. it's a .snode, we can't build a path, or whatever else) then // If we fail along the way (e.g. it's a .snode, we can't build a path, or whatever else) then
// we invoke the resultHandler with an empty vector. // we invoke the resultHandler with an empty vector.
lookup_name( lookup_name(
name, [this, resultHandler, service = std::move(service)](oxen::quic::message m) mutable { name, [this, resultHandler, service = std::move(service)](std::string name_result, bool success) mutable {
if (!m) if (!success)
return resultHandler({}); return resultHandler({});
std::string name; std::string name;
try try
{ {
oxenc::bt_dict_consumer btdc{m.body()}; oxenc::bt_dict_consumer btdc{name_result};
name = btdc.require<std::string>("NAME"); name = btdc.require<std::string>("NAME");
} }
catch (...) catch (...)
{ {
log::warning(link_cat, "Failed to parse find name response!"); log::warning(link_cat, "Failed to parse find name response!");
throw; return resultHandler({});
} }
auto saddr = service::Address(); auto saddr = service::Address();
@ -816,14 +816,18 @@ namespace llarp::service
std::shuffle(chosenpaths.begin(), chosenpaths.end(), llarp::csrng); std::shuffle(chosenpaths.begin(), chosenpaths.end(), llarp::csrng);
chosenpaths.resize(std::min(paths.size(), MAX_ONS_LOOKUP_ENDPOINTS)); chosenpaths.resize(std::min(paths.size(), MAX_ONS_LOOKUP_ENDPOINTS));
auto response_cb = [func = std::move(func)](std::string resp, bool timeout) { // TODO: only want one successful response to call the callback, or failed if all fail
if (timeout) auto response_cb = [func = std::move(func)](std::string resp) {
func(""s, false);
std::string name{}; std::string name{};
try try
{ {
oxenc::bt_dict_consumer btdc{resp}; oxenc::bt_dict_consumer btdc{resp};
auto status = btdc.require<std::string_view>(messages::STATUS_KEY);
if (status != messages::STATUS_OK)
{
log::info(link_cat, "Error on ONS lookup: {}", status);
func(""s, false);
}
name = btdc.require<std::string>("NAME"); name = btdc.require<std::string>("NAME");
} }
catch (...) catch (...)
@ -1354,9 +1358,9 @@ namespace llarp::service
for (const auto& path : paths) for (const auto& path : paths)
{ {
path->find_intro( path->find_intro(
location, false, 0, [this, hook, got_it](std::string resp, bool timeout) mutable { location, false, 0, [this, hook, got_it](std::string resp) mutable {
// asking many, use only first successful // asking many, use only first successful
if (timeout or *got_it) if (*got_it)
return; return;
std::string introset; std::string introset;
@ -1364,6 +1368,12 @@ namespace llarp::service
try try
{ {
oxenc::bt_dict_consumer btdc{resp}; oxenc::bt_dict_consumer btdc{resp};
auto status = btdc.require<std::string_view>(messages::STATUS_KEY);
if (status != messages::STATUS_OK)
{
log::info(link_cat, "Error in find intro set response: {}", status);
return;
}
introset = btdc.require<std::string>("INTROSET"); introset = btdc.require<std::string>("INTROSET");
} }
catch (...) catch (...)

@ -157,6 +157,7 @@ namespace llarp::service
return "OBContext:" + current_intro.address_keys.Addr().ToString(); return "OBContext:" + current_intro.address_keys.Addr().ToString();
} }
// TODO: it seems a lot of this logic is duplicated in service/endpoint
void void
OutboundContext::UpdateIntroSet() OutboundContext::UpdateIntroSet()
{ {
@ -173,7 +174,7 @@ namespace llarp::service
for (const auto& path : paths) for (const auto& path : paths)
{ {
path->find_intro(location, false, relayOrder, [this](std::string resp, bool timeout) mutable { path->find_intro(location, false, relayOrder, [this](std::string resp) mutable {
if (marked_bad) if (marked_bad)
{ {
log::info(link_cat, "Outbound context has been marked bad (whatever that means)"); log::info(link_cat, "Outbound context has been marked bad (whatever that means)");
@ -182,14 +183,17 @@ namespace llarp::service
updatingIntroSet = false; updatingIntroSet = false;
if (timeout)
return;
// TODO: this parsing is probably elsewhere, may need DRYed // TODO: this parsing is probably elsewhere, may need DRYed
std::string introset; std::string introset;
try try
{ {
oxenc::bt_dict_consumer btdc{resp}; oxenc::bt_dict_consumer btdc{resp};
auto status = btdc.require<std::string_view>(messages::STATUS_KEY);
if (status != messages::STATUS_OK)
{
log::info(link_cat, "Error in find intro set response: {}", status);
return;
}
introset = btdc.require<std::string>("INTROSET"); introset = btdc.require<std::string>("INTROSET");
} }
catch (...) catch (...)
@ -539,10 +543,9 @@ namespace llarp::service
ex->msg.proto = ProtocolType::Auth; ex->msg.proto = ProtocolType::Auth;
ex->hook = [this, path, cb = std::move(func)](auto frame) mutable { ex->hook = [this, path, cb = std::move(func)](auto frame) mutable {
auto hook = [&, frame, path](std::string resp, bool timeout) { auto hook = [&, frame, path](std::string resp) {
// TODO: revisit this // TODO: revisit this
(void)resp; (void)resp;
(void)timeout;
ep.HandleHiddenServiceFrame(path, *frame.get()); ep.HandleHiddenServiceFrame(path, *frame.get());
}; };

Loading…
Cancel
Save