fix(mesh): route send-content-inline over federation for radio-less peers
mesh.send-content-inline always called send_typed_wire (the LoRa/radio path), which fails with "Peer is federation-only (no radio twin)" for any contact reachable only via Tor federation — reproduced sending a picture from the companion app to a federation-only peer. mesh.send-content already resolves the peer's federation onion and falls back to send_typed_wire_via_federation; mirror that same lookup here. Landed from PR #133 (re-committed to drop private host details from the original message; content identical). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
committed by
archipelago
co-authored by
Claude Sonnet 5
parent
b4714f1773
commit
a9e52fa310
@@ -491,6 +491,48 @@ impl RpcHandler {
|
|||||||
seq,
|
seq,
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
|
} else {
|
||||||
|
// Federation-only peers have no radio twin for
|
||||||
|
// send_typed_wire's LoRa dest-prefix resolution — route over
|
||||||
|
// Tor federation instead, mirroring mesh.send-content's onion
|
||||||
|
// lookup, or the send fails with "Peer is federation-only (no
|
||||||
|
// radio twin)" (picture-send from a federation-only contact,
|
||||||
|
// 2026-08-07).
|
||||||
|
let federation_onion = {
|
||||||
|
let state = svc.shared_state();
|
||||||
|
let peers = state.peers.read().await;
|
||||||
|
peers
|
||||||
|
.get(&contact_id)
|
||||||
|
.map(|p| (p.pubkey_hex.clone(), p.did.clone()))
|
||||||
|
};
|
||||||
|
let federation_onion = match federation_onion {
|
||||||
|
Some((Some(pubkey_hex), did)) => {
|
||||||
|
let nodes = crate::federation::load_nodes(&self.config.data_dir)
|
||||||
|
.await
|
||||||
|
.unwrap_or_default();
|
||||||
|
nodes
|
||||||
|
.iter()
|
||||||
|
.find(|n| n.pubkey == pubkey_hex)
|
||||||
|
.map(|n| n.onion.clone())
|
||||||
|
.or_else(|| {
|
||||||
|
did.as_ref().and_then(|d| {
|
||||||
|
nodes.iter().find(|n| &n.did == d).map(|n| n.onion.clone())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(onion) = federation_onion {
|
||||||
|
svc.send_typed_wire_via_federation(
|
||||||
|
contact_id,
|
||||||
|
&onion,
|
||||||
|
wire,
|
||||||
|
"content_ref",
|
||||||
|
&display,
|
||||||
|
Some(typed_json),
|
||||||
|
seq,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
} else {
|
} else {
|
||||||
svc.send_typed_wire(
|
svc.send_typed_wire(
|
||||||
contact_id,
|
contact_id,
|
||||||
@@ -502,6 +544,7 @@ impl RpcHandler {
|
|||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
|
|||||||
Reference in New Issue
Block a user