fix(e2ee): aggressive video re-keying after track subscription (MAT-144)
Video frame cryptors may not be fully initialized when set_key() is first called during on_track_subscribed. Audio works immediately but video oscillates OK↔DEC_FAILED with the same key. Add staggered re-keying at 0.3s, 0.8s, 2s, 5s after video track subscription to ensure the key is applied after the frame cryptor is fully ready. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
21
voice.py
21
voice.py
@@ -693,8 +693,25 @@ class VoiceSession:
|
|||||||
if self._caller_all_keys:
|
if self._caller_all_keys:
|
||||||
for idx, base_k in sorted(self._caller_all_keys.items()):
|
for idx, base_k in sorted(self._caller_all_keys.items()):
|
||||||
_derive_and_set_key(kp_local, caller_id, base_k, idx)
|
_derive_and_set_key(kp_local, caller_id, base_k, idx)
|
||||||
logger.info("on_ts: derived+set key[%d] for %s (%s track)",
|
logger.info("on_ts: set key[%d] for %s (%s track)",
|
||||||
idx, caller_id, track_type)
|
idx, caller_id, track_type)
|
||||||
|
# MAT-144: Video frame cryptors may not be fully initialized
|
||||||
|
# when set_key is first called. Schedule aggressive re-keying.
|
||||||
|
if int(t.kind) == 2:
|
||||||
|
async def _video_rekey(pid=caller_id):
|
||||||
|
for delay in (0.3, 0.8, 2.0, 5.0):
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
if not self.lk_room:
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
kp_v = self.lk_room.e2ee_manager.key_provider
|
||||||
|
for idx, base_k in sorted(self._caller_all_keys.items()):
|
||||||
|
_derive_and_set_key(kp_v, pid, base_k, idx)
|
||||||
|
logger.info("video_rekey: re-set %d keys for %s (delay=%.1fs)",
|
||||||
|
len(self._caller_all_keys), pid, delay)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning("video_rekey failed: %s", exc)
|
||||||
|
asyncio.ensure_future(_video_rekey())
|
||||||
else:
|
else:
|
||||||
logger.warning("on_ts: no caller keys yet — scheduling 0.5s retry")
|
logger.warning("on_ts: no caller keys yet — scheduling 0.5s retry")
|
||||||
async def _brief_key_retry(pid=caller_id):
|
async def _brief_key_retry(pid=caller_id):
|
||||||
@@ -704,7 +721,7 @@ class VoiceSession:
|
|||||||
kp_r = self.lk_room.e2ee_manager.key_provider
|
kp_r = self.lk_room.e2ee_manager.key_provider
|
||||||
for idx, base_k in sorted(self._caller_all_keys.items()):
|
for idx, base_k in sorted(self._caller_all_keys.items()):
|
||||||
_derive_and_set_key(kp_r, pid, base_k, idx)
|
_derive_and_set_key(kp_r, pid, base_k, idx)
|
||||||
logger.info("on_ts_retry: derived+set key[%d] for %s", idx, pid)
|
logger.info("on_ts_retry: set key[%d] for %s", idx, pid)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.warning("on_ts_retry: set_key failed: %s", exc)
|
logger.warning("on_ts_retry: set_key failed: %s", exc)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user