Compare commits
2 Commits
82b439595c
...
f843a934fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f843a934fe | ||
|
|
b79073c649 |
@@ -688,18 +688,28 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Phase 6: MediaPathReport forwarded across
|
// Phase 6: MediaPathReport forwarded across
|
||||||
// federation — deliver to the local participant
|
// federation — deliver to the LOCAL participant.
|
||||||
// of the matching call.
|
// 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, .. } => {
|
SignalMessage::MediaPathReport { ref call_id, .. } => {
|
||||||
// Deliver to the local caller (the cross-relay
|
let (caller_fp, callee_fp) = {
|
||||||
// dispatcher only handles calls where the caller
|
|
||||||
// is local and the callee is remote, or vice versa)
|
|
||||||
let caller_fp = {
|
|
||||||
let reg = call_registry_d.lock().await;
|
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),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if let Some(fp) = caller_fp {
|
|
||||||
let hub = signal_hub_d.lock().await;
|
let hub = signal_hub_d.lock().await;
|
||||||
|
if let Some(fp) = caller_fp {
|
||||||
|
let _ = hub.send_to(&fp, &inner).await;
|
||||||
|
}
|
||||||
|
if let Some(fp) = callee_fp {
|
||||||
let _ = hub.send_to(&fp, &inner).await;
|
let _ = hub.send_to(&fp, &inner).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1315,16 +1325,45 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
// call peer so both sides can negotiate
|
// call peer so both sides can negotiate
|
||||||
// the media path before committing.
|
// the media path before committing.
|
||||||
SignalMessage::MediaPathReport { ref call_id, .. } => {
|
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;
|
let reg = call_registry.lock().await;
|
||||||
|
match reg.get(call_id) {
|
||||||
|
Some(c) => (
|
||||||
reg.peer_fingerprint(call_id, &client_fp)
|
reg.peer_fingerprint(call_id, &client_fp)
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string()),
|
||||||
|
c.peer_relay_fp.clone(),
|
||||||
|
),
|
||||||
|
None => (None, None),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(fp) = peer_fp {
|
if let Some(fp) = peer_fp {
|
||||||
|
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 = signal_hub.lock().await;
|
||||||
let _ = hub.send_to(&fp, &msg).await;
|
let _ = hub.send_to(&fp, &msg).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SignalMessage::Ping { timestamp_ms } => {
|
SignalMessage::Ping { timestamp_ms } => {
|
||||||
let _ = transport.send_signal(&SignalMessage::Pong { timestamp_ms }).await;
|
let _ = transport.send_signal(&SignalMessage::Pong { timestamp_ms }).await;
|
||||||
|
|||||||
@@ -503,29 +503,13 @@ async fn connect(
|
|||||||
peer_ok
|
peer_ok
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Timeout — the peer's report
|
// Timeout or channel error — peer
|
||||||
// didn't arrive. This happens when
|
// may be on an old build without
|
||||||
// peers are on different relays
|
// Phase 6. Fall back to relay.
|
||||||
// (no federation for MediaPathReport)
|
emit_call_debug(&app, "connect:peer_report_timeout", serde_json::json!({}));
|
||||||
// or the peer is on an old build.
|
|
||||||
//
|
|
||||||
// If OUR direct path succeeded and
|
|
||||||
// the transport is still alive,
|
|
||||||
// trust it — the timeout is a relay
|
|
||||||
// forwarding issue, not a direct
|
|
||||||
// path failure.
|
|
||||||
let mut sig = state.signal.lock().await;
|
let mut sig = state.signal.lock().await;
|
||||||
sig.pending_path_report = None;
|
sig.pending_path_report = None;
|
||||||
let trust_direct = local_direct_ok
|
false
|
||||||
&& race_result.direct_transport.as_ref()
|
|
||||||
.map(|t| t.connection().close_reason().is_none())
|
|
||||||
.unwrap_or(false);
|
|
||||||
emit_call_debug(&app, "connect:peer_report_timeout", serde_json::json!({
|
|
||||||
"local_direct_ok": local_direct_ok,
|
|
||||||
"direct_transport_alive": trust_direct,
|
|
||||||
"fallback": if trust_direct { "Direct" } else { "Relay" },
|
|
||||||
}));
|
|
||||||
trust_direct
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user