1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
"""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
|