mediasoup 3.19.19 → 3.19.21

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.
Files changed (91) hide show
  1. package/README.md +4 -4
  2. package/node/lib/Worker.d.ts +1 -1
  3. package/node/lib/Worker.d.ts.map +1 -1
  4. package/node/lib/Worker.js +8 -2
  5. package/node/lib/WorkerTypes.d.ts +8 -4
  6. package/node/lib/WorkerTypes.d.ts.map +1 -1
  7. package/node/lib/index.d.ts +1 -1
  8. package/node/lib/index.d.ts.map +1 -1
  9. package/node/lib/index.js +2 -1
  10. package/node/lib/sctpParametersTypes.d.ts +3 -13
  11. package/node/lib/sctpParametersTypes.d.ts.map +1 -1
  12. package/node/lib/test/test-PlainTransport.js +8 -3
  13. package/node/lib/test/test-WebRtcTransport.js +9 -4
  14. package/package.json +10 -10
  15. package/worker/Makefile +0 -4
  16. package/worker/fuzzer/src/fuzzer.cpp +6 -5
  17. package/worker/include/RTC/DataConsumer.hpp +4 -14
  18. package/worker/include/RTC/SCTP/TODO_SCTP.md +18 -10
  19. package/worker/include/RTC/SCTP/association/Association.hpp +39 -31
  20. package/worker/include/RTC/SCTP/association/{AssociationDeferredListener.hpp → AssociationListenerDeferrer.hpp} +10 -8
  21. package/worker/include/RTC/SCTP/association/HeartbeatHandler.hpp +77 -0
  22. package/worker/include/RTC/SCTP/association/NegotiatedCapabilities.hpp +2 -2
  23. package/worker/include/RTC/SCTP/association/PacketSender.hpp +2 -2
  24. package/worker/include/RTC/SCTP/association/StateCookie.hpp +2 -2
  25. package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +272 -0
  26. package/worker/include/RTC/SCTP/association/TCBContext.hpp +67 -0
  27. package/worker/include/RTC/SCTP/association/TransmissionControlBlock.hpp +81 -11
  28. package/worker/include/RTC/SCTP/common/UnwrappedSequenceNumber.hpp +274 -0
  29. package/worker/include/RTC/SCTP/packet/Chunk.hpp +0 -1
  30. package/worker/include/RTC/SCTP/packet/UserData.hpp +1 -0
  31. package/worker/include/RTC/SCTP/packet/parameters/IncomingSsnResetRequestParameter.hpp +14 -10
  32. package/worker/include/RTC/SCTP/packet/parameters/OutgoingSsnResetRequestParameter.hpp +14 -10
  33. package/worker/include/RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp +13 -2
  34. package/worker/include/RTC/SCTP/public/AssociationInterface.hpp +7 -1
  35. package/worker/include/RTC/SCTP/public/AssociationListener.hpp +11 -0
  36. package/worker/include/RTC/SCTP/public/Message.hpp +1 -0
  37. package/worker/include/RTC/SCTP/public/SctpOptions.hpp +4 -4
  38. package/worker/include/RTC/SctpAssociation.hpp +2 -2
  39. package/worker/include/RTC/Transport.hpp +9 -13
  40. package/worker/include/Settings.hpp +2 -1
  41. package/worker/include/Utils.hpp +130 -6
  42. package/worker/meson.build +10 -39
  43. package/worker/meson_options.txt +0 -1
  44. package/worker/scripts/package-lock.json +6 -6
  45. package/worker/src/DepLibUring.cpp +1 -1
  46. package/worker/src/RTC/DataConsumer.cpp +5 -29
  47. package/worker/src/RTC/PipeTransport.cpp +15 -12
  48. package/worker/src/RTC/PlainTransport.cpp +15 -12
  49. package/worker/src/RTC/RTP/RetransmissionBuffer.cpp +5 -5
  50. package/worker/src/RTC/RTP/RtpStream.cpp +2 -2
  51. package/worker/src/RTC/RTP/RtxStream.cpp +1 -1
  52. package/worker/src/RTC/RateCalculator.cpp +5 -5
  53. package/worker/src/RTC/SCTP/association/Association.cpp +218 -148
  54. package/worker/src/RTC/SCTP/association/{AssociationDeferredListener.cpp → AssociationListenerDeferrer.cpp} +38 -30
  55. package/worker/src/RTC/SCTP/association/HeartbeatHandler.cpp +244 -0
  56. package/worker/src/RTC/SCTP/association/NegotiatedCapabilities.cpp +8 -6
  57. package/worker/src/RTC/SCTP/association/PacketSender.cpp +7 -2
  58. package/worker/src/RTC/SCTP/association/StateCookie.cpp +8 -8
  59. package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +512 -0
  60. package/worker/src/RTC/SCTP/association/TransmissionControlBlock.cpp +45 -39
  61. package/worker/src/RTC/SCTP/packet/chunks/SackChunk.cpp +1 -1
  62. package/worker/src/RTC/SCTP/packet/errorCauses/UserInitiatedAbortErrorCause.cpp +1 -1
  63. package/worker/src/RTC/SCTP/packet/parameters/IncomingSsnResetRequestParameter.cpp +22 -5
  64. package/worker/src/RTC/SCTP/packet/parameters/OutgoingSsnResetRequestParameter.cpp +22 -5
  65. package/worker/src/RTC/SCTP/tx/RetransmissionErrorCounter.cpp +1 -1
  66. package/worker/src/RTC/SctpAssociation.cpp +1 -2
  67. package/worker/src/RTC/SeqManager.cpp +4 -4
  68. package/worker/src/RTC/Transport.cpp +247 -134
  69. package/worker/src/RTC/WebRtcTransport.cpp +9 -5
  70. package/worker/src/Settings.cpp +21 -1
  71. package/worker/src/Worker.cpp +13 -10
  72. package/worker/src/lib.cpp +11 -8
  73. package/worker/tasks.py +2 -35
  74. package/worker/test/src/RTC/SCTP/association/TestNegotiatedCapabilities.cpp +13 -12
  75. package/worker/test/src/RTC/SCTP/association/TestStateCookie.cpp +20 -20
  76. package/worker/test/src/RTC/SCTP/common/TestUnwrappedSequenceNumber.cpp +210 -0
  77. package/worker/test/src/RTC/SCTP/packet/chunks/TestAbortAssociationChunk.cpp +2 -2
  78. package/worker/test/src/RTC/SCTP/packet/chunks/TestHeartbeatAckChunk.cpp +9 -4
  79. package/worker/test/src/RTC/SCTP/packet/chunks/TestHeartbeatRequestChunk.cpp +5 -0
  80. package/worker/test/src/RTC/SCTP/packet/chunks/TestInitAckChunk.cpp +1 -1
  81. package/worker/test/src/RTC/SCTP/packet/chunks/TestInitChunk.cpp +5 -5
  82. package/worker/test/src/RTC/SCTP/packet/chunks/TestReConfigChunk.cpp +19 -20
  83. package/worker/test/src/RTC/SCTP/packet/chunks/TestUnknownChunk.cpp +3 -0
  84. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestUnknownErrorCause.cpp +3 -0
  85. package/worker/test/src/RTC/SCTP/packet/parameters/TestIncomingSsnResetRequestParameter.cpp +24 -27
  86. package/worker/test/src/RTC/SCTP/packet/parameters/TestOutgoingSsnResetRequestParameter.cpp +25 -30
  87. package/worker/test/src/RTC/SCTP/packet/parameters/TestStateCookieParameter.cpp +8 -6
  88. package/worker/test/src/RTC/SCTP/packet/parameters/TestSupportedExtensionsParameter.cpp +12 -0
  89. package/worker/test/src/RTC/SCTP/packet/parameters/TestZeroChecksumAcceptableParameter.cpp +5 -8
  90. package/worker/test/src/Utils/TestNumber.cpp +119 -49
  91. package/worker/test/src/tests.cpp +11 -8
@@ -1,5 +1,5 @@
1
- #ifndef MS_RTC_SCTP_ASSOCIATION_DEFERRED_LISTENER_HPP
2
- #define MS_RTC_SCTP_ASSOCIATION_DEFERRED_LISTENER_HPP
1
+ #ifndef MS_RTC_SCTP_ASSOCIATION_LISTENER_DEFERRED_HPP
2
+ #define MS_RTC_SCTP_ASSOCIATION_LISTENER_DEFERRED_HPP
3
3
 
4
4
  #include "common.hpp"
5
5
  #include "RTC/SCTP/public/AssociationListener.hpp"
@@ -15,18 +15,18 @@ namespace RTC
15
15
  {
16
16
  namespace SCTP
17
17
  {
18
- class AssociationDeferredListener : public AssociationListener
18
+ class AssociationListenerDeferrer : public AssociationListener
19
19
  {
20
20
  public:
21
- class ScopedDeferred
21
+ class ScopedDeferrer
22
22
  {
23
23
  public:
24
- explicit ScopedDeferred(AssociationDeferredListener& deferredListener);
24
+ explicit ScopedDeferrer(AssociationListenerDeferrer& listenerDeferrer);
25
25
 
26
- ~ScopedDeferred();
26
+ ~ScopedDeferrer();
27
27
 
28
28
  private:
29
- AssociationDeferredListener& deferredListener;
29
+ AssociationListenerDeferrer& listenerDeferrer;
30
30
  };
31
31
 
32
32
  private:
@@ -49,7 +49,7 @@ namespace RTC
49
49
  using Callback = std::function<void(CallbackData, AssociationListener*)>;
50
50
 
51
51
  public:
52
- explicit AssociationDeferredListener(AssociationListener* innerListener);
52
+ explicit AssociationListenerDeferrer(AssociationListener* innerListener);
53
53
 
54
54
  private:
55
55
  void SetReady();
@@ -85,6 +85,8 @@ namespace RTC
85
85
 
86
86
  void OnAssociationTotalBufferedAmountLow() override;
87
87
 
88
+ bool OnAssociationIsTransportReadyForSctp() override;
89
+
88
90
  private:
89
91
  AssociationListener* innerListener;
90
92
  bool ready{ false };
@@ -0,0 +1,77 @@
1
+ #ifndef MS_RTC_SCTP_HEARTBEAT_HANDLER_HPP
2
+ #define MS_RTC_SCTP_HEARTBEAT_HANDLER_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/SCTP/association/TCBContext.hpp"
6
+ #include "RTC/SCTP/packet/chunks/HeartbeatAckChunk.hpp"
7
+ #include "RTC/SCTP/packet/chunks/HeartbeatRequestChunk.hpp"
8
+ #include "RTC/SCTP/public/AssociationListener.hpp"
9
+ #include "RTC/SCTP/public/SctpOptions.hpp"
10
+ #include "handles/BackoffTimerHandle.hpp"
11
+
12
+ namespace RTC
13
+ {
14
+ namespace SCTP
15
+ {
16
+ /**
17
+ * HeartbeatHandler handles all logic around sending heartbeats and receiving
18
+ * the responses, as well as receiving incoming heartbeat requests.
19
+ *
20
+ * Heartbeats are sent on idle connections to ensure that the connection is
21
+ * still healthy and to measure the RTT. If a number of heartbeats time out,
22
+ * the connection will eventually be closed.
23
+ */
24
+ class HeartbeatHandler : public BackoffTimerHandle::Listener
25
+ {
26
+ public:
27
+ HeartbeatHandler(
28
+ AssociationListener& associationListener,
29
+ const SctpOptions& sctpOptions,
30
+ TCBContext* tcbContext);
31
+
32
+ ~HeartbeatHandler() override;
33
+
34
+ public:
35
+ /**
36
+ * Called when the heartbeat interval timer should be restarted. This is
37
+ * generally done every time data is sent, which makes the timer expire
38
+ * when the connection is idle.
39
+ */
40
+ void RestartTimer();
41
+
42
+ /**
43
+ * Called on received HEARTBEAT_REQUEST Chunk.
44
+ */
45
+ void HandleReceivedHeartbeatRequestChunk(
46
+ const HeartbeatRequestChunk* receivedHeartbeatRequestChunk);
47
+
48
+ /**
49
+ * Called on received HEARTBEAT_ACK Chunk.
50
+ */
51
+ void HandleReceivedHeartbeatAckChunk(const HeartbeatAckChunk* receivedHeartbeatAckChunk);
52
+
53
+ private:
54
+ void OnIntervalTimer(uint64_t& baseTimeoutMs, bool& stop);
55
+
56
+ void OnTimeoutTimer(uint64_t& baseTimeoutMs, bool& stop);
57
+
58
+ /* Pure virtual methods inherited from BackoffTimerHandle::Listener. */
59
+ public:
60
+ void OnTimer(BackoffTimerHandle* backoffTimer, uint64_t& baseTimeoutMs, bool& stop) override;
61
+
62
+ private:
63
+ AssociationListener& associationListener;
64
+ const SctpOptions sctpOptions;
65
+ TCBContext* tcbContext{ nullptr };
66
+ // The time for a connection to be idle before a heartbeat is sent.
67
+ const uint64_t intervalDurationMs{ 0 };
68
+ // Adding RTT to the duration will add some jitter, which is good in
69
+ // production, but less good in unit tests, which is why it can be disabled.
70
+ const bool intervalDurationShouldIncludeRtt{ false };
71
+ const std::unique_ptr<BackoffTimerHandle> intervalTimer;
72
+ const std::unique_ptr<BackoffTimerHandle> timeoutTimer;
73
+ };
74
+ } // namespace SCTP
75
+ } // namespace RTC
76
+
77
+ #endif
@@ -29,12 +29,12 @@ namespace RTC
29
29
  /**
30
30
  * Negotiated maximum number of outbound streams (OS).
31
31
  */
32
- uint16_t maxOutboundStreams{ 0 };
32
+ uint16_t negotiatedMaxOutboundStreams{ 0 };
33
33
 
34
34
  /**
35
35
  * Negotiated maximum number of inbound streams (MIS).
36
36
  */
37
- uint16_t maxInboundStreams{ 0 };
37
+ uint16_t negotiatedMaxInboundStreams{ 0 };
38
38
 
39
39
  /**
40
40
  * Partial Reliability Extension.
@@ -23,7 +23,7 @@ namespace RTC
23
23
  };
24
24
 
25
25
  public:
26
- PacketSender(Listener& listener, AssociationListener& associationListener);
26
+ PacketSender(Listener* listener, AssociationListener& associationListener);
27
27
 
28
28
  ~PacketSender();
29
29
 
@@ -42,7 +42,7 @@ namespace RTC
42
42
  bool SendPacket(Packet* packet, bool writeChecksum = true);
43
43
 
44
44
  private:
45
- Listener& listener;
45
+ Listener* listener;
46
46
  AssociationListener& associationListener;
47
47
  };
48
48
  } // namespace SCTP
@@ -79,8 +79,8 @@ namespace RTC
79
79
  uint8_t bitA : 1;
80
80
  #endif
81
81
  uint16_t magic2;
82
- uint16_t maxOutboundStreams;
83
- uint16_t maxInboundStreams;
82
+ uint16_t negotiatedMaxOutboundStreams;
83
+ uint16_t negotiatedMaxInboundStreams;
84
84
  };
85
85
 
86
86
  public:
@@ -0,0 +1,272 @@
1
+ #ifndef MS_RTC_SCTP_STREAM_RESET_HANDLER_HPP
2
+ #define MS_RTC_SCTP_STREAM_RESET_HANDLER_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/SCTP/association/TCBContext.hpp"
6
+ #include "RTC/SCTP/common/UnwrappedSequenceNumber.hpp"
7
+ #include "RTC/SCTP/packet/Packet.hpp"
8
+ #include "RTC/SCTP/packet/chunks/ReConfigChunk.hpp"
9
+ #include "RTC/SCTP/packet/parameters/IncomingSsnResetRequestParameter.hpp"
10
+ #include "RTC/SCTP/packet/parameters/OutgoingSsnResetRequestParameter.hpp"
11
+ #include "RTC/SCTP/packet/parameters/ReconfigurationResponseParameter.hpp"
12
+ #include "RTC/SCTP/public/AssociationListener.hpp"
13
+ #include "handles/BackoffTimerHandle.hpp"
14
+ #include <span>
15
+ #include <vector>
16
+
17
+ namespace RTC
18
+ {
19
+ namespace SCTP
20
+ {
21
+ /**
22
+ * StreamResetHandler handles sending outgoing stream reset requests (to
23
+ * close an SCTP stream, which translates to closing a data channel in
24
+ * WebRTC).
25
+ *
26
+ * It also handles incoming "outgoing stream reset requests", when the peer
27
+ * wants to close its streams.
28
+ *
29
+ * Resetting streams is an asynchronous operation where the client will
30
+ * request a request a stream to be reset, but then it might not be
31
+ * performed exactly at this point. First, the sender might need to discard
32
+ * all messages that have been enqueued for this stream, or it may select to
33
+ * wait until all have been sent. At least, it must wait for the currently
34
+ * sending fragmented message to be fully sent, because a stream can't be
35
+ * reset while having received half a message. In the stream reset request,
36
+ * the "sender's last assigned TSN" is provided, which is simply the TSN for
37
+ * which the receiver should've received all messages before this value,
38
+ * before the stream can be reset. Since fragments can get lost or sent
39
+ * out-of-order, the receiver of a request may not have received all the
40
+ * data just yet, and then it will respond to the sender: "In progress". In
41
+ * other words, try again. The sender will then need to start a timer and
42
+ * try the very same request again (but with a new sequence number) until
43
+ * the receiver successfully performs the operation.
44
+ *
45
+ * All this can take some time, and may be driven by timers, so the client
46
+ * will ultimately be notified using callbacks.
47
+ *
48
+ * In this implementation, when a stream is reset, the queued but
49
+ * not-yet-sent messages will be discarded, but that may change in the future.
50
+ * RFC8831 allows both behaviors.
51
+ */
52
+ class StreamResetHandler : public TCBContext, public BackoffTimerHandle::Listener
53
+ {
54
+ private:
55
+ enum class ReqSeqNbrValidationResult : uint8_t
56
+ {
57
+ VALID,
58
+ RETRANSMISSION,
59
+ BAD_SEQUENCE_NUMBER,
60
+ };
61
+
62
+ /**
63
+ * Represents a stream request operation. There can only be one ongoing at
64
+ * any time, and a sent request may either succeed, fail or result in the
65
+ * receiver signaling that it can't process it right now, and then it will
66
+ * be retried.
67
+ */
68
+ class CurrentRequest
69
+ {
70
+ public:
71
+ CurrentRequest(uint32_t senderLastAssignedTsn, std::vector<uint16_t> streamIds)
72
+ : reqSeqNbr(std::nullopt),
73
+ senderLastAssignedTsn(senderLastAssignedTsn),
74
+ streamIds(std::move(streamIds))
75
+ {
76
+ }
77
+
78
+ /**
79
+ * Returns the current request sequence number, if this request has been
80
+ * sent (check `HasBeenFirst()` first). Will return 0 if the request is
81
+ * just prepared (or scheduled for retransmission) but not yet sent.
82
+ */
83
+ uint32_t GetReqSeqNbr() const
84
+ {
85
+ return this->reqSeqNbr.value_or(0);
86
+ }
87
+
88
+ /**
89
+ * The sender's last assigned TSN, from the retransmission queue. The
90
+ * receiver uses this to know when all data up to this TSN has been
91
+ * received, to know when to safely reset the stream.
92
+ */
93
+ uint32_t GetSenderLastAssignedTsn() const
94
+ {
95
+ return senderLastAssignedTsn;
96
+ }
97
+
98
+ /**
99
+ * The streams that are to be reset.
100
+ */
101
+ const std::vector<uint16_t>& GetStreamIds() const
102
+ {
103
+ return this->streamIds;
104
+ }
105
+
106
+ /**
107
+ * If this request has been sent yet. If not, then it's either because
108
+ * it has only been prepared and not yet sent, or because the received
109
+ * couldn't apply the request, and then the exact same request will be
110
+ * retried, but with a new sequence number.
111
+ */
112
+ bool HasBeenSent() const
113
+ {
114
+ return this->reqSeqNbr.has_value();
115
+ }
116
+
117
+ /**
118
+ * If the receiver can't apply the request yet (and answered "In
119
+ * Progress"), this will be called to prepare the request to be
120
+ * retransmitted at a later time.
121
+ */
122
+ void PrepareRetransmission()
123
+ {
124
+ this->reqSeqNbr = std::nullopt;
125
+ }
126
+
127
+ /**
128
+ * If the request hasn't been sent yet, this assigns it a request
129
+ * number.
130
+ */
131
+ void PrepareToSend(uint32_t newReqSeqNbr)
132
+ {
133
+ this->reqSeqNbr = newReqSeqNbr;
134
+ }
135
+
136
+ void SetDeferred(bool isDeferred)
137
+ {
138
+ this->isDeferred = isDeferred;
139
+ }
140
+
141
+ bool IsDeferred() const
142
+ {
143
+ return this->isDeferred;
144
+ }
145
+
146
+ private:
147
+ // If this is set, this request has been sent. If it's not set, the
148
+ // request has been prepared, but has not yet been sent. This is
149
+ // typically used when the peer responded "in progress" and the same
150
+ // request (but a different request number) must be sent again.
151
+ std::optional<uint32_t> reqSeqNbr{ 0 };
152
+ // The sender's (that's us) last assigned TSN, from the retransmission
153
+ // queue.
154
+ uint32_t senderLastAssignedTsn{ 0 };
155
+ // The streams that are to be reset in this request.
156
+ std::vector<uint16_t> streamIds;
157
+ // If the request is deferred (received "In Progress"), the next timeout
158
+ // should not be treated as a timeout.
159
+ bool isDeferred{ false };
160
+ };
161
+
162
+ private:
163
+ using UnwrappedReConfigRequestSn = UnwrappedSequenceNumber<uint32_t>;
164
+
165
+ public:
166
+ StreamResetHandler(
167
+ AssociationListener& associationListener, TCBContext* tcbContext
168
+ // TODO: SCTP: Implement
169
+ // DataTracker* dataTracker,
170
+ // ReassemblyQueue* reassemblyQueue,
171
+ // RetransmissionQueue* retransmissionQueue
172
+ );
173
+
174
+ ~StreamResetHandler() override;
175
+
176
+ public:
177
+ /**
178
+ * Initiates reset of the provided streams. While there can only be one
179
+ * ongoing stream reset request at any time, this method can be called at
180
+ * any time and also multiple times. It will enqueue requests that can't
181
+ * be directly fulfilled, and will asynchronously process them when any
182
+ * ongoing request has completed.
183
+ */
184
+ void ResetStreams(std::span<const uint16_t> outgoingStreamIds);
185
+
186
+ /**
187
+ * Called when handling and incoming RE-CONFIG chunk. Processes a stream
188
+ * reconfiguration chunk and may send a RE-CONFIG back to the peer with
189
+ * either 1 or 2 responses.
190
+ */
191
+ void HandleReceivedReConfigChunk(const ReConfigChunk* receivedReConfigChunk);
192
+
193
+ private:
194
+ /**
195
+ * Called to validate a received RE-CONFIG chunk.
196
+ */
197
+ bool ValidateReceivedReConfigChunk(const ReConfigChunk* receivedReConfigChunk);
198
+
199
+ /**
200
+ * Creates a Reset Streams request that must be sent if returned. Will
201
+ * start the reconfig timer. Will return `nullptr` if there is no need
202
+ * to create a request (no streams to reset) or if there already is an
203
+ * ongoing stream reset request that hasn't completed yet.
204
+ */
205
+ ReConfigChunk* CreateStreamResetRequest();
206
+
207
+ /**
208
+ * Creates the actual RE-CONFIG chunk. A request (which set
209
+ * `currentRequest`) must have been created prior.
210
+ */
211
+ ReConfigChunk* CreateReconfigChunk();
212
+
213
+ /**
214
+ * Called to validate the `reqSeqNbr`, that it's the next in sequence.
215
+ */
216
+ ReqSeqNbrValidationResult ValidateReqSeqNbr(UnwrappedReConfigRequestSn reqSeqNbr);
217
+
218
+ /**
219
+ * Called when this Association receives an outgoing stream reset request.
220
+ * It might either be performed straight away, or have to be deferred, and
221
+ * the result of that will be put in `responses`.
222
+ */
223
+ void HandleReceivedOutgoingSsnResetRequestParameter(
224
+ const OutgoingSsnResetRequestParameter* receivedOutgoingSsnResetRequestParameter,
225
+ ReConfigChunk* reConfigChunk);
226
+
227
+ /**
228
+ * Called when this Association receives an incoming stream reset request.
229
+ * This isn't really supported, but a successful response is put in
230
+ * `responses`.
231
+ */
232
+ void HandleReceivedIncomingSsnResetRequestParameter(
233
+ const IncomingSsnResetRequestParameter* receivedIncomingSsnResetRequestParameter,
234
+ ReConfigChunk* reConfigChunk);
235
+
236
+ /**
237
+ * Called when receiving a response to an outgoing stream reset request.
238
+ * It will either commit the stream resetting, if the operation was
239
+ * successful, or will schedule a retry if it was deferred. And if it
240
+ * failed, the operation will be rolled back.
241
+ */
242
+ void HandleReceivedReconfigurationResponseParameter(
243
+ const ReconfigurationResponseParameter* receivedReconfigurationResponseParameter);
244
+
245
+ void OnReConfigTimer(uint64_t& baseTimeoutMs, bool& stop);
246
+
247
+ /* Pure virtual methods inherited from BackoffTimerHandle::Listener. */
248
+ public:
249
+ void OnTimer(BackoffTimerHandle* backoffTimer, uint64_t& baseTimeoutMs, bool& stop) override;
250
+
251
+ private:
252
+ AssociationListener& associationListener;
253
+ TCBContext* tcbContext{ nullptr };
254
+ // TODO: SCTP: Implement
255
+ // DataTracker* dataTracker{ nullptr };,
256
+ // ReassemblyQueue* reassemblyQueue{ nullptr };,
257
+ // RetransmissionQueue* retransmissionQueue{ nullptr };
258
+ UnwrappedReConfigRequestSn::Unwrapper incomingReConfigRequestSnUnwrapper;
259
+ const std::unique_ptr<BackoffTimerHandle> reConfigTimer;
260
+ // The next sequence number for outgoing stream requests.
261
+ uint32_t nextOutgoingReqSeqNbr{ 0 };
262
+ // The current stream request operation.
263
+ std::optional<CurrentRequest> currentRequest;
264
+ // For incoming requests. Last processed request sequence number.
265
+ UnwrappedReConfigRequestSn lastProcessedReqSeqNbr;
266
+ // The result from last processed incoming request.
267
+ ReconfigurationResponseParameter::Result lastProcessedReqResult;
268
+ };
269
+ } // namespace SCTP
270
+ } // namespace RTC
271
+
272
+ #endif
@@ -0,0 +1,67 @@
1
+ #ifndef MS_RTC_SCTP_TCB_CONTEXT_HPP
2
+ #define MS_RTC_SCTP_TCB_CONTEXT_HPP
3
+
4
+ #include "common.hpp"
5
+ #include "RTC/SCTP/packet/Packet.hpp"
6
+ #include <string_view>
7
+
8
+ namespace RTC
9
+ {
10
+ namespace SCTP
11
+ {
12
+ class TCBContext
13
+ {
14
+ public:
15
+ virtual ~TCBContext() = default;
16
+
17
+ /**
18
+ * Indicates if the SCTP Association has been established.
19
+ */
20
+ virtual bool IsAssociationEstablished() const = 0;
21
+
22
+ /**
23
+ * The value of the Initiate Tag field the peer put in its INIT or
24
+ * INIT_ACK Chunk.
25
+ */
26
+ virtual uint32_t GetLocalInitialTsn() const = 0;
27
+
28
+ /**
29
+ * The value of the Initial TSN field the peer put in its INIT or
30
+ * INIT_ACK Chunk.
31
+ */
32
+ virtual uint32_t GetRemoteInitialTsn() const = 0;
33
+
34
+ /**
35
+ * To be called when a RTT has been measured, to update the RTO value.
36
+ */
37
+ virtual void ObserveRtt(uint64_t rtt) = 0;
38
+
39
+ /**
40
+ * Returns the Retransmission Timeout (RTO) value.
41
+ */
42
+ virtual uint64_t GetCurrentRtoMs() const = 0;
43
+
44
+ /**
45
+ * Increments the transmission error counter, given a human readable
46
+ * reason.
47
+ */
48
+ virtual bool IncrementTxErrorCounter(std::string_view reason) = 0;
49
+
50
+ /**
51
+ * Clears the transmission error counter.
52
+ */
53
+ virtual void ClearTxErrorCounter() = 0;
54
+
55
+ /**
56
+ * Returns true if there have been too many retransmission errors.
57
+ */
58
+ virtual bool HasTooManyTxErrors() const = 0;
59
+
60
+ virtual std::unique_ptr<Packet> CreatePacket() const = 0;
61
+
62
+ virtual void Send(Packet* packet) = 0;
63
+ };
64
+ } // namespace SCTP
65
+ } // namespace RTC
66
+
67
+ #endif
@@ -2,14 +2,17 @@
2
2
  #define MS_RTC_SCTP_TRANSMISSION_CONTROL_BLOCK_HPP
3
3
 
4
4
  #include "common.hpp"
5
+ #include "RTC/SCTP/association/HeartbeatHandler.hpp"
5
6
  #include "RTC/SCTP/association/NegotiatedCapabilities.hpp"
6
7
  #include "RTC/SCTP/association/PacketSender.hpp"
8
+ #include "RTC/SCTP/association/TCBContext.hpp"
7
9
  #include "RTC/SCTP/packet/Packet.hpp"
8
10
  #include "RTC/SCTP/public/AssociationListener.hpp"
9
11
  #include "RTC/SCTP/public/SctpOptions.hpp"
10
12
  #include "RTC/SCTP/tx/RetransmissionErrorCounter.hpp"
11
13
  #include "RTC/SCTP/tx/RetransmissionTimeout.hpp"
12
14
  #include "handles/BackoffTimerHandle.hpp"
15
+ #include <string_view>
13
16
  #include <vector>
14
17
 
15
18
  namespace RTC
@@ -22,7 +25,7 @@ namespace RTC
22
25
  *
23
26
  * @see https://datatracker.ietf.org/doc/html/rfc9260#section-14
24
27
  */
25
- class TransmissionControlBlock : public BackoffTimerHandle::Listener
28
+ class TransmissionControlBlock : public TCBContext, public BackoffTimerHandle::Listener
26
29
  {
27
30
  public:
28
31
  TransmissionControlBlock(
@@ -35,13 +38,23 @@ namespace RTC
35
38
  uint32_t remoteInitialTsn,
36
39
  uint32_t remoteAdvertisedReceiverWindowCredit,
37
40
  uint64_t tieTag,
38
- const NegotiatedCapabilities& negotiatedCapabilities);
41
+ const NegotiatedCapabilities& negotiatedCapabilities,
42
+ std::function<bool()> isAssociationEstablished);
39
43
 
40
44
  ~TransmissionControlBlock() override;
41
45
 
42
46
  public:
43
47
  void Dump(int indentation = 0) const;
44
48
 
49
+ /**
50
+ * @remarks
51
+ * - Implements TCBContext interface.
52
+ */
53
+ bool IsAssociationEstablished() const override
54
+ {
55
+ return this->isAssociationEstablished();
56
+ }
57
+
45
58
  /**
46
59
  * The value of the Initiate Tag field we put in our INIT or INIT_ACK
47
60
  * Chunk. Packets sent by the remote peer must include this value in
@@ -65,8 +78,11 @@ namespace RTC
65
78
  /**
66
79
  * The value of the Initial TSN field we put in our INIT or INIT_ACK
67
80
  * Chunk.
81
+ *
82
+ * @remarks
83
+ * - Implements TCBContext interface.
68
84
  */
69
- uint32_t GetLocalInitialTsn() const
85
+ uint32_t GetLocalInitialTsn() const override
70
86
  {
71
87
  return this->localInitialTsn;
72
88
  }
@@ -74,8 +90,11 @@ namespace RTC
74
90
  /**
75
91
  * The value of the Initial TSN field the peer put in its INIT or
76
92
  * INIT_ACK Chunk.
93
+ *
94
+ * @remarks
95
+ * - Implements TCBContext interface.
77
96
  */
78
- uint32_t GetRemoteInitialTsn() const
97
+ uint32_t GetRemoteInitialTsn() const override
79
98
  {
80
99
  return this->remoteInitialTsn;
81
100
  }
@@ -105,9 +124,17 @@ namespace RTC
105
124
  return this->negotiatedCapabilities;
106
125
  }
107
126
 
108
- void ObserveRtt(uint64_t rtt);
127
+ /**
128
+ * @remarks
129
+ * - Implements TCBContext interface.
130
+ */
131
+ void ObserveRtt(uint64_t rtt) override;
109
132
 
110
- uint64_t GetCurrentRtoMs() const
133
+ /**
134
+ * @remarks
135
+ * - Implements TCBContext interface.
136
+ */
137
+ uint64_t GetCurrentRtoMs() const override
111
138
  {
112
139
  return this->rto.GetRtoMs();
113
140
  }
@@ -117,10 +144,25 @@ namespace RTC
117
144
  return this->rto.GetSrttMs();
118
145
  }
119
146
 
120
- std::unique_ptr<Packet> CreatePacket() const;
147
+ /**
148
+ * @remarks
149
+ * - Implements TCBContext interface.
150
+ */
151
+ std::unique_ptr<Packet> CreatePacket() const override;
121
152
 
122
153
  std::unique_ptr<Packet> CreatePacketWithVerificationTag(uint32_t verificationTag) const;
123
154
 
155
+ /**
156
+ * @remarks
157
+ * - Implements TCBContext interface.
158
+ */
159
+ void Send(Packet* packet) override;
160
+
161
+ HeartbeatHandler& GetHeartbeatHandler()
162
+ {
163
+ return this->heartbeatHandler;
164
+ }
165
+
124
166
  void SetRemoteStateCookie(std::vector<uint8_t> remoteStateCookie);
125
167
 
126
168
  void ClearRemoteStateCookie();
@@ -132,9 +174,34 @@ namespace RTC
132
174
 
133
175
  void MaySendSackChunk();
134
176
 
135
- private:
136
- void Send(Packet* packet);
177
+ /**
178
+ * @remarks
179
+ * - Implements TCBContext interface.
180
+ */
181
+ bool IncrementTxErrorCounter(std::string_view reason) override
182
+ {
183
+ return this->txErrorCounter.Increment(reason);
184
+ }
185
+
186
+ /**
187
+ * @remarks
188
+ * - Implements TCBContext interface.
189
+ */
190
+ void ClearTxErrorCounter() override
191
+ {
192
+ return this->txErrorCounter.Clear();
193
+ }
194
+
195
+ /**
196
+ * @remarks
197
+ * - Implements TCBContext interface.
198
+ */
199
+ bool HasTooManyTxErrors() const override
200
+ {
201
+ return this->txErrorCounter.IsExhausted();
202
+ }
137
203
 
204
+ private:
138
205
  void OnT3RtxTimer(uint64_t& baseTimeoutMs, bool& stop);
139
206
 
140
207
  void OnDelayedAckTimer(uint64_t& baseTimeoutMs, bool& stop);
@@ -155,16 +222,19 @@ namespace RTC
155
222
  // Nonce, used to detect reconnections.
156
223
  uint64_t tieTag{ 0 };
157
224
  NegotiatedCapabilities negotiatedCapabilities;
158
- // data retransmission timer).
225
+ std::function<bool()> isAssociationEstablished;
226
+ // The data retransmission timer.
159
227
  const std::unique_ptr<BackoffTimerHandle> t3RtxTimer;
160
228
  // Delayed ack timer, which triggers when acks should be sent (when
161
229
  // delayed).
162
230
  const std::unique_ptr<BackoffTimerHandle> delayedAckTimer;
163
231
  RetransmissionTimeout rto;
164
232
  RetransmissionErrorCounter txErrorCounter;
233
+ HeartbeatHandler heartbeatHandler;
165
234
  // Rate limiting of FORWARD_TSN. Next can be sent at or after this
166
235
  // timestamp.
167
- uint64_t limitForwardTsnUntilMs{ 0 };
236
+ // TODO: SCTP: Uncomment.
237
+ // uint64_t limitForwardTsnUntilMs{ 0 };
168
238
  // Only valid when state is State::COOKIE_ECHOED. In this state, the
169
239
  // Association must wait for COOKIE_ACK to continue sending any packets (not
170
240
  // including a COOKIE_ECHO). So if this state cookie is present, the