mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-10-22 22:11:26 +00:00
diag: request network keys for unknown LXMF sources (Sideband request-keys equivalent)
on_message_received now fires a rate-limited RNS path request when an LXMF message arrives from a SOURCE_UNKNOWN sender, mirroring Sideband's 'Query Network For Keys' button (RNS.Transport.request_path). Any peer that already knows the source's announce (hub, phone, other node) can answer with the cached identity, letting the NEXT message from that peer validate and reach location ingest. 5-minute per-source cooldown, 64-entry cap. App-only diagnostic; remove with the other ingest diagnostics once the root cause closes.
This commit is contained in:
1 parent
ac9c14e8f9
commit
e9fe63e9e4
1 file changed
+64
@@ -168,6 +168,62 @@ uint64_t monotonicMillis() {
|
||||
return static_cast<uint64_t>(esp_timer_get_time() / 1000LL);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// App-only diagnostic: on-demand identity acquisition for unknown LXMF
|
||||
// sources (mirrors Sideband's "Query Network For Keys" button).
|
||||
//
|
||||
// When an LXMF message arrives from a source whose RNS identity has not been
|
||||
// learned, the router accepts the message but UIManager::on_message_received
|
||||
// skips location ingest for unauthenticated senders. Nothing in the firmware
|
||||
// ever triggered the identity learning that microLXMF's comment at
|
||||
// LXMRouter.cpp:1267 expects ("signature will be validated later if the
|
||||
// source identity is learned via announce"). This fires a bounded
|
||||
// RNS path request — the exact mechanism of Sideband's
|
||||
// RNS.Transport.request_path — so any peer that already knows the source's
|
||||
// key (the hub, a phone, or another node) can answer with the cached
|
||||
// announce. The next message from that peer then validates and plots.
|
||||
//
|
||||
// Rate-limited per source hash (5 min) and globally (64 entries) to keep
|
||||
// opportunistic-flood cost to zero in the steady state. Diagnostic for the
|
||||
// missing-map-pin investigation; remove with the other ingest diagnostics
|
||||
// once the root cause is closed.
|
||||
namespace {
|
||||
struct KeyRequestState {
|
||||
std::vector<std::pair<std::string, uint64_t>> last_requested;
|
||||
};
|
||||
KeyRequestState s_key_request_state;
|
||||
|
||||
void request_key_for_unknown_source(const ::LXMF::LXMessage& message) {
|
||||
if (message.unverified_reason() !=
|
||||
::LXMF::Type::Message::SOURCE_UNKNOWN) {
|
||||
return; // Bad signature is not recoverable by asking the network.
|
||||
}
|
||||
const RNS::Bytes& source_hash = message.source_hash();
|
||||
if (source_hash.size() != Telemetry::PEER_ID_SIZE) {
|
||||
return;
|
||||
}
|
||||
const std::string source_hex = source_hash.toHex();
|
||||
const uint64_t now = monotonicMillis();
|
||||
const static constexpr uint64_t kKeyRequestIntervalMillis = 5 * 60 * 1000;
|
||||
for (auto& e : s_key_request_state.last_requested) {
|
||||
if (e.first == source_hex) {
|
||||
if (now < e.second + kKeyRequestIntervalMillis) {
|
||||
return; // Recently requested — wait for the answer to land.
|
||||
}
|
||||
e.second = now; // Expired — re-request below.
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (s_key_request_state.last_requested.size() >= 64U) {
|
||||
s_key_request_state.last_requested.erase(s_key_request_state.last_requested.begin());
|
||||
}
|
||||
s_key_request_state.last_requested.emplace_back(source_hex, now);
|
||||
INFO(("Requesting network keys for unknown LXMF source " +
|
||||
source_hex.substr(0, 8) + "...").c_str());
|
||||
Transport::request_path(source_hash);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool peerIdFromHash(const Bytes& hash, Telemetry::PeerId& output) {
|
||||
if (hash.size() != Telemetry::PEER_ID_SIZE) return false;
|
||||
std::memcpy(output.bytes, hash.data(), Telemetry::PEER_ID_SIZE);
|
||||
@@ -1585,6 +1641,14 @@ void UIManager::on_message_received(::LXMF::LXMessage& message) {
|
||||
pyxis_test_hook_record_rx(message);
|
||||
#endif
|
||||
|
||||
// Diagnostic: unauthenticated messages are accepted by the router but
|
||||
// skipped below for location ingest. Ask the network for the source's
|
||||
// key (Sideband "request keys" equivalent) so the NEXT message from
|
||||
// this peer can validate and be plotted.
|
||||
if (!message.signature_validated()) {
|
||||
request_key_for_unknown_source(message);
|
||||
}
|
||||
|
||||
// Classify authenticated location fields before any conversation write.
|
||||
// Raw field keys and values are MessagePack spans retained by LXMessage.
|
||||
Telemetry::InboundLocationMessage inbound{};
|
||||
|
||||
Reference in new issue
Block a user