fix(mesh): route ContentRef over federation when >160B
mesh.send-content was failing with "Message too large for LoRa: 624
bytes (max 160)" because a single ContentRef envelope (cid + onion +
cap_token + thumb) dwarfs a LoRa frame. Add a federation Tor fallback:
- New POST /archipelago/mesh-typed endpoint accepts
{from_pubkey, typed_envelope_b64, signature}, verifies ed25519 over
the raw wire bytes, and injects the decoded envelope into MeshState
via a new MeshService::inject_typed_from_federation helper. This
shares the same dispatch match as LoRa receives via a new pub(crate)
handle_typed_envelope_direct extracted from handle_typed_message.
- MeshService::send_typed_wire_via_federation POSTs the signed wire to
a peer's onion over TOR_SOCKS_PROXY and records a local Sent record.
- handle_mesh_send_content looks up the peer's onion in federation
storage and routes via federation when available, falling back to
LoRa only when no federation presence is known (still fails on
oversized — chunking is Phase 4).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
649433b7fd
commit
bc3729d99f
@@ -286,9 +286,35 @@ impl RpcHandler {
|
||||
(None, None) => format!("{} ({} bytes)", content.mime, content.size),
|
||||
};
|
||||
let typed_json = serde_json::to_value(&content).ok();
|
||||
let msg = svc
|
||||
.send_typed_wire(contact_id, wire, "content_ref", &display, typed_json, seq)
|
||||
.await?;
|
||||
|
||||
// ContentRef envelopes routinely exceed LoRa's ~160-byte per-frame
|
||||
// budget (cid alone is 64 hex chars, plus onion + cap). Route via
|
||||
// federation when the peer has a known onion; fall back to LoRa
|
||||
// only for tiny envelopes that could theoretically fit.
|
||||
let federation_onion = {
|
||||
let nodes = crate::federation::load_nodes(&self.config.data_dir)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
nodes
|
||||
.into_iter()
|
||||
.find(|n| n.pubkey == peer_pubkey_hex)
|
||||
.map(|n| n.onion)
|
||||
};
|
||||
let msg = if let Some(onion) = federation_onion {
|
||||
svc.send_typed_wire_via_federation(
|
||||
contact_id,
|
||||
&onion,
|
||||
wire,
|
||||
"content_ref",
|
||||
&display,
|
||||
typed_json,
|
||||
seq,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
svc.send_typed_wire(contact_id, wire, "content_ref", &display, typed_json, seq)
|
||||
.await?
|
||||
};
|
||||
|
||||
info!(contact_id, cid = %cid, size = meta.size, "Sent content_ref over mesh");
|
||||
Ok(serde_json::json!({
|
||||
|
||||
Reference in New Issue
Block a user