diff --git a/external/oxen-libquic b/external/oxen-libquic index 78b46d4f4..b35cab3a3 160000 --- a/external/oxen-libquic +++ b/external/oxen-libquic @@ -1 +1 @@ -Subproject commit 78b46d4f4df45747b70918386672228ead2c7ed3 +Subproject commit b35cab3a310cf358580ef9f418553f71436766ab diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 1e9c4a950..ac99d38c0 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -230,15 +230,16 @@ namespace llarp if (_router.is_bootstrap_seed()) { - if (node_db->whitelist().count(other)) + if (node_db->registered_routers().count(other)) { log::critical(logcat, "Saving bootstrap seed requester..."); - auto [it, b] = node_db->seeds().emplace(other); - result |= b; + auto [it, b] = node_db->seeds().insert(other); + result &= b; } + log::critical( logcat, - "Bootstrap seed node was {} to confirm remote is white-listed; {}successfully " + "Bootstrap seed node was {} to confirm remote is registered; {}successfully " "saved RID", result ? "able" : "unable", result ? "" : "un"); @@ -323,6 +324,8 @@ namespace llarp } else { + log::critical(logcat, "Searching for RID:{} in pending conns...", rid); + if (auto itr = ep.pending_conns.find(rid); itr != ep.pending_conns.end()) { ep.connid_map.emplace(scid, rid); diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 455d6ca8c..6244d104a 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -808,10 +808,10 @@ namespace llarp if (whitelist.empty()) return; - registered_routers.clear(); - registered_routers.insert(whitelist.begin(), whitelist.end()); - registered_routers.insert(greylist.begin(), greylist.end()); - registered_routers.insert(greenlist.begin(), greenlist.end()); + _registered_routers.clear(); + _registered_routers.insert(whitelist.begin(), whitelist.end()); + _registered_routers.insert(greylist.begin(), greylist.end()); + _registered_routers.insert(greenlist.begin(), greenlist.end()); router_whitelist.clear(); router_whitelist.insert(whitelist.begin(), whitelist.end()); @@ -820,10 +820,8 @@ namespace llarp router_greenlist.clear(); router_greenlist.insert(greenlist.begin(), greenlist.end()); - log::info( - logcat, - "lokinet service node whitelist now has {} active router RIDs", - router_whitelist.size()); + log::critical( + logcat, "Service node whitelist now has {} active router RIDs", router_whitelist.size()); } std::optional diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index 340f03922..5f4588edf 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -150,7 +150,7 @@ namespace llarp std::set router_greenlist{}; // All registered relays (service nodes) - std::set registered_routers; + std::set _registered_routers; // timing (note: Router holds the variables for last rc and rid request times) std::unordered_map last_rc_update_times; // if populated from a config file, lists specific exclusively used as path first-hops @@ -372,10 +372,16 @@ namespace llarp return router_greylist; } + std::set& + registered_routers() + { + return _registered_routers; + } + const std::set& - get_registered_routers() const + registered_routers() const { - return registered_routers; + return _registered_routers; } const std::set& diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index a7a17c79f..a530c6712 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -476,7 +476,7 @@ namespace llarp Router::appears_registered() const { return _is_service_node and have_snode_whitelist() - and node_db()->get_registered_routers().count(pubkey()); + and node_db()->registered_routers().count(pubkey()); } bool @@ -866,17 +866,11 @@ namespace llarp { log::critical(logcat, "Regenerating and gossiping RC..."); -<<<<<<< Updated upstream router_contact.resign(); save_rc(); -======= - auto view = router_contact.view(); ->>>>>>> Stashed changes _link_manager->gossip_rc( - router_contact.router_id(), - router_contact.router_id(), - std::string{oxen::quic::to_sv(router_contact.view())}); + local_rid(), local_rid(), std::string{oxen::quic::to_sv(router_contact.view())}); last_rc_gossip = now_timepoint; diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index bd3b33330..39d0c8693 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -187,10 +187,10 @@ namespace llarp return client_router_connections; } - RouterID + const RouterID& local_rid() const { - return RouterID{pubkey()}; + return router_contact.router_id(); } bool diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index d75c5625e..ebd87e701 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -12,12 +12,42 @@ namespace llarp { void - RouterContact::bt_load(oxenc::bt_dict_consumer& data) + RouterContact::bt_verify(oxenc::bt_dict_consumer& btdc, bool reject_expired) const { - if (int rc_ver = data.require(""); rc_ver != RC_VERSION) + btdc.require_signature("~", [this, reject_expired](ustring_view msg, ustring_view sig) { + if (sig.size() != 64) + throw std::runtime_error{"Invalid signature: not 64 bytes"}; + + if (reject_expired and is_expired(time_now_ms())) + throw std::runtime_error{"Rejecting expired RemoteRC!"}; + + // TODO: revisit if this is needed; detail from previous implementation + const auto* net = net::Platform::Default_ptr(); + + if (net->IsBogon(addr().in4()) and BLOCK_BOGONS) + { + auto err = "Unable to verify expired RemoteRC address!"; + log::info(logcat, err); + throw std::runtime_error{err}; + } + + if (not crypto::verify(router_id(), msg, sig)) + throw std::runtime_error{"Failed to verify RemoteRC signature"}; + }); + + if (not btdc.is_finished()) + throw std::runtime_error{"RouterContact has some fucked up shit at the end"}; + + btdc.finish(); + } + + void + RouterContact::bt_load(oxenc::bt_dict_consumer& btdc) + { + if (int rc_ver = btdc.require(""); rc_ver != RC_VERSION) throw std::runtime_error{"Invalid RC: do not know how to parse v{} RCs"_format(rc_ver)}; - auto ipv4_port = data.require("4"); + auto ipv4_port = btdc.require("4"); if (ipv4_port.size() != 6) throw std::runtime_error{ @@ -34,7 +64,7 @@ namespace llarp if (!_addr.is_public()) throw std::runtime_error{"Invalid RC: IPv4 address is not a publicly routable IP"}; - if (auto ipv6_port = data.maybe("6")) + if (auto ipv6_port = btdc.maybe("6")) { if (ipv6_port->size() != 18) throw std::runtime_error{ @@ -55,22 +85,22 @@ namespace llarp _addr6.reset(); } - auto netid = data.maybe("i").value_or(llarp::LOKINET_DEFAULT_NETID); + auto netid = btdc.maybe("i").value_or(llarp::LOKINET_DEFAULT_NETID); if (netid != ACTIVE_NETID) throw std::runtime_error{ "Invalid RC netid: expected {}, got {}; this is an RC for a different network!"_format( ACTIVE_NETID, netid)}; - auto pubkey = data.require("p"); + auto pubkey = btdc.require("p"); if (pubkey.size() != 32) throw std::runtime_error{ "Invalid RC pubkey: expected 32 bytes, got {}"_format(pubkey.size())}; std::memcpy(_router_id.data(), pubkey.data(), 32); - _timestamp = rc_time{std::chrono::seconds{data.require("t")}}; + _timestamp = rc_time{std::chrono::seconds{btdc.require("t")}}; - auto ver = data.require("v"); + auto ver = btdc.require("v"); if (ver.size() != 3) throw std::runtime_error{ @@ -120,106 +150,6 @@ namespace llarp return obj; } - bool - RouterContact::BDecode(llarp_buffer_t* buf) - { - // TODO: unfuck all of this - - (void)buf; - - // clear(); - - // if (*buf->cur == 'd') // old format - // { - // return DecodeVersion_0(buf); - // } - // else if (*buf->cur != 'l') // if not dict, should be new format and start with list - // { - // return false; - // } - - // try - // { - // std::string_view buf_view(reinterpret_cast(buf->cur), buf->size_left()); - // oxenc::bt_list_consumer btlist(buf_view); - - // uint64_t outer_version = btlist.consume_integer(); - - // if (outer_version == 1) - // { - // bool decode_result = DecodeVersion_1(btlist); - - // // advance the llarp_buffer_t since lokimq serialization is unaware of it. - // // FIXME: this is broken (current_buffer got dropped), but the whole thing is getting - // // replaced. - // // buf->cur += btlist. - // // current_buffer().data() - buf_view.data() + 1; - - // return decode_result; - // } - // else - // { - // log::warning(logcat, "Received RouterContact with unkown version ({})", outer_version); - // return false; - // } - // } - // catch (const std::exception& e) - // { - // log::debug(logcat, "RouterContact::BDecode failed: {}", e.what()); - // } - - return false; - } - - bool - RouterContact::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) - { - bool read = false; - (void)key; - - // TOFIX: fuck everything about llarp_buffer_t - - // if (!BEncodeMaybeReadDictEntry("a", addr, read, key, buf)) - // return false; - - // if (!BEncodeMaybeReadDictEntry("i", netID, read, key, buf)) - // return false; - - // if (!BEncodeMaybeReadDictEntry("k", _router_id, read, key, buf)) - // return false; - - // if (key.startswith("r")) - // { - // RouterVersion r; - // if (not r.BDecode(buf)) - // return false; - // routerVersion = r; - // return true; - // } - - // if (not BEncodeMaybeReadDictList("s", srvRecords, read, key, buf)) - // return false; - - // if (!BEncodeMaybeReadDictEntry("p", enckey, read, key, buf)) - // return false; - - // if (!BEncodeMaybeReadDictInt("u", _timestamp, read, key, buf)) - // return false; - - // if (!BEncodeMaybeReadDictInt("v", version, read, key, buf)) - // return false; - - // if (key.startswith("x") and serializeExit) - // { - // return bencode_discard(buf); - // } - - // if (!BEncodeMaybeReadDictEntry("z", signature, read, key, buf)) - // return false; - - return read or bencode_discard(buf); - } - bool RouterContact::is_public_addressable() const { diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 47bf2e633..c37652fe5 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -167,12 +167,6 @@ namespace llarp clear() {} - bool - BDecode(llarp_buffer_t* buf); - - bool - decode_key(const llarp_buffer_t& k, llarp_buffer_t* buf); - bool is_public_addressable() const; @@ -201,6 +195,9 @@ namespace llarp bool is_obsolete_bootstrap() const; + void + bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired = false) const; + void bt_load(oxenc::bt_dict_consumer& data); }; @@ -233,7 +230,6 @@ namespace llarp public: LocalRC() = default; - explicit LocalRC(std::string payload, const SecretKey sk); ~LocalRC() = default; RemoteRC @@ -309,9 +305,6 @@ namespace llarp struct RemoteRC final : public RouterContact { private: - void - bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired = false) const; - explicit RemoteRC(oxenc::bt_dict_consumer btdc); public: diff --git a/llarp/router_contact_local.cpp b/llarp/router_contact_local.cpp index 8c9d8b39b..82520daa4 100644 --- a/llarp/router_contact_local.cpp +++ b/llarp/router_contact_local.cpp @@ -34,43 +34,6 @@ namespace llarp return RemoteRC{view()}; } - LocalRC::LocalRC(std::string payload, const SecretKey sk) : _secret_key{std::move(sk)} - { - _router_id = llarp::seckey_to_pubkey(_secret_key); - - try - { - oxenc::bt_dict_consumer btdc{payload}; - bt_load(btdc); - - btdc.require_signature("~", [this](ustring_view msg, ustring_view sig) { - if (sig.size() != 64) - throw std::runtime_error{"Invalid signature: not 64 bytes"}; - - if (is_expired(time_now_ms())) - throw std::runtime_error{"Unable to verify expired RemoteRC!"}; - - // TODO: revisit if this is needed; detail from previous implementation - const auto* net = net::Platform::Default_ptr(); - - if (net->IsBogon(addr().in4()) and BLOCK_BOGONS) - { - auto err = "Unable to verify expired LocalRC!"; - log::info(logcat, err); - throw std::runtime_error{err}; - } - - if (not crypto::verify(router_id(), msg, sig)) - throw std::runtime_error{"Failed to verify LocalRC"}; - }); - } - catch (const std::exception& e) - { - log::warning(logcat, "Failed to parse LocalRC: {}", e.what()); - throw; - } - } - void LocalRC::bt_sign(oxenc::bt_dict_producer& btdp) { diff --git a/llarp/router_contact_remote.cpp b/llarp/router_contact_remote.cpp index 98d70a4d6..141c6fc84 100644 --- a/llarp/router_contact_remote.cpp +++ b/llarp/router_contact_remote.cpp @@ -26,47 +26,19 @@ namespace llarp } } - void - RemoteRC::bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired) const - { - data.require_signature("~", [this, reject_expired](ustring_view msg, ustring_view sig) { - if (sig.size() != 64) - throw std::runtime_error{"Invalid signature: not 64 bytes"}; - - if (reject_expired and is_expired(time_now_ms())) - throw std::runtime_error{"Rejecting expired RemoteRC!"}; - - // TODO: revisit if this is needed; detail from previous implementation - const auto* net = net::Platform::Default_ptr(); - - if (net->IsBogon(addr().in4()) and BLOCK_BOGONS) - { - auto err = "Unable to verify expired RemoteRC address!"; - log::info(logcat, err); - throw std::runtime_error{err}; - } - - if (not crypto::verify(router_id(), msg, sig)) - throw std::runtime_error{"Failed to verify RemoteRC signature"}; - }); - } - bool RemoteRC::read(const fs::path& fname) { - ustring buf; - buf.resize(MAX_RC_SIZE); + _payload.resize(MAX_RC_SIZE); try { - auto nread = util::file_to_buffer(fname, buf.data(), buf.size()); - buf.resize(nread); + auto nread = util::file_to_buffer(fname, _payload.data(), _payload.size()); + _payload.resize(nread); - oxenc::bt_dict_consumer btdc{buf}; + oxenc::bt_dict_consumer btdc{_payload}; bt_load(btdc); bt_verify(btdc); - - _payload = buf; } catch (const std::exception& e) {