diff --git a/external/oxen-libquic b/external/oxen-libquic index c9271e87e..55d81cbbc 160000 --- a/external/oxen-libquic +++ b/external/oxen-libquic @@ -1 +1 @@ -Subproject commit c9271e87eaa2d6bcbdf4e49936fcce2b7bc9e693 +Subproject commit 55d81cbbc7bc5ea3667e87389d8143702731a32a diff --git a/llarp/link/connection.cpp b/llarp/link/connection.cpp index dace3d299..eb16b9174 100644 --- a/llarp/link/connection.cpp +++ b/llarp/link/connection.cpp @@ -3,7 +3,7 @@ namespace llarp::link { Connection::Connection( - std::shared_ptr& c, + const std::shared_ptr& c, std::shared_ptr& s, const RemoteRC& rc) : conn{c}, control_stream{s}, remote_rc{std::move(rc)} diff --git a/llarp/link/connection.hpp b/llarp/link/connection.hpp index 46aef9328..b71a6e9f9 100644 --- a/llarp/link/connection.hpp +++ b/llarp/link/connection.hpp @@ -18,7 +18,7 @@ namespace llarp::link bool remote_is_relay{true}; Connection( - std::shared_ptr& c, + const std::shared_ptr& c, std::shared_ptr& s, const RemoteRC& rc); }; diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 74a7d0ff0..323ee132e 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -175,6 +175,7 @@ namespace llarp if (auto itr = rids_pending_verification.find(other); itr != rids_pending_verification.end()) { + verified_rids[other] = itr->second; rids_pending_verification.erase(itr); result = true; } @@ -351,7 +352,7 @@ namespace llarp const auto& remote_addr = rc.addr(); const auto& rid = rc.router_id(); - rids_pending_verification.insert(rid); + rids_pending_verification[rid] = rc; // TODO: confirm remote end is using the expected pubkey (RouterID). // TODO: ALPN for "client" vs "relay" (could just be set on endpoint creation) @@ -368,13 +369,34 @@ namespace llarp log::warning(quic_cat, "Failed to begin establishing connection to {}", remote_addr); } + void + LinkManager::on_inbound_conn(oxen::quic::connection_interface& ci) + { + const auto& scid = ci.scid(); + RouterID rid{ci.remote_key()}; + + const auto& rc = verified_rids[rid]; + ep.connid_map.emplace(scid, rid); + auto [itr, b] = ep.conns.emplace(rid, nullptr); + + auto control_stream = ci.get_new_stream(); + itr->second = std::make_shared(ci.shared_from_this(), control_stream, rc); + log::critical(logcat, "Successfully configured inbound connection fom {}; storing RC...", rid); + } + // TODO: should we add routes here now that Router::SessionOpen is gone? void LinkManager::on_conn_open(oxen::quic::connection_interface& ci) { _router.loop()->call([this, &conn_interface = ci]() { - const auto& scid = conn_interface.scid(); - const auto& rid = ep.connid_map[scid]; + const auto rid = RouterID{conn_interface.remote_key()}; + const auto& remote = conn_interface.remote(); + + if (conn_interface.is_inbound()) + { + log::critical(logcat, "Inbound connection fom {} (remote:{})", rid, remote); + on_inbound_conn(conn_interface); + } log::critical( logcat, @@ -599,12 +621,15 @@ namespace llarp assert(_router.is_service_node()); const auto& rcs = node_db->get_rcs(); + RemoteRC remote; size_t quantity; try { oxenc::bt_dict_consumer btdc{m.body()}; quantity = btdc.require("quantity"); + btdc.required("local"); + remote = RemoteRC{btdc.consume_dict_consumer()}; } catch (const std::exception& e) { @@ -613,6 +638,8 @@ namespace llarp return; } + node_db->put_rc(remote); + auto rc_size = rcs.size(); auto now = llarp::time_now_ms(); size_t i = 0; diff --git a/llarp/link/link_manager.hpp b/llarp/link/link_manager.hpp index 55bd7d686..b97a6c7a9 100644 --- a/llarp/link/link_manager.hpp +++ b/llarp/link/link_manager.hpp @@ -180,7 +180,10 @@ namespace llarp std::unordered_map pending_conn_msg_queue; // when establishing a connection, the rid of the remote is placed here to be cross- // checked by the tls verification callback - std::set rids_pending_verification; + std::map rids_pending_verification; + // in the interim of verifying an inbound connection and the creation of its link::Connection + // object, we store the rid and rc here + std::map verified_rids; util::DecayingHashSet clients{path::DEFAULT_LIFETIME}; @@ -203,6 +206,9 @@ namespace llarp void recv_control_message(oxen::quic::message msg); + void + on_inbound_conn(oxen::quic::connection_interface& ci); + void on_conn_open(oxen::quic::connection_interface& ci); diff --git a/llarp/messages/fetch.hpp b/llarp/messages/fetch.hpp index 933521544..839a5d458 100644 --- a/llarp/messages/fetch.hpp +++ b/llarp/messages/fetch.hpp @@ -37,10 +37,12 @@ namespace llarp namespace BootstrapFetchMessage { + // the LocalRC is converted to a RemoteRC type to send to the bootstrap seed inline static std::string - serialize(size_t quantity) + serialize(const RemoteRC& local_rc, size_t quantity) { oxenc::bt_dict_producer btdp; + btdp.append_encoded("local", local_rc.view()); btdp.append("quantity", quantity); return std::move(btdp).str(); } diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 1c4eea3fe..000f51734 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -670,7 +670,8 @@ namespace llarp _router.link_manager().fetch_bootstrap_rcs( _bootstraps->current(), - BootstrapFetchMessage::serialize(BOOTSTRAP_SOURCE_COUNT), + BootstrapFetchMessage::serialize( + _router.router_contact.to_remote(), BOOTSTRAP_SOURCE_COUNT), [this](oxen::quic::message m) mutable { if (not m) { diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 19e63b2e1..3723301cb 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -207,6 +207,8 @@ namespace llarp bt_load(oxenc::bt_dict_consumer& data); }; + struct RemoteRC; + /// Extension of RouterContact used to store a local "RC," and inserts a RouterContact by /// re-parsing and sending it out. This sub-class contains a pubkey and all the other attributes /// required for signing and serialization @@ -236,6 +238,9 @@ namespace llarp explicit LocalRC(std::string payload, const SecretKey sk); ~LocalRC() = default; + RemoteRC + to_remote(); + void resign(); diff --git a/llarp/router_contact_local.cpp b/llarp/router_contact_local.cpp index b1b0268d4..da692787f 100644 --- a/llarp/router_contact_local.cpp +++ b/llarp/router_contact_local.cpp @@ -27,6 +27,12 @@ namespace llarp resign(); } + RemoteRC + LocalRC::to_remote() + { + return RemoteRC{view()}; + } + LocalRC::LocalRC(std::string payload, const SecretKey sk) : _secret_key{std::move(sk)} { _router_id = llarp::seckey_to_pubkey(_secret_key); diff --git a/llarp/router_id.hpp b/llarp/router_id.hpp index fea9d4d54..6a25ff9d4 100644 --- a/llarp/router_id.hpp +++ b/llarp/router_id.hpp @@ -21,6 +21,9 @@ namespace llarp RouterID(const Data& data) : PubKey(data) {} + RouterID(ustring_view data) : PubKey(data.data()) + {} + util::StatusObject ExtractStatus() const;