fix(relay): forward MediaPathReport across federation

MediaPathReport was only delivered via local signal_hub, so calls
between peers on different relays always hit peer_report_timeout
and fell back to relay — even when direct P2P worked perfectly.

Fix: check peer_relay_fp in call_registry (same pattern as
DirectCallAnswer). If the peer is on a remote relay, wrap in
FederatedSignalForward and send via federation link. Also fix
the cross-relay dispatcher to deliver to BOTH caller and callee
(not just caller), since the report can come from either side.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-12 14:14:30 +04:00
parent b79073c649
commit f843a934fe
2 changed files with 53 additions and 14 deletions

View File

@@ -688,18 +688,28 @@ async fn main() -> anyhow::Result<()> {
}
// Phase 6: MediaPathReport forwarded across
// federation — deliver to the local participant
// of the matching call.
// federation — deliver to the LOCAL participant.
// The report comes from the remote side, so we
// deliver to whichever participant is local. In
// the cross-relay case, one is local and one is
// remote. Try both — send_to is a no-op if the
// target isn't connected to this relay.
SignalMessage::MediaPathReport { ref call_id, .. } => {
// Deliver to the local caller (the cross-relay
// dispatcher only handles calls where the caller
// is local and the callee is remote, or vice versa)
let caller_fp = {
let (caller_fp, callee_fp) = {
let reg = call_registry_d.lock().await;
reg.get(call_id).map(|c| c.caller_fingerprint.clone())
match reg.get(call_id) {
Some(c) => (
Some(c.caller_fingerprint.clone()),
Some(c.callee_fingerprint.clone()),
),
None => (None, None),
}
};
let hub = signal_hub_d.lock().await;
if let Some(fp) = caller_fp {
let hub = signal_hub_d.lock().await;
let _ = hub.send_to(&fp, &inner).await;
}
if let Some(fp) = callee_fp {
let _ = hub.send_to(&fp, &inner).await;
}
}
@@ -1315,14 +1325,43 @@ async fn main() -> anyhow::Result<()> {
// call peer so both sides can negotiate
// the media path before committing.
SignalMessage::MediaPathReport { ref call_id, .. } => {
let peer_fp = {
// Look up peer AND check if this is a
// cross-relay call (same pattern as
// DirectCallAnswer).
let (peer_fp, peer_relay_fp) = {
let reg = call_registry.lock().await;
reg.peer_fingerprint(call_id, &client_fp)
.map(|s| s.to_string())
match reg.get(call_id) {
Some(c) => (
reg.peer_fingerprint(call_id, &client_fp)
.map(|s| s.to_string()),
c.peer_relay_fp.clone(),
),
None => (None, None),
}
};
if let Some(fp) = peer_fp {
let hub = signal_hub.lock().await;
let _ = hub.send_to(&fp, &msg).await;
if let Some(ref origin_fp) = peer_relay_fp {
// Cross-relay: wrap and forward
if let Some(ref fm) = federation_mgr {
let forward = SignalMessage::FederatedSignalForward {
inner: Box::new(msg.clone()),
origin_relay_fp: tls_fp.clone(),
};
if let Err(e) = fm.send_signal_to_peer(origin_fp, &forward).await {
warn!(
%call_id,
%origin_fp,
error = %e,
"cross-relay MediaPathReport forward failed"
);
}
}
} else {
// Local call
let hub = signal_hub.lock().await;
let _ = hub.send_to(&fp, &msg).await;
}
}
}

View File

@@ -73,7 +73,7 @@ if [ "$USE_ALT" = "1" ]; then
GIT_ORIGIN="ssh://git@git.tbs.amn.gg:2222/manawenuz/wzp.git"
# Alt server uploads directly (no .env file)
UPLOAD_MODE="direct"
PASTE_URL="http://paste.tbs.amn.gg"
PASTE_URL="https://paste.tbs.manko.yoga"
PASTE_AUTH="X2j6szIQaoJGaxZjLkpl3A8IX9/mTkDgdhhgyYFcpaU="
else
SERVER_TAG="PRI"