mediasoup 3.19.21 → 3.19.22

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 (130) hide show
  1. package/node/lib/Worker.d.ts +1 -0
  2. package/node/lib/Worker.d.ts.map +1 -1
  3. package/node/lib/Worker.js +14 -0
  4. package/package.json +4 -2
  5. package/worker/fuzzer/src/RTC/FuzzerDtlsTransport.cpp +9 -3
  6. package/worker/fuzzer/src/RTC/RTP/FuzzerRtpStreamSend.cpp +9 -1
  7. package/worker/include/Channel/ChannelMessageRegistrator.hpp +39 -0
  8. package/worker/include/Channel/ChannelMessageRegistratorInterface.hpp +32 -0
  9. package/worker/include/Channel/ChannelSocket.hpp +1 -1
  10. package/worker/include/DepUsrSCTP.hpp +8 -7
  11. package/worker/include/RTC/ActiveSpeakerObserver.hpp +7 -7
  12. package/worker/include/RTC/AudioLevelObserver.hpp +7 -7
  13. package/worker/include/RTC/Consumer.hpp +3 -3
  14. package/worker/include/RTC/DataConsumer.hpp +3 -3
  15. package/worker/include/RTC/DataProducer.hpp +3 -3
  16. package/worker/include/RTC/DirectTransport.hpp +2 -2
  17. package/worker/include/RTC/DtlsTransport.hpp +8 -6
  18. package/worker/include/RTC/ICE/IceServer.hpp +8 -5
  19. package/worker/include/RTC/KeyFrameRequestManager.hpp +15 -12
  20. package/worker/include/RTC/NackGenerator.hpp +7 -6
  21. package/worker/include/RTC/PipeConsumer.hpp +1 -2
  22. package/worker/include/RTC/PipeTransport.hpp +2 -2
  23. package/worker/include/RTC/PlainTransport.hpp +2 -2
  24. package/worker/include/RTC/Producer.hpp +3 -3
  25. package/worker/include/RTC/RTP/RtpStream.hpp +7 -1
  26. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +6 -5
  27. package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -1
  28. package/worker/include/RTC/Router.hpp +3 -3
  29. package/worker/include/RTC/RtpObserver.hpp +3 -3
  30. package/worker/include/RTC/SCTP/TODO_SCTP.md +18 -6
  31. package/worker/include/RTC/SCTP/association/Association.hpp +11 -8
  32. package/worker/include/RTC/SCTP/association/HeartbeatHandler.hpp +9 -6
  33. package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +37 -23
  34. package/worker/include/RTC/SCTP/association/TCBContext.hpp +3 -2
  35. package/worker/include/RTC/SCTP/association/TransmissionControlBlock.hpp +81 -8
  36. package/worker/include/RTC/SCTP/packet/UserData.hpp +36 -0
  37. package/worker/include/RTC/SCTP/packet/chunks/ForwardTsnChunk.hpp +1 -1
  38. package/worker/include/RTC/SCTP/packet/chunks/IForwardTsnChunk.hpp +1 -1
  39. package/worker/include/RTC/SCTP/public/SctpOptions.hpp +2 -1
  40. package/worker/include/RTC/SCTP/tx/OutstandingData.hpp +604 -0
  41. package/worker/include/RTC/SCTP/tx/RetransmissionQueue.hpp +336 -0
  42. package/worker/include/RTC/SCTP/tx/RetransmissionTimeout.hpp +5 -4
  43. package/worker/include/RTC/Serializable.hpp +8 -0
  44. package/worker/include/RTC/SimpleConsumer.hpp +1 -2
  45. package/worker/include/RTC/SimulcastConsumer.hpp +1 -2
  46. package/worker/include/RTC/SvcConsumer.hpp +1 -2
  47. package/worker/include/RTC/Transport.hpp +8 -8
  48. package/worker/include/RTC/TransportCongestionControlClient.hpp +8 -5
  49. package/worker/include/RTC/TransportCongestionControlServer.hpp +8 -5
  50. package/worker/include/RTC/WebRtcServer.hpp +3 -3
  51. package/worker/include/RTC/WebRtcTransport.hpp +3 -3
  52. package/worker/include/Shared.hpp +40 -0
  53. package/worker/include/SharedInterface.hpp +44 -0
  54. package/worker/include/Utils.hpp +6 -0
  55. package/worker/include/Worker.hpp +3 -3
  56. package/worker/include/common.hpp +1 -1
  57. package/worker/include/handles/BackoffTimerHandle.hpp +27 -65
  58. package/worker/include/handles/BackoffTimerHandleInterface.hpp +116 -0
  59. package/worker/include/handles/TimerHandle.hpp +36 -20
  60. package/worker/include/handles/TimerHandleInterface.hpp +43 -0
  61. package/worker/meson.build +21 -4
  62. package/worker/meson_options.txt +2 -1
  63. package/worker/mocks/include/Channel/MockChannelMessageRegistrator.hpp +45 -0
  64. package/worker/mocks/include/MockShared.hpp +43 -0
  65. package/worker/mocks/src/Channel/MockChannelMessageRegistrator.cpp +128 -0
  66. package/worker/mocks/src/MockShared.cpp +26 -0
  67. package/worker/scripts/clang-scripts.mjs +4 -1
  68. package/worker/src/Channel/ChannelMessageRegistrator.cpp +125 -0
  69. package/worker/src/Channel/ChannelSocket.cpp +1 -1
  70. package/worker/src/DepUsrSCTP.cpp +10 -4
  71. package/worker/src/RTC/ActiveSpeakerObserver.cpp +7 -7
  72. package/worker/src/RTC/AudioLevelObserver.cpp +12 -10
  73. package/worker/src/RTC/Consumer.cpp +23 -20
  74. package/worker/src/RTC/DataConsumer.cpp +11 -11
  75. package/worker/src/RTC/DataProducer.cpp +3 -3
  76. package/worker/src/RTC/DirectTransport.cpp +16 -16
  77. package/worker/src/RTC/DtlsTransport.cpp +4 -4
  78. package/worker/src/RTC/ICE/IceServer.cpp +4 -3
  79. package/worker/src/RTC/KeyFrameRequestManager.cpp +15 -15
  80. package/worker/src/RTC/NackGenerator.cpp +3 -3
  81. package/worker/src/RTC/PipeConsumer.cpp +5 -4
  82. package/worker/src/RTC/PipeTransport.cpp +3 -3
  83. package/worker/src/RTC/PlainTransport.cpp +10 -9
  84. package/worker/src/RTC/Producer.cpp +30 -28
  85. package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +1 -2
  86. package/worker/src/RTC/RTP/RtpStream.cpp +9 -2
  87. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +5 -4
  88. package/worker/src/RTC/RTP/RtpStreamSend.cpp +5 -2
  89. package/worker/src/RTC/Router.cpp +3 -3
  90. package/worker/src/RTC/RtpObserver.cpp +2 -1
  91. package/worker/src/RTC/SCTP/association/Association.cpp +94 -114
  92. package/worker/src/RTC/SCTP/association/HeartbeatHandler.cpp +27 -21
  93. package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +52 -55
  94. package/worker/src/RTC/SCTP/association/TransmissionControlBlock.cpp +144 -25
  95. package/worker/src/RTC/SCTP/packet/chunks/ForwardTsnChunk.cpp +2 -2
  96. package/worker/src/RTC/SCTP/packet/chunks/IForwardTsnChunk.cpp +2 -2
  97. package/worker/src/RTC/SCTP/tx/OutstandingData.cpp +905 -0
  98. package/worker/src/RTC/SCTP/tx/RetransmissionQueue.cpp +799 -0
  99. package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +1 -1
  100. package/worker/src/RTC/SctpAssociation.cpp +1 -1
  101. package/worker/src/RTC/SimpleConsumer.cpp +8 -7
  102. package/worker/src/RTC/SimulcastConsumer.cpp +11 -10
  103. package/worker/src/RTC/SvcConsumer.cpp +11 -10
  104. package/worker/src/RTC/Transport.cpp +36 -26
  105. package/worker/src/RTC/TransportCongestionControlClient.cpp +4 -2
  106. package/worker/src/RTC/TransportCongestionControlServer.cpp +4 -3
  107. package/worker/src/RTC/WebRtcServer.cpp +5 -4
  108. package/worker/src/RTC/WebRtcTransport.cpp +39 -26
  109. package/worker/src/Shared.cpp +35 -0
  110. package/worker/src/Worker.cpp +10 -23
  111. package/worker/src/handles/BackoffTimerHandle.cpp +11 -16
  112. package/worker/src/handles/TimerHandle.cpp +5 -4
  113. package/worker/src/lib.cpp +14 -1
  114. package/worker/tasks.py +1 -1
  115. package/worker/test/include/RTC/ICE/iceCommon.hpp +1 -0
  116. package/worker/test/include/RTC/RTP/rtpCommon.hpp +1 -0
  117. package/worker/test/include/RTC/SCTP/sctpCommon.hpp +6 -0
  118. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +12 -5
  119. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +34 -23
  120. package/worker/test/src/RTC/SCTP/tx/TestOutstandingData.cpp +1196 -0
  121. package/worker/test/src/RTC/SCTP/tx/TestRetransmissionTimeout.cpp +33 -33
  122. package/worker/test/src/RTC/TestKeyFrameRequestManager.cpp +14 -6
  123. package/worker/test/src/RTC/TestNackGenerator.cpp +6 -2
  124. package/worker/test/src/RTC/TestSimpleConsumer.cpp +6 -10
  125. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +9 -2
  126. package/worker/test/src/Utils/TestByte.cpp +98 -0
  127. package/worker/include/ChannelMessageRegistrator.hpp +0 -30
  128. package/worker/include/RTC/Shared.hpp +0 -23
  129. package/worker/src/ChannelMessageRegistrator.cpp +0 -119
  130. package/worker/src/RTC/Shared.cpp +0 -23
@@ -17,6 +17,7 @@
17
17
  #include "RTC/SCTP/packet/parameters/StateCookieParameter.hpp"
18
18
  #include "RTC/SCTP/packet/parameters/SupportedExtensionsParameter.hpp"
19
19
  #include "RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp"
20
+ #include "handles/BackoffTimerHandle.hpp"
20
21
  #include <limits> // std::numeric_limits()
21
22
  #include <sstream> // std::ostringstream
22
23
  #include <string>
@@ -39,33 +40,36 @@ namespace RTC
39
40
 
40
41
  /* Instance methods. */
41
42
 
42
- Association::Association(const SctpOptions& sctpOptions, AssociationListener* listener)
43
+ Association::Association(
44
+ const SctpOptions& sctpOptions, AssociationListener* listener, SharedInterface* shared)
43
45
  : sctpOptions(sctpOptions),
44
46
  // Our `listener` member is a `AssociationListenerDeferrer` which takes
45
47
  // `AssociationListener` as constructor argument.
46
48
  listener(listener),
49
+ shared(shared),
47
50
  packetSender(this, this->listener),
48
- t1InitTimer(
49
- std::make_unique<BackoffTimerHandle>(
50
- /*listener*/ this,
51
- /*baseTimeoutMs*/ sctpOptions.t1InitTimeoutMs,
52
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::EXPONENTIAL,
53
- /*maxBackoffTimeoutMs*/ sctpOptions.timerMaxBackoffTimeoutMs,
54
- /*maxRestarts*/ sctpOptions.maxInitRetransmissions)),
55
- t1CookieTimer(
56
- std::make_unique<BackoffTimerHandle>(
57
- /*listener*/ this,
58
- /*baseTimeoutMs*/ sctpOptions.t1CookieTimeoutMs,
59
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::EXPONENTIAL,
60
- /*maxBackoffTimeoutMs*/ sctpOptions.timerMaxBackoffTimeoutMs,
61
- /*maxRestarts*/ sctpOptions.maxInitRetransmissions)),
62
- t2ShutdownTimer(
63
- std::make_unique<BackoffTimerHandle>(
64
- /*listener*/ this,
65
- /*baseTimeoutMs*/ sctpOptions.t2ShutdownTimeoutMs,
66
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::EXPONENTIAL,
67
- /*maxBackoffTimeoutMs*/ sctpOptions.timerMaxBackoffTimeoutMs,
68
- /*maxRestarts*/ sctpOptions.maxRetransmissions))
51
+ t1InitTimer(this->shared->CreateBackoffTimer(
52
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
53
+ .listener = this,
54
+ .baseTimeoutMs = sctpOptions.t1InitTimeoutMs,
55
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::EXPONENTIAL,
56
+ .maxBackoffTimeoutMs = sctpOptions.timerMaxBackoffTimeoutMs,
57
+ .maxRestarts = sctpOptions.maxInitRetransmissions,
58
+ })),
59
+ t1CookieTimer(this->shared->CreateBackoffTimer(
60
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
61
+ .listener = this,
62
+ .baseTimeoutMs = sctpOptions.t1CookieTimeoutMs,
63
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::EXPONENTIAL,
64
+ .maxBackoffTimeoutMs = sctpOptions.timerMaxBackoffTimeoutMs,
65
+ .maxRestarts = sctpOptions.maxInitRetransmissions })),
66
+ t2ShutdownTimer(this->shared->CreateBackoffTimer(
67
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
68
+ .listener = this,
69
+ .baseTimeoutMs = sctpOptions.t2ShutdownTimeoutMs,
70
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::EXPONENTIAL,
71
+ .maxBackoffTimeoutMs = sctpOptions.timerMaxBackoffTimeoutMs,
72
+ .maxRestarts = sctpOptions.maxRetransmissions }))
69
73
  {
70
74
  MS_TRACE();
71
75
  }
@@ -342,15 +346,15 @@ namespace RTC
342
346
  .txMessagesCount = this->privateMetrics.txMessagesCount,
343
347
  .rxPacketsCount = this->privateMetrics.rxPacketsCount,
344
348
  .rxMessagesCount = this->privateMetrics.rxMessagesCount,
345
- // .rtxPacketsCount = this->tcb->GetRetransmissionQueue().GetRtxPacketsCount(),
346
- // .rtxBytesCount = this->tcb->GetRetransmissionQueue().GetRtxBytesCount(),
347
- // .cwndBytes = this->tcb->GetCwnd(),
348
- .srttMs = this->tcb->GetCurrentSrttMs(),
349
+ .rtxPacketsCount = this->tcb->GetRetransmissionQueue().GetRtxPacketsCount(),
350
+ .rtxBytesCount = this->tcb->GetRetransmissionQueue().GetRtxBytesCount(),
351
+ .cwndBytes = this->tcb->GetCwnd(),
352
+ .srttMs = this->tcb->GetCurrentSrttMs(),
349
353
  // .unackDataCount =
350
354
  // this->tcb->GetRetransmissionQueue().GetUnackedItems() +
351
355
  // (this->sendQueue.GetTotalBufferedAmount() + packetPayloadLength - 1) / packetPayloadLength,
352
- // .peerRwndBytes = this->tcb->GetRetransmissionQueue().GetRwnd(),
353
- .peerImplementation = this->privateMetrics.peerImplementation,
356
+ .peerRwndBytes = static_cast<uint32_t>(this->tcb->GetRetransmissionQueue().GetRwnd()),
357
+ .peerImplementation = this->privateMetrics.peerImplementation,
354
358
  .negotiatedMaxOutboundStreams = this->privateMetrics.negotiatedMaxOutboundStreams,
355
359
  .negotiatedMaxInboundStreams = this->privateMetrics.negotiatedMaxInboundStreams,
356
360
  .usesPartialReliability = this->privateMetrics.usesPartialReliability,
@@ -419,7 +423,7 @@ namespace RTC
419
423
  // this->sendQueue.SetBufferedAmountLowThreshold(streamId, bytes);
420
424
  }
421
425
 
422
- Types::ResetStreamsStatus Association::ResetStreams(std::span<const uint16_t> /*outboundStreamIds*/)
426
+ Types::ResetStreamsStatus Association::ResetStreams(std::span<const uint16_t> outboundStreamIds)
423
427
  {
424
428
  MS_TRACE();
425
429
 
@@ -443,8 +447,7 @@ namespace RTC
443
447
  return Types::ResetStreamsStatus::NOT_SUPPORTED;
444
448
  }
445
449
 
446
- // TODO: SCTP: Implement it.
447
- // this->tcb->GetStreamResetHandler().ResetStreams(outboundStreamIds);
450
+ this->tcb->GetStreamResetHandler().ResetStreams(outboundStreamIds);
448
451
 
449
452
  MaySendResetStreamsRequest();
450
453
  AssertStateIsConsistent();
@@ -467,17 +470,17 @@ namespace RTC
467
470
  }
468
471
 
469
472
  // TODO: SCTP: Uncomment.
470
- // const uint64_t now = DepLibUV::GetTimeMs();
473
+ // const uint64_t nowMs = DepLibUV::GetTimeMs();
471
474
 
472
475
  this->privateMetrics.txMessagesCount++;
473
476
 
474
477
  // TODO: SCTP: Implement it.
475
- // this->sendQueue.AddMessage(now, std::move(message), sendMessageOptions);
478
+ // this->sendQueue.AddMessage(nowMs, std::move(message), sendMessageOptions);
476
479
 
477
480
  if (this->tcb)
478
481
  {
479
482
  // TODO: SCTP: Implement it.
480
- // this->tcb->SendBufferedPackets(now);
483
+ // this->tcb->SendBufferedPackets(nowMs);
481
484
  }
482
485
 
483
486
  AssertStateIsConsistent();
@@ -493,7 +496,7 @@ namespace RTC
493
496
  const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
494
497
 
495
498
  // TODO: SCTP: Uncomment.
496
- // const uint64_t now = DepLibUV::GetTimeMs();
499
+ // const uint64_t nowMs = DepLibUV::GetTimeMs();
497
500
  std::vector<Types::SendMessageStatus> statuses;
498
501
 
499
502
  statuses.reserve(messages.size());
@@ -512,13 +515,13 @@ namespace RTC
512
515
  this->privateMetrics.txMessagesCount++;
513
516
 
514
517
  // TODO: SCTP: Implement it.
515
- // this->sendQueue.AddMessage(now, std::move(message), sendMessageOptions);
518
+ // this->sendQueue.AddMessage(nowMs, std::move(message), sendMessageOptions);
516
519
  }
517
520
 
518
521
  if (this->tcb)
519
522
  {
520
523
  // TODO: SCTP: Implement it.
521
- // this->tcb->SendBufferedPackets(now);
524
+ // this->tcb->SendBufferedPackets(nowMs);
522
525
  }
523
526
 
524
527
  AssertStateIsConsistent();
@@ -726,6 +729,7 @@ namespace RTC
726
729
  this->tcb = std::make_unique<TransmissionControlBlock>(
727
730
  this->listener,
728
731
  this->sctpOptions,
732
+ this->shared,
729
733
  this->packetSender,
730
734
  localVerificationTag,
731
735
  remoteVerificationTag,
@@ -836,10 +840,10 @@ namespace RTC
836
840
 
837
841
  AssertHasTcb();
838
842
 
839
- // TODO: SCTP: Implement it.
840
- // if (this->tcb->GetRetransmissionQueue().GetUnackedItems() != 0) {
841
- // return;
842
- // }
843
+ if (this->tcb->GetRetransmissionQueue().GetUnackedItems() != 0)
844
+ {
845
+ return;
846
+ }
843
847
 
844
848
  // https://datatracker.ietf.org/doc/html/rfc9260#section-9.2
845
849
  //
@@ -913,37 +917,13 @@ namespace RTC
913
917
 
914
918
  AssertHasTcb();
915
919
 
916
- // TODO: SCTP: I don't like this. I don't want to use Packet::AddChunk() (which
917
- // clones the given Chunk). I want to use Packet::BuildChunkInPlace() so
918
- // we need that `tcb->GetStreamResetHandler().MakeStreamResetRequest()`
919
- // doesn't return a `ReConfigChunk` but something different such as the
920
- // Re-configuration Request Parameter(s) (OutgoingSSNResetRequestParameter):
921
- // https://datatracker.ietf.org/doc/html/rfc6525#section-8.2
922
- // Mmmm, but not even that because we also want to use
923
- // ReConfigChunk::BuildParameterInPlace() instead of AddParameter() for
924
- // same reasons... Ok, let's see.
925
- // NOTE: What about if we do some std::move() somewhere?
926
-
927
- // const auto* reConfigChunk =
928
- // this->tcb->GetStreamResetHandler().MakeStreamResetRequest();
929
- // const auto* outgoingSSNResetRequestParameter =
930
- // this->tcb->GetStreamResetHandler().MakeOutgoingSSNResetRequestParameter();
931
-
932
- // if (!outgoingSSNResetRequestParameter)
933
- // {
934
- // return;
935
- // }
936
-
937
- // auto packet = this->tcb->CreatePacket();
938
- // auto* reConfigChunk = packet->BuildChunkInPlace<ReConfigChunk>();
939
-
940
- // reConfigChunk->AddParameter(outgoingSSNResetRequestParameter);
941
-
942
- // delete outgoingSSNResetRequestParameter;
943
-
944
- // reConfigChunk->Consolidate();
920
+ if (this->tcb->GetStreamResetHandler().ShouldCreateStreamResetRequest())
921
+ {
922
+ auto packet = this->tcb->CreatePacket();
945
923
 
946
- // this->packetSender.SendPacket(packet.get());
924
+ this->tcb->GetStreamResetHandler().CreateStreamResetRequest(packet.get());
925
+ this->packetSender.SendPacket(packet.get());
926
+ }
947
927
  }
948
928
 
949
929
  void Association::MayDeliverMessages()
@@ -1620,7 +1600,7 @@ namespace RTC
1620
1600
  // TODO: SCTP: tcb->SendBufferedPackets() must check that the remote state cookie
1621
1601
  // is set in TCB and must send a COOKIE_ECHO Chunk before potentially
1622
1602
  // buffered messages.
1623
- // this->tcb->SendBufferedPackets(callbacks_.Now());
1603
+ // this->tcb->SendBufferedPackets(nowMs);
1624
1604
 
1625
1605
  this->t1CookieTimer->Start();
1626
1606
  this->listener.OnAssociationConnecting();
@@ -1721,7 +1701,7 @@ namespace RTC
1721
1701
  // SACK chunks), but the COOKIE ACK chunk MUST be the first chunk in the
1722
1702
  // packet."
1723
1703
  // TODO: SCTP: Implement it. Note that we pass Packet as argument!
1724
- // this->tcb->SendBufferedPackets(packet.get(), callbacks_.Now());
1704
+ // this->tcb->SendBufferedPackets(packet.get(), nowMs);
1725
1705
 
1726
1706
  // TODO: SCTP: Remove this since COOKIE_ACK must be sent by
1727
1707
  // tcb->SendBufferedPackets() call above.
@@ -1845,7 +1825,7 @@ namespace RTC
1845
1825
  SetState(State::ESTABLISHED, "COOKIE_ACK received");
1846
1826
 
1847
1827
  // TODO: SCTP: Implement this.
1848
- // this->tcb->SendBufferedPackets(callbacks_.Now());
1828
+ // this->tcb->SendBufferedPackets(nowMs);
1849
1829
 
1850
1830
  this->listener.OnAssociationConnected();
1851
1831
  }
@@ -2101,7 +2081,7 @@ namespace RTC
2101
2081
  }
2102
2082
 
2103
2083
  void Association::HandleReceivedReConfigChunk(
2104
- const Packet* /*receivedPacket*/, const ReConfigChunk* /*receivedReConfigChunk*/)
2084
+ const Packet* /*receivedPacket*/, const ReConfigChunk* receivedReConfigChunk)
2105
2085
  {
2106
2086
  MS_TRACE();
2107
2087
 
@@ -2110,8 +2090,7 @@ namespace RTC
2110
2090
  return;
2111
2091
  }
2112
2092
 
2113
- // TODO: SCTP: Implement it.
2114
- // this->tcb->GetStreamResetHandler().HandleReConfig(*std::move(receivedReConfigChunk));
2093
+ this->tcb->GetStreamResetHandler().HandleReceivedReConfigChunk(receivedReConfigChunk);
2115
2094
 
2116
2095
  // Handling this response may result in outgoing stream resets finishing
2117
2096
  // (either successfully or with failure). If there still are pending
@@ -2122,7 +2101,7 @@ namespace RTC
2122
2101
  // If a response was processed, pending to-be-reset streams may now have
2123
2102
  // become unpaused. Try to send more DATA/I_DATA chunks.
2124
2103
  // TODO: SCTP: Implement it.
2125
- // this->tcb->SendBufferedPackets(callbacks_.Now());
2104
+ // this->tcb->SendBufferedPackets(nowMs);
2126
2105
 
2127
2106
  // If it leaves "deferred reset processing", there may be chunks to
2128
2107
  // deliver that were queued while waiting for the stream to reset.
@@ -2329,7 +2308,7 @@ namespace RTC
2329
2308
  }
2330
2309
 
2331
2310
  void Association::HandleReceivedSackChunk(
2332
- const Packet* /*receivedPacket*/, const SackChunk* /*receivedSackChunk*/)
2311
+ const Packet* /*receivedPacket*/, const SackChunk* receivedSackChunk)
2333
2312
  {
2334
2313
  MS_TRACE();
2335
2314
 
@@ -2338,37 +2317,37 @@ namespace RTC
2338
2317
  return;
2339
2318
  }
2340
2319
 
2341
- // TODO: SCTP: Implement it.
2342
- // if (this->tcb->GetRetransmissionQueue()->HandleReceivedSack(receivedSackChunk))
2343
- // {
2344
- // MaySendShutdownOrShutdownAckChunk();
2345
-
2346
- // // Receiving an ACK may make the Association go into fast recovery mode.
2347
- // //
2348
- // // https://datatracker.ietf.org/doc/html/rfc9260#section-7.2.4
2349
- // //
2350
- // // "If not in Fast Recovery, determine how many of the earliest (i.e.,
2351
- // // lowest TSN) DATA chunks marked for retransmission will fit into a
2352
- // // single packet, subject to constraint of the PMTU of the destination
2353
- // // transport address to which the packet is being sent. Call this value
2354
- // // K. Retransmit those K DATA chunks in a single packet. When a Fast
2355
- // // Retransmit is being performed, the sender SHOULD ignore the value of
2356
- // // cwnd and SHOULD NOT delay retransmission for this single packet."
2357
- // this->tcb->MaySendFastRetransmit();
2358
-
2359
- // // Receiving an ACK will decrease outstanding bytes (maybe now below
2360
- // // cwnd?) or indicate packet loss that may result in sending FORWARD-TSN.
2361
- // const uint64_t now = DepLibUV::GetTimeMs();
2362
-
2363
- // this->tcb->SendBufferedPackets(now);
2364
- // }
2365
- // else
2366
- // {
2367
- // MS_WARN_TAG(
2368
- // sctp,
2369
- // "dropping received out-of-order SACK [TSN:%" PRIu32 "]",
2370
- // receivedSackChunk->GetCumulativeTsnAck());
2371
- // }
2320
+ const uint64_t nowMs = DepLibUV::GetTimeMs();
2321
+
2322
+ if (this->tcb->GetRetransmissionQueue().HandleReceivedSackChunk(nowMs, receivedSackChunk))
2323
+ {
2324
+ MaySendShutdownOrShutdownAckChunk();
2325
+
2326
+ // Receiving an ACK may make the Association go into fast recovery mode.
2327
+ //
2328
+ // https://datatracker.ietf.org/doc/html/rfc9260#section-7.2.4
2329
+ //
2330
+ // "If not in Fast Recovery, determine how many of the earliest (i.e.,
2331
+ // lowest TSN) DATA chunks marked for retransmission will fit into a
2332
+ // single packet, subject to constraint of the PMTU of the destination
2333
+ // transport address to which the packet is being sent. Call this value
2334
+ // K. Retransmit those K DATA chunks in a single packet. When a Fast
2335
+ // Retransmit is being performed, the sender SHOULD ignore the value of
2336
+ // cwnd and SHOULD NOT delay retransmission for this single packet."
2337
+ this->tcb->MaySendFastRetransmit();
2338
+
2339
+ // Receiving an ACK will decrease outstanding bytes (maybe now below
2340
+ // cwnd?) or indicate packet loss that may result in sending FORWARD-TSN.
2341
+ // TODO: SCTP: Implement it.
2342
+ // this->tcb->SendBufferedPackets(nowMs);
2343
+ }
2344
+ else
2345
+ {
2346
+ MS_WARN_TAG(
2347
+ sctp,
2348
+ "dropping received out-of-order SACK [TSN:%" PRIu32 "]",
2349
+ receivedSackChunk->GetCumulativeTsnAck());
2350
+ }
2372
2351
  }
2373
2352
 
2374
2353
  bool Association::HandleReceivedUnknownChunk(
@@ -2435,7 +2414,7 @@ namespace RTC
2435
2414
 
2436
2415
  MS_DEBUG_TAG(
2437
2416
  sctp,
2438
- "T1-init timer has expired %zu/%s]",
2417
+ "T1-init timer has expired [%zu/%s]",
2439
2418
  this->t1InitTimer->GetExpirationCount(),
2440
2419
  maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
2441
2420
 
@@ -2463,7 +2442,7 @@ namespace RTC
2463
2442
 
2464
2443
  MS_DEBUG_TAG(
2465
2444
  sctp,
2466
- "T1-cookie timer has expired %zu/%s]",
2445
+ "T1-cookie timer has expired [%zu/%s]",
2467
2446
  this->t1CookieTimer->GetExpirationCount(),
2468
2447
  maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
2469
2448
 
@@ -2472,7 +2451,7 @@ namespace RTC
2472
2451
  if (this->t1CookieTimer->IsRunning())
2473
2452
  {
2474
2453
  // TODO: SCTP: Implement it.
2475
- // this->tcb->SendBufferedPackets(now);
2454
+ // this->tcb->SendBufferedPackets(nowMs);
2476
2455
  }
2477
2456
  else
2478
2457
  {
@@ -2807,7 +2786,8 @@ namespace RTC
2807
2786
  }
2808
2787
  }
2809
2788
 
2810
- void Association::OnTimer(BackoffTimerHandle* backoffTimer, uint64_t& baseTimeoutMs, bool& stop)
2789
+ void Association::OnTimer(
2790
+ BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop)
2811
2791
  {
2812
2792
  MS_TRACE();
2813
2793
 
@@ -8,6 +8,7 @@
8
8
  #include "Utils.hpp"
9
9
  #include "RTC/SCTP/packet/parameters/HeartbeatInfoParameter.hpp"
10
10
  #include "RTC/SCTP/public/SctpTypes.hpp"
11
+ #include "handles/BackoffTimerHandle.hpp"
11
12
  #include <string>
12
13
 
13
14
  namespace RTC
@@ -21,26 +22,30 @@ namespace RTC
21
22
  /* Instance methods. */
22
23
 
23
24
  HeartbeatHandler::HeartbeatHandler(
24
- AssociationListener& associationListener, const SctpOptions& sctpOptions, TCBContext* tcbContext)
25
+ AssociationListener& associationListener,
26
+ const SctpOptions& sctpOptions,
27
+ SharedInterface* shared,
28
+ TCBContext* tcbContext)
25
29
  : associationListener(associationListener),
26
30
  sctpOptions(sctpOptions),
31
+ shared(shared),
27
32
  tcbContext(tcbContext),
28
33
  intervalDurationMs(sctpOptions.heartbeatIntervalMs),
29
34
  intervalDurationShouldIncludeRtt(sctpOptions.heartbeatIntervalIncludeRtt),
30
- intervalTimer(
31
- std::make_unique<BackoffTimerHandle>(
32
- /*listener*/ this,
33
- /*baseTimeoutMs*/ sctpOptions.initialRtoMs,
34
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::EXPONENTIAL,
35
- /*maxBackoffTimeoutMs*/ sctpOptions.timerMaxBackoffTimeoutMs,
36
- /*maxRestarts*/ std::nullopt)),
37
- timeoutTimer(
38
- std::make_unique<BackoffTimerHandle>(
39
- /*listener*/ this,
40
- /*baseTimeoutMs*/ sctpOptions.initialRtoMs,
41
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::FIXED,
42
- /*maxBackoffTimeoutMs*/ std::nullopt,
43
- /*maxRestarts*/ 0))
35
+ intervalTimer(this->shared->CreateBackoffTimer(
36
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
37
+ .listener = this,
38
+ .baseTimeoutMs = sctpOptions.initialRtoMs,
39
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::EXPONENTIAL,
40
+ .maxBackoffTimeoutMs = sctpOptions.timerMaxBackoffTimeoutMs,
41
+ .maxRestarts = std::nullopt })),
42
+ timeoutTimer(this->shared->CreateBackoffTimer(
43
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
44
+ .listener = this,
45
+ .baseTimeoutMs = sctpOptions.initialRtoMs,
46
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::FIXED,
47
+ .maxBackoffTimeoutMs = std::nullopt,
48
+ .maxRestarts = 0 }))
44
49
  {
45
50
  MS_TRACE();
46
51
  }
@@ -145,11 +150,11 @@ namespace RTC
145
150
 
146
151
  if (createdAtMs > 0 && createdAtMs <= nowMs)
147
152
  {
148
- const uint64_t rtt = nowMs - createdAtMs;
153
+ const uint64_t rttMs = nowMs - createdAtMs;
149
154
 
150
- MS_DEBUG_DEV("valid HEARTBEAT_ACK Chunk received, calling ObserveRtt(%" PRIu64 ")", rtt);
155
+ MS_DEBUG_DEV("valid HEARTBEAT_ACK Chunk received, calling ObserveRttMs(%" PRIu64 ")", rttMs);
151
156
 
152
- this->tcbContext->ObserveRtt(rtt);
157
+ this->tcbContext->ObserveRttMs(rttMs);
153
158
  }
154
159
  else
155
160
  {
@@ -182,7 +187,7 @@ namespace RTC
182
187
 
183
188
  MS_DEBUG_TAG(
184
189
  sctp,
185
- "interval timer has expired %zu/%s]",
190
+ "interval timer has expired [%zu/%s]",
186
191
  this->intervalTimer->GetExpirationCount(),
187
192
  maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
188
193
 
@@ -216,7 +221,7 @@ namespace RTC
216
221
 
217
222
  MS_DEBUG_TAG(
218
223
  sctp,
219
- "timeout timer has expired %zu/%s]",
224
+ "timeout timer has expired [%zu/%s]",
220
225
  this->timeoutTimer->GetExpirationCount(),
221
226
  maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
222
227
 
@@ -227,7 +232,8 @@ namespace RTC
227
232
  this->tcbContext->IncrementTxErrorCounter("hearbeat timeout");
228
233
  }
229
234
 
230
- void HeartbeatHandler::OnTimer(BackoffTimerHandle* backoffTimer, uint64_t& baseTimeoutMs, bool& stop)
235
+ void HeartbeatHandler::OnTimer(
236
+ BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop)
231
237
  {
232
238
  MS_TRACE();
233
239
 
@@ -4,36 +4,36 @@
4
4
 
5
5
  #include "RTC/SCTP/association/StreamResetHandler.hpp"
6
6
  #include "Logger.hpp"
7
- #include "RTC/Consts.hpp"
8
7
  #include "RTC/SCTP/packet/Parameter.hpp"
9
8
  #include "RTC/SCTP/packet/parameters/ReconfigurationResponseParameter.hpp"
9
+ #include "handles/BackoffTimerHandle.hpp"
10
10
 
11
11
  namespace RTC
12
12
  {
13
13
  namespace SCTP
14
14
  {
15
- /* Static. */
16
-
17
- alignas(4) thread_local static uint8_t ChunkFactoryBuffer[RTC::Consts::MaxSafeMtuSizeForSctp];
18
-
19
15
  /* Instance methods. */
20
16
 
21
17
  StreamResetHandler::StreamResetHandler(
22
- AssociationListener& associationListener, TCBContext* tcbContext
18
+ AssociationListener& associationListener,
19
+ SharedInterface* shared,
20
+ TCBContext* tcbContext,
23
21
  // TODO: SCTP: Implement
24
22
  // DataTracker* dataTracker,
25
23
  // ReassemblyQueue* reassemblyQueue,
26
- // RetransmissionQueue* retransmissionQueue
27
- )
24
+ RetransmissionQueue* retransmissionQueue)
28
25
  : associationListener(associationListener),
26
+ shared(shared),
29
27
  tcbContext(tcbContext),
30
- reConfigTimer(
31
- std::make_unique<BackoffTimerHandle>(
32
- /*listener*/ this,
33
- /*baseTimeoutMs*/ 0,
34
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::EXPONENTIAL,
35
- /*maxBackoffTimeoutMs*/ std::nullopt,
36
- /*maxRestarts*/ std::nullopt)),
28
+ retransmissionQueue(retransmissionQueue),
29
+ reConfigTimer(this->shared->CreateBackoffTimer(
30
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
31
+ .listener = this,
32
+ .baseTimeoutMs = 0,
33
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::EXPONENTIAL,
34
+ .maxBackoffTimeoutMs = std::nullopt,
35
+ .maxRestarts = std::nullopt,
36
+ })),
37
37
  nextOutgoingReqSeqNbr(tcbContext->GetLocalInitialTsn()),
38
38
  lastProcessedReqSeqNbr(
39
39
  this->incomingReConfigRequestSnUnwrapper.Unwrap(tcbContext->GetRemoteInitialTsn() - 1)),
@@ -47,18 +47,42 @@ namespace RTC
47
47
  MS_TRACE();
48
48
  }
49
49
 
50
- void StreamResetHandler::ResetStreams(std::span<const uint16_t> /*outgoingStreamIds*/)
50
+ void StreamResetHandler::ResetStreams(std::span<const uint16_t> outgoingStreamIds)
51
51
  {
52
52
  MS_TRACE();
53
53
 
54
- // TODO: SCTP: Uncomment.
55
- // for (const auto streamId : outgoingStreamIds)
54
+ for (const auto streamId : outgoingStreamIds)
56
55
  {
57
- // TODO: SCTP: Implement it.
58
- // this->retransmissionQueue->PrepareResetStream(streamId);
56
+ this->retransmissionQueue->PrepareResetStream(streamId);
59
57
  }
60
58
  }
61
59
 
60
+ bool StreamResetHandler::ShouldCreateStreamResetRequest() const
61
+ {
62
+ MS_TRACE();
63
+
64
+ // Only send stream resets if there are streams to reset and no current
65
+ // ongoing request (there can only be one at a time).
66
+ return !this->currentRequest.has_value() &&
67
+ this->retransmissionQueue->HasStreamsReadyToBeReset();
68
+ }
69
+
70
+ void StreamResetHandler::CreateStreamResetRequest(Packet* packet)
71
+ {
72
+ MS_TRACE();
73
+
74
+ MS_ASSERT(ShouldCreateStreamResetRequest(), "should not create a stream reset request");
75
+
76
+ this->currentRequest.emplace(
77
+ this->retransmissionQueue->GetLastAssignedTsn(),
78
+ this->retransmissionQueue->BeginResetStreams());
79
+
80
+ this->reConfigTimer->SetBaseTimeoutMs(this->tcbContext->GetCurrentRtoMs());
81
+ this->reConfigTimer->Start();
82
+
83
+ CreateReConfigChunk(packet);
84
+ }
85
+
62
86
  void StreamResetHandler::HandleReceivedReConfigChunk(const ReConfigChunk* receivedReConfigChunk)
63
87
  {
64
88
  MS_TRACE();
@@ -169,32 +193,7 @@ namespace RTC
169
193
  return false;
170
194
  }
171
195
 
172
- ReConfigChunk* StreamResetHandler::CreateStreamResetRequest()
173
- {
174
- MS_TRACE();
175
-
176
- // Only send stream resets if there are streams to reset, and no current
177
- // ongoing request (there can only be one at a time), and if the stream
178
- // can be reset.
179
- // TODO: SCTP: Implement it.
180
- // if (this->currentRequest.has_value() ||
181
- // !this->retransmissionQueue->HasStreamsReadyToBeReset())
182
- // {
183
- // return nullptr;
184
- // }
185
-
186
- // TODO: SCTP: Implement it.
187
- // this->currentRequest.emplace(
188
- // this->retransmissionQueue->GetLastAssignedTsn(),
189
- // this->retransmissionQueue->BeginResetStreams());
190
-
191
- this->reConfigTimer->SetBaseTimeoutMs(this->tcbContext->GetCurrentRtoMs());
192
- this->reConfigTimer->Start();
193
-
194
- return CreateReconfigChunk();
195
- }
196
-
197
- ReConfigChunk* StreamResetHandler::CreateReconfigChunk()
196
+ void StreamResetHandler::CreateReConfigChunk(Packet* packet)
198
197
  {
199
198
  MS_TRACE();
200
199
 
@@ -211,7 +210,7 @@ namespace RTC
211
210
  this->nextOutgoingReqSeqNbr = uint32_t{ this->nextOutgoingReqSeqNbr + 1 };
212
211
  }
213
212
 
214
- auto* reConfigChunk = ReConfigChunk::Factory(ChunkFactoryBuffer, sizeof(ChunkFactoryBuffer));
213
+ auto* reConfigChunk = packet->BuildChunkInPlace<ReConfigChunk>();
215
214
  auto* outgoingSsnResetRequestParameter =
216
215
  reConfigChunk->BuildParameterInPlace<OutgoingSsnResetRequestParameter>();
217
216
 
@@ -228,8 +227,7 @@ namespace RTC
228
227
  }
229
228
 
230
229
  outgoingSsnResetRequestParameter->Consolidate();
231
-
232
- return reConfigChunk;
230
+ reConfigChunk->Consolidate();
233
231
  }
234
232
 
235
233
  StreamResetHandler::ReqSeqNbrValidationResult StreamResetHandler::ValidateReqSeqNbr(
@@ -413,8 +411,7 @@ namespace RTC
413
411
 
414
412
  this->currentRequest = std::nullopt;
415
413
 
416
- // TODO: SCTP: Implement it.
417
- // this->retransmissionQueue->CommitResetSteam();
414
+ this->retransmissionQueue->CommitResetStreams();
418
415
 
419
416
  break;
420
417
  }
@@ -454,8 +451,7 @@ namespace RTC
454
451
 
455
452
  this->currentRequest = std::nullopt;
456
453
 
457
- // TODO: SCTP: Implement it.
458
- // this->retransmissionQueue->RollbackResetStreams();
454
+ this->retransmissionQueue->RollbackResetStreams();
459
455
 
460
456
  break;
461
457
  }
@@ -492,14 +488,15 @@ namespace RTC
492
488
 
493
489
  auto packet = this->tcbContext->CreatePacket();
494
490
 
495
- packet->AddChunk(CreateReconfigChunk());
491
+ CreateReConfigChunk(packet.get());
496
492
 
497
493
  this->tcbContext->Send(packet.get());
498
494
 
499
495
  baseTimeoutMs = this->tcbContext->GetCurrentRtoMs();
500
496
  }
501
497
 
502
- void StreamResetHandler::OnTimer(BackoffTimerHandle* backoffTimer, uint64_t& baseTimeoutMs, bool& stop)
498
+ void StreamResetHandler::OnTimer(
499
+ BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop)
503
500
  {
504
501
  MS_TRACE();
505
502