T3.3: SignalMessage version field

This commit is contained in:
Siavash Sameni
2026-05-12 06:08:31 +04:00
parent 1b4f7b0772
commit e73f8a7150
30 changed files with 531 additions and 69 deletions

View File

@@ -15,7 +15,7 @@ use std::time::{Duration, Instant};
use clap::Parser;
use tracing::info;
use wzp_proto::{CodecId, MediaPacket, MediaTransport};
use wzp_proto::{CodecId, MediaPacket, MediaTransport, default_signal_version};
// ---------------------------------------------------------------------------
// CLI
@@ -919,6 +919,7 @@ async fn main() -> anyhow::Result<()> {
// Auth if token provided
if let Some(ref token) = args.token {
let auth = wzp_proto::SignalMessage::AuthToken {
version: default_signal_version(),
token: token.clone(),
};
transport.send_signal(&auth).await?;

View File

@@ -17,7 +17,7 @@ use std::sync::Arc;
use tracing::{error, info};
use wzp_client::call::{CallConfig, CallDecoder, CallEncoder};
use wzp_proto::MediaTransport;
use wzp_proto::{MediaTransport, default_signal_version};
const FRAME_SAMPLES: usize = 960; // 20ms @ 48kHz
@@ -380,6 +380,7 @@ async fn main() -> anyhow::Result<()> {
// Send auth token if provided (relay with --auth-url expects this first)
if let Some(ref token) = cli.token {
let auth = wzp_proto::SignalMessage::AuthToken {
version: default_signal_version(),
token: token.clone(),
};
transport.send_signal(&auth).await?;
@@ -473,6 +474,7 @@ async fn run_silence(transport: Arc<wzp_transport::QuinnTransport>) -> anyhow::R
info!(total_source, total_repair, total_bytes, "done — closing");
let hangup = wzp_proto::SignalMessage::Hangup {
version: default_signal_version(),
reason: wzp_proto::HangupReason::Normal,
call_id: None,
};
@@ -632,6 +634,7 @@ async fn run_file_mode(
// Send Hangup signal so the relay knows we're done
let hangup = wzp_proto::SignalMessage::Hangup {
version: default_signal_version(),
reason: wzp_proto::HangupReason::Normal,
call_id: None,
};
@@ -769,7 +772,7 @@ async fn run_signal_mode(
token: Option<String>,
call_target: Option<String>,
) -> anyhow::Result<()> {
use wzp_proto::SignalMessage;
use wzp_proto::{SignalMessage, default_signal_version};
let identity = seed.derive_identity();
let pub_id = identity.public_identity();
@@ -792,13 +795,17 @@ async fn run_signal_mode(
// Auth if token provided
if let Some(ref tok) = token {
transport
.send_signal(&SignalMessage::AuthToken { token: tok.clone() })
.send_signal(&SignalMessage::AuthToken {
version: default_signal_version(),
token: tok.clone(),
})
.await?;
}
// Register presence (signature not verified in Phase 1)
transport
.send_signal(&SignalMessage::RegisterPresence {
version: default_signal_version(),
identity_pub,
signature: vec![], // Phase 1: not verified
alias: None,
@@ -835,6 +842,7 @@ async fn run_signal_mode(
transport
.send_signal(&SignalMessage::DirectCallOffer {
version: default_signal_version(),
caller_fingerprint: fp.clone(),
caller_alias: None,
target_fingerprint: target.clone(),
@@ -861,7 +869,7 @@ async fn run_signal_mode(
loop {
match signal_transport.recv_signal().await {
Ok(Some(msg)) => match msg {
SignalMessage::CallRinging { call_id } => {
SignalMessage::CallRinging { call_id, .. } => {
info!(call_id = %call_id, "ringing...");
}
SignalMessage::DirectCallOffer {
@@ -879,6 +887,7 @@ async fn run_signal_mode(
// Auto-accept for CLI testing
let _ = signal_transport
.send_signal(&SignalMessage::DirectCallAnswer {
version: default_signal_version(),
call_id,
accept_mode: wzp_proto::CallAcceptMode::AcceptGeneric,
identity_pub: Some(identity_pub),
@@ -908,6 +917,7 @@ async fn run_signal_mode(
peer_direct_addr: _,
peer_local_addrs: _,
peer_mapped_addr: _,
..
} => {
info!(call_id = %call_id, room = %room, relay = %setup_relay, "call setup — connecting to media room");
@@ -970,6 +980,7 @@ async fn run_signal_mode(
_ = tokio::signal::ctrl_c() => {
info!("hanging up...");
let _ = signal_transport.send_signal(&SignalMessage::Hangup {
version: default_signal_version(),
reason: wzp_proto::HangupReason::Normal,
call_id: None,
}).await;

View File

@@ -11,7 +11,7 @@
//! 5. Connects QUIC to relay for media
use serde::{Deserialize, Serialize};
use wzp_proto::packet::SignalMessage;
use wzp_proto::packet::{SignalMessage, default_signal_version};
/// featherChat CallSignal types (mirrors warzone-protocol::message::CallSignalType).
#[derive(Clone, Debug, Serialize, Deserialize)]
@@ -152,6 +152,7 @@ mod tests {
#[test]
fn payload_roundtrip() {
let signal = SignalMessage::CallOffer {
version: default_signal_version(),
identity_pub: [1u8; 32],
ephemeral_pub: [2u8; 32],
signature: vec![3u8; 64],
@@ -172,6 +173,7 @@ mod tests {
#[test]
fn signal_type_mapping() {
let offer = SignalMessage::CallOffer {
version: default_signal_version(),
identity_pub: [0; 32],
ephemeral_pub: [0; 32],
signature: vec![],
@@ -183,6 +185,7 @@ mod tests {
assert!(matches!(signal_to_call_type(&offer), CallSignalType::Offer));
let hangup = SignalMessage::Hangup {
version: default_signal_version(),
reason: wzp_proto::HangupReason::Normal,
call_id: None,
};
@@ -209,6 +212,7 @@ mod tests {
));
let transfer = SignalMessage::Transfer {
version: default_signal_version(),
target_fingerprint: "abc".to_string(),
relay_addr: None,
};

View File

@@ -4,7 +4,9 @@
//! send `CallOffer` → recv `CallAnswer` → derive shared `CryptoSession`.
use wzp_crypto::{CryptoSession, KeyExchange, WarzoneKeyExchange};
use wzp_proto::{HangupReason, MediaTransport, QualityProfile, SignalMessage};
use wzp_proto::{
HangupReason, MediaTransport, QualityProfile, SignalMessage, default_signal_version,
};
/// Errors that can occur during the client-side cryptographic handshake.
#[derive(Debug)]
@@ -78,6 +80,7 @@ pub async fn perform_handshake(
// 4. Send CallOffer
let offer = SignalMessage::CallOffer {
version: default_signal_version(),
identity_pub,
ephemeral_pub,
signature,
@@ -112,6 +115,7 @@ pub async fn perform_handshake(
ephemeral_pub,
signature,
chosen_profile,
..
} => (identity_pub, ephemeral_pub, signature, chosen_profile),
SignalMessage::Hangup {
reason: HangupReason::ProtocolVersionMismatch { server_supported },

View File

@@ -17,7 +17,7 @@ use std::net::SocketAddr;
use std::sync::atomic::{AtomicU32, Ordering};
use std::time::Duration;
use wzp_proto::SignalMessage;
use wzp_proto::{SignalMessage, default_signal_version};
use crate::dual_path::PeerCandidates;
use crate::portmap;
@@ -133,6 +133,7 @@ impl IceAgent {
let candidates = self.gather().await;
let update = SignalMessage::CandidateUpdate {
version: default_signal_version(),
call_id: self.call_id.clone(),
reflexive_addr: candidates.reflexive.map(|a| a.to_string()),
local_addrs: candidates.local.iter().map(|a| a.to_string()).collect(),
@@ -206,6 +207,7 @@ mod tests {
// First update (gen=1) should succeed.
let update1 = SignalMessage::CandidateUpdate {
version: default_signal_version(),
call_id: "test-call".into(),
reflexive_addr: Some("203.0.113.5:4433".into()),
local_addrs: vec!["192.168.1.10:4433".into()],
@@ -223,6 +225,7 @@ mod tests {
// Same generation (gen=1) should be rejected.
let update1b = SignalMessage::CandidateUpdate {
version: default_signal_version(),
call_id: "test-call".into(),
reflexive_addr: Some("198.51.100.9:4433".into()),
local_addrs: vec![],
@@ -233,6 +236,7 @@ mod tests {
// Older generation (gen=0) should be rejected.
let update0 = SignalMessage::CandidateUpdate {
version: default_signal_version(),
call_id: "test-call".into(),
reflexive_addr: Some("10.0.0.1:4433".into()),
local_addrs: vec![],
@@ -243,6 +247,7 @@ mod tests {
// Newer generation (gen=2) should succeed.
let update2 = SignalMessage::CandidateUpdate {
version: default_signal_version(),
call_id: "test-call".into(),
reflexive_addr: Some("198.51.100.9:5555".into()),
local_addrs: vec![],
@@ -287,6 +292,7 @@ mod tests {
let agent = IceAgent::new("test-call".into(), IceAgentConfig::default());
let update = SignalMessage::CandidateUpdate {
version: default_signal_version(),
call_id: "test-call".into(),
reflexive_addr: Some("203.0.113.5:4433".into()),
local_addrs: vec!["192.168.1.10:4433".into(), "10.0.0.5:4433".into()],
@@ -315,6 +321,7 @@ mod tests {
let agent = IceAgent::new("test".into(), IceAgentConfig::default());
let update = SignalMessage::CandidateUpdate {
version: default_signal_version(),
call_id: "test".into(),
reflexive_addr: None,
local_addrs: vec![],
@@ -333,6 +340,7 @@ mod tests {
let agent = IceAgent::new("test".into(), IceAgentConfig::default());
let update = SignalMessage::CandidateUpdate {
version: default_signal_version(),
call_id: "test".into(),
reflexive_addr: Some("not-an-addr".into()),
local_addrs: vec![

View File

@@ -30,7 +30,7 @@ use std::net::SocketAddr;
use std::time::{Duration, Instant};
use serde::Serialize;
use wzp_proto::{MediaTransport, SignalMessage};
use wzp_proto::{MediaTransport, SignalMessage, default_signal_version};
use wzp_transport::{QuinnTransport, client_config, create_endpoint};
/// Result of one probe against one relay. Always returned so the
@@ -123,6 +123,7 @@ pub async fn probe_reflect_addr(
// path does in desktop/src-tauri/src/lib.rs register_signal.
transport
.send_signal(&SignalMessage::RegisterPresence {
version: default_signal_version(),
identity_pub: [0u8; 32],
signature: vec![],
alias: None,
@@ -150,7 +151,7 @@ pub async fn probe_reflect_addr(
.map_err(|e| format!("send Reflect: {e}"))?;
match transport.recv_signal().await {
Ok(Some(SignalMessage::ReflectResponse { observed_addr })) => {
Ok(Some(SignalMessage::ReflectResponse { observed_addr, .. })) => {
let parsed: SocketAddr = observed_addr
.parse()
.map_err(|e| format!("parse observed_addr {observed_addr:?}: {e}"))?;

View File

@@ -11,7 +11,7 @@ use tokio::sync::mpsc;
use wzp_proto::packet::MediaPacket;
use wzp_proto::traits::{MediaTransport, PathQuality};
use wzp_proto::{SignalMessage, TransportError};
use wzp_proto::{SignalMessage, TransportError, default_signal_version};
/// A mock transport backed by two mpsc channels (one per direction).
///
@@ -151,6 +151,7 @@ async fn handshake_rejects_tampered_signature() {
let bad_signature = kx.sign(b"wrong-data-intentionally");
let offer = SignalMessage::CallOffer {
version: default_signal_version(),
identity_pub,
ephemeral_pub,
signature: bad_signature,
@@ -197,6 +198,7 @@ async fn client_receives_protocol_version_mismatch() {
// Respond with ProtocolVersionMismatch.
let mismatch = SignalMessage::Hangup {
version: default_signal_version(),
reason: wzp_proto::HangupReason::ProtocolVersionMismatch {
server_supported: vec![3],
},