oxpulse_sfu_kit/sframe.rs
1//! SFrame (RFC 9605) key-epoch forwarding seam.
2//!
3//! The SFU does not encrypt or decrypt payloads — SFrame encryption is
4//! frame-level and end-to-end (publisher ↔ subscriber). This module provides
5//! the [`KeyEpoch`] newtype for forwarding the key-epoch RTP header extension
6//! so application code can route key distribution independently of the SFU
7//! forwarding path.
8
9/// The key-epoch value carried in the SFrame RTP header extension.
10///
11/// Maps to the `KID` (key identifier) field in SFrame (RFC 9605 §4.2).
12/// Increment on each group key rotation. Receivers use this to select the
13/// correct decryption key.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15pub struct KeyEpoch(pub u64);
16
17impl KeyEpoch {
18 /// Create from a raw `u64` KID value.
19 pub fn new(kid: u64) -> Self {
20 Self(kid)
21 }
22
23 /// Raw KID value.
24 #[must_use]
25 pub fn as_u64(self) -> u64 {
26 self.0
27 }
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33
34 #[test]
35 fn key_epoch_roundtrip() {
36 let k = KeyEpoch::new(42);
37 assert_eq!(k.as_u64(), 42);
38 }
39
40 #[test]
41 fn key_epoch_zero() {
42 let k = KeyEpoch::new(0);
43 assert_eq!(k.as_u64(), 0);
44 }
45}