diff --git a/crates/wzp-proto/src/packet.rs b/crates/wzp-proto/src/packet.rs index 3bc59e0..855f7ee 100644 --- a/crates/wzp-proto/src/packet.rs +++ b/crates/wzp-proto/src/packet.rs @@ -686,6 +686,10 @@ pub struct RoomParticipant { pub fingerprint: String, /// Optional display name set by the client. pub alias: Option, + /// Relay label — identifies which relay this participant is connected to. + /// None for local participants, Some("Relay B") for federated. + #[serde(default)] + pub relay_label: Option, } /// Reasons for ending a call. diff --git a/crates/wzp-relay/src/federation.rs b/crates/wzp-relay/src/federation.rs index 84ac10d..ee1dc21 100644 --- a/crates/wzp-relay/src/federation.rs +++ b/crates/wzp-relay/src/federation.rs @@ -539,7 +539,15 @@ async fn handle_signal( let total: usize = links.values().map(|l| l.active_rooms.len()).sum(); fm.metrics.federation_active_rooms.set(total as i64); if let Some(link) = links.get_mut(peer_fp) { - link.remote_participants.insert(room.clone(), participants.clone()); + // Tag remote participants with their relay label + let tagged: Vec<_> = participants.iter().map(|p| { + let mut tagged = p.clone(); + if tagged.relay_label.is_none() { + tagged.relay_label = Some(link.label.clone()); + } + tagged + }).collect(); + link.remote_participants.insert(room.clone(), tagged); } // Propagate to other peers for (fp, link) in links.iter() { diff --git a/crates/wzp-relay/src/room.rs b/crates/wzp-relay/src/room.rs index 21cc643..b1c5b86 100644 --- a/crates/wzp-relay/src/room.rs +++ b/crates/wzp-relay/src/room.rs @@ -180,6 +180,7 @@ impl Room { .map(|p| wzp_proto::packet::RoomParticipant { fingerprint: p.fingerprint.clone().unwrap_or_default(), alias: p.alias.clone(), + relay_label: None, // local participant }) .collect() }