"""aiortc's SCTP sender must not leak bytes in flight (see sctp_fix.py). Replayed against aiortc's own RTCSctpTransport: three chunks sent, the first lost and the other two acknowledged in a gap block, T3 expires and they are sent again, then a cumulative ack covers all three. Nothing is outstanding, so nothing may be counted in flight; before the fix one chunk stayed counted, and enough of those stop the node from sending anything on that connection. """ import asyncio from aiortc.rtcsctptransport import RTCSctpTransport, SackChunk import meshbay_node.transport.webrtc.core # noqa: F401 (applies the fix) class _Dtls: state = "connected" def _register_data_receiver(self, *a): pass def _sack(cumulative_tsn: int, gaps: list) -> SackChunk: sack = SackChunk() sack.cumulative_tsn = cumulative_tsn % 2**32 sack.gaps = gaps sack.duplicates = [] sack.advertised_rwnd = 1 << 20 return sack async def _replay() -> RTCSctpTransport: s = RTCSctpTransport(_Dtls()) s._association_state = s.State.ESTABLISHED async def sent(*_a, **_k): pass s._send_chunk = sent for name in ("_t3_start", "_t3_restart", "_t3_cancel"): setattr(s, name, lambda: None) s._cwnd = 100_000 for _ in range(3): await s._send(1, 51, b"x" * 1000) tsns = [c.tsn for c in s._sent_queue] await s._receive_sack_chunk(_sack(tsns[0] - 1, [(1, 2)])) s._t3_expired() await s._transmit() await s._receive_sack_chunk(_sack(tsns[-1], [])) return s def test_nothing_outstanding_means_nothing_in_flight(): s = asyncio.run(_replay()) assert not s._sent_queue assert s._flight_size == 0