"""A fix to aiortc's SCTP sender, applied on import (aiortc 1.15). aiortc counts the bytes in flight and sends nothing new while that count is at or above the congestion window. A chunk the peer acknowledged in a gap block is marked `_acked` and taken out of the count. If the T3 timer then expires, every chunk still queued is sent again, that one included, and goes back into the count with `_acked` still set. When the cumulative ack finally covers it, the SACK handler skips it because it reads as acknowledged already, and its bytes stay counted for the life of the association. Each such loss leaks a chunk. On a lossy path (a phone on Wi-Fi) the leak grows past the window, which T3 itself keeps small. From then on the node sends nothing on that connection: nothing is outstanding, so no timer runs to unstick it, and the association still reads as established. The peer keeps talking and the node keeps answering into a queue that never moves. Live symptom: the photo backup stalled after a few dozen photos, its slot granted and the grant never delivered (docs/MESHBAY_DESIGN.md ยง9.12). The fix is the invariant the code assumed: a chunk being sent again is in flight, so it is not acknowledged. `test_sctp_fix.py` replays the sequence against aiortc itself. """ from aiortc.rtcsctptransport import RTCSctpTransport def _flight_size_increase(self, chunk) -> None: chunk._acked = False self._flight_size += chunk._book_size RTCSctpTransport._flight_size_increase = _flight_size_increase