2021-03-09 22:24:35 +00:00
|
|
|
#pragma once
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2023-10-24 13:18:03 +00:00
|
|
|
#include "connection.hpp"
|
|
|
|
|
2024-02-06 15:33:11 +00:00
|
|
|
#include <llarp/address/address.hpp>
|
2023-10-03 20:00:23 +00:00
|
|
|
#include <llarp/constants/path.hpp>
|
2023-10-24 13:18:03 +00:00
|
|
|
#include <llarp/crypto/crypto.hpp>
|
2023-11-06 17:46:42 +00:00
|
|
|
#include <llarp/messages/common.hpp>
|
2023-10-21 03:30:10 +00:00
|
|
|
#include <llarp/path/transit_hop.hpp>
|
2024-01-19 14:11:03 +00:00
|
|
|
#include <llarp/router/router.hpp>
|
2021-03-09 22:24:35 +00:00
|
|
|
#include <llarp/util/compare_ptr.hpp>
|
2023-10-24 13:18:03 +00:00
|
|
|
#include <llarp/util/decaying_hashset.hpp>
|
2023-10-19 21:59:57 +00:00
|
|
|
#include <llarp/util/logging.hpp>
|
|
|
|
#include <llarp/util/priority_queue.hpp>
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2024-01-19 00:47:36 +00:00
|
|
|
#include <oxen/quic.hpp>
|
2024-06-02 18:52:43 +00:00
|
|
|
#include <oxen/quic/format.hpp>
|
2023-10-24 13:18:03 +00:00
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <set>
|
|
|
|
#include <unordered_map>
|
2023-09-14 14:54:51 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
2024-02-01 12:43:43 +00:00
|
|
|
struct LinkManager;
|
|
|
|
class NodeDB;
|
2023-09-15 14:55:32 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
using conn_open_hook = oxen::quic::connection_established_callback;
|
|
|
|
using conn_closed_hook = oxen::quic::connection_closed_callback;
|
|
|
|
using stream_open_hook = oxen::quic::stream_open_callback;
|
|
|
|
using stream_closed_hook = oxen::quic::stream_close_callback;
|
2023-12-04 18:26:58 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
using keep_alive = oxen::quic::opt::keep_alive;
|
|
|
|
using inbound_alpns = oxen::quic::opt::inbound_alpns;
|
|
|
|
using outbound_alpns = oxen::quic::opt::outbound_alpns;
|
2023-12-15 13:52:31 +00:00
|
|
|
|
2024-02-12 13:01:00 +00:00
|
|
|
using static_secret = oxen::quic::opt::static_secret;
|
|
|
|
|
2024-06-13 20:48:30 +00:00
|
|
|
inline const keep_alive RELAY_KEEP_ALIVE{10s};
|
2024-02-01 12:43:43 +00:00
|
|
|
inline const keep_alive CLIENT_KEEP_ALIVE{10s};
|
2023-12-15 13:52:31 +00:00
|
|
|
|
2024-09-16 15:30:37 +00:00
|
|
|
inline constexpr int MIN_CLIENT_ROUTER_CONNS{8};
|
|
|
|
inline constexpr int MAX_CLIENT_ROUTER_CONNS{10};
|
2023-12-20 22:21:10 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
namespace alpns
|
|
|
|
{
|
|
|
|
inline const auto SN_ALPNS = "SERVICE_NODE"_us;
|
|
|
|
inline const auto C_ALPNS = "CLIENT"_us;
|
|
|
|
|
|
|
|
inline const inbound_alpns SERVICE_INBOUND{{SN_ALPNS, C_ALPNS}};
|
|
|
|
inline const outbound_alpns SERVICE_OUTBOUND{{SN_ALPNS}};
|
|
|
|
|
|
|
|
inline const inbound_alpns CLIENT_INBOUND{};
|
|
|
|
inline const outbound_alpns CLIENT_OUTBOUND{{C_ALPNS}};
|
|
|
|
} // namespace alpns
|
|
|
|
|
|
|
|
namespace link
|
|
|
|
{
|
|
|
|
struct Connection;
|
|
|
|
|
|
|
|
struct Endpoint
|
|
|
|
{
|
|
|
|
Endpoint(std::shared_ptr<oxen::quic::Endpoint> ep, LinkManager& lm);
|
|
|
|
|
|
|
|
std::shared_ptr<oxen::quic::Endpoint> endpoint;
|
|
|
|
LinkManager& link_manager;
|
|
|
|
|
|
|
|
/** Connection containers:
|
|
|
|
- service_conns: holds all connections where the remote (from the perspective
|
|
|
|
of the local lokinet instance) is a service node. This means all relay to
|
|
|
|
relay connections are held here; clients will also hold their connections to
|
|
|
|
relays here as well
|
|
|
|
- client_conns: holds all connections wehre the remote is a client. This is only
|
|
|
|
used by service nodes to store their client connections
|
|
|
|
*/
|
|
|
|
std::unordered_map<RouterID, std::shared_ptr<link::Connection>> service_conns;
|
|
|
|
std::unordered_map<RouterID, std::shared_ptr<link::Connection>> client_conns;
|
|
|
|
|
|
|
|
std::shared_ptr<link::Connection> get_conn(const RouterID&) const;
|
|
|
|
|
|
|
|
std::shared_ptr<link::Connection> get_service_conn(const RouterID&) const;
|
|
|
|
|
|
|
|
bool have_conn(const RouterID& remote) const;
|
|
|
|
|
|
|
|
bool have_client_conn(const RouterID& remote) const;
|
2023-12-18 22:15:45 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
bool have_service_conn(const RouterID& remote) const;
|
2023-12-18 22:15:45 +00:00
|
|
|
|
2024-02-02 20:50:23 +00:00
|
|
|
std::tuple<size_t, size_t, size_t, size_t> connection_stats() const;
|
2023-12-18 22:15:45 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
size_t num_client_conns() const;
|
2023-09-15 14:55:32 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
size_t num_router_conns() const;
|
|
|
|
|
|
|
|
template <typename... Opt>
|
2024-08-23 21:38:39 +00:00
|
|
|
bool establish_connection(KeyedAddress remote, RemoteRC rc, Opt&&... opts);
|
2024-02-01 12:43:43 +00:00
|
|
|
|
|
|
|
template <typename... Opt>
|
|
|
|
bool establish_and_send(
|
2024-08-23 21:38:39 +00:00
|
|
|
KeyedAddress remote,
|
|
|
|
RemoteRC rc,
|
2024-02-01 12:43:43 +00:00
|
|
|
std::optional<std::string> endpoint,
|
|
|
|
std::string body,
|
|
|
|
std::function<void(oxen::quic::message m)> func = nullptr,
|
|
|
|
Opt&&... opts);
|
|
|
|
|
|
|
|
void for_each_connection(std::function<void(link::Connection&)> func);
|
|
|
|
|
|
|
|
void close_connection(RouterID rid);
|
|
|
|
|
2024-06-19 12:06:14 +00:00
|
|
|
void close_all();
|
|
|
|
|
2024-03-17 14:02:46 +00:00
|
|
|
private:
|
2024-02-01 12:43:43 +00:00
|
|
|
const bool _is_service_node;
|
|
|
|
};
|
|
|
|
} // namespace link
|
|
|
|
|
|
|
|
struct Router;
|
|
|
|
|
|
|
|
struct LinkManager
|
2023-09-15 14:55:32 +00:00
|
|
|
{
|
2024-03-17 14:02:46 +00:00
|
|
|
public:
|
2024-07-03 16:27:36 +00:00
|
|
|
static std::unique_ptr<LinkManager> make(Router& r);
|
2023-09-15 14:55:32 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
bool send_control_message(
|
|
|
|
const RouterID& remote,
|
|
|
|
std::string endpoint,
|
|
|
|
std::string body,
|
|
|
|
std::function<void(oxen::quic::message)> = nullptr);
|
2023-09-15 14:55:32 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
bool send_data_message(const RouterID& remote, std::string data);
|
2023-12-13 17:41:56 +00:00
|
|
|
|
2024-05-17 12:55:18 +00:00
|
|
|
Router& router() const { return _router; }
|
2023-11-02 12:30:38 +00:00
|
|
|
|
2024-03-17 14:02:46 +00:00
|
|
|
private:
|
2024-07-03 16:27:36 +00:00
|
|
|
explicit LinkManager(Router& r);
|
2023-12-19 11:31:26 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
friend struct link::Endpoint;
|
2024-08-28 21:31:39 +00:00
|
|
|
friend class NodeDB;
|
2023-12-15 17:45:00 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
// sessions to persist -> timestamp to end persist at
|
2024-03-25 13:39:47 +00:00
|
|
|
std::unordered_map<RouterID, std::chrono::milliseconds> persisting_conns;
|
2023-09-15 14:55:32 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
util::DecayingHashSet<RouterID> clients{path::DEFAULT_LIFETIME};
|
2023-12-16 00:04:09 +00:00
|
|
|
|
2024-04-09 12:58:48 +00:00
|
|
|
Router& _router;
|
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
std::shared_ptr<NodeDB> node_db;
|
2023-12-20 22:21:10 +00:00
|
|
|
|
2024-08-23 17:23:21 +00:00
|
|
|
std::shared_ptr<EventTicker> _gossip_ticker;
|
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
oxen::quic::Address addr;
|
2023-09-15 14:55:32 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
const bool _is_service_node;
|
2024-01-07 21:15:55 +00:00
|
|
|
|
2024-04-09 12:58:48 +00:00
|
|
|
// NOTE: DO NOT CHANGE THE ORDER OF THESE THREE OBJECTS
|
|
|
|
// The quic Network must be created prior to the GNUTLS credentials, which are necessary for the creation of the
|
|
|
|
// quic endpoint. These are delegate initialized in the LinkManager constructor sequentially
|
2024-07-03 16:27:36 +00:00
|
|
|
std::unique_ptr<oxen::quic::Network> quic;
|
2024-02-01 12:43:43 +00:00
|
|
|
std::shared_ptr<oxen::quic::GNUTLSCreds> tls_creds;
|
2024-09-13 21:12:54 +00:00
|
|
|
std::shared_ptr<link::Endpoint> ep;
|
2023-09-19 20:09:18 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
std::atomic<bool> is_stopping;
|
|
|
|
|
2024-04-22 20:07:27 +00:00
|
|
|
void handle_path_data_message(bstring dgram);
|
2023-09-19 20:09:18 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
std::shared_ptr<oxen::quic::BTRequestStream> make_control(
|
|
|
|
oxen::quic::connection_interface& ci, const RouterID& rid);
|
2023-09-15 14:55:32 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void on_inbound_conn(oxen::quic::connection_interface& ci);
|
2023-09-14 14:54:51 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void on_outbound_conn(oxen::quic::connection_interface& ci);
|
2023-09-21 14:20:49 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void on_conn_open(oxen::quic::connection_interface& ci);
|
2023-09-21 14:20:49 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void on_conn_closed(oxen::quic::connection_interface& ci, uint64_t ec);
|
2023-09-21 14:20:49 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
std::shared_ptr<oxen::quic::Endpoint> startup_endpoint();
|
2023-10-12 13:43:07 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void register_commands(
|
2024-02-02 20:50:23 +00:00
|
|
|
const std::shared_ptr<oxen::quic::BTRequestStream>& s, const RouterID& rid, bool client_only = false);
|
2023-12-06 21:54:51 +00:00
|
|
|
|
2024-03-17 14:02:46 +00:00
|
|
|
public:
|
2024-08-23 17:23:21 +00:00
|
|
|
void start_tickers();
|
|
|
|
|
2024-05-17 12:55:18 +00:00
|
|
|
const oxen::quic::Address& local() { return addr; }
|
2023-09-18 21:50:07 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void gossip_rc(const RouterID& last_sender, const RemoteRC& rc);
|
2023-09-18 21:50:07 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void handle_gossip_rc(oxen::quic::message m);
|
2023-09-18 21:50:07 +00:00
|
|
|
|
2024-02-02 20:50:23 +00:00
|
|
|
void fetch_rcs(const RouterID& source, std::string payload, std::function<void(oxen::quic::message m)> func);
|
2023-09-18 21:50:07 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void handle_fetch_rcs(oxen::quic::message m);
|
2023-09-18 21:50:07 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void fetch_router_ids(
|
2024-02-02 20:50:23 +00:00
|
|
|
const RouterID& via, std::string payload, std::function<void(oxen::quic::message m)> func);
|
2023-09-18 21:50:07 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void handle_fetch_router_ids(oxen::quic::message m);
|
2023-12-18 22:15:45 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void fetch_bootstrap_rcs(
|
2024-02-02 20:50:23 +00:00
|
|
|
const RemoteRC& source, std::string payload, std::function<void(oxen::quic::message m)> func);
|
2023-09-18 21:50:07 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void handle_fetch_bootstrap_rcs(oxen::quic::message m);
|
2023-09-21 14:20:49 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
bool have_connection_to(const RouterID& remote) const;
|
2023-12-19 11:31:26 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
bool have_service_connection_to(const RouterID& remote) const;
|
2023-12-11 15:08:02 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
bool have_client_connection_to(const RouterID& remote) const;
|
2023-12-19 11:31:26 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void test_reachability(const RouterID& rid, conn_open_hook, conn_closed_hook);
|
2023-09-18 21:50:07 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void connect_to(const RemoteRC& rc, conn_open_hook = nullptr, conn_closed_hook = nullptr);
|
2023-09-19 20:09:18 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void connect_and_send(
|
|
|
|
const RouterID& router,
|
|
|
|
std::optional<std::string> endpoint,
|
|
|
|
std::string body,
|
|
|
|
std::function<void(oxen::quic::message m)> func = nullptr);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void close_connection(RouterID rid);
|
2023-09-27 14:09:48 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void stop();
|
2023-09-19 20:09:18 +00:00
|
|
|
|
2024-07-03 16:27:36 +00:00
|
|
|
void close_all_links();
|
|
|
|
|
2024-03-25 13:39:47 +00:00
|
|
|
void set_conn_persist(const RouterID& remote, std::chrono::milliseconds until);
|
2023-09-19 20:09:18 +00:00
|
|
|
|
2024-02-02 20:50:23 +00:00
|
|
|
std::tuple<size_t, size_t, size_t, size_t> connection_stats() const;
|
2023-11-15 02:53:19 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
size_t get_num_connected_routers() const;
|
2023-11-15 02:53:19 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
size_t get_num_connected_clients() const;
|
2023-11-17 07:41:42 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
bool is_service_node() const;
|
2023-11-17 07:41:42 +00:00
|
|
|
|
2024-03-25 13:39:47 +00:00
|
|
|
void check_persisting_conns(std::chrono::milliseconds now);
|
2023-11-25 00:40:51 +00:00
|
|
|
|
2024-04-12 15:20:42 +00:00
|
|
|
nlohmann::json extract_status() const;
|
2023-11-25 00:40:51 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
void for_each_connection(std::function<void(link::Connection&)> func);
|
2023-11-30 21:53:41 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
// Attempts to connect to a number of random routers.
|
|
|
|
//
|
|
|
|
// This will try to connect to *up to* num_conns routers, but will not
|
|
|
|
// check if we already have a connection to any of the random set, as making
|
|
|
|
// that thread safe would be slow...I think.
|
2024-09-18 22:24:09 +00:00
|
|
|
void connect_to_random(size_t num_conns);
|
2024-02-01 12:43:43 +00:00
|
|
|
|
|
|
|
/// always maintain this many client connections to other routers
|
|
|
|
int client_router_connections = 4;
|
|
|
|
|
2024-03-17 14:02:46 +00:00
|
|
|
private:
|
2024-02-01 12:43:43 +00:00
|
|
|
// DHT messages
|
2024-03-25 13:39:47 +00:00
|
|
|
void handle_resolve_ons(std::string_view body, std::function<void(std::string)> respond); // relay
|
2024-02-02 20:50:23 +00:00
|
|
|
void handle_find_intro(std::string_view body, std::function<void(std::string)> respond); // relay
|
|
|
|
void handle_publish_intro(std::string_view body, std::function<void(std::string)> respond); // relay
|
2024-01-07 21:15:55 +00:00
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
// Path messages
|
|
|
|
void handle_path_build(oxen::quic::message, const RouterID& from); // relay
|
|
|
|
void handle_path_latency(oxen::quic::message); // relay
|
|
|
|
void handle_path_transfer(oxen::quic::message); // relay
|
|
|
|
|
|
|
|
// Exit messages
|
|
|
|
void handle_obtain_exit(oxen::quic::message); // relay
|
|
|
|
void handle_update_exit(oxen::quic::message); // relay
|
|
|
|
void handle_close_exit(oxen::quic::message); // relay
|
|
|
|
|
2024-03-25 13:39:47 +00:00
|
|
|
// Sessions
|
|
|
|
void handle_initiate_session(oxen::quic::message);
|
|
|
|
void handle_set_session_tag(oxen::quic::message);
|
|
|
|
void handle_set_session_path(oxen::quic::message);
|
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
// Misc
|
|
|
|
void handle_convo_intro(oxen::quic::message);
|
|
|
|
|
|
|
|
// These requests come over a path (as a "path_control" request),
|
|
|
|
// may or may not need to make a request to another relay,
|
|
|
|
// then respond (onioned) back along the path.
|
|
|
|
std::unordered_map<
|
|
|
|
std::string_view,
|
|
|
|
void (LinkManager::*)(std::string_view body, std::function<void(std::string)> respond)>
|
|
|
|
path_requests = {
|
2024-03-25 13:39:47 +00:00
|
|
|
{"resolve_ons"sv, &LinkManager::handle_resolve_ons},
|
2024-02-01 12:43:43 +00:00
|
|
|
{"publish_intro"sv, &LinkManager::handle_publish_intro},
|
|
|
|
{"find_intro"sv, &LinkManager::handle_find_intro}};
|
|
|
|
|
|
|
|
// Path relaying
|
|
|
|
void handle_path_control(oxen::quic::message, const RouterID& from);
|
|
|
|
|
2024-02-02 20:50:23 +00:00
|
|
|
void handle_inner_request(oxen::quic::message m, std::string payload, std::shared_ptr<path::TransitHop> hop);
|
2024-02-01 12:43:43 +00:00
|
|
|
|
|
|
|
// DHT responses
|
2024-03-25 13:39:47 +00:00
|
|
|
void handle_resolve_ons_response(oxen::quic::message);
|
2024-02-01 12:43:43 +00:00
|
|
|
void handle_find_intro_response(oxen::quic::message);
|
|
|
|
void handle_publish_intro_response(oxen::quic::message);
|
|
|
|
|
|
|
|
// Path responses
|
|
|
|
void handle_path_latency_response(oxen::quic::message);
|
|
|
|
void handle_path_transfer_response(oxen::quic::message);
|
|
|
|
|
|
|
|
// Exit responses
|
|
|
|
void handle_obtain_exit_response(oxen::quic::message);
|
|
|
|
void handle_update_exit_response(oxen::quic::message);
|
|
|
|
void handle_close_exit_response(oxen::quic::message);
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace link
|
2023-09-15 14:55:32 +00:00
|
|
|
{
|
2024-03-18 12:52:01 +00:00
|
|
|
static auto logcat = log::Cat("link_manager");
|
|
|
|
|
2024-02-01 12:43:43 +00:00
|
|
|
template <typename... Opt>
|
|
|
|
bool Endpoint::establish_and_send(
|
2024-08-28 21:31:39 +00:00
|
|
|
KeyedAddress remote,
|
|
|
|
RemoteRC rc,
|
|
|
|
std::optional<std::string> ep,
|
|
|
|
std::string body,
|
|
|
|
std::function<void(oxen::quic::message m)> func,
|
|
|
|
Opt&&... opts)
|
2024-01-19 14:11:03 +00:00
|
|
|
{
|
2024-08-28 21:31:39 +00:00
|
|
|
return link_manager.router().loop()->call_get([&]() {
|
2024-02-01 12:43:43 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
const auto& rid = rc.router_id();
|
|
|
|
const auto& is_control = ep.has_value();
|
2024-06-13 20:48:30 +00:00
|
|
|
const auto us = _is_service_node ? "Relay"s : "Client"s;
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-16 16:02:08 +00:00
|
|
|
log::debug(logcat, "Establishing connection to RID:{}", rid);
|
2024-02-01 12:43:43 +00:00
|
|
|
// add to service conns
|
|
|
|
auto [itr, b] = service_conns.try_emplace(rid, nullptr);
|
|
|
|
|
|
|
|
if (not b)
|
|
|
|
{
|
2024-08-16 16:02:08 +00:00
|
|
|
log::debug(logcat, "ERROR: attempting to establish an already-existing connection");
|
2024-02-02 20:50:23 +00:00
|
|
|
(is_control)
|
|
|
|
? itr->second->control_stream->command(std::move(*ep), std::move(body), std::move(func))
|
|
|
|
: itr->second->conn->send_datagram(std::move(body));
|
2024-02-01 12:43:43 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto conn_interface = endpoint->connect(
|
|
|
|
remote,
|
|
|
|
link_manager.tls_creds,
|
2024-06-13 20:48:30 +00:00
|
|
|
_is_service_node ? RELAY_KEEP_ALIVE : CLIENT_KEEP_ALIVE,
|
2024-02-01 12:43:43 +00:00
|
|
|
std::forward<Opt>(opts)...);
|
|
|
|
|
|
|
|
// auto
|
2024-08-28 21:31:39 +00:00
|
|
|
auto control_stream = conn_interface->template open_stream<oxen::quic::BTRequestStream>(
|
|
|
|
[](oxen::quic::Stream&, uint64_t error_code) {
|
|
|
|
log::warning(logcat, "BTRequestStream closed unexpectedly (ec:{})", error_code);
|
|
|
|
});
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-06-13 20:48:30 +00:00
|
|
|
link_manager.register_commands(control_stream, rid, not _is_service_node);
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-16 16:02:08 +00:00
|
|
|
log::debug(
|
2024-02-01 12:43:43 +00:00
|
|
|
logcat,
|
|
|
|
"{} dispatching {} on outbound connection to remote (rid:{})",
|
|
|
|
us,
|
2024-06-13 20:48:30 +00:00
|
|
|
is_control ? "control message (ep:{})"_format(*ep) : "data message",
|
2024-02-01 12:43:43 +00:00
|
|
|
rid);
|
|
|
|
|
2024-02-02 20:50:23 +00:00
|
|
|
(is_control) ? control_stream->command(std::move(*ep), std::move(body), std::move(func))
|
|
|
|
: conn_interface->send_datagram(std::move(body));
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
itr->second =
|
|
|
|
std::make_shared<link::Connection>(std::move(conn_interface), std::move(control_stream), true);
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-16 16:02:08 +00:00
|
|
|
log::info(logcat, "Outbound connection to RID:{} added to service conns...", rid);
|
2024-02-01 12:43:43 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
2024-03-18 12:52:01 +00:00
|
|
|
log::error(logcat, "Error: failed to establish connection to {}", remote);
|
2024-02-01 12:43:43 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
2024-01-19 14:11:03 +00:00
|
|
|
}
|
2024-02-01 12:43:43 +00:00
|
|
|
|
|
|
|
template <typename... Opt>
|
2024-08-28 21:31:39 +00:00
|
|
|
bool Endpoint::establish_connection(KeyedAddress remote, RemoteRC rc, Opt&&... opts)
|
2024-01-19 14:11:03 +00:00
|
|
|
{
|
2024-08-28 21:31:39 +00:00
|
|
|
return link_manager.router().loop()->call_get([&]() {
|
|
|
|
try
|
|
|
|
{
|
|
|
|
const auto& rid = rc.router_id();
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
log::debug(logcat, "Establishing connection to RID:{}", rid);
|
|
|
|
// add to service conns
|
|
|
|
auto [itr, b] = service_conns.try_emplace(rid, nullptr);
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
if (not b)
|
|
|
|
{
|
|
|
|
log::debug(logcat, "ERROR: attempting to establish an already-existing connection");
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto conn_interface = endpoint->connect(
|
|
|
|
remote,
|
|
|
|
link_manager.tls_creds,
|
|
|
|
_is_service_node ? RELAY_KEEP_ALIVE : CLIENT_KEEP_ALIVE,
|
|
|
|
std::forward<Opt>(opts)...);
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
log::critical(logcat, "Created outbound connection with path: {}", conn_interface->path());
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
auto control_stream = conn_interface->template open_stream<oxen::quic::BTRequestStream>(
|
|
|
|
[](oxen::quic::Stream&, uint64_t error_code) {
|
|
|
|
log::warning(logcat, "BTRequestStream closed unexpectedly (ec:{})", error_code);
|
|
|
|
});
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
link_manager.register_commands(control_stream, rid, not _is_service_node);
|
2024-06-13 20:48:30 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
itr->second =
|
|
|
|
std::make_shared<link::Connection>(std::move(conn_interface), std::move(control_stream), true);
|
2024-02-01 12:43:43 +00:00
|
|
|
|
2024-08-28 21:31:39 +00:00
|
|
|
log::info(logcat, "Outbound connection to RID:{} added to service conns...", rid);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
log::error(logcat, "Error: failed to establish connection to {}", remote);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
2024-01-19 14:11:03 +00:00
|
|
|
}
|
2024-02-01 12:43:43 +00:00
|
|
|
} // namespace link
|
2019-06-26 21:39:29 +00:00
|
|
|
} // namespace llarp
|