fix(voice): reduce key rotation wait to 2s, increase E2EE poll to every 10s

Phase 2 diagnostics: caller audio arrives immediately; setting the key
earlier (2s vs 10s) avoids dropping initial frames. E2EE_CRYPTOR log
now fires every 10s (was 30s) to confirm decryption state for incoming
caller audio.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-02-22 10:27:19 +02:00
parent 5973ed1db3
commit c4581c2917

View File

@@ -263,7 +263,7 @@ class VoiceSession:
# NOTE: HTTP fetch is useless here — keys are Matrix-E2EE encrypted (m.room.encrypted). # NOTE: HTTP fetch is useless here — keys are Matrix-E2EE encrypted (m.room.encrypted).
pre_max_idx = max(self._caller_all_keys.keys()) if self._caller_all_keys else -1 pre_max_idx = max(self._caller_all_keys.keys()) if self._caller_all_keys else -1
logger.info("Waiting for EC key rotation via nio sync (current max_idx=%d)...", pre_max_idx) logger.info("Waiting for EC key rotation via nio sync (current max_idx=%d)...", pre_max_idx)
for _attempt in range(20): # up to 10s (20 × 0.5s) for _attempt in range(4): # up to 2s (4 × 0.5s)
await asyncio.sleep(0.5) await asyncio.sleep(0.5)
new_max = max(self._caller_all_keys.keys()) if self._caller_all_keys else -1 new_max = max(self._caller_all_keys.keys()) if self._caller_all_keys else -1
if new_max > pre_max_idx: if new_max > pre_max_idx:
@@ -271,10 +271,10 @@ class VoiceSession:
logger.info("Key rotated: index %d%d (%d bytes)", logger.info("Key rotated: index %d%d (%d bytes)",
pre_max_idx, new_max, len(self._caller_key)) pre_max_idx, new_max, len(self._caller_key))
break break
if _attempt % 4 == 3: # log every 2s if _attempt % 2 == 1: # log every 1s
logger.info("Key rotation wait %ds: max_idx still %d", (_attempt + 1) // 2, new_max) logger.info("Key rotation wait %0.1fs: max_idx still %d", (_attempt + 1) * 0.5, new_max)
else: else:
logger.warning("No key rotation after 10s — using pre-join key[%d]", pre_max_idx) logger.warning("No key rotation after 2s — using pre-join key[%d]", pre_max_idx)
# Set per-participant keys via key provider — pass raw base keys. # Set per-participant keys via key provider — pass raw base keys.
# KDF_HKDF=1: Rust FFI applies HKDF(base_key, ratchetSalt, ...) internally. # KDF_HKDF=1: Rust FFI applies HKDF(base_key, ratchetSalt, ...) internally.
@@ -367,7 +367,7 @@ class VoiceSession:
while True: while True:
await asyncio.sleep(5) await asyncio.sleep(5)
_poll_count += 1 _poll_count += 1
if _poll_count % 6 == 0: # Every 30s if _poll_count % 2 == 0: # Every 10s
try: try:
cryptors = self.lk_room.e2ee_manager.frame_cryptors() cryptors = self.lk_room.e2ee_manager.frame_cryptors()
for c in cryptors: for c in cryptors: