mediasoup 3.20.2 → 3.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/npm-scripts.mjs +26 -0
- package/package.json +4 -3
- package/worker/include/RTC/SCTP/association/Association.hpp +16 -2
- package/worker/include/RTC/SCTP/association/HeartbeatHandler.hpp +3 -3
- package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +3 -3
- package/worker/include/RTC/SCTP/association/TransmissionControlBlock.hpp +19 -4
- package/worker/include/RTC/SCTP/association/TransmissionControlBlockContextInterface.hpp +19 -2
- package/worker/include/RTC/SCTP/public/SctpTypes.hpp +2 -0
- package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +7 -0
- package/worker/include/RTC/SCTP/tx/RetransmissionErrorCounter.hpp +3 -4
- package/worker/meson.build +3 -0
- package/worker/mocks/include/RTC/SCTP/association/MockAssociationListener.hpp +68 -7
- package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +10 -4
- package/worker/mocks/src/handles/MockBackoffTimerHandle.cpp +7 -0
- package/worker/src/RTC/SCTP/association/Association.cpp +52 -12
- package/worker/src/RTC/SCTP/association/HeartbeatHandler.cpp +48 -18
- package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +26 -17
- package/worker/src/RTC/SCTP/association/TransmissionControlBlock.cpp +48 -15
- package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +17 -8
- package/worker/src/RTC/Transport.cpp +1 -1
- package/worker/test/src/RTC/SCTP/association/TestAssociation.cpp +1755 -0
- package/worker/test/src/RTC/SCTP/association/TestHeartbeatHandler.cpp +4 -1
- package/worker/test/src/RTC/SCTP/association/TestPacketSender.cpp +121 -0
- package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +369 -0
- package/worker/test/src/RTC/SCTP/association/TestTransmissionControlBlock.cpp +16 -2
- package/worker/test/src/RTC/SCTP/rx/TestReassemblyQueue.cpp +24 -0
package/npm-scripts.mjs
CHANGED
|
@@ -232,6 +232,12 @@ async function run() {
|
|
|
232
232
|
break;
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
case 'publish:dry-run': {
|
|
236
|
+
publishDryRun();
|
|
237
|
+
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
|
|
235
241
|
case 'release:check': {
|
|
236
242
|
await checkRelease();
|
|
237
243
|
|
|
@@ -511,6 +517,23 @@ function installNodeDeps() {
|
|
|
511
517
|
executeCmd('npm audit --prefix worker/scripts');
|
|
512
518
|
}
|
|
513
519
|
|
|
520
|
+
function publishDryRun() {
|
|
521
|
+
logInfo('publishDryRun()');
|
|
522
|
+
|
|
523
|
+
// NOTE: We use `npm pack --dry-run` rather than `npm publish --dry-run`
|
|
524
|
+
// because the latter contacts the registry and fails with "You cannot
|
|
525
|
+
// publish over the previously published versions" whenever the version in
|
|
526
|
+
// package.json is already published (which is the usual state between
|
|
527
|
+
// releases), making it useless in CI.
|
|
528
|
+
//
|
|
529
|
+
// `npm pack --dry-run` still runs the `prepare` script (flatbuffers
|
|
530
|
+
// generation and TypeScript build) and assembles the tarball exactly as a
|
|
531
|
+
// real publish would, reporting its contents without writing any file or
|
|
532
|
+
// contacting the registry. Useful to validate the `files` list in
|
|
533
|
+
// package.json and that the package builds before tagging a release.
|
|
534
|
+
executeCmd('npm pack --dry-run');
|
|
535
|
+
}
|
|
536
|
+
|
|
514
537
|
async function checkRelease() {
|
|
515
538
|
logInfo('checkRelease()');
|
|
516
539
|
|
|
@@ -522,6 +545,9 @@ async function checkRelease() {
|
|
|
522
545
|
lintWorker();
|
|
523
546
|
testNode();
|
|
524
547
|
testWorker();
|
|
548
|
+
// Validate packaging (the `files` list in package.json) before the
|
|
549
|
+
// irreversible release steps (git push, GitHub release, npm publish).
|
|
550
|
+
publishDryRun();
|
|
525
551
|
}
|
|
526
552
|
|
|
527
553
|
async function release() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mediasoup",
|
|
3
|
-
"version": "3.20.
|
|
3
|
+
"version": "3.20.4",
|
|
4
4
|
"description": "Cutting Edge WebRTC Video Conferencing",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"test:worker": "node npm-scripts.mjs test:worker",
|
|
97
97
|
"coverage": "node npm-scripts.mjs coverage:node",
|
|
98
98
|
"coverage:node": "node npm-scripts.mjs coverage:node",
|
|
99
|
+
"publish:dry-run": "node npm-scripts.mjs publish:dry-run",
|
|
99
100
|
"release:check": "node npm-scripts.mjs release:check",
|
|
100
101
|
"release": "node npm-scripts.mjs release"
|
|
101
102
|
},
|
|
@@ -121,8 +122,8 @@
|
|
|
121
122
|
"globals": "^17.6.0",
|
|
122
123
|
"ini": "^6.0.0",
|
|
123
124
|
"jest": "^30.4.2",
|
|
124
|
-
"knip": "^6.
|
|
125
|
-
"marked": "^18.0.
|
|
125
|
+
"knip": "^6.16.1",
|
|
126
|
+
"marked": "^18.0.5",
|
|
126
127
|
"open-cli": "^9.0.0",
|
|
127
128
|
"pick-port": "^2.2.0",
|
|
128
129
|
"prettier": "^3.8.3",
|
|
@@ -53,7 +53,8 @@ namespace RTC
|
|
|
53
53
|
*/
|
|
54
54
|
class Association : public AssociationInterface,
|
|
55
55
|
public PacketSender::Listener,
|
|
56
|
-
public BackoffTimerHandleInterface::Listener
|
|
56
|
+
public BackoffTimerHandleInterface::Listener,
|
|
57
|
+
public TransmissionControlBlockContextInterface::Listener
|
|
57
58
|
{
|
|
58
59
|
public:
|
|
59
60
|
/**
|
|
@@ -172,7 +173,13 @@ namespace RTC
|
|
|
172
173
|
const SctpOptions& sctpOptions,
|
|
173
174
|
AssociationListenerInterface* listener,
|
|
174
175
|
SharedInterface* shared,
|
|
175
|
-
bool isDataChannel
|
|
176
|
+
bool isDataChannel,
|
|
177
|
+
// Whether `MayConnect()` should be called when SCTP data is received.
|
|
178
|
+
// This is always true in production (the association auto-initiates the
|
|
179
|
+
// connection as soon as the transport is ready or data arrives). It's
|
|
180
|
+
// only set to false in tests that need a purely passive peer to mimic
|
|
181
|
+
// dcsctp's asymmetric handshake.
|
|
182
|
+
bool mayConnectOnReceivedSctpData);
|
|
176
183
|
|
|
177
184
|
~Association() override;
|
|
178
185
|
|
|
@@ -494,6 +501,10 @@ namespace RTC
|
|
|
494
501
|
void OnBackoffTimer(
|
|
495
502
|
BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop) override;
|
|
496
503
|
|
|
504
|
+
/* Pure virtual methods inherited from TransmissionControlBlockContextInterface::Listener. */
|
|
505
|
+
public:
|
|
506
|
+
void OnTransmissionControlBlockTooManyTxErrors() override;
|
|
507
|
+
|
|
497
508
|
private:
|
|
498
509
|
// SCTP options given in the constructor.
|
|
499
510
|
SctpOptions sctpOptions;
|
|
@@ -526,6 +537,9 @@ namespace RTC
|
|
|
526
537
|
const size_t maxPacketLength;
|
|
527
538
|
// Whether this is DataChannel based SCTP.
|
|
528
539
|
bool isDataChannel;
|
|
540
|
+
// Whether `MayConnect()` should be called when SCTP data is received.
|
|
541
|
+
// See the constructor for details.
|
|
542
|
+
bool mayConnectOnReceivedSctpData;
|
|
529
543
|
};
|
|
530
544
|
} // namespace SCTP
|
|
531
545
|
} // namespace RTC
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
#include "common.hpp"
|
|
5
5
|
#include "handles/BackoffTimerHandleInterface.hpp"
|
|
6
|
+
#include "RTC/SCTP/association/AssociationListenerDeferrer.hpp"
|
|
6
7
|
#include "RTC/SCTP/association/TransmissionControlBlockContextInterface.hpp"
|
|
7
8
|
#include "RTC/SCTP/packet/chunks/HeartbeatAckChunk.hpp"
|
|
8
9
|
#include "RTC/SCTP/packet/chunks/HeartbeatRequestChunk.hpp"
|
|
9
|
-
#include "RTC/SCTP/public/AssociationListenerInterface.hpp"
|
|
10
10
|
#include "RTC/SCTP/public/SctpOptions.hpp"
|
|
11
11
|
#include "SharedInterface.hpp"
|
|
12
12
|
|
|
@@ -26,7 +26,7 @@ namespace RTC
|
|
|
26
26
|
{
|
|
27
27
|
public:
|
|
28
28
|
HeartbeatHandler(
|
|
29
|
-
|
|
29
|
+
AssociationListenerDeferrer& associationListenerDeferrer,
|
|
30
30
|
const SctpOptions& sctpOptions,
|
|
31
31
|
SharedInterface* shared,
|
|
32
32
|
TransmissionControlBlockContextInterface* tcbContext);
|
|
@@ -63,7 +63,7 @@ namespace RTC
|
|
|
63
63
|
BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop) override;
|
|
64
64
|
|
|
65
65
|
private:
|
|
66
|
-
|
|
66
|
+
AssociationListenerDeferrer& associationListenerDeferrer;
|
|
67
67
|
const SctpOptions sctpOptions;
|
|
68
68
|
SharedInterface* shared;
|
|
69
69
|
TransmissionControlBlockContextInterface* tcbContext;
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
#include "common.hpp"
|
|
5
5
|
#include "Utils/UnwrappedSequenceNumber.hpp"
|
|
6
6
|
#include "handles/BackoffTimerHandleInterface.hpp"
|
|
7
|
+
#include "RTC/SCTP/association/AssociationListenerDeferrer.hpp"
|
|
7
8
|
#include "RTC/SCTP/association/TransmissionControlBlockContextInterface.hpp"
|
|
8
9
|
#include "RTC/SCTP/packet/Packet.hpp"
|
|
9
10
|
#include "RTC/SCTP/packet/chunks/ReConfigChunk.hpp"
|
|
10
11
|
#include "RTC/SCTP/packet/parameters/IncomingSsnResetRequestParameter.hpp"
|
|
11
12
|
#include "RTC/SCTP/packet/parameters/OutgoingSsnResetRequestParameter.hpp"
|
|
12
13
|
#include "RTC/SCTP/packet/parameters/ReconfigurationResponseParameter.hpp"
|
|
13
|
-
#include "RTC/SCTP/public/AssociationListenerInterface.hpp"
|
|
14
14
|
#include "RTC/SCTP/rx/DataTracker.hpp"
|
|
15
15
|
#include "RTC/SCTP/rx/ReassemblyQueue.hpp"
|
|
16
16
|
#include "RTC/SCTP/tx/RetransmissionQueue.hpp"
|
|
@@ -168,7 +168,7 @@ namespace RTC
|
|
|
168
168
|
|
|
169
169
|
public:
|
|
170
170
|
StreamResetHandler(
|
|
171
|
-
|
|
171
|
+
AssociationListenerDeferrer& associationListenerDeferrer,
|
|
172
172
|
SharedInterface* shared,
|
|
173
173
|
TransmissionControlBlockContextInterface* tcbContext,
|
|
174
174
|
DataTracker* dataTracker,
|
|
@@ -263,7 +263,7 @@ namespace RTC
|
|
|
263
263
|
BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop) override;
|
|
264
264
|
|
|
265
265
|
private:
|
|
266
|
-
|
|
266
|
+
AssociationListenerDeferrer& associationListenerDeferrer;
|
|
267
267
|
SharedInterface* shared;
|
|
268
268
|
TransmissionControlBlockContextInterface* tcbContext;
|
|
269
269
|
DataTracker* dataTracker;
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
|
|
4
4
|
#include "common.hpp"
|
|
5
5
|
#include "handles/BackoffTimerHandleInterface.hpp"
|
|
6
|
+
#include "RTC/SCTP/association/AssociationListenerDeferrer.hpp"
|
|
6
7
|
#include "RTC/SCTP/association/HeartbeatHandler.hpp"
|
|
7
8
|
#include "RTC/SCTP/association/NegotiatedCapabilities.hpp"
|
|
8
9
|
#include "RTC/SCTP/association/PacketSender.hpp"
|
|
9
10
|
#include "RTC/SCTP/association/StreamResetHandler.hpp"
|
|
10
11
|
#include "RTC/SCTP/association/TransmissionControlBlockContextInterface.hpp"
|
|
11
12
|
#include "RTC/SCTP/packet/Packet.hpp"
|
|
12
|
-
#include "RTC/SCTP/public/AssociationListenerInterface.hpp"
|
|
13
13
|
#include "RTC/SCTP/public/SctpOptions.hpp"
|
|
14
14
|
#include "RTC/SCTP/rx/DataTracker.hpp"
|
|
15
15
|
#include "RTC/SCTP/rx/ReassemblyQueue.hpp"
|
|
@@ -37,7 +37,8 @@ namespace RTC
|
|
|
37
37
|
{
|
|
38
38
|
public:
|
|
39
39
|
TransmissionControlBlock(
|
|
40
|
-
|
|
40
|
+
TransmissionControlBlockContextInterface::Listener* listener,
|
|
41
|
+
AssociationListenerDeferrer& associationListenerDeferrer,
|
|
41
42
|
const SctpOptions& sctpOptions,
|
|
42
43
|
SharedInterface* shared,
|
|
43
44
|
SendQueueInterface& sendQueue,
|
|
@@ -250,7 +251,20 @@ namespace RTC
|
|
|
250
251
|
*/
|
|
251
252
|
bool IncrementTxErrorCounter(std::string_view reason) override
|
|
252
253
|
{
|
|
253
|
-
|
|
254
|
+
const bool withinLimit = this->txErrorCounter.Increment(reason);
|
|
255
|
+
|
|
256
|
+
if (!withinLimit)
|
|
257
|
+
{
|
|
258
|
+
// NOTE: This closes (and destroys) this TCB synchronously. It's safe to
|
|
259
|
+
// do so from within a timer handler because the handler sets the
|
|
260
|
+
// BackoffTimerHandle `stop` flag and doesn't touch any member
|
|
261
|
+
// afterwards, so the (now destroyed) firing timer won't be accessed.
|
|
262
|
+
this->listener->OnTransmissionControlBlockTooManyTxErrors();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// NOTE: `withinLimit` is a local, so this is safe even if `this` was
|
|
266
|
+
// destroyed above.
|
|
267
|
+
return withinLimit;
|
|
254
268
|
}
|
|
255
269
|
|
|
256
270
|
/**
|
|
@@ -288,7 +302,8 @@ namespace RTC
|
|
|
288
302
|
BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop) override;
|
|
289
303
|
|
|
290
304
|
private:
|
|
291
|
-
|
|
305
|
+
TransmissionControlBlockContextInterface::Listener* listener;
|
|
306
|
+
AssociationListenerDeferrer& associationListenerDeferrer;
|
|
292
307
|
const SctpOptions sctpOptions;
|
|
293
308
|
SharedInterface* shared;
|
|
294
309
|
PacketSender& packetSender;
|
|
@@ -11,6 +11,23 @@ namespace RTC
|
|
|
11
11
|
{
|
|
12
12
|
class TransmissionControlBlockContextInterface
|
|
13
13
|
{
|
|
14
|
+
public:
|
|
15
|
+
class Listener
|
|
16
|
+
{
|
|
17
|
+
public:
|
|
18
|
+
virtual ~Listener() = default;
|
|
19
|
+
|
|
20
|
+
public:
|
|
21
|
+
/**
|
|
22
|
+
* Called when the transmission error counter has exceeded its limit and
|
|
23
|
+
* the association must therefore be closed.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* - It mirrors dcsctp's `CloseConnectionBecauseOfTooManyTransmissionErrors()`.
|
|
27
|
+
*/
|
|
28
|
+
virtual void OnTransmissionControlBlockTooManyTxErrors() = 0;
|
|
29
|
+
};
|
|
30
|
+
|
|
14
31
|
public:
|
|
15
32
|
virtual ~TransmissionControlBlockContextInterface() = default;
|
|
16
33
|
|
|
@@ -44,8 +61,8 @@ namespace RTC
|
|
|
44
61
|
|
|
45
62
|
/**
|
|
46
63
|
* Increments the transmission error counter, given a human readable
|
|
47
|
-
* reason. Returns `
|
|
48
|
-
* `
|
|
64
|
+
* reason. Returns `false` if the maximum error count has been reached,
|
|
65
|
+
* `true` otherwise.
|
|
49
66
|
*/
|
|
50
67
|
virtual bool IncrementTxErrorCounter(std::string_view reason) = 0;
|
|
51
68
|
|
|
@@ -178,6 +178,13 @@ namespace RTC
|
|
|
178
178
|
ReassemblyStreamsInterface::OnAssembledMessage onAssembledMessage,
|
|
179
179
|
bool useMessageInterleaving);
|
|
180
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Treat Forward-TSN message as payload. size is calculated based on wire
|
|
183
|
+
* size rather than used memory size: 32bit for TSN + 16+16 bits for each
|
|
184
|
+
* skipped stream entry.
|
|
185
|
+
*/
|
|
186
|
+
size_t ForwardTsnCost(size_t numStreams);
|
|
187
|
+
|
|
181
188
|
void AddReassembledMessage(std::span<const Types::UnwrappedTsn> tsns, Message message);
|
|
182
189
|
|
|
183
190
|
void AssertIsConsistent() const;
|
|
@@ -18,7 +18,7 @@ namespace RTC
|
|
|
18
18
|
class RetransmissionErrorCounter
|
|
19
19
|
{
|
|
20
20
|
public:
|
|
21
|
-
RetransmissionErrorCounter(const SctpOptions& sctpOptions);
|
|
21
|
+
explicit RetransmissionErrorCounter(const SctpOptions& sctpOptions);
|
|
22
22
|
|
|
23
23
|
~RetransmissionErrorCounter();
|
|
24
24
|
|
|
@@ -26,14 +26,13 @@ namespace RTC
|
|
|
26
26
|
void Dump(int indentation = 0) const;
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Increments the retransmission timer. Returns `
|
|
30
|
-
* error count has been reached, `
|
|
29
|
+
* Increments the retransmission timer. Returns `false` if the maximum
|
|
30
|
+
* error count has been reached, `true` otherwise.
|
|
31
31
|
*/
|
|
32
32
|
bool Increment(std::string_view reason);
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Whether maximum error count has been reached.
|
|
36
|
-
* @return [description]
|
|
37
36
|
*/
|
|
38
37
|
bool IsExhausted() const
|
|
39
38
|
{
|
package/worker/meson.build
CHANGED
|
@@ -494,9 +494,12 @@ test_sources = [
|
|
|
494
494
|
'test/src/RTC/RTCP/TestPacket.cpp',
|
|
495
495
|
'test/src/RTC/RTCP/TestXr.cpp',
|
|
496
496
|
'test/src/RTC/SCTP/sctpCommon.cpp',
|
|
497
|
+
'test/src/RTC/SCTP/association/TestAssociation.cpp',
|
|
497
498
|
'test/src/RTC/SCTP/association/TestHeartbeatHandler.cpp',
|
|
498
499
|
'test/src/RTC/SCTP/association/TestNegotiatedCapabilities.cpp',
|
|
500
|
+
'test/src/RTC/SCTP/association/TestPacketSender.cpp',
|
|
499
501
|
'test/src/RTC/SCTP/association/TestStateCookie.cpp',
|
|
502
|
+
'test/src/RTC/SCTP/association/TestStreamResetHandler.cpp',
|
|
500
503
|
'test/src/RTC/SCTP/association/TestTransmissionControlBlock.cpp',
|
|
501
504
|
'test/src/RTC/SCTP/rx/TestDataTracker.cpp',
|
|
502
505
|
'test/src/RTC/SCTP/rx/TestInterleavedReassemblyStreams.cpp',
|
|
@@ -21,7 +21,7 @@ namespace mocks
|
|
|
21
21
|
{
|
|
22
22
|
this->sentPackets.emplace_back(data, data + len);
|
|
23
23
|
|
|
24
|
-
return
|
|
24
|
+
return this->sendDataResult;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
void OnAssociationConnecting() override
|
|
@@ -75,20 +75,35 @@ namespace mocks
|
|
|
75
75
|
this->receivedMessages.emplace_back(std::move(message));
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
void OnAssociationStreamsResetPerformed(std::span<const uint16_t>
|
|
78
|
+
void OnAssociationStreamsResetPerformed(std::span<const uint16_t> outboundStreamIds) override
|
|
79
79
|
{
|
|
80
|
-
|
|
80
|
+
++this->onStreamsResetPerformedCalls;
|
|
81
|
+
|
|
82
|
+
for (const auto streamId : outboundStreamIds)
|
|
83
|
+
{
|
|
84
|
+
this->streamsResetPerformed.insert(streamId);
|
|
85
|
+
}
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
void OnAssociationStreamsResetFailed(
|
|
84
|
-
std::span<const uint16_t>
|
|
89
|
+
std::span<const uint16_t> outboundStreamIds, std::string_view /*errorMessage*/) override
|
|
85
90
|
{
|
|
86
|
-
|
|
91
|
+
++this->onStreamsResetFailedCalls;
|
|
92
|
+
|
|
93
|
+
for (const auto streamId : outboundStreamIds)
|
|
94
|
+
{
|
|
95
|
+
this->streamsResetFailed.insert(streamId);
|
|
96
|
+
}
|
|
87
97
|
}
|
|
88
98
|
|
|
89
|
-
void OnAssociationInboundStreamsReset(std::span<const uint16_t>
|
|
99
|
+
void OnAssociationInboundStreamsReset(std::span<const uint16_t> inboundStreamIds) override
|
|
90
100
|
{
|
|
91
|
-
|
|
101
|
+
++this->onInboundStreamsResetCalls;
|
|
102
|
+
|
|
103
|
+
for (const auto streamId : inboundStreamIds)
|
|
104
|
+
{
|
|
105
|
+
this->inboundStreamsReset.insert(streamId);
|
|
106
|
+
}
|
|
92
107
|
}
|
|
93
108
|
|
|
94
109
|
void OnAssociationStreamBufferedAmountLow(uint16_t streamId) override
|
|
@@ -208,6 +223,45 @@ namespace mocks
|
|
|
208
223
|
return this->onTotalBufferedAmountLowCalls;
|
|
209
224
|
}
|
|
210
225
|
|
|
226
|
+
size_t CountOnStreamsResetPerformedCalls() const
|
|
227
|
+
{
|
|
228
|
+
return this->onStreamsResetPerformedCalls;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
bool HasStreamsResetPerformedForStreamId(uint16_t streamId) const
|
|
232
|
+
{
|
|
233
|
+
return this->streamsResetPerformed.contains(streamId);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
size_t CountOnStreamsResetFailedCalls() const
|
|
237
|
+
{
|
|
238
|
+
return this->onStreamsResetFailedCalls;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
bool HasStreamsResetFailedForStreamId(uint16_t streamId) const
|
|
242
|
+
{
|
|
243
|
+
return this->streamsResetFailed.contains(streamId);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
size_t CountOnInboundStreamsResetCalls() const
|
|
247
|
+
{
|
|
248
|
+
return this->onInboundStreamsResetCalls;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
bool HasInboundStreamsResetForStreamId(uint16_t streamId) const
|
|
252
|
+
{
|
|
253
|
+
return this->inboundStreamsReset.contains(streamId);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Sets the value that `OnAssociationSendData()` will return, allowing
|
|
258
|
+
* tests to simulate a failed send.
|
|
259
|
+
*/
|
|
260
|
+
void SetSendDataResult(bool sendDataResult)
|
|
261
|
+
{
|
|
262
|
+
this->sendDataResult = sendDataResult;
|
|
263
|
+
}
|
|
264
|
+
|
|
211
265
|
bool HasSentPackets() const
|
|
212
266
|
{
|
|
213
267
|
return !this->sentPackets.empty();
|
|
@@ -293,6 +347,13 @@ namespace mocks
|
|
|
293
347
|
std::string erroredErrorMessage;
|
|
294
348
|
std::map<uint16_t /*streamId*/, size_t /*count*/> onStreamBufferedAmountLowCalls;
|
|
295
349
|
size_t onTotalBufferedAmountLowCalls{ 0 };
|
|
350
|
+
size_t onStreamsResetPerformedCalls{ 0 };
|
|
351
|
+
std::set<uint16_t /*streamId*/> streamsResetPerformed;
|
|
352
|
+
size_t onStreamsResetFailedCalls{ 0 };
|
|
353
|
+
std::set<uint16_t /*streamId*/> streamsResetFailed;
|
|
354
|
+
size_t onInboundStreamsResetCalls{ 0 };
|
|
355
|
+
std::set<uint16_t /*streamId*/> inboundStreamsReset;
|
|
356
|
+
bool sendDataResult{ true };
|
|
296
357
|
std::deque<std::vector<uint8_t>> sentPackets;
|
|
297
358
|
std::deque<::RTC::SCTP::Message> receivedMessages;
|
|
298
359
|
bool transportReady{ true };
|
|
@@ -36,14 +36,20 @@ namespace mocks
|
|
|
36
36
|
|
|
37
37
|
void Start() override
|
|
38
38
|
{
|
|
39
|
-
this->running
|
|
40
|
-
|
|
39
|
+
this->running = true;
|
|
40
|
+
// NOTE: Reset the expiration count, just like the real BackoffTimerHandle
|
|
41
|
+
// does, so that the backoff starts over from the base timeout.
|
|
42
|
+
this->expirationCount = 0;
|
|
43
|
+
this->expiresAtMs = this->getTimeMs() + ComputeNextTimeoutMs();
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
void Stop() override
|
|
44
47
|
{
|
|
45
|
-
this->running
|
|
46
|
-
|
|
48
|
+
this->running = false;
|
|
49
|
+
// NOTE: Reset the expiration count, just like the real BackoffTimerHandle
|
|
50
|
+
// does.
|
|
51
|
+
this->expirationCount = 0;
|
|
52
|
+
this->expiresAtMs = std::numeric_limits<uint64_t>::max();
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
/**
|
|
@@ -123,5 +123,12 @@ namespace mocks
|
|
|
123
123
|
{
|
|
124
124
|
this->expiresAtMs = this->getTimeMs() + ComputeNextTimeoutMs();
|
|
125
125
|
}
|
|
126
|
+
// Once the timer is no longer running (e.g. max restarts reached), the real
|
|
127
|
+
// BackoffTimerHandle doesn't restart the underlying timer, so it won't fire
|
|
128
|
+
// again. Mirror that here so a stopped timer doesn't keep expiring.
|
|
129
|
+
else
|
|
130
|
+
{
|
|
131
|
+
this->expiresAtMs = std::numeric_limits<uint64_t>::max();
|
|
132
|
+
}
|
|
126
133
|
}
|
|
127
134
|
} // namespace mocks
|
|
@@ -40,7 +40,8 @@ namespace RTC
|
|
|
40
40
|
const SctpOptions& sctpOptions,
|
|
41
41
|
AssociationListenerInterface* listener,
|
|
42
42
|
SharedInterface* shared,
|
|
43
|
-
bool isDataChannel
|
|
43
|
+
bool isDataChannel,
|
|
44
|
+
bool mayConnectOnReceivedSctpData)
|
|
44
45
|
: sctpOptions(sctpOptions),
|
|
45
46
|
// Our `listener` member is a `AssociationListenerDeferrer` which takes
|
|
46
47
|
// `listener` argument as constructor argument.
|
|
@@ -78,7 +79,8 @@ namespace RTC
|
|
|
78
79
|
.maxBackoffTimeoutMs = sctpOptions.timerMaxBackoffTimeoutMs,
|
|
79
80
|
.maxRestarts = sctpOptions.maxRetransmissions })),
|
|
80
81
|
maxPacketLength(Utils::Byte::PadDownTo4Bytes(this->sctpOptions.mtu)),
|
|
81
|
-
isDataChannel(isDataChannel)
|
|
82
|
+
isDataChannel(isDataChannel),
|
|
83
|
+
mayConnectOnReceivedSctpData(mayConnectOnReceivedSctpData)
|
|
82
84
|
{
|
|
83
85
|
MS_TRACE();
|
|
84
86
|
}
|
|
@@ -542,7 +544,13 @@ namespace RTC
|
|
|
542
544
|
|
|
543
545
|
// If we are received SCTP data from the remote peer it means that we may
|
|
544
546
|
// initiate the SCTP association (if not already connected).
|
|
545
|
-
|
|
547
|
+
//
|
|
548
|
+
// NOTE: This is disabled in tests that need a purely passive peer to
|
|
549
|
+
// mimic dcsctp's asymmetric handshake.
|
|
550
|
+
if (this->mayConnectOnReceivedSctpData)
|
|
551
|
+
{
|
|
552
|
+
MayConnect();
|
|
553
|
+
}
|
|
546
554
|
|
|
547
555
|
// NOTE: It's important to create the deferrer here, otherwise it may
|
|
548
556
|
// happen that MayConnect() ends calling to Connect() so we end with two
|
|
@@ -749,6 +757,7 @@ namespace RTC
|
|
|
749
757
|
MS_TRACE();
|
|
750
758
|
|
|
751
759
|
this->tcb = std::make_unique<TransmissionControlBlock>(
|
|
760
|
+
this,
|
|
752
761
|
this->associationListenerDeferrer,
|
|
753
762
|
this->sctpOptions,
|
|
754
763
|
this->shared,
|
|
@@ -2425,6 +2434,15 @@ namespace RTC
|
|
|
2425
2434
|
{
|
|
2426
2435
|
MS_TRACE();
|
|
2427
2436
|
|
|
2437
|
+
const auto maxRestarts = this->t1InitTimer->GetMaxRestarts();
|
|
2438
|
+
|
|
2439
|
+
MS_DEBUG_TAG(
|
|
2440
|
+
sctp,
|
|
2441
|
+
"%s timer has expired [expirations:%zu, maxRestarts:%s]",
|
|
2442
|
+
this->t1InitTimer->GetLabel().c_str(),
|
|
2443
|
+
this->t1InitTimer->GetExpirationCount(),
|
|
2444
|
+
maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
|
|
2445
|
+
|
|
2428
2446
|
const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
|
|
2429
2447
|
|
|
2430
2448
|
AssertState(State::COOKIE_WAIT);
|
|
@@ -2445,6 +2463,15 @@ namespace RTC
|
|
|
2445
2463
|
{
|
|
2446
2464
|
MS_TRACE();
|
|
2447
2465
|
|
|
2466
|
+
const auto maxRestarts = this->t1CookieTimer->GetMaxRestarts();
|
|
2467
|
+
|
|
2468
|
+
MS_DEBUG_TAG(
|
|
2469
|
+
sctp,
|
|
2470
|
+
"%s timer has expired [expirations:%zu, maxRestarts:%s]",
|
|
2471
|
+
this->t1CookieTimer->GetLabel().c_str(),
|
|
2472
|
+
this->t1CookieTimer->GetExpirationCount(),
|
|
2473
|
+
maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
|
|
2474
|
+
|
|
2448
2475
|
const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
|
|
2449
2476
|
|
|
2450
2477
|
AssertState(State::COOKIE_ECHOED);
|
|
@@ -2467,6 +2494,15 @@ namespace RTC
|
|
|
2467
2494
|
{
|
|
2468
2495
|
MS_TRACE();
|
|
2469
2496
|
|
|
2497
|
+
const auto maxRestarts = this->t2ShutdownTimer->GetMaxRestarts();
|
|
2498
|
+
|
|
2499
|
+
MS_DEBUG_TAG(
|
|
2500
|
+
sctp,
|
|
2501
|
+
"%s timer has expired [expirations:%zu, maxRestarts:%s]",
|
|
2502
|
+
this->t2ShutdownTimer->GetLabel().c_str(),
|
|
2503
|
+
this->t2ShutdownTimer->GetExpirationCount(),
|
|
2504
|
+
maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
|
|
2505
|
+
|
|
2470
2506
|
AssertState(State::SHUTDOWN_SENT, State::SHUTDOWN_ACK_SENT);
|
|
2471
2507
|
AssertHasTcb();
|
|
2472
2508
|
|
|
@@ -2811,15 +2847,6 @@ namespace RTC
|
|
|
2811
2847
|
{
|
|
2812
2848
|
MS_TRACE();
|
|
2813
2849
|
|
|
2814
|
-
const auto maxRestarts = backoffTimer->GetMaxRestarts();
|
|
2815
|
-
|
|
2816
|
-
MS_DEBUG_TAG(
|
|
2817
|
-
sctp,
|
|
2818
|
-
"%s timer has expired [expìrations:%zu/%s]",
|
|
2819
|
-
backoffTimer->GetLabel().c_str(),
|
|
2820
|
-
backoffTimer->GetExpirationCount(),
|
|
2821
|
-
maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
|
|
2822
|
-
|
|
2823
2850
|
if (backoffTimer == this->t1InitTimer.get())
|
|
2824
2851
|
{
|
|
2825
2852
|
OnT1InitTimer(baseTimeoutMs, stop);
|
|
@@ -2833,5 +2860,18 @@ namespace RTC
|
|
|
2833
2860
|
OnT2ShutdownTimer(baseTimeoutMs, stop);
|
|
2834
2861
|
}
|
|
2835
2862
|
}
|
|
2863
|
+
|
|
2864
|
+
void Association::OnTransmissionControlBlockTooManyTxErrors()
|
|
2865
|
+
{
|
|
2866
|
+
MS_TRACE();
|
|
2867
|
+
|
|
2868
|
+
// NOTE: This is invoked from within a TCB timer handler (t3-rtx, heartbeat
|
|
2869
|
+
// or RE-CONFIG timeout). `InternalClose()` destroys the TCB synchronously,
|
|
2870
|
+
// which is safe because the calling timer handler sets the BackoffTimerHandle
|
|
2871
|
+
// `stop` flag and doesn't touch any member afterwards. `InternalClose()` does
|
|
2872
|
+
// not establish its own deferrer scope, so it relies on the active one set up
|
|
2873
|
+
// by the timer handler.
|
|
2874
|
+
InternalClose(Types::ErrorKind::TOO_MANY_RETRIES, "too many transmission errors");
|
|
2875
|
+
}
|
|
2836
2876
|
} // namespace SCTP
|
|
2837
2877
|
} // namespace RTC
|