fix(audit): M1 — add version: u8 to all SignalMessage variants
Convert Hold/Unhold/Mute/Unmute/TransferAck from unit variants to struct variants with `version: u8` (serde default = 2). Every SignalMessage variant now carries a version field, enabling future semantic versioning and clean rejection of deprecated variants during federation routing. 305 tests passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -99,12 +99,12 @@ pub fn signal_to_call_type(signal: &SignalMessage) -> CallSignalType {
|
|||||||
SignalMessage::LossRecoveryUpdate { .. } => CallSignalType::Offer, // reuse (telemetry)
|
SignalMessage::LossRecoveryUpdate { .. } => CallSignalType::Offer, // reuse (telemetry)
|
||||||
SignalMessage::Ping { .. } | SignalMessage::Pong { .. } => CallSignalType::Offer,
|
SignalMessage::Ping { .. } | SignalMessage::Pong { .. } => CallSignalType::Offer,
|
||||||
SignalMessage::AuthToken { .. } => CallSignalType::Offer,
|
SignalMessage::AuthToken { .. } => CallSignalType::Offer,
|
||||||
SignalMessage::Hold => CallSignalType::Hold,
|
SignalMessage::Hold { .. } => CallSignalType::Hold,
|
||||||
SignalMessage::Unhold => CallSignalType::Unhold,
|
SignalMessage::Unhold { .. } => CallSignalType::Unhold,
|
||||||
SignalMessage::Mute => CallSignalType::Mute,
|
SignalMessage::Mute { .. } => CallSignalType::Mute,
|
||||||
SignalMessage::Unmute => CallSignalType::Unmute,
|
SignalMessage::Unmute { .. } => CallSignalType::Unmute,
|
||||||
SignalMessage::Transfer { .. } => CallSignalType::Transfer,
|
SignalMessage::Transfer { .. } => CallSignalType::Transfer,
|
||||||
SignalMessage::TransferAck => CallSignalType::Offer, // reuse
|
SignalMessage::TransferAck { .. } => CallSignalType::Offer, // reuse
|
||||||
SignalMessage::PresenceUpdate { .. } => CallSignalType::Offer, // reuse
|
SignalMessage::PresenceUpdate { .. } => CallSignalType::Offer, // reuse
|
||||||
SignalMessage::RouteQuery { .. } => CallSignalType::Offer, // reuse
|
SignalMessage::RouteQuery { .. } => CallSignalType::Offer, // reuse
|
||||||
SignalMessage::TransportFeedback { .. } => CallSignalType::Offer, // reuse (BWE)
|
SignalMessage::TransportFeedback { .. } => CallSignalType::Offer, // reuse (BWE)
|
||||||
@@ -199,19 +199,19 @@ mod tests {
|
|||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
signal_to_call_type(&SignalMessage::Hold),
|
signal_to_call_type(&SignalMessage::Hold { version: default_signal_version() }),
|
||||||
CallSignalType::Hold
|
CallSignalType::Hold
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
signal_to_call_type(&SignalMessage::Unhold),
|
signal_to_call_type(&SignalMessage::Unhold { version: default_signal_version() }),
|
||||||
CallSignalType::Unhold
|
CallSignalType::Unhold
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
signal_to_call_type(&SignalMessage::Mute),
|
signal_to_call_type(&SignalMessage::Mute { version: default_signal_version() }),
|
||||||
CallSignalType::Mute
|
CallSignalType::Mute
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
signal_to_call_type(&SignalMessage::Unmute),
|
signal_to_call_type(&SignalMessage::Unmute { version: default_signal_version() }),
|
||||||
CallSignalType::Unmute
|
CallSignalType::Unmute
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|||||||
@@ -669,13 +669,25 @@ pub enum SignalMessage {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/// Put the call on hold (stop sending media, keep session alive).
|
/// Put the call on hold (stop sending media, keep session alive).
|
||||||
Hold,
|
Hold {
|
||||||
|
#[serde(default = "default_signal_version")]
|
||||||
|
version: u8,
|
||||||
|
},
|
||||||
/// Resume a held call.
|
/// Resume a held call.
|
||||||
Unhold,
|
Unhold {
|
||||||
|
#[serde(default = "default_signal_version")]
|
||||||
|
version: u8,
|
||||||
|
},
|
||||||
/// Mute request from the remote side (server-initiated mute, like IAX2 QUELCH).
|
/// Mute request from the remote side (server-initiated mute, like IAX2 QUELCH).
|
||||||
Mute,
|
Mute {
|
||||||
|
#[serde(default = "default_signal_version")]
|
||||||
|
version: u8,
|
||||||
|
},
|
||||||
/// Unmute request from the remote side (like IAX2 UNQUELCH).
|
/// Unmute request from the remote side (like IAX2 UNQUELCH).
|
||||||
Unmute,
|
Unmute {
|
||||||
|
#[serde(default = "default_signal_version")]
|
||||||
|
version: u8,
|
||||||
|
},
|
||||||
/// Transfer the call to another peer.
|
/// Transfer the call to another peer.
|
||||||
Transfer {
|
Transfer {
|
||||||
#[serde(default = "default_signal_version")]
|
#[serde(default = "default_signal_version")]
|
||||||
@@ -685,7 +697,10 @@ pub enum SignalMessage {
|
|||||||
relay_addr: Option<String>,
|
relay_addr: Option<String>,
|
||||||
},
|
},
|
||||||
/// Acknowledge a transfer request.
|
/// Acknowledge a transfer request.
|
||||||
TransferAck,
|
TransferAck {
|
||||||
|
#[serde(default = "default_signal_version")]
|
||||||
|
version: u8,
|
||||||
|
},
|
||||||
|
|
||||||
/// Presence update from a peer relay (gossip protocol).
|
/// Presence update from a peer relay (gossip protocol).
|
||||||
/// Sent periodically over probe connections to share which fingerprints
|
/// Sent periodically over probe connections to share which fingerprints
|
||||||
@@ -1729,7 +1744,7 @@ mod tests {
|
|||||||
version: default_signal_version(),
|
version: default_signal_version(),
|
||||||
timestamp_ms: 12345,
|
timestamp_ms: 12345,
|
||||||
},
|
},
|
||||||
SignalMessage::Hold,
|
SignalMessage::Hold { version: default_signal_version() },
|
||||||
SignalMessage::Hangup {
|
SignalMessage::Hangup {
|
||||||
version: default_signal_version(),
|
version: default_signal_version(),
|
||||||
reason: HangupReason::Normal,
|
reason: HangupReason::Normal,
|
||||||
@@ -1750,28 +1765,28 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hold_unhold_serialize() {
|
fn hold_unhold_serialize() {
|
||||||
let hold = SignalMessage::Hold;
|
let hold = SignalMessage::Hold { version: default_signal_version() };
|
||||||
let json = serde_json::to_string(&hold).unwrap();
|
let json = serde_json::to_string(&hold).unwrap();
|
||||||
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
||||||
assert!(matches!(decoded, SignalMessage::Hold));
|
assert!(matches!(decoded, SignalMessage::Hold { .. }));
|
||||||
|
|
||||||
let unhold = SignalMessage::Unhold;
|
let unhold = SignalMessage::Unhold { version: default_signal_version() };
|
||||||
let json = serde_json::to_string(&unhold).unwrap();
|
let json = serde_json::to_string(&unhold).unwrap();
|
||||||
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
||||||
assert!(matches!(decoded, SignalMessage::Unhold));
|
assert!(matches!(decoded, SignalMessage::Unhold { .. }));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mute_unmute_serialize() {
|
fn mute_unmute_serialize() {
|
||||||
let mute = SignalMessage::Mute;
|
let mute = SignalMessage::Mute { version: default_signal_version() };
|
||||||
let json = serde_json::to_string(&mute).unwrap();
|
let json = serde_json::to_string(&mute).unwrap();
|
||||||
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
||||||
assert!(matches!(decoded, SignalMessage::Mute));
|
assert!(matches!(decoded, SignalMessage::Mute { .. }));
|
||||||
|
|
||||||
let unmute = SignalMessage::Unmute;
|
let unmute = SignalMessage::Unmute { version: default_signal_version() };
|
||||||
let json = serde_json::to_string(&unmute).unwrap();
|
let json = serde_json::to_string(&unmute).unwrap();
|
||||||
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
||||||
assert!(matches!(decoded, SignalMessage::Unmute));
|
assert!(matches!(decoded, SignalMessage::Unmute { .. }));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1818,10 +1833,10 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn transfer_ack_serialize() {
|
fn transfer_ack_serialize() {
|
||||||
let ack = SignalMessage::TransferAck;
|
let ack = SignalMessage::TransferAck { version: default_signal_version() };
|
||||||
let json = serde_json::to_string(&ack).unwrap();
|
let json = serde_json::to_string(&ack).unwrap();
|
||||||
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
let decoded: SignalMessage = serde_json::from_str(&json).unwrap();
|
||||||
assert!(matches!(decoded, SignalMessage::TransferAck));
|
assert!(matches!(decoded, SignalMessage::TransferAck { .. }));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user