mediasoup 3.26.0 → 3.27.0
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/CHANGELOG.md +11 -0
- package/node/lib/DataConsumer.js +1 -1
- package/node/lib/Router.js +1 -1
- package/node/lib/Transport.js +15 -15
- package/node/lib/fbs/rtp-parameters/encoding-mapping.d.ts +2 -6
- package/node/lib/fbs/rtp-parameters/encoding-mapping.d.ts.map +1 -1
- package/node/lib/fbs/rtp-parameters/encoding-mapping.js +7 -19
- package/node/lib/fbs/rtp-parameters/rtp-encoding-parameters.d.ts +4 -4
- package/node/lib/fbs/rtp-parameters/rtp-encoding-parameters.js +2 -2
- package/node/lib/fbs/rtp-stream/bitrate-by-layer.d.ts +5 -5
- package/node/lib/fbs/rtp-stream/bitrate-by-layer.d.ts.map +1 -1
- package/node/lib/fbs/rtp-stream/bitrate-by-layer.js +3 -3
- package/node/lib/fbs/rtp-stream/recv-stats.d.ts +5 -5
- package/node/lib/fbs/rtp-stream/recv-stats.d.ts.map +1 -1
- package/node/lib/fbs/rtp-stream/recv-stats.js +3 -3
- package/node/lib/fbs/rtp-stream/send-stats.d.ts +5 -5
- package/node/lib/fbs/rtp-stream/send-stats.d.ts.map +1 -1
- package/node/lib/fbs/rtp-stream/send-stats.js +3 -3
- package/node/lib/fbs/transport/bwe-trace-info.d.ts +23 -23
- package/node/lib/fbs/transport/bwe-trace-info.d.ts.map +1 -1
- package/node/lib/fbs/transport/bwe-trace-info.js +15 -15
- package/node/lib/fbs/transport/options.d.ts +5 -5
- package/node/lib/fbs/transport/options.js +2 -2
- package/node/lib/fbs/transport/set-max-incoming-bitrate-request.d.ts +5 -5
- package/node/lib/fbs/transport/set-max-incoming-bitrate-request.d.ts.map +1 -1
- package/node/lib/fbs/transport/set-max-incoming-bitrate-request.js +3 -3
- package/node/lib/fbs/transport/set-max-outgoing-bitrate-request.d.ts +5 -5
- package/node/lib/fbs/transport/set-max-outgoing-bitrate-request.d.ts.map +1 -1
- package/node/lib/fbs/transport/set-max-outgoing-bitrate-request.js +3 -3
- package/node/lib/fbs/transport/set-min-outgoing-bitrate-request.d.ts +5 -5
- package/node/lib/fbs/transport/set-min-outgoing-bitrate-request.d.ts.map +1 -1
- package/node/lib/fbs/transport/set-min-outgoing-bitrate-request.js +3 -3
- package/node/lib/fbs/transport/stats.d.ts +38 -38
- package/node/lib/fbs/transport/stats.d.ts.map +1 -1
- package/node/lib/fbs/transport/stats.js +25 -25
- package/node/lib/ortc.d.ts +0 -1
- package/node/lib/ortc.d.ts.map +1 -1
- package/node/lib/ortc.js +1 -2
- package/node/lib/rtpParametersFbsUtils.d.ts.map +1 -1
- package/node/lib/rtpParametersFbsUtils.js +2 -2
- package/package.json +9 -9
- package/worker/deps/libwebrtc/libwebrtc/call/rtp_transport_controller_send.cc +10 -10
- package/worker/deps/libwebrtc/libwebrtc/mediasoup_helpers.h +6 -6
- package/worker/deps/libwebrtc/libwebrtc/modules/congestion_controller/goog_cc/alr_detector.cc +1 -1
- package/worker/deps/libwebrtc/libwebrtc/modules/pacing/paced_sender.cc +7 -7
- package/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h +1 -1
- package/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc +1 -1
- package/worker/fbs/rtpParameters.fbs +1 -2
- package/worker/fbs/rtpStream.fbs +3 -3
- package/worker/fbs/transport.fbs +23 -23
- package/worker/fuzzer/include/RTC/FuzzerDtlsTransport.hpp +4 -1
- package/worker/fuzzer/src/FuzzerUtils.cpp +5 -3
- package/worker/fuzzer/src/RTC/FuzzerDtlsTransport.cpp +8 -5
- package/worker/fuzzer/src/RTC/FuzzerRateCalculator.cpp +3 -3
- package/worker/fuzzer/src/RTC/FuzzerTrendCalculator.cpp +6 -6
- package/worker/fuzzer/src/RTC/RTCP/FuzzerFeedbackRtpTransport.cpp +3 -3
- package/worker/fuzzer/src/RTC/RTP/FuzzerPacket.cpp +2 -2
- package/worker/fuzzer/src/RTC/RTP/FuzzerRetransmissionBuffer.cpp +5 -5
- package/worker/fuzzer/src/RTC/RTP/FuzzerRtpStreamSend.cpp +3 -3
- package/worker/fuzzer/src/fuzzer.cpp +4 -0
- package/worker/include/Channel/ChannelNotification.hpp +3 -3
- package/worker/include/Channel/ChannelRequest.hpp +1 -1
- package/worker/include/Channel/ChannelSocket.hpp +11 -0
- package/worker/include/DepLibUV.hpp +16 -33
- package/worker/include/RTC/ActiveSpeakerObserver.hpp +11 -11
- package/worker/include/RTC/AudioLevelObserver.hpp +4 -4
- package/worker/include/RTC/BWE/AcknowledgedBitrateEstimatorInterface.hpp +55 -0
- package/worker/include/RTC/BWE/AimdRateControl.hpp +190 -0
- package/worker/include/RTC/BWE/BweTypes.hpp +211 -0
- package/worker/include/RTC/BWE/DelayBasedBwe.hpp +173 -0
- package/worker/include/RTC/BWE/FeedbackAdapter.hpp +72 -0
- package/worker/include/RTC/BWE/InterArrivalDelta.hpp +106 -0
- package/worker/include/RTC/BWE/LinkCapacityEstimator.hpp +84 -0
- package/worker/include/RTC/BWE/RobustThroughputEstimator.hpp +94 -0
- package/worker/include/RTC/BWE/SendPacketHistory.hpp +137 -0
- package/worker/include/RTC/BWE/TrendlineEstimator.hpp +101 -0
- package/worker/include/RTC/Consts.hpp +6 -6
- package/worker/include/RTC/Consumer.hpp +14 -12
- package/worker/include/RTC/DataConsumer.hpp +3 -3
- package/worker/include/RTC/DataProducer.hpp +3 -3
- package/worker/include/RTC/DtlsTransport.hpp +5 -2
- package/worker/include/RTC/ICE/IceCandidate.hpp +2 -2
- package/worker/include/RTC/ICE/IceServer.hpp +3 -3
- package/worker/include/RTC/KeyFrameRequestManager.hpp +3 -3
- package/worker/include/RTC/NEW_RTCP/packet/Packet.hpp +1 -1
- package/worker/include/RTC/NackGenerator.hpp +12 -12
- package/worker/include/RTC/PipeProducerStreamManager.hpp +3 -4
- package/worker/include/RTC/PipeTransport.hpp +18 -5
- package/worker/include/RTC/PlainTransport.hpp +18 -5
- package/worker/include/RTC/PortManager.hpp +4 -4
- package/worker/include/RTC/Producer.hpp +21 -12
- package/worker/include/RTC/ProducerStreamManager.hpp +12 -6
- package/worker/include/RTC/RTCP/Bye.hpp +2 -2
- package/worker/include/RTC/RTCP/FeedbackPsRemb.hpp +4 -4
- package/worker/include/RTC/RTCP/FeedbackRtpTmmb.hpp +3 -3
- package/worker/include/RTC/RTCP/FeedbackRtpTransport.hpp +54 -39
- package/worker/include/RTC/RTCP/Packet.hpp +3 -3
- package/worker/include/RTC/RTCP/ReceiverReport.hpp +3 -3
- package/worker/include/RTC/RTCP/Sdes.hpp +2 -2
- package/worker/include/RTC/RTCP/XR.hpp +2 -2
- package/worker/include/RTC/RTCP/XrDelaySinceLastRr.hpp +1 -1
- package/worker/include/RTC/RTP/Codecs/H264.hpp +1 -1
- package/worker/include/RTC/RTP/Codecs/Opus.hpp +2 -2
- package/worker/include/RTC/RTP/Codecs/PayloadDescriptorHandler.hpp +3 -3
- package/worker/include/RTC/RTP/Codecs/VP8.hpp +2 -2
- package/worker/include/RTC/RTP/Codecs/VP9.hpp +2 -2
- package/worker/include/RTC/RTP/HeaderExtensionIds.hpp +12 -12
- package/worker/include/RTC/RTP/Packet.hpp +13 -13
- package/worker/include/RTC/RTP/ProbationGenerator.hpp +1 -1
- package/worker/include/RTC/RTP/RetransmissionBuffer.hpp +7 -7
- package/worker/include/RTC/RTP/RtpStream.hpp +37 -51
- package/worker/include/RTC/RTP/RtpStreamRecv.hpp +59 -41
- package/worker/include/RTC/RTP/RtpStreamSend.hpp +20 -14
- package/worker/include/RTC/RTP/RtxStream.hpp +12 -13
- package/worker/include/RTC/RateCalculator.hpp +50 -44
- package/worker/include/RTC/RemoteCaptureTimeEstimator.hpp +5 -4
- package/worker/include/RTC/RemoteClockOffsetEstimator.hpp +11 -11
- package/worker/include/RTC/Router.hpp +6 -0
- package/worker/include/RTC/RtcLogger.hpp +1 -1
- package/worker/include/RTC/RtpDictionaries.hpp +10 -10
- package/worker/include/RTC/SCTP/association/Association.hpp +56 -28
- package/worker/include/RTC/SCTP/association/HeartbeatHandler.hpp +4 -4
- package/worker/include/RTC/SCTP/association/StateCookie.hpp +14 -14
- package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +2 -2
- package/worker/include/RTC/SCTP/association/TransmissionControlBlock.hpp +12 -12
- package/worker/include/RTC/SCTP/association/TransmissionControlBlockContextInterface.hpp +4 -4
- package/worker/include/RTC/SCTP/packet/TLV.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/StateCookieParameter.hpp +3 -3
- package/worker/include/RTC/SCTP/public/AssociationInterface.hpp +4 -1
- package/worker/include/RTC/SCTP/public/AssociationMetrics.hpp +1 -1
- package/worker/include/RTC/SCTP/public/SctpOptions.hpp +12 -12
- package/worker/include/RTC/SCTP/public/SctpTypes.hpp +1 -1
- package/worker/include/RTC/SCTP/tx/OutstandingData.hpp +15 -16
- package/worker/include/RTC/SCTP/tx/RetransmissionQueue.hpp +7 -8
- package/worker/include/RTC/SCTP/tx/RetransmissionTimeout.hpp +20 -16
- package/worker/include/RTC/SCTP/tx/RoundRobinSendQueue.hpp +5 -6
- package/worker/include/RTC/SCTP/tx/SendQueueInterface.hpp +2 -2
- package/worker/include/RTC/SCTP/tx/StreamScheduler.hpp +5 -5
- package/worker/include/RTC/SctpDictionaries.hpp +3 -3
- package/worker/include/RTC/Serializable.hpp +1 -1
- package/worker/include/RTC/SimpleProducerStreamManager.hpp +3 -4
- package/worker/include/RTC/SimulcastProducerStreamManager.hpp +6 -7
- package/worker/include/RTC/SvcProducerStreamManager.hpp +6 -5
- package/worker/include/RTC/TcpConnection.hpp +9 -3
- package/worker/include/RTC/TcpServer.hpp +3 -0
- package/worker/include/RTC/Transport.hpp +52 -45
- package/worker/include/RTC/TransportCongestionControlClient.hpp +30 -25
- package/worker/include/RTC/TransportCongestionControlServer.hpp +17 -17
- package/worker/include/RTC/TrendCalculator.hpp +5 -5
- package/worker/include/RTC/UdpSocket.hpp +11 -2
- package/worker/include/RTC/WebRtcServer.hpp +20 -5
- package/worker/include/RTC/WebRtcTransport.hpp +35 -10
- package/worker/include/Settings.hpp +4 -2
- package/worker/include/Shared.hpp +5 -20
- package/worker/include/SharedInterface.hpp +6 -28
- package/worker/include/Utils.hpp +40 -21
- package/worker/include/common.hpp +4 -0
- package/worker/include/handles/BackoffTimerHandle.hpp +4 -4
- package/worker/include/handles/BackoffTimerHandleInterface.hpp +5 -5
- package/worker/include/handles/TcpConnectionHandle.hpp +6 -6
- package/worker/include/handles/TcpServerHandle.hpp +1 -1
- package/worker/include/handles/TimerHandle.hpp +15 -9
- package/worker/include/handles/TimerHandleInterface.hpp +10 -4
- package/worker/include/handles/UdpSocketHandle.hpp +3 -3
- package/worker/include/handles/UnixStreamSocketHandle.hpp +2 -2
- package/worker/meson.build +81 -36
- package/worker/meson_options.txt +1 -0
- package/worker/mocks/include/MockShared.hpp +24 -23
- package/worker/mocks/include/RTC/SCTP/association/MockTransmissionControlBlockContext.hpp +51 -27
- package/worker/mocks/include/RTC/SCTP/tx/MockSendQueue.hpp +11 -11
- package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +10 -10
- package/worker/mocks/include/handles/MockTimerHandle.hpp +60 -22
- package/worker/mocks/src/MockShared.cpp +51 -5
- package/worker/mocks/src/handles/MockBackoffTimerHandle.cpp +29 -15
- package/worker/mocks/src/handles/MockTimerHandle.cpp +117 -0
- package/worker/scripts/clang-scripts.mjs +2 -2
- package/worker/src/Channel/ChannelNotification.cpp +5 -6
- package/worker/src/Channel/ChannelSocket.cpp +20 -2
- package/worker/src/DepLibUV.cpp +4 -5
- package/worker/src/RTC/ActiveSpeakerObserver.cpp +59 -47
- package/worker/src/RTC/AudioLevelObserver.cpp +7 -7
- package/worker/src/RTC/BWE/AimdRateControl.cpp +468 -0
- package/worker/src/RTC/BWE/BweTypes.cpp +61 -0
- package/worker/src/RTC/BWE/DelayBasedBwe.cpp +275 -0
- package/worker/src/RTC/BWE/FeedbackAdapter.cpp +148 -0
- package/worker/src/RTC/BWE/InterArrivalDelta.cpp +181 -0
- package/worker/src/RTC/BWE/LinkCapacityEstimator.cpp +133 -0
- package/worker/src/RTC/BWE/RobustThroughputEstimator.cpp +245 -0
- package/worker/src/RTC/BWE/SendPacketHistory.cpp +184 -0
- package/worker/src/RTC/BWE/TrendlineEstimator.cpp +233 -0
- package/worker/src/RTC/Consumer.cpp +48 -35
- package/worker/src/RTC/DataConsumer.cpp +4 -4
- package/worker/src/RTC/DataProducer.cpp +3 -3
- package/worker/src/RTC/DirectTransport.cpp +2 -2
- package/worker/src/RTC/DtlsTransport.cpp +14 -11
- package/worker/src/RTC/ICE/IceServer.cpp +2 -2
- package/worker/src/RTC/KeyFrameRequestManager.cpp +16 -12
- package/worker/src/RTC/NackGenerator.cpp +12 -12
- package/worker/src/RTC/PipeProducerStreamManager.cpp +6 -6
- package/worker/src/RTC/PipeTransport.cpp +16 -13
- package/worker/src/RTC/PlainTransport.cpp +25 -16
- package/worker/src/RTC/Producer.cpp +50 -36
- package/worker/src/RTC/RTCP/FeedbackPsRemb.cpp +13 -6
- package/worker/src/RTC/RTCP/FeedbackRtpTmmb.cpp +14 -5
- package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +76 -50
- package/worker/src/RTC/RTP/Codecs/VP8.cpp +1 -1
- package/worker/src/RTC/RTP/Codecs/VP9.cpp +4 -4
- package/worker/src/RTC/RTP/Packet.cpp +9 -10
- package/worker/src/RTC/RTP/RetransmissionBuffer.cpp +6 -6
- package/worker/src/RTC/RTP/RtpStream.cpp +19 -19
- package/worker/src/RTC/RTP/RtpStreamRecv.cpp +146 -81
- package/worker/src/RTC/RTP/RtpStreamSend.cpp +49 -44
- package/worker/src/RTC/RTP/RtxStream.cpp +7 -10
- package/worker/src/RTC/RateCalculator.cpp +99 -136
- package/worker/src/RTC/RemoteCaptureTimeEstimator.cpp +13 -13
- package/worker/src/RTC/RemoteClockOffsetEstimator.cpp +18 -17
- package/worker/src/RTC/Router.cpp +18 -1
- package/worker/src/RTC/RtpDictionaries/RtpEncodingParameters.cpp +5 -2
- package/worker/src/RTC/SCTP/association/Association.cpp +131 -102
- package/worker/src/RTC/SCTP/association/AssociationListenerDeferrer.cpp +4 -4
- package/worker/src/RTC/SCTP/association/Capabilities.cpp +1 -1
- package/worker/src/RTC/SCTP/association/HeartbeatHandler.cpp +25 -18
- package/worker/src/RTC/SCTP/association/StateCookie.cpp +7 -6
- package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +16 -13
- package/worker/src/RTC/SCTP/association/TransmissionControlBlock.cpp +28 -26
- package/worker/src/RTC/SCTP/packet/chunks/SackChunk.cpp +0 -1
- package/worker/src/RTC/SCTP/packet/parameters/StateCookieParameter.cpp +2 -2
- package/worker/src/RTC/SCTP/public/AssociationMetrics.cpp +1 -1
- package/worker/src/RTC/SCTP/public/SctpOptions.cpp +13 -13
- package/worker/src/RTC/SCTP/rx/DataTracker.cpp +1 -1
- package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +5 -5
- package/worker/src/RTC/SCTP/tx/OutstandingData.cpp +15 -15
- package/worker/src/RTC/SCTP/tx/RetransmissionQueue.cpp +15 -15
- package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +29 -26
- package/worker/src/RTC/SCTP/tx/RoundRobinSendQueue.cpp +12 -11
- package/worker/src/RTC/SCTP/tx/StreamScheduler.cpp +4 -4
- package/worker/src/RTC/SctpDictionaries/SctpStreamParameters.cpp +2 -2
- package/worker/src/RTC/SimpleProducerStreamManager.cpp +10 -10
- package/worker/src/RTC/SimulcastProducerStreamManager.cpp +39 -37
- package/worker/src/RTC/SvcProducerStreamManager.cpp +39 -25
- package/worker/src/RTC/TcpConnection.cpp +9 -3
- package/worker/src/RTC/TcpServer.cpp +7 -2
- package/worker/src/RTC/Transport.cpp +242 -302
- package/worker/src/RTC/TransportCongestionControlClient.cpp +78 -71
- package/worker/src/RTC/TransportCongestionControlServer.cpp +38 -40
- package/worker/src/RTC/TrendCalculator.cpp +3 -3
- package/worker/src/RTC/UdpSocket.cpp +14 -3
- package/worker/src/RTC/WebRtcServer.cpp +20 -14
- package/worker/src/RTC/WebRtcTransport.cpp +35 -30
- package/worker/src/Settings.cpp +10 -0
- package/worker/src/Shared.cpp +2 -2
- package/worker/src/Utils/Crypto.cpp +2 -2
- package/worker/src/Worker.cpp +5 -1
- package/worker/src/handles/BackoffTimerHandle.cpp +24 -11
- package/worker/src/handles/TimerHandle.cpp +74 -25
- package/worker/src/lib.cpp +6 -0
- package/worker/tasks.py +171 -44
- package/worker/test/include/RTC/BWE/helpers/LinkSimulator.hpp +117 -0
- package/worker/test/src/RTC/BWE/TestAimdRateControl.cpp +400 -0
- package/worker/test/src/RTC/BWE/TestDelayBasedBwe.cpp +568 -0
- package/worker/test/src/RTC/BWE/TestFeedbackAdapter.cpp +546 -0
- package/worker/test/src/RTC/BWE/TestInterArrivalDelta.cpp +301 -0
- package/worker/test/src/RTC/BWE/TestLinkCapacityEstimator.cpp +115 -0
- package/worker/test/src/RTC/BWE/TestRobustThroughputEstimator.cpp +433 -0
- package/worker/test/src/RTC/BWE/TestSendPacketHistory.cpp +259 -0
- package/worker/test/src/RTC/BWE/TestTrendlineEstimator.cpp +137 -0
- package/worker/test/src/RTC/BWE/helpers/LinkSimulator.cpp +171 -0
- package/worker/test/src/RTC/RTCP/TestFeedbackPsRemb.cpp +1 -1
- package/worker/test/src/RTC/RTCP/TestFeedbackRtpTmmb.cpp +1 -1
- package/worker/test/src/RTC/RTCP/TestFeedbackRtpTransport.cpp +246 -208
- package/worker/test/src/RTC/RTP/TestPacket.cpp +11 -11
- package/worker/test/src/RTC/RTP/TestRetransmissionBuffer.cpp +12 -12
- package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +23 -16
- package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +13 -13
- package/worker/test/src/RTC/SCTP/association/TestAssociation.cpp +27 -22
- package/worker/test/src/RTC/SCTP/association/TestHeartbeatHandler.cpp +21 -15
- package/worker/test/src/RTC/SCTP/association/TestStateCookie.cpp +6 -6
- package/worker/test/src/RTC/SCTP/association/TestStreamResetHandler.cpp +17 -13
- package/worker/test/src/RTC/SCTP/association/TestTransmissionControlBlock.cpp +3 -3
- package/worker/test/src/RTC/SCTP/packet/chunks/TestForwardTsnChunk.cpp +2 -2
- package/worker/test/src/RTC/SCTP/packet/chunks/TestIForwardTsnChunk.cpp +23 -23
- package/worker/test/src/RTC/SCTP/packet/chunks/TestInitChunk.cpp +1 -1
- package/worker/test/src/RTC/SCTP/packet/chunks/TestSackChunk.cpp +1 -1
- package/worker/test/src/RTC/SCTP/packet/parameters/TestIPv6AddressParameter.cpp +1 -1
- package/worker/test/src/RTC/SCTP/rx/TestDataTracker.cpp +37 -37
- package/worker/test/src/RTC/SCTP/rx/TestInterleavedReassemblyStreams.cpp +10 -10
- package/worker/test/src/RTC/SCTP/rx/TestReassemblyQueue.cpp +1 -1
- package/worker/test/src/RTC/SCTP/tx/TestOutstandingData.cpp +93 -93
- package/worker/test/src/RTC/SCTP/tx/TestRetransmissionQueue.cpp +247 -247
- package/worker/test/src/RTC/SCTP/tx/TestRetransmissionTimeout.cpp +100 -80
- package/worker/test/src/RTC/SCTP/tx/TestRoundRobinSendQueue.cpp +163 -163
- package/worker/test/src/RTC/SCTP/tx/TestStreamScheduler.cpp +76 -77
- package/worker/test/src/RTC/TestConsumer.cpp +8 -3
- package/worker/test/src/RTC/TestKeyFrameRequestManager.cpp +3 -3
- package/worker/test/src/RTC/TestNackGenerator.cpp +3 -3
- package/worker/test/src/RTC/TestPipeProducerStreamManager.cpp +5 -5
- package/worker/test/src/RTC/TestRateCalculator.cpp +110 -14
- package/worker/test/src/RTC/TestRemoteCaptureTimeEstimator.cpp +22 -17
- package/worker/test/src/RTC/TestRemoteClockOffsetEstimator.cpp +87 -85
- package/worker/test/src/RTC/TestSimpleProducerStreamManager.cpp +54 -47
- package/worker/test/src/RTC/TestSimulcastProducerStreamManager.cpp +83 -69
- package/worker/test/src/RTC/TestSvcProducerStreamManager.cpp +76 -65
- package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +72 -66
- package/worker/test/src/RTC/TestTransportTuple.cpp +19 -4
- package/worker/test/src/TestDepLibUV.cpp +19 -0
- package/worker/test/src/Utils/TestTime.cpp +57 -26
- package/worker/test/src/testHelpers.cpp +1 -1
- package/worker/test/src/tests.cpp +6 -0
- package/worker/include/RTC/SenderBandwidthEstimator.hpp +0 -118
- package/worker/src/RTC/SenderBandwidthEstimator.cpp +0 -269
|
@@ -24,9 +24,9 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
24
24
|
class MockRetransmissionQueueListener : public RTC::SCTP::RetransmissionQueue::Listener
|
|
25
25
|
{
|
|
26
26
|
public:
|
|
27
|
-
void
|
|
27
|
+
void OnRetransmissionQueueNewRttUs(int64_t rttUs) override
|
|
28
28
|
{
|
|
29
|
-
this->
|
|
29
|
+
this->lastRttUs = rttUs;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
void OnRetransmissionQueueClearRetransmissionCounter() override
|
|
@@ -35,7 +35,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
public:
|
|
38
|
-
|
|
38
|
+
int64_t lastRttUs{ 0 };
|
|
39
39
|
size_t clearRetransmissionCounterCalls{ 0 };
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -44,7 +44,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
44
44
|
/* Pure virtual methods inherited from BackoffTimerHandleInterface::Listener. */
|
|
45
45
|
public:
|
|
46
46
|
void OnBackoffTimer(
|
|
47
|
-
BackoffTimerHandleInterface* /*backoffTimer*/,
|
|
47
|
+
BackoffTimerHandleInterface* /*backoffTimer*/, int64_t& /*baseTimeoutMs*/, bool& /*stop*/) override
|
|
48
48
|
{
|
|
49
49
|
}
|
|
50
50
|
};
|
|
@@ -63,11 +63,11 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
63
63
|
MockBackoffTimerHandleListener backoffTimerHandleListener;
|
|
64
64
|
mocks::RTC::SCTP::MockAssociationListener associationListener;
|
|
65
65
|
mocks::RTC::SCTP::MockSendQueue sendQueue;
|
|
66
|
-
|
|
67
|
-
mocks::MockShared shared(/*
|
|
68
|
-
[&
|
|
66
|
+
int64_t nowUs{ 10000 * 1000 };
|
|
67
|
+
mocks::MockShared shared(/*getTimeUs*/
|
|
68
|
+
[&nowUs]() -> int64_t
|
|
69
69
|
{
|
|
70
|
-
return
|
|
70
|
+
return nowUs;
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
const std::unique_ptr<BackoffTimerHandleInterface> t3RtxTimerUniquePtr{ shared.CreateBackoffTimer(
|
|
@@ -101,7 +101,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
101
101
|
uint32_t outgoingMessageId,
|
|
102
102
|
uint16_t maxRetransmissions = RTC::SCTP::Types::MaxRetransmitsNoLimit)
|
|
103
103
|
{
|
|
104
|
-
return [outgoingMessageId, maxRetransmissions](
|
|
104
|
+
return [outgoingMessageId, maxRetransmissions](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
105
105
|
{
|
|
106
106
|
RTC::SCTP::UserData data(
|
|
107
107
|
/*streamId*/ 1,
|
|
@@ -153,11 +153,11 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
153
153
|
return tsns;
|
|
154
154
|
};
|
|
155
155
|
|
|
156
|
-
auto getSentPacketTSNs = [&
|
|
156
|
+
auto getSentPacketTSNs = [&nowUs](RTC::SCTP::RetransmissionQueue& queue, size_t maxLength = 10000)
|
|
157
157
|
{
|
|
158
158
|
std::vector<uint32_t> tsns;
|
|
159
159
|
|
|
160
|
-
for (const auto& elem : queue.GetChunksToSend(
|
|
160
|
+
for (const auto& elem : queue.GetChunksToSend(nowUs, maxLength))
|
|
161
161
|
{
|
|
162
162
|
tsns.push_back(elem.first);
|
|
163
163
|
}
|
|
@@ -172,12 +172,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
172
172
|
REQUIRE(retransmissionQueue.GetUnackedItems() == 0);
|
|
173
173
|
REQUIRE(retransmissionQueue.GetUnackedPacketBytes() == 0);
|
|
174
174
|
REQUIRE(retransmissionQueue.GetNextTsn() == InitialTsn);
|
|
175
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
175
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
176
176
|
REQUIRE(
|
|
177
177
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
178
178
|
std::vector<std::pair<uint32_t, RTC::SCTP::OutstandingData::State>>{
|
|
179
179
|
{ InitialTsn - 1, RTC::SCTP::OutstandingData::State::ACKED },
|
|
180
|
-
|
|
180
|
+
});
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
SECTION("send one chunk")
|
|
@@ -186,7 +186,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
186
186
|
|
|
187
187
|
sendQueue.WillProduceOnce(createDataToSend(0))
|
|
188
188
|
.WillProduceRepeatedly(
|
|
189
|
-
[](
|
|
189
|
+
[](int64_t, size_t)
|
|
190
190
|
{
|
|
191
191
|
return std::nullopt;
|
|
192
192
|
});
|
|
@@ -197,7 +197,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
197
197
|
std::vector<std::pair<uint32_t, RTC::SCTP::OutstandingData::State>>{
|
|
198
198
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
199
199
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
200
|
-
|
|
200
|
+
});
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
SECTION("send one chunk and ack")
|
|
@@ -206,20 +206,20 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
206
206
|
|
|
207
207
|
sendQueue.WillProduceOnce(createDataToSend(0))
|
|
208
208
|
.WillProduceRepeatedly(
|
|
209
|
-
[](
|
|
209
|
+
[](int64_t, size_t)
|
|
210
210
|
{
|
|
211
211
|
return std::nullopt;
|
|
212
212
|
});
|
|
213
213
|
|
|
214
214
|
REQUIRE(getSentPacketTSNs(retransmissionQueue) == std::vector<uint32_t>{ 10 });
|
|
215
215
|
|
|
216
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
216
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, Arwnd).get());
|
|
217
217
|
|
|
218
218
|
REQUIRE(
|
|
219
219
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
220
220
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
221
221
|
{ 10, RTC::SCTP::OutstandingData::State::ACKED },
|
|
222
|
-
|
|
222
|
+
});
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
SECTION("send three chunks and ack two")
|
|
@@ -230,21 +230,21 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
230
230
|
.WillProduceOnce(createDataToSend(1))
|
|
231
231
|
.WillProduceOnce(createDataToSend(2))
|
|
232
232
|
.WillProduceRepeatedly(
|
|
233
|
-
[](
|
|
233
|
+
[](int64_t, size_t)
|
|
234
234
|
{
|
|
235
235
|
return std::nullopt;
|
|
236
236
|
});
|
|
237
237
|
|
|
238
238
|
REQUIRE(getSentPacketTSNs(retransmissionQueue) == std::vector<uint32_t>{ 10, 11, 12 });
|
|
239
239
|
|
|
240
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
240
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(11, Arwnd).get());
|
|
241
241
|
|
|
242
242
|
REQUIRE(
|
|
243
243
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
244
244
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
245
245
|
{ 11, RTC::SCTP::OutstandingData::State::ACKED },
|
|
246
246
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
247
|
-
|
|
247
|
+
});
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
SECTION("ack with gap blocks from RFC 4960 section 334")
|
|
@@ -260,7 +260,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
260
260
|
.WillProduceOnce(createDataToSend(6))
|
|
261
261
|
.WillProduceOnce(createDataToSend(7))
|
|
262
262
|
.WillProduceRepeatedly(
|
|
263
|
-
[](
|
|
263
|
+
[](int64_t, size_t)
|
|
264
264
|
{
|
|
265
265
|
return std::nullopt;
|
|
266
266
|
});
|
|
@@ -270,7 +270,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
270
270
|
std::vector<uint32_t>{ 10, 11, 12, 13, 14, 15, 16, 17 });
|
|
271
271
|
|
|
272
272
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
273
|
-
|
|
273
|
+
nowUs,
|
|
274
274
|
createSackChunk(
|
|
275
275
|
12,
|
|
276
276
|
Arwnd,
|
|
@@ -289,7 +289,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
289
289
|
{ 15, RTC::SCTP::OutstandingData::State::ACKED },
|
|
290
290
|
{ 16, RTC::SCTP::OutstandingData::State::NACKED },
|
|
291
291
|
{ 17, RTC::SCTP::OutstandingData::State::ACKED },
|
|
292
|
-
|
|
292
|
+
});
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
SECTION("resend packet when nacked three times")
|
|
@@ -305,7 +305,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
305
305
|
.WillProduceOnce(createDataToSend(6))
|
|
306
306
|
.WillProduceOnce(createDataToSend(7))
|
|
307
307
|
.WillProduceRepeatedly(
|
|
308
|
-
[](
|
|
308
|
+
[](int64_t, size_t)
|
|
309
309
|
{
|
|
310
310
|
return std::nullopt;
|
|
311
311
|
});
|
|
@@ -320,7 +320,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
320
320
|
// Send TSN 18.
|
|
321
321
|
sendQueue.WillProduceOnce(createDataToSend(8))
|
|
322
322
|
.WillProduceRepeatedly(
|
|
323
|
-
[](
|
|
323
|
+
[](int64_t, size_t)
|
|
324
324
|
{
|
|
325
325
|
return std::nullopt;
|
|
326
326
|
});
|
|
@@ -329,7 +329,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
329
329
|
|
|
330
330
|
// Ack 12, 14-15, 17-18.
|
|
331
331
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
332
|
-
|
|
332
|
+
nowUs,
|
|
333
333
|
createSackChunk(
|
|
334
334
|
12,
|
|
335
335
|
Arwnd,
|
|
@@ -349,12 +349,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
349
349
|
{ 16, RTC::SCTP::OutstandingData::State::NACKED },
|
|
350
350
|
{ 17, RTC::SCTP::OutstandingData::State::ACKED },
|
|
351
351
|
{ 18, RTC::SCTP::OutstandingData::State::ACKED },
|
|
352
|
-
|
|
352
|
+
});
|
|
353
353
|
|
|
354
354
|
// Send TSN 19.
|
|
355
355
|
sendQueue.WillProduceOnce(createDataToSend(9))
|
|
356
356
|
.WillProduceRepeatedly(
|
|
357
|
-
[](
|
|
357
|
+
[](int64_t, size_t)
|
|
358
358
|
{
|
|
359
359
|
return std::nullopt;
|
|
360
360
|
});
|
|
@@ -363,7 +363,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
363
363
|
|
|
364
364
|
// Ack 12, 14-15, 17-19.
|
|
365
365
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
366
|
-
|
|
366
|
+
nowUs,
|
|
367
367
|
createSackChunk(
|
|
368
368
|
12,
|
|
369
369
|
Arwnd,
|
|
@@ -376,7 +376,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
376
376
|
// Send TSN 20.
|
|
377
377
|
sendQueue.WillProduceOnce(createDataToSend(10))
|
|
378
378
|
.WillProduceRepeatedly(
|
|
379
|
-
[](
|
|
379
|
+
[](int64_t, size_t)
|
|
380
380
|
{
|
|
381
381
|
return std::nullopt;
|
|
382
382
|
});
|
|
@@ -385,7 +385,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
385
385
|
|
|
386
386
|
// Ack 12, 14-15, 17-20.
|
|
387
387
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
388
|
-
|
|
388
|
+
nowUs,
|
|
389
389
|
createSackChunk(
|
|
390
390
|
12,
|
|
391
391
|
Arwnd,
|
|
@@ -407,7 +407,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
407
407
|
{ 18, RTC::SCTP::OutstandingData::State::ACKED },
|
|
408
408
|
{ 19, RTC::SCTP::OutstandingData::State::ACKED },
|
|
409
409
|
{ 20, RTC::SCTP::OutstandingData::State::ACKED },
|
|
410
|
-
|
|
410
|
+
});
|
|
411
411
|
|
|
412
412
|
// This will trigger "fast retransmit" mode and only chunks 13 and 16 will
|
|
413
413
|
// be resent right now. The send queue will not even be queried.
|
|
@@ -426,7 +426,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
426
426
|
{ 18, RTC::SCTP::OutstandingData::State::ACKED },
|
|
427
427
|
{ 19, RTC::SCTP::OutstandingData::State::ACKED },
|
|
428
428
|
{ 20, RTC::SCTP::OutstandingData::State::ACKED },
|
|
429
|
-
|
|
429
|
+
});
|
|
430
430
|
REQUIRE_VERIFICATION_RESULT(sendQueue.VerifyExpectations());
|
|
431
431
|
}
|
|
432
432
|
|
|
@@ -438,27 +438,27 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
438
438
|
.WillProduceOnce(createDataToSend(1))
|
|
439
439
|
.WillProduceOnce(createDataToSend(2))
|
|
440
440
|
.WillProduceRepeatedly(
|
|
441
|
-
[](
|
|
441
|
+
[](int64_t, size_t)
|
|
442
442
|
{
|
|
443
443
|
return std::nullopt;
|
|
444
444
|
});
|
|
445
445
|
|
|
446
446
|
// Starting time.
|
|
447
|
-
|
|
447
|
+
nowUs = 100 * 1000 * 1000; // 100 seconds.
|
|
448
448
|
|
|
449
449
|
REQUIRE(getSentPacketTSNs(retransmissionQueue) == std::vector<uint32_t>{ 10, 11, 12 });
|
|
450
450
|
|
|
451
451
|
// Ack 10, 12, after 100ms.
|
|
452
|
-
|
|
452
|
+
nowUs += 100 * 1000;
|
|
453
453
|
|
|
454
454
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
455
|
-
|
|
455
|
+
nowUs,
|
|
456
456
|
createSackChunk(
|
|
457
457
|
10,
|
|
458
458
|
Arwnd,
|
|
459
459
|
{
|
|
460
460
|
{ 2, 2 },
|
|
461
|
-
|
|
461
|
+
})
|
|
462
462
|
.get());
|
|
463
463
|
|
|
464
464
|
REQUIRE(
|
|
@@ -467,12 +467,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
467
467
|
{ 10, RTC::SCTP::OutstandingData::State::ACKED },
|
|
468
468
|
{ 11, RTC::SCTP::OutstandingData::State::NACKED },
|
|
469
469
|
{ 12, RTC::SCTP::OutstandingData::State::ACKED },
|
|
470
|
-
|
|
470
|
+
});
|
|
471
471
|
|
|
472
472
|
// Send 13.
|
|
473
473
|
sendQueue.WillProduceOnce(createDataToSend(3))
|
|
474
474
|
.WillProduceRepeatedly(
|
|
475
|
-
[](
|
|
475
|
+
[](int64_t, size_t)
|
|
476
476
|
{
|
|
477
477
|
return std::nullopt;
|
|
478
478
|
});
|
|
@@ -480,22 +480,22 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
480
480
|
REQUIRE(getSentPacketTSNs(retransmissionQueue) == std::vector<uint32_t>{ 13 });
|
|
481
481
|
|
|
482
482
|
// Ack 10, 12-13, after 100ms.
|
|
483
|
-
|
|
483
|
+
nowUs += 100 * 1000;
|
|
484
484
|
|
|
485
485
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
486
|
-
|
|
486
|
+
nowUs,
|
|
487
487
|
createSackChunk(
|
|
488
488
|
10,
|
|
489
489
|
Arwnd,
|
|
490
490
|
{
|
|
491
491
|
{ 2, 3 },
|
|
492
|
-
|
|
492
|
+
})
|
|
493
493
|
.get());
|
|
494
494
|
|
|
495
495
|
// Send 14.
|
|
496
496
|
sendQueue.WillProduceOnce(createDataToSend(4))
|
|
497
497
|
.WillProduceRepeatedly(
|
|
498
|
-
[](
|
|
498
|
+
[](int64_t, size_t)
|
|
499
499
|
{
|
|
500
500
|
return std::nullopt;
|
|
501
501
|
});
|
|
@@ -503,16 +503,16 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
503
503
|
REQUIRE(getSentPacketTSNs(retransmissionQueue) == std::vector<uint32_t>{ 14 });
|
|
504
504
|
|
|
505
505
|
// Ack 10, 12-14, after 100 ms.
|
|
506
|
-
|
|
506
|
+
nowUs += 100 * 1000;
|
|
507
507
|
|
|
508
508
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
509
|
-
|
|
509
|
+
nowUs,
|
|
510
510
|
createSackChunk(
|
|
511
511
|
10,
|
|
512
512
|
Arwnd,
|
|
513
513
|
{
|
|
514
514
|
{ 2, 4 },
|
|
515
|
-
|
|
515
|
+
})
|
|
516
516
|
.get());
|
|
517
517
|
|
|
518
518
|
REQUIRE(
|
|
@@ -523,7 +523,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
523
523
|
{ 12, RTC::SCTP::OutstandingData::State::ACKED },
|
|
524
524
|
{ 13, RTC::SCTP::OutstandingData::State::ACKED },
|
|
525
525
|
{ 14, RTC::SCTP::OutstandingData::State::ACKED },
|
|
526
|
-
|
|
526
|
+
});
|
|
527
527
|
|
|
528
528
|
// This will trigger "fast retransmit" mode and only chunks 13 and 16 will
|
|
529
529
|
// be resent right now. The send queue will not even be queried.
|
|
@@ -539,19 +539,19 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
539
539
|
{ 12, RTC::SCTP::OutstandingData::State::ACKED },
|
|
540
540
|
{ 13, RTC::SCTP::OutstandingData::State::ACKED },
|
|
541
541
|
{ 14, RTC::SCTP::OutstandingData::State::ACKED },
|
|
542
|
-
|
|
542
|
+
});
|
|
543
543
|
|
|
544
544
|
// Verify that the timer was really restarted when fast-retransmitting. The
|
|
545
545
|
// timeout is `sctpOptions.initialRtoMs`, so advance the time just before
|
|
546
546
|
// that.
|
|
547
|
-
|
|
547
|
+
nowUs += static_cast<int64_t>(sctpOptions.initialRtoMs - 1) * 1000;
|
|
548
548
|
|
|
549
549
|
auto* backoffTimer = shared.GetBackoffTimer("mock-sctp-t3-rtx");
|
|
550
550
|
|
|
551
551
|
REQUIRE(backoffTimer);
|
|
552
552
|
REQUIRE(backoffTimer->EvaluateHasExpired() == false);
|
|
553
553
|
|
|
554
|
-
|
|
554
|
+
nowUs += 1000;
|
|
555
555
|
|
|
556
556
|
REQUIRE(backoffTimer->EvaluateHasExpired() == true);
|
|
557
557
|
}
|
|
@@ -563,7 +563,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
563
563
|
sendQueue.WillProduceOnce(createDataToSend(0))
|
|
564
564
|
.WillProduceOnce(createDataToSend(1))
|
|
565
565
|
.WillProduceRepeatedly(
|
|
566
|
-
[](
|
|
566
|
+
[](int64_t, size_t)
|
|
567
567
|
{
|
|
568
568
|
return std::nullopt;
|
|
569
569
|
});
|
|
@@ -575,7 +575,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
575
575
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
576
576
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
577
577
|
{ 11, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
578
|
-
|
|
578
|
+
});
|
|
579
579
|
}
|
|
580
580
|
|
|
581
581
|
SECTION("retransmits on T3-rtx expiry")
|
|
@@ -584,19 +584,19 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
584
584
|
|
|
585
585
|
sendQueue.WillProduceOnce(createDataToSend(0))
|
|
586
586
|
.WillProduceRepeatedly(
|
|
587
|
-
[](
|
|
587
|
+
[](int64_t, size_t)
|
|
588
588
|
{
|
|
589
589
|
return std::nullopt;
|
|
590
590
|
});
|
|
591
591
|
|
|
592
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
592
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
593
593
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, 1000) == std::vector<uint32_t>{ 10 });
|
|
594
594
|
REQUIRE(
|
|
595
595
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
596
596
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
597
597
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
598
598
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
599
|
-
|
|
599
|
+
});
|
|
600
600
|
|
|
601
601
|
// Will force chunks to be retransmitted.
|
|
602
602
|
retransmissionQueue.HandleT3RtxTimerExpiry();
|
|
@@ -606,16 +606,16 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
606
606
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
607
607
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
608
608
|
{ 10, RTC::SCTP::OutstandingData::State::TO_BE_RETRANSMITTED },
|
|
609
|
-
|
|
609
|
+
});
|
|
610
610
|
|
|
611
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
611
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
612
612
|
|
|
613
613
|
REQUIRE(
|
|
614
614
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
615
615
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
616
616
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
617
617
|
{ 10, RTC::SCTP::OutstandingData::State::TO_BE_RETRANSMITTED },
|
|
618
|
-
|
|
618
|
+
});
|
|
619
619
|
|
|
620
620
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, 1000) == std::vector<uint32_t>{ 10 });
|
|
621
621
|
REQUIRE(
|
|
@@ -623,7 +623,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
623
623
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
624
624
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
625
625
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
626
|
-
|
|
626
|
+
});
|
|
627
627
|
}
|
|
628
628
|
|
|
629
629
|
SECTION("limited retransmission only with RFC 3758 support")
|
|
@@ -632,19 +632,19 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
632
632
|
|
|
633
633
|
sendQueue.WillProduceOnce(createDataToSend(42, /*maxRetransmissions*/ 0))
|
|
634
634
|
.WillProduceRepeatedly(
|
|
635
|
-
[](
|
|
635
|
+
[](int64_t, size_t)
|
|
636
636
|
{
|
|
637
637
|
return std::nullopt;
|
|
638
638
|
});
|
|
639
639
|
|
|
640
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
640
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
641
641
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, 1000) == std::vector<uint32_t>{ 10 });
|
|
642
642
|
REQUIRE(
|
|
643
643
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
644
644
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
645
645
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
646
646
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
647
|
-
|
|
647
|
+
});
|
|
648
648
|
|
|
649
649
|
// Will force chunks to be retransmitted.
|
|
650
650
|
retransmissionQueue.HandleT3RtxTimerExpiry();
|
|
@@ -654,12 +654,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
654
654
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
655
655
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
656
656
|
{ 10, RTC::SCTP::OutstandingData::State::TO_BE_RETRANSMITTED },
|
|
657
|
-
|
|
657
|
+
});
|
|
658
658
|
|
|
659
659
|
// Discard must NOT be called.
|
|
660
660
|
sendQueue.ExpectDiscardCalledTimes(0);
|
|
661
661
|
|
|
662
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
662
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
663
663
|
REQUIRE_VERIFICATION_RESULT(sendQueue.VerifyExpectations());
|
|
664
664
|
}
|
|
665
665
|
|
|
@@ -669,12 +669,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
669
669
|
|
|
670
670
|
sendQueue.WillProduceOnce(createDataToSend(42, /*maxRetransmissions*/ 0))
|
|
671
671
|
.WillProduceRepeatedly(
|
|
672
|
-
[](
|
|
672
|
+
[](int64_t, size_t)
|
|
673
673
|
{
|
|
674
674
|
return std::nullopt;
|
|
675
675
|
});
|
|
676
676
|
|
|
677
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
677
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
678
678
|
|
|
679
679
|
REQUIRE(getSentPacketTSNs(retransmissionQueue) == std::vector<uint32_t>{ 10 });
|
|
680
680
|
REQUIRE(
|
|
@@ -682,7 +682,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
682
682
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
683
683
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
684
684
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
685
|
-
|
|
685
|
+
});
|
|
686
686
|
|
|
687
687
|
// Will force chunks to be retransmitted (abandoned because
|
|
688
688
|
// `maxRetransmissions: 0`).
|
|
@@ -695,16 +695,16 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
695
695
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
696
696
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
697
697
|
{ 10, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
698
|
-
|
|
698
|
+
});
|
|
699
699
|
|
|
700
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
700
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
701
701
|
|
|
702
702
|
REQUIRE(
|
|
703
703
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
704
704
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
705
705
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
706
706
|
{ 10, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
707
|
-
|
|
707
|
+
});
|
|
708
708
|
|
|
709
709
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, 1000).empty());
|
|
710
710
|
REQUIRE(
|
|
@@ -712,7 +712,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
712
712
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
713
713
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
714
714
|
{ 10, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
715
|
-
|
|
715
|
+
});
|
|
716
716
|
}
|
|
717
717
|
|
|
718
718
|
SECTION("limits retransmissions to three sends")
|
|
@@ -721,12 +721,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
721
721
|
|
|
722
722
|
sendQueue.WillProduceOnce(createDataToSend(42, /*maxRetransmissions*/ 3))
|
|
723
723
|
.WillProduceRepeatedly(
|
|
724
|
-
[](
|
|
724
|
+
[](int64_t, size_t)
|
|
725
725
|
{
|
|
726
726
|
return std::nullopt;
|
|
727
727
|
});
|
|
728
728
|
|
|
729
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
729
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
730
730
|
|
|
731
731
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, 1000) == std::vector<uint32_t>{ 10 });
|
|
732
732
|
REQUIRE(
|
|
@@ -734,7 +734,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
734
734
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
735
735
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
736
736
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
737
|
-
|
|
737
|
+
});
|
|
738
738
|
|
|
739
739
|
// `Discard()` must NOT be called for the first three retransmissions.
|
|
740
740
|
sendQueue.ExpectDiscardCalledTimes(0);
|
|
@@ -742,20 +742,20 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
742
742
|
// Retransmission 1.
|
|
743
743
|
retransmissionQueue.HandleT3RtxTimerExpiry();
|
|
744
744
|
|
|
745
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
746
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
745
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
746
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 1000).size() == 1);
|
|
747
747
|
|
|
748
748
|
// Retransmission 2.
|
|
749
749
|
retransmissionQueue.HandleT3RtxTimerExpiry();
|
|
750
750
|
|
|
751
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
752
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
751
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
752
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 1000).size() == 1);
|
|
753
753
|
|
|
754
754
|
// Retransmission 3.
|
|
755
755
|
retransmissionQueue.HandleT3RtxTimerExpiry();
|
|
756
756
|
|
|
757
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
758
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
757
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
758
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 1000).size() == 1);
|
|
759
759
|
|
|
760
760
|
REQUIRE_VERIFICATION_RESULT(sendQueue.VerifyExpectations());
|
|
761
761
|
|
|
@@ -764,15 +764,15 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
764
764
|
|
|
765
765
|
retransmissionQueue.HandleT3RtxTimerExpiry();
|
|
766
766
|
|
|
767
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
768
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
767
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
768
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 1000).empty());
|
|
769
769
|
|
|
770
770
|
REQUIRE(
|
|
771
771
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
772
772
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
773
773
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
774
774
|
{ 10, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
775
|
-
|
|
775
|
+
});
|
|
776
776
|
}
|
|
777
777
|
|
|
778
778
|
SECTION("retransmits when send buffer is full on T3-rtx expiry")
|
|
@@ -791,13 +791,13 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
791
791
|
|
|
792
792
|
sendQueue
|
|
793
793
|
.WillProduceOnce(
|
|
794
|
-
[&payload](
|
|
794
|
+
[&payload](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
795
795
|
{
|
|
796
796
|
return RTC::SCTP::SendQueueInterface::DataToSend(
|
|
797
797
|
0, RTC::SCTP::UserData(1, 0, 0, 0, 53, payload, true, true, false));
|
|
798
798
|
})
|
|
799
799
|
.WillProduceRepeatedly(
|
|
800
|
-
[](
|
|
800
|
+
[](int64_t, size_t)
|
|
801
801
|
{
|
|
802
802
|
return std::nullopt;
|
|
803
803
|
});
|
|
@@ -808,7 +808,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
808
808
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
809
809
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
810
810
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
811
|
-
|
|
811
|
+
});
|
|
812
812
|
REQUIRE(
|
|
813
813
|
retransmissionQueue.GetUnackedPacketBytes() ==
|
|
814
814
|
payload.size() + RTC::SCTP::DataChunk::DataChunkHeaderLength);
|
|
@@ -822,7 +822,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
822
822
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
823
823
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
824
824
|
{ 10, RTC::SCTP::OutstandingData::State::TO_BE_RETRANSMITTED },
|
|
825
|
-
|
|
825
|
+
});
|
|
826
826
|
|
|
827
827
|
// After T3 expiry in-flight counters are cleared.
|
|
828
828
|
REQUIRE(retransmissionQueue.GetUnackedPacketBytes() == 0);
|
|
@@ -833,7 +833,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
833
833
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
834
834
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
835
835
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
836
|
-
|
|
836
|
+
});
|
|
837
837
|
REQUIRE(
|
|
838
838
|
retransmissionQueue.GetUnackedPacketBytes() ==
|
|
839
839
|
payload.size() + RTC::SCTP::DataChunk::DataChunkHeaderLength);
|
|
@@ -851,7 +851,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
851
851
|
// "B" — beginning.
|
|
852
852
|
sendQueue
|
|
853
853
|
.WillProduceOnce(
|
|
854
|
-
[](
|
|
854
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
855
855
|
{
|
|
856
856
|
RTC::SCTP::UserData data(1, 42, 0, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, false, false);
|
|
857
857
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -862,7 +862,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
862
862
|
})
|
|
863
863
|
// Middle fragment.
|
|
864
864
|
.WillProduceOnce(
|
|
865
|
-
[](
|
|
865
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
866
866
|
{
|
|
867
867
|
RTC::SCTP::UserData data(1, 42, 0, 0, 53, { 0x05, 0x06, 0x07, 0x08 }, false, false, false);
|
|
868
868
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -873,7 +873,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
873
873
|
})
|
|
874
874
|
// Another middle fragment (message not fully sent — no "E").
|
|
875
875
|
.WillProduceOnce(
|
|
876
|
-
[](
|
|
876
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
877
877
|
{
|
|
878
878
|
RTC::SCTP::UserData data(1, 42, 0, 0, 53, { 0x09, 0x0a, 0x0b, 0x0c }, false, false, false);
|
|
879
879
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -883,7 +883,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
883
883
|
return dataToSend;
|
|
884
884
|
})
|
|
885
885
|
.WillProduceRepeatedly(
|
|
886
|
-
[](
|
|
886
|
+
[](int64_t, size_t)
|
|
887
887
|
{
|
|
888
888
|
return std::nullopt;
|
|
889
889
|
});
|
|
@@ -896,10 +896,10 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
896
896
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
897
897
|
{ 11, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
898
898
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
899
|
-
|
|
899
|
+
});
|
|
900
900
|
|
|
901
901
|
// Ack TSN 10, but the remaining are lost.
|
|
902
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
902
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, Arwnd).get());
|
|
903
903
|
|
|
904
904
|
// T3 expiry: TSN 11, 12 abandoned. `Discard()` returns true, placeholder TSN 13.
|
|
905
905
|
sendQueue.WillDiscardOnce(1, 42, /*returnValue*/ true);
|
|
@@ -914,9 +914,9 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
914
914
|
{ 11, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
915
915
|
{ 12, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
916
916
|
{ 13, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
917
|
-
|
|
917
|
+
});
|
|
918
918
|
|
|
919
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
919
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
920
920
|
|
|
921
921
|
const std::unique_ptr<RTC::SCTP::Packet> packet{ RTC::SCTP::Packet::Factory(
|
|
922
922
|
sctpCommon::FactoryBuffer, sctpOptions.mtu) };
|
|
@@ -940,7 +940,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
940
940
|
|
|
941
941
|
sendQueue
|
|
942
942
|
.WillProduceOnce(
|
|
943
|
-
[](
|
|
943
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
944
944
|
{
|
|
945
945
|
RTC::SCTP::UserData data(1, 42, 0, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, false, false);
|
|
946
946
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -950,7 +950,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
950
950
|
return dataToSend;
|
|
951
951
|
})
|
|
952
952
|
.WillProduceOnce(
|
|
953
|
-
[](
|
|
953
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
954
954
|
{
|
|
955
955
|
RTC::SCTP::UserData data(1, 42, 0, 0, 53, { 0x05, 0x06, 0x07, 0x08 }, false, false, false);
|
|
956
956
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -961,7 +961,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
961
961
|
})
|
|
962
962
|
// "E" — end fragment (message fully sent).
|
|
963
963
|
.WillProduceOnce(
|
|
964
|
-
[](
|
|
964
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
965
965
|
{
|
|
966
966
|
RTC::SCTP::UserData data(1, 42, 0, 0, 53, { 0x09, 0x0a, 0x0b, 0x0c }, false, true, false);
|
|
967
967
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -971,7 +971,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
971
971
|
return dataToSend;
|
|
972
972
|
})
|
|
973
973
|
.WillProduceRepeatedly(
|
|
974
|
-
[](
|
|
974
|
+
[](int64_t, size_t)
|
|
975
975
|
{
|
|
976
976
|
return std::nullopt;
|
|
977
977
|
});
|
|
@@ -984,10 +984,10 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
984
984
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
985
985
|
{ 11, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
986
986
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
987
|
-
|
|
987
|
+
});
|
|
988
988
|
|
|
989
989
|
// Ack TSN 10, but the remaining are lost.
|
|
990
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
990
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, Arwnd).get());
|
|
991
991
|
|
|
992
992
|
// T3 expiry: TSN 11, 12 abandoned. `Discard()` returns false, no placeholder.
|
|
993
993
|
sendQueue.WillDiscardOnce(1, 42, /*returnValue*/ false);
|
|
@@ -1000,9 +1000,9 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1000
1000
|
{ 10, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1001
1001
|
{ 11, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1002
1002
|
{ 12, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1003
|
-
|
|
1003
|
+
});
|
|
1004
1004
|
|
|
1005
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1005
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
1006
1006
|
|
|
1007
1007
|
const std::unique_ptr<RTC::SCTP::Packet> packet{ RTC::SCTP::Packet::Factory(
|
|
1008
1008
|
sctpCommon::FactoryBuffer, sctpOptions.mtu) };
|
|
@@ -1025,7 +1025,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1025
1025
|
// Stream 1, ordered, outgoingMessageId=42, mid=42, "B".
|
|
1026
1026
|
sendQueue
|
|
1027
1027
|
.WillProduceOnce(
|
|
1028
|
-
[](
|
|
1028
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1029
1029
|
{
|
|
1030
1030
|
RTC::SCTP::UserData data(1, 0, 42, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, false, false);
|
|
1031
1031
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -1036,7 +1036,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1036
1036
|
})
|
|
1037
1037
|
// Stream 2, unordered, outgoingMessageId=43, mid=42, "B".
|
|
1038
1038
|
.WillProduceOnce(
|
|
1039
|
-
[](
|
|
1039
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1040
1040
|
{
|
|
1041
1041
|
RTC::SCTP::UserData data(2, 0, 42, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, false, true);
|
|
1042
1042
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(43, std::move(data));
|
|
@@ -1047,7 +1047,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1047
1047
|
})
|
|
1048
1048
|
// Stream 3, ordered, outgoingMessageId=44, mid=42, "B".
|
|
1049
1049
|
.WillProduceOnce(
|
|
1050
|
-
[](
|
|
1050
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1051
1051
|
{
|
|
1052
1052
|
RTC::SCTP::UserData data(3, 0, 42, 0, 53, { 0x09, 0x0a, 0x0b, 0x0c }, true, false, false);
|
|
1053
1053
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(44, std::move(data));
|
|
@@ -1058,7 +1058,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1058
1058
|
})
|
|
1059
1059
|
// Stream 4, ordered, outgoingMessageId=45, mid=42, "B".
|
|
1060
1060
|
.WillProduceOnce(
|
|
1061
|
-
[](
|
|
1061
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1062
1062
|
{
|
|
1063
1063
|
RTC::SCTP::UserData data(4, 0, 42, 0, 53, { 0x0d, 0x0e, 0x0f, 0x10 }, true, false, false);
|
|
1064
1064
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(45, std::move(data));
|
|
@@ -1068,7 +1068,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1068
1068
|
return dataToSend;
|
|
1069
1069
|
})
|
|
1070
1070
|
.WillProduceRepeatedly(
|
|
1071
|
-
[](
|
|
1071
|
+
[](int64_t, size_t)
|
|
1072
1072
|
{
|
|
1073
1073
|
return std::nullopt;
|
|
1074
1074
|
});
|
|
@@ -1082,17 +1082,17 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1082
1082
|
{ 11, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1083
1083
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1084
1084
|
{ 13, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1085
|
-
|
|
1085
|
+
});
|
|
1086
1086
|
|
|
1087
1087
|
// TSN 13 is acked via gap block; TSN 10-12 are nacked.
|
|
1088
1088
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1089
|
-
|
|
1089
|
+
nowUs,
|
|
1090
1090
|
createSackChunk(
|
|
1091
1091
|
9,
|
|
1092
1092
|
Arwnd,
|
|
1093
1093
|
{
|
|
1094
1094
|
{ 4, 4 },
|
|
1095
|
-
|
|
1095
|
+
})
|
|
1096
1096
|
.get());
|
|
1097
1097
|
|
|
1098
1098
|
REQUIRE(
|
|
@@ -1103,7 +1103,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1103
1103
|
{ 11, RTC::SCTP::OutstandingData::State::NACKED },
|
|
1104
1104
|
{ 12, RTC::SCTP::OutstandingData::State::NACKED },
|
|
1105
1105
|
{ 13, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1106
|
-
|
|
1106
|
+
});
|
|
1107
1107
|
|
|
1108
1108
|
// T3 expiry: TSN 10-12 abandoned. `Discard()` called 3 times (one per stream),
|
|
1109
1109
|
// each returns true, placeholder TSNs 14, 15, 16.
|
|
@@ -1125,9 +1125,9 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1125
1125
|
{ 14, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1126
1126
|
{ 15, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1127
1127
|
{ 16, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1128
|
-
|
|
1128
|
+
});
|
|
1129
1129
|
|
|
1130
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1130
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
1131
1131
|
|
|
1132
1132
|
// I-FORWARD-TSN: newCumulativeTsn=12 (can't go past ACKED TSN 13).
|
|
1133
1133
|
std::unique_ptr<RTC::SCTP::Packet> packet{ RTC::SCTP::Packet::Factory(
|
|
@@ -1143,20 +1143,20 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1143
1143
|
{ false, 1, 42 },
|
|
1144
1144
|
{ false, 3, 42 },
|
|
1145
1145
|
{ true, 2, 42 },
|
|
1146
|
-
|
|
1146
|
+
});
|
|
1147
1147
|
|
|
1148
1148
|
// When TSN 13 is acked, the placeholder end fragments must be skipped too.
|
|
1149
1149
|
// A receiver is more likely to ack TSN 13, but do it incrementally.
|
|
1150
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1150
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(12, Arwnd).get());
|
|
1151
1151
|
|
|
1152
1152
|
sendQueue.ExpectDiscardCalledTimes(0);
|
|
1153
1153
|
|
|
1154
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1154
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
1155
1155
|
REQUIRE_VERIFICATION_RESULT(sendQueue.VerifyExpectations());
|
|
1156
1156
|
|
|
1157
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1157
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(13, Arwnd).get());
|
|
1158
1158
|
|
|
1159
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1159
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
1160
1160
|
|
|
1161
1161
|
REQUIRE(
|
|
1162
1162
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
@@ -1165,7 +1165,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1165
1165
|
{ 14, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1166
1166
|
{ 15, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1167
1167
|
{ 16, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1168
|
-
|
|
1168
|
+
});
|
|
1169
1169
|
|
|
1170
1170
|
packet.reset(RTC::SCTP::Packet::Factory(sctpCommon::FactoryBuffer, sctpOptions.mtu));
|
|
1171
1171
|
|
|
@@ -1179,7 +1179,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1179
1179
|
{ false, 1, 42 },
|
|
1180
1180
|
{ false, 3, 42 },
|
|
1181
1181
|
{ true, 2, 42 },
|
|
1182
|
-
|
|
1182
|
+
});
|
|
1183
1183
|
}
|
|
1184
1184
|
|
|
1185
1185
|
SECTION("measure RTT")
|
|
@@ -1189,20 +1189,20 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1189
1189
|
|
|
1190
1190
|
sendQueue.WillProduceOnce(createDataToSend(0, /*maxRetranmissions*/ 0))
|
|
1191
1191
|
.WillProduceRepeatedly(
|
|
1192
|
-
[](
|
|
1192
|
+
[](int64_t, size_t)
|
|
1193
1193
|
{
|
|
1194
1194
|
return std::nullopt;
|
|
1195
1195
|
});
|
|
1196
1196
|
|
|
1197
1197
|
REQUIRE(getSentPacketTSNs(retransmissionQueue) == std::vector<uint32_t>{ 10 });
|
|
1198
1198
|
|
|
1199
|
-
constexpr
|
|
1199
|
+
constexpr int64_t DurationUs{ 123 * 1000 };
|
|
1200
1200
|
|
|
1201
|
-
|
|
1201
|
+
nowUs += DurationUs;
|
|
1202
1202
|
|
|
1203
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1203
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, Arwnd).get());
|
|
1204
1204
|
|
|
1205
|
-
REQUIRE(retransmissionQueueListener.
|
|
1205
|
+
REQUIRE(retransmissionQueueListener.lastRttUs == DurationUs);
|
|
1206
1206
|
}
|
|
1207
1207
|
|
|
1208
1208
|
SECTION("validate cumulative TSN at rest")
|
|
@@ -1214,11 +1214,11 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1214
1214
|
auto retransmissionQueue = createRetransmissionQueue();
|
|
1215
1215
|
|
|
1216
1216
|
REQUIRE(
|
|
1217
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1217
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(8, Arwnd).get()) == false);
|
|
1218
1218
|
REQUIRE(
|
|
1219
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1219
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(9, Arwnd).get()) == true);
|
|
1220
1220
|
REQUIRE(
|
|
1221
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1221
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, Arwnd).get()) == false);
|
|
1222
1222
|
}
|
|
1223
1223
|
|
|
1224
1224
|
SECTION("validate cumulative TSN ack on inflight data")
|
|
@@ -1234,7 +1234,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1234
1234
|
.WillProduceOnce(createDataToSend(6))
|
|
1235
1235
|
.WillProduceOnce(createDataToSend(7))
|
|
1236
1236
|
.WillProduceRepeatedly(
|
|
1237
|
-
[](
|
|
1237
|
+
[](int64_t, size_t)
|
|
1238
1238
|
{
|
|
1239
1239
|
return std::nullopt;
|
|
1240
1240
|
});
|
|
@@ -1244,28 +1244,28 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1244
1244
|
std::vector<uint32_t>{ 10, 11, 12, 13, 14, 15, 16, 17 });
|
|
1245
1245
|
|
|
1246
1246
|
REQUIRE(
|
|
1247
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1247
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(8, Arwnd).get()) == false);
|
|
1248
1248
|
REQUIRE(
|
|
1249
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1249
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(9, Arwnd).get()) == true);
|
|
1250
1250
|
REQUIRE(
|
|
1251
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1251
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, Arwnd).get()) == true);
|
|
1252
1252
|
REQUIRE(
|
|
1253
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1253
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(11, Arwnd).get()) == true);
|
|
1254
1254
|
REQUIRE(
|
|
1255
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1255
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(12, Arwnd).get()) == true);
|
|
1256
1256
|
REQUIRE(
|
|
1257
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1257
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(13, Arwnd).get()) == true);
|
|
1258
1258
|
REQUIRE(
|
|
1259
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1259
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(14, Arwnd).get()) == true);
|
|
1260
1260
|
REQUIRE(
|
|
1261
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1261
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(15, Arwnd).get()) == true);
|
|
1262
1262
|
REQUIRE(
|
|
1263
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1263
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(16, Arwnd).get()) == true);
|
|
1264
1264
|
REQUIRE(
|
|
1265
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1265
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(17, Arwnd).get()) == true);
|
|
1266
1266
|
// TSN 18 has never been sent -> rejected.
|
|
1267
1267
|
REQUIRE(
|
|
1268
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1268
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(18, Arwnd).get()) == false);
|
|
1269
1269
|
}
|
|
1270
1270
|
|
|
1271
1271
|
SECTION("handle gap-ack-blocks matching no inflight data")
|
|
@@ -1281,7 +1281,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1281
1281
|
.WillProduceOnce(createDataToSend(6))
|
|
1282
1282
|
.WillProduceOnce(createDataToSend(7))
|
|
1283
1283
|
.WillProduceRepeatedly(
|
|
1284
|
-
[](
|
|
1284
|
+
[](int64_t, size_t)
|
|
1285
1285
|
{
|
|
1286
1286
|
return std::nullopt;
|
|
1287
1287
|
});
|
|
@@ -1292,13 +1292,13 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1292
1292
|
|
|
1293
1293
|
// Ack 9, 20-25. This is an invalid SACK chunk, but should still be handled.
|
|
1294
1294
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1295
|
-
|
|
1295
|
+
nowUs,
|
|
1296
1296
|
createSackChunk(
|
|
1297
1297
|
9,
|
|
1298
1298
|
Arwnd,
|
|
1299
1299
|
{
|
|
1300
1300
|
{ 11, 16 },
|
|
1301
|
-
|
|
1301
|
+
})
|
|
1302
1302
|
.get());
|
|
1303
1303
|
|
|
1304
1304
|
REQUIRE(
|
|
@@ -1313,7 +1313,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1313
1313
|
{ 15, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1314
1314
|
{ 16, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1315
1315
|
{ 17, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1316
|
-
|
|
1316
|
+
});
|
|
1317
1317
|
}
|
|
1318
1318
|
|
|
1319
1319
|
SECTION("handle invalid gap-ack-blocks")
|
|
@@ -1326,20 +1326,20 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1326
1326
|
// cumTsn=9 (no change), gap {3,4} -> TSN 12-13, both beyond
|
|
1327
1327
|
// highestOutstandingTsn(9) -> rejected. State unchanged.
|
|
1328
1328
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1329
|
-
|
|
1329
|
+
nowUs,
|
|
1330
1330
|
createSackChunk(
|
|
1331
1331
|
9,
|
|
1332
1332
|
Arwnd,
|
|
1333
1333
|
{
|
|
1334
1334
|
{ 3, 4 },
|
|
1335
|
-
|
|
1335
|
+
})
|
|
1336
1336
|
.get());
|
|
1337
1337
|
|
|
1338
1338
|
REQUIRE(
|
|
1339
1339
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
1340
1340
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
1341
1341
|
{ 9, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1342
|
-
|
|
1342
|
+
});
|
|
1343
1343
|
}
|
|
1344
1344
|
|
|
1345
1345
|
SECTION("gap-ack-blocks do not move cumulative TSN ack")
|
|
@@ -1358,7 +1358,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1358
1358
|
.WillProduceOnce(createDataToSend(6))
|
|
1359
1359
|
.WillProduceOnce(createDataToSend(7))
|
|
1360
1360
|
.WillProduceRepeatedly(
|
|
1361
|
-
[](
|
|
1361
|
+
[](int64_t, size_t)
|
|
1362
1362
|
{
|
|
1363
1363
|
return std::nullopt;
|
|
1364
1364
|
});
|
|
@@ -1371,13 +1371,13 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1371
1371
|
// adjacent to the cum-tsn-ack, but it's not strictly forbidden. However,
|
|
1372
1372
|
// the cum-tsn-ack should not move, as the gap-ack-blocks are just advisory.
|
|
1373
1373
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1374
|
-
|
|
1374
|
+
nowUs,
|
|
1375
1375
|
createSackChunk(
|
|
1376
1376
|
9,
|
|
1377
1377
|
Arwnd,
|
|
1378
1378
|
{
|
|
1379
1379
|
{ 1, 5 },
|
|
1380
|
-
|
|
1380
|
+
})
|
|
1381
1381
|
.get());
|
|
1382
1382
|
|
|
1383
1383
|
REQUIRE(
|
|
@@ -1392,12 +1392,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1392
1392
|
{ 15, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1393
1393
|
{ 16, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1394
1394
|
{ 17, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1395
|
-
|
|
1395
|
+
});
|
|
1396
1396
|
}
|
|
1397
1397
|
|
|
1398
1398
|
SECTION("stays within available size")
|
|
1399
1399
|
{
|
|
1400
|
-
// With `GetChunksToSend(
|
|
1400
|
+
// With `GetChunksToSend(nowUs, 1188-12=1176)`, the first `Produce()` receives
|
|
1401
1401
|
// 1176 - DataChunkHeaderLength bytes, the second receives the remainder.
|
|
1402
1402
|
|
|
1403
1403
|
auto retransmissionQueue = createRetransmissionQueue();
|
|
@@ -1408,7 +1408,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1408
1408
|
|
|
1409
1409
|
sendQueue
|
|
1410
1410
|
.WillProduceOnce(
|
|
1411
|
-
[&sizeCheck1Ok](
|
|
1411
|
+
[&sizeCheck1Ok](int64_t /*nowUs*/, size_t maxLength)
|
|
1412
1412
|
{
|
|
1413
1413
|
sizeCheck1Ok = (maxLength == AvailableBytes - RTC::SCTP::DataChunk::DataChunkHeaderLength);
|
|
1414
1414
|
|
|
@@ -1418,7 +1418,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1418
1418
|
0, RTC::SCTP::UserData(1, 0, 0, 0, 53, std::move(payload), true, true, false));
|
|
1419
1419
|
})
|
|
1420
1420
|
.WillProduceOnce(
|
|
1421
|
-
[&sizeCheck2Ok](
|
|
1421
|
+
[&sizeCheck2Ok](int64_t /*nowUs*/, size_t maxLength)
|
|
1422
1422
|
{
|
|
1423
1423
|
sizeCheck2Ok = (maxLength == 976 - RTC::SCTP::DataChunk::DataChunkHeaderLength);
|
|
1424
1424
|
|
|
@@ -1444,7 +1444,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1444
1444
|
// Three middle fragments of the same message, maxRetransmissions=0.
|
|
1445
1445
|
sendQueue
|
|
1446
1446
|
.WillProduceOnce(
|
|
1447
|
-
[](
|
|
1447
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1448
1448
|
{
|
|
1449
1449
|
RTC::SCTP::UserData data(1, 0, 0, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, false, false);
|
|
1450
1450
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -1454,7 +1454,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1454
1454
|
return dataToSend;
|
|
1455
1455
|
})
|
|
1456
1456
|
.WillProduceOnce(
|
|
1457
|
-
[](
|
|
1457
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1458
1458
|
{
|
|
1459
1459
|
RTC::SCTP::UserData data(1, 0, 0, 0, 53, { 0x05, 0x06, 0x07, 0x08 }, false, false, false);
|
|
1460
1460
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -1464,7 +1464,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1464
1464
|
return dataToSend;
|
|
1465
1465
|
})
|
|
1466
1466
|
.WillProduceOnce(
|
|
1467
|
-
[](
|
|
1467
|
+
[](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1468
1468
|
{
|
|
1469
1469
|
RTC::SCTP::UserData data(1, 0, 0, 0, 53, { 0x09, 0x0a, 0x0b, 0x0c }, false, false, false);
|
|
1470
1470
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
@@ -1474,7 +1474,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1474
1474
|
return dataToSend;
|
|
1475
1475
|
})
|
|
1476
1476
|
.WillProduceRepeatedly(
|
|
1477
|
-
[](
|
|
1477
|
+
[](int64_t, size_t)
|
|
1478
1478
|
{
|
|
1479
1479
|
return std::nullopt;
|
|
1480
1480
|
});
|
|
@@ -1487,7 +1487,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1487
1487
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1488
1488
|
{ 11, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1489
1489
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1490
|
-
|
|
1490
|
+
});
|
|
1491
1491
|
REQUIRE(retransmissionQueue.GetUnackedPacketBytes() == chunkSerializedLength * 3);
|
|
1492
1492
|
REQUIRE(retransmissionQueue.GetUnackedItems() == 3);
|
|
1493
1493
|
|
|
@@ -1496,7 +1496,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1496
1496
|
|
|
1497
1497
|
retransmissionQueue.HandleT3RtxTimerExpiry();
|
|
1498
1498
|
|
|
1499
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1499
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
1500
1500
|
|
|
1501
1501
|
REQUIRE(
|
|
1502
1502
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
@@ -1505,23 +1505,23 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1505
1505
|
{ 10, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1506
1506
|
{ 11, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1507
1507
|
{ 12, RTC::SCTP::OutstandingData::State::ABANDONED },
|
|
1508
|
-
|
|
1508
|
+
});
|
|
1509
1509
|
// Abandoned chunks are not counted as outstanding.
|
|
1510
1510
|
REQUIRE(retransmissionQueue.GetUnackedPacketBytes() == 0);
|
|
1511
1511
|
REQUIRE(retransmissionQueue.GetUnackedItems() == 0);
|
|
1512
1512
|
|
|
1513
1513
|
// Acking abandoned chunks one by one changes nothing in the counters.
|
|
1514
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1514
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, Arwnd).get());
|
|
1515
1515
|
|
|
1516
1516
|
REQUIRE(retransmissionQueue.GetUnackedPacketBytes() == 0);
|
|
1517
1517
|
REQUIRE(retransmissionQueue.GetUnackedItems() == 0);
|
|
1518
1518
|
|
|
1519
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1519
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(11, Arwnd).get());
|
|
1520
1520
|
|
|
1521
1521
|
REQUIRE(retransmissionQueue.GetUnackedPacketBytes() == 0);
|
|
1522
1522
|
REQUIRE(retransmissionQueue.GetUnackedItems() == 0);
|
|
1523
1523
|
|
|
1524
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
1524
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(12, Arwnd).get());
|
|
1525
1525
|
|
|
1526
1526
|
REQUIRE(retransmissionQueue.GetUnackedPacketBytes() == 0);
|
|
1527
1527
|
REQUIRE(retransmissionQueue.GetUnackedItems() == 0);
|
|
@@ -1530,55 +1530,55 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1530
1530
|
SECTION("expire from send queue when partially sent")
|
|
1531
1531
|
{
|
|
1532
1532
|
// Two fragments on stream 17, outgoingMessageId=42. First is produced and
|
|
1533
|
-
// goes in flight. After
|
|
1533
|
+
// goes in flight. After nowUs advances past `expiresAtUs`, the second is
|
|
1534
1534
|
// produced but expired on Insert() -> first also abandoned, `Discard()`
|
|
1535
1535
|
// called (returns true -> placeholder TSN 12).
|
|
1536
1536
|
|
|
1537
1537
|
auto retransmissionQueue = createRetransmissionQueue();
|
|
1538
1538
|
|
|
1539
|
-
const
|
|
1539
|
+
const int64_t expiresAtUs = nowUs + (10 * 1000);
|
|
1540
1540
|
|
|
1541
1541
|
sendQueue
|
|
1542
1542
|
.WillProduceOnce(
|
|
1543
|
-
[
|
|
1543
|
+
[expiresAtUs](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1544
1544
|
{
|
|
1545
1545
|
RTC::SCTP::UserData data(17, 0, 0, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, false, false);
|
|
1546
1546
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
1547
1547
|
|
|
1548
|
-
dataToSend.
|
|
1548
|
+
dataToSend.expiresAtUs = expiresAtUs;
|
|
1549
1549
|
|
|
1550
1550
|
return dataToSend;
|
|
1551
1551
|
})
|
|
1552
1552
|
.WillProduceOnce(
|
|
1553
|
-
[
|
|
1553
|
+
[expiresAtUs](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1554
1554
|
{
|
|
1555
1555
|
RTC::SCTP::UserData data(17, 0, 0, 0, 53, { 0x05, 0x06, 0x07, 0x08 }, false, false, false);
|
|
1556
1556
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
1557
1557
|
|
|
1558
|
-
dataToSend.
|
|
1558
|
+
dataToSend.expiresAtUs = expiresAtUs;
|
|
1559
1559
|
|
|
1560
1560
|
return dataToSend;
|
|
1561
1561
|
})
|
|
1562
1562
|
.WillProduceRepeatedly(
|
|
1563
|
-
[](
|
|
1563
|
+
[](int64_t, size_t)
|
|
1564
1564
|
{
|
|
1565
1565
|
return std::nullopt;
|
|
1566
1566
|
});
|
|
1567
1567
|
|
|
1568
|
-
// First `GetChunksToSend()` produces TSN 10 (
|
|
1568
|
+
// First `GetChunksToSend()` produces TSN 10 (nowUs < expiresAtUs).
|
|
1569
1569
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, 24) == std::vector<uint32_t>{ 10 });
|
|
1570
1570
|
|
|
1571
1571
|
// Advance past expiry.
|
|
1572
|
-
|
|
1572
|
+
nowUs += 100 * 1000;
|
|
1573
1573
|
|
|
1574
1574
|
// `Discard()` called for TSN 11 (unsent tail) -> returns true -> placeholder
|
|
1575
1575
|
// TSN 12.
|
|
1576
1576
|
sendQueue.WillDiscardOnce(17, 42, /*returnValue*/ true);
|
|
1577
1577
|
|
|
1578
|
-
// Second `GetChunksToSend()` produces TSN 11 but now >
|
|
1578
|
+
// Second `GetChunksToSend()` produces TSN 11 but now > expiresAtUs ->
|
|
1579
1579
|
// abandoned on `Insert()`, TSN 10 also abandoned, placeholder TSN 12
|
|
1580
1580
|
// created.
|
|
1581
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
1581
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 24).empty());
|
|
1582
1582
|
|
|
1583
1583
|
REQUIRE(
|
|
1584
1584
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
@@ -1587,7 +1587,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1587
1587
|
{ 10, RTC::SCTP::OutstandingData::State::ABANDONED }, // Produced and in-flight.
|
|
1588
1588
|
{ 11, RTC::SCTP::OutstandingData::State::ABANDONED }, // Produced and expired.
|
|
1589
1589
|
{ 12, RTC::SCTP::OutstandingData::State::ABANDONED }, // Placeholder end.
|
|
1590
|
-
|
|
1590
|
+
});
|
|
1591
1591
|
}
|
|
1592
1592
|
|
|
1593
1593
|
SECTION("expire correct message from send queue")
|
|
@@ -1600,55 +1600,55 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1600
1600
|
|
|
1601
1601
|
auto retransmissionQueue = createRetransmissionQueue();
|
|
1602
1602
|
|
|
1603
|
-
const
|
|
1603
|
+
const int64_t expiresAtUs = nowUs + (10 * 1000);
|
|
1604
1604
|
|
|
1605
1605
|
// outgoingMessageId=42, mid=0, "BE" — complete message.
|
|
1606
1606
|
sendQueue
|
|
1607
1607
|
.WillProduceOnce(
|
|
1608
|
-
[
|
|
1608
|
+
[expiresAtUs](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1609
1609
|
{
|
|
1610
1610
|
RTC::SCTP::UserData data(1, 0, 0, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, true, false);
|
|
1611
1611
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(42, std::move(data));
|
|
1612
1612
|
|
|
1613
|
-
dataToSend.
|
|
1613
|
+
dataToSend.expiresAtUs = expiresAtUs;
|
|
1614
1614
|
|
|
1615
1615
|
return dataToSend;
|
|
1616
1616
|
})
|
|
1617
1617
|
// outgoingMessageId=43, mid=1, "BE" — complete message.
|
|
1618
1618
|
.WillProduceOnce(
|
|
1619
|
-
[
|
|
1619
|
+
[expiresAtUs](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1620
1620
|
{
|
|
1621
1621
|
RTC::SCTP::UserData data(1, 0, 1, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, true, false);
|
|
1622
1622
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(43, std::move(data));
|
|
1623
1623
|
|
|
1624
|
-
dataToSend.
|
|
1624
|
+
dataToSend.expiresAtUs = expiresAtUs;
|
|
1625
1625
|
|
|
1626
1626
|
return dataToSend;
|
|
1627
1627
|
})
|
|
1628
1628
|
// outgoingMessageId=44, mid=0 (stream reset), "B" — beginning only.
|
|
1629
1629
|
.WillProduceOnce(
|
|
1630
|
-
[
|
|
1630
|
+
[expiresAtUs](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1631
1631
|
{
|
|
1632
1632
|
RTC::SCTP::UserData data(1, 0, 0, 0, 53, { 0x01, 0x02, 0x03, 0x04 }, true, false, false);
|
|
1633
1633
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(44, std::move(data));
|
|
1634
1634
|
|
|
1635
|
-
dataToSend.
|
|
1635
|
+
dataToSend.expiresAtUs = expiresAtUs;
|
|
1636
1636
|
|
|
1637
1637
|
return dataToSend;
|
|
1638
1638
|
})
|
|
1639
1639
|
// outgoingMessageId=44, mid=0, middle fragment (produced after expiry).
|
|
1640
1640
|
.WillProduceOnce(
|
|
1641
|
-
[
|
|
1641
|
+
[expiresAtUs](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
1642
1642
|
{
|
|
1643
1643
|
RTC::SCTP::UserData data(1, 0, 0, 0, 53, { 0x05, 0x06, 0x07, 0x08 }, false, false, false);
|
|
1644
1644
|
RTC::SCTP::SendQueueInterface::DataToSend dataToSend(44, std::move(data));
|
|
1645
1645
|
|
|
1646
|
-
dataToSend.
|
|
1646
|
+
dataToSend.expiresAtUs = expiresAtUs;
|
|
1647
1647
|
|
|
1648
1648
|
return dataToSend;
|
|
1649
1649
|
})
|
|
1650
1650
|
.WillProduceRepeatedly(
|
|
1651
|
-
[](
|
|
1651
|
+
[](int64_t, size_t)
|
|
1652
1652
|
{
|
|
1653
1653
|
return std::nullopt;
|
|
1654
1654
|
});
|
|
@@ -1663,7 +1663,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1663
1663
|
true, true, false
|
|
1664
1664
|
});
|
|
1665
1665
|
|
|
1666
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
1666
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 24) == expectedChunksToSend);
|
|
1667
1667
|
|
|
1668
1668
|
// TSN 11, msgId=43.
|
|
1669
1669
|
expectedChunksToSend.clear();
|
|
@@ -1674,7 +1674,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1674
1674
|
true, true, false
|
|
1675
1675
|
});
|
|
1676
1676
|
|
|
1677
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
1677
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 24) == expectedChunksToSend);
|
|
1678
1678
|
|
|
1679
1679
|
// TSN 12, msgId=44 "B"
|
|
1680
1680
|
expectedChunksToSend.clear();
|
|
@@ -1685,10 +1685,10 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1685
1685
|
true, false, false
|
|
1686
1686
|
});
|
|
1687
1687
|
|
|
1688
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
1688
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 24) == expectedChunksToSend);
|
|
1689
1689
|
|
|
1690
1690
|
// Advance past expiry.
|
|
1691
|
-
|
|
1691
|
+
nowUs += 100 * 1000;
|
|
1692
1692
|
|
|
1693
1693
|
// `Discard()` called for message 44 (unsent middle fragment), returns true
|
|
1694
1694
|
// -> placeholder TSN 14 created.
|
|
@@ -1696,7 +1696,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1696
1696
|
|
|
1697
1697
|
// Fourth call produces TSN 13 (middle of message 44) but it's now expired
|
|
1698
1698
|
// -> TSN 12 and 13 abandoned, placeholder TSN 14 created.
|
|
1699
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
1699
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 24).empty());
|
|
1700
1700
|
|
|
1701
1701
|
REQUIRE(
|
|
1702
1702
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
@@ -1707,7 +1707,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1707
1707
|
{ 12, RTC::SCTP::OutstandingData::State::ABANDONED }, // msgId=44, B.
|
|
1708
1708
|
{ 13, RTC::SCTP::OutstandingData::State::ABANDONED }, // msgId=44, produced and expired.
|
|
1709
1709
|
{ 14, RTC::SCTP::OutstandingData::State::ABANDONED }, // Placeholder end.
|
|
1710
|
-
|
|
1710
|
+
});
|
|
1711
1711
|
}
|
|
1712
1712
|
|
|
1713
1713
|
SECTION("limits retransmissions only when nacked three times")
|
|
@@ -1724,12 +1724,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1724
1724
|
.WillProduceOnce(createDataToSend(1)) // TSN 12.
|
|
1725
1725
|
.WillProduceOnce(createDataToSend(2)) // TSN 13.
|
|
1726
1726
|
.WillProduceRepeatedly(
|
|
1727
|
-
[](
|
|
1727
|
+
[](int64_t, size_t)
|
|
1728
1728
|
{
|
|
1729
1729
|
return std::nullopt;
|
|
1730
1730
|
});
|
|
1731
1731
|
|
|
1732
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1732
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
1733
1733
|
|
|
1734
1734
|
REQUIRE(getSentPacketTSNs(retransmissionQueue) == std::vector<uint32_t>{ 10, 11, 12, 13 });
|
|
1735
1735
|
REQUIRE(
|
|
@@ -1740,22 +1740,22 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1740
1740
|
{ 11, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1741
1741
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1742
1742
|
{ 13, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1743
|
-
|
|
1743
|
+
});
|
|
1744
1744
|
|
|
1745
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1745
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
1746
1746
|
|
|
1747
1747
|
// `Discard()` must NOT be called for the first two nacks.
|
|
1748
1748
|
sendQueue.ExpectDiscardCalledTimes(0);
|
|
1749
1749
|
|
|
1750
1750
|
// First nack for TSN 10.
|
|
1751
1751
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1752
|
-
|
|
1752
|
+
nowUs,
|
|
1753
1753
|
createSackChunk(
|
|
1754
1754
|
9,
|
|
1755
1755
|
Arwnd,
|
|
1756
1756
|
{
|
|
1757
1757
|
{ 2, 2 },
|
|
1758
|
-
|
|
1758
|
+
})
|
|
1759
1759
|
.get());
|
|
1760
1760
|
|
|
1761
1761
|
REQUIRE(
|
|
@@ -1766,19 +1766,19 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1766
1766
|
{ 11, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1767
1767
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1768
1768
|
{ 13, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1769
|
-
|
|
1769
|
+
});
|
|
1770
1770
|
|
|
1771
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1771
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
1772
1772
|
|
|
1773
1773
|
// Second nack for TSN 10.
|
|
1774
1774
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1775
|
-
|
|
1775
|
+
nowUs,
|
|
1776
1776
|
createSackChunk(
|
|
1777
1777
|
9,
|
|
1778
1778
|
Arwnd,
|
|
1779
1779
|
{
|
|
1780
1780
|
{ 2, 3 },
|
|
1781
|
-
|
|
1781
|
+
})
|
|
1782
1782
|
.get());
|
|
1783
1783
|
|
|
1784
1784
|
REQUIRE(
|
|
@@ -1789,9 +1789,9 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1789
1789
|
{ 11, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1790
1790
|
{ 12, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1791
1791
|
{ 13, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1792
|
-
|
|
1792
|
+
});
|
|
1793
1793
|
|
|
1794
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1794
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
1795
1795
|
|
|
1796
1796
|
REQUIRE_VERIFICATION_RESULT(sendQueue.VerifyExpectations());
|
|
1797
1797
|
|
|
@@ -1800,13 +1800,13 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1800
1800
|
sendQueue.WillDiscardOnce(1, 42, /*returnValue*/ false);
|
|
1801
1801
|
|
|
1802
1802
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1803
|
-
|
|
1803
|
+
nowUs,
|
|
1804
1804
|
createSackChunk(
|
|
1805
1805
|
9,
|
|
1806
1806
|
Arwnd,
|
|
1807
1807
|
{
|
|
1808
1808
|
{ 2, 4 },
|
|
1809
|
-
|
|
1809
|
+
})
|
|
1810
1810
|
.get());
|
|
1811
1811
|
|
|
1812
1812
|
REQUIRE(
|
|
@@ -1817,9 +1817,9 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1817
1817
|
{ 11, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1818
1818
|
{ 12, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1819
1819
|
{ 13, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1820
|
-
|
|
1820
|
+
});
|
|
1821
1821
|
|
|
1822
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1822
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
1823
1823
|
}
|
|
1824
1824
|
|
|
1825
1825
|
SECTION("abandons rtx limit 2 when nacked nine times")
|
|
@@ -1841,12 +1841,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1841
1841
|
.WillProduceOnce(createDataToSend(7)) // TSN 18.
|
|
1842
1842
|
.WillProduceOnce(createDataToSend(8)) // TSN 19.
|
|
1843
1843
|
.WillProduceRepeatedly(
|
|
1844
|
-
[](
|
|
1844
|
+
[](int64_t, size_t)
|
|
1845
1845
|
{
|
|
1846
1846
|
return std::nullopt;
|
|
1847
1847
|
});
|
|
1848
1848
|
|
|
1849
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1849
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
1850
1850
|
|
|
1851
1851
|
REQUIRE(
|
|
1852
1852
|
getSentPacketTSNs(retransmissionQueue) ==
|
|
@@ -1865,7 +1865,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1865
1865
|
{ 17, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1866
1866
|
{ 18, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1867
1867
|
{ 19, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1868
|
-
|
|
1868
|
+
});
|
|
1869
1869
|
|
|
1870
1870
|
// No `Discard()` calls during nack rounds 1 and 2.
|
|
1871
1871
|
sendQueue.ExpectDiscardCalledTimes(0);
|
|
@@ -1874,7 +1874,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1874
1874
|
for (uint32_t tsn{ 11 }; tsn <= 13; ++tsn)
|
|
1875
1875
|
{
|
|
1876
1876
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1877
|
-
|
|
1877
|
+
nowUs,
|
|
1878
1878
|
createSackChunk(
|
|
1879
1879
|
9,
|
|
1880
1880
|
Arwnd,
|
|
@@ -1898,7 +1898,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1898
1898
|
{ 17, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1899
1899
|
{ 18, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1900
1900
|
{ 19, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1901
|
-
|
|
1901
|
+
});
|
|
1902
1902
|
|
|
1903
1903
|
// Fast retransmit #1.
|
|
1904
1904
|
REQUIRE(getTSNsForFastRetransmit(retransmissionQueue) == std::vector<uint32_t>{ 10 });
|
|
@@ -1907,7 +1907,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1907
1907
|
for (uint32_t tsn{ 14 }; tsn <= 16; ++tsn)
|
|
1908
1908
|
{
|
|
1909
1909
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1910
|
-
|
|
1910
|
+
nowUs,
|
|
1911
1911
|
createSackChunk(
|
|
1912
1912
|
9,
|
|
1913
1913
|
Arwnd,
|
|
@@ -1931,7 +1931,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1931
1931
|
{ 17, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1932
1932
|
{ 18, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1933
1933
|
{ 19, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1934
|
-
|
|
1934
|
+
});
|
|
1935
1935
|
|
|
1936
1936
|
// Regular retransmit #2.
|
|
1937
1937
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, 1000) == std::vector<uint32_t>{ 10 });
|
|
@@ -1940,7 +1940,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1940
1940
|
for (uint32_t tsn{ 17 }; tsn <= 18; ++tsn)
|
|
1941
1941
|
{
|
|
1942
1942
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1943
|
-
|
|
1943
|
+
nowUs,
|
|
1944
1944
|
createSackChunk(
|
|
1945
1945
|
9,
|
|
1946
1946
|
Arwnd,
|
|
@@ -1964,9 +1964,9 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1964
1964
|
{ 17, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1965
1965
|
{ 18, RTC::SCTP::OutstandingData::State::ACKED },
|
|
1966
1966
|
{ 19, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
1967
|
-
|
|
1967
|
+
});
|
|
1968
1968
|
|
|
1969
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
1969
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == false);
|
|
1970
1970
|
|
|
1971
1971
|
REQUIRE_VERIFICATION_RESULT(sendQueue.VerifyExpectations());
|
|
1972
1972
|
|
|
@@ -1975,7 +1975,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1975
1975
|
sendQueue.WillDiscardOnce(1, 42, /*returnValue*/ false);
|
|
1976
1976
|
|
|
1977
1977
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
1978
|
-
|
|
1978
|
+
nowUs,
|
|
1979
1979
|
createSackChunk(
|
|
1980
1980
|
9,
|
|
1981
1981
|
Arwnd,
|
|
@@ -1984,7 +1984,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
1984
1984
|
})
|
|
1985
1985
|
.get());
|
|
1986
1986
|
|
|
1987
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
1987
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, 1000).empty());
|
|
1988
1988
|
|
|
1989
1989
|
REQUIRE(
|
|
1990
1990
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
@@ -2000,9 +2000,9 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2000
2000
|
{ 17, RTC::SCTP::OutstandingData::State::ACKED },
|
|
2001
2001
|
{ 18, RTC::SCTP::OutstandingData::State::ACKED },
|
|
2002
2002
|
{ 19, RTC::SCTP::OutstandingData::State::ACKED },
|
|
2003
|
-
|
|
2003
|
+
});
|
|
2004
2004
|
|
|
2005
|
-
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(
|
|
2005
|
+
REQUIRE(retransmissionQueue.ShouldSendForwardTsn(nowUs) == true);
|
|
2006
2006
|
}
|
|
2007
2007
|
|
|
2008
2008
|
SECTION("cwnd recovers when acking")
|
|
@@ -2020,13 +2020,13 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2020
2020
|
|
|
2021
2021
|
sendQueue
|
|
2022
2022
|
.WillProduceOnce(
|
|
2023
|
-
[&payload](
|
|
2023
|
+
[&payload](int64_t /*nowUs*/, size_t /*maxLength*/)
|
|
2024
2024
|
{
|
|
2025
2025
|
return RTC::SCTP::SendQueueInterface::DataToSend(
|
|
2026
2026
|
0, RTC::SCTP::UserData(1, 0, 0, 0, 53, payload, true, true, false));
|
|
2027
2027
|
})
|
|
2028
2028
|
.WillProduceRepeatedly(
|
|
2029
|
-
[](
|
|
2029
|
+
[](int64_t, size_t)
|
|
2030
2030
|
{
|
|
2031
2031
|
return std::nullopt;
|
|
2032
2032
|
});
|
|
@@ -2034,7 +2034,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2034
2034
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, 1500) == std::vector<uint32_t>{ 10 });
|
|
2035
2035
|
REQUIRE(retransmissionQueue.GetUnackedPacketBytes() == chunkSerializedLength);
|
|
2036
2036
|
|
|
2037
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
2037
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, Arwnd).get());
|
|
2038
2038
|
|
|
2039
2039
|
REQUIRE(retransmissionQueue.GetCwnd() == Cwnd + chunkSerializedLength);
|
|
2040
2040
|
}
|
|
@@ -2048,37 +2048,37 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2048
2048
|
|
|
2049
2049
|
sendQueue
|
|
2050
2050
|
.WillProduceOnce(
|
|
2051
|
-
[&payload](
|
|
2051
|
+
[&payload](int64_t, size_t)
|
|
2052
2052
|
{
|
|
2053
2053
|
return RTC::SCTP::SendQueueInterface::DataToSend(
|
|
2054
2054
|
0, RTC::SCTP::UserData(1, 0, 0, 0, 53, payload, true, false, false));
|
|
2055
2055
|
})
|
|
2056
2056
|
.WillProduceOnce(
|
|
2057
|
-
[&payload](
|
|
2057
|
+
[&payload](int64_t, size_t)
|
|
2058
2058
|
{
|
|
2059
2059
|
return RTC::SCTP::SendQueueInterface::DataToSend(
|
|
2060
2060
|
0, RTC::SCTP::UserData(1, 0, 0, 0, 53, payload, false, false, false));
|
|
2061
2061
|
})
|
|
2062
2062
|
.WillProduceOnce(
|
|
2063
|
-
[&payload](
|
|
2063
|
+
[&payload](int64_t, size_t)
|
|
2064
2064
|
{
|
|
2065
2065
|
return RTC::SCTP::SendQueueInterface::DataToSend(
|
|
2066
2066
|
0, RTC::SCTP::UserData(1, 0, 0, 0, 53, payload, false, false, false));
|
|
2067
2067
|
})
|
|
2068
2068
|
.WillProduceOnce(
|
|
2069
|
-
[&payload](
|
|
2069
|
+
[&payload](int64_t, size_t)
|
|
2070
2070
|
{
|
|
2071
2071
|
return RTC::SCTP::SendQueueInterface::DataToSend(
|
|
2072
2072
|
0, RTC::SCTP::UserData(1, 0, 0, 0, 53, payload, false, false, false));
|
|
2073
2073
|
})
|
|
2074
2074
|
.WillProduceOnce(
|
|
2075
|
-
[&payload](
|
|
2075
|
+
[&payload](int64_t, size_t)
|
|
2076
2076
|
{
|
|
2077
2077
|
return RTC::SCTP::SendQueueInterface::DataToSend(
|
|
2078
2078
|
0, RTC::SCTP::UserData(1, 0, 0, 0, 53, payload, false, true, false));
|
|
2079
2079
|
})
|
|
2080
2080
|
.WillProduceRepeatedly(
|
|
2081
|
-
[](
|
|
2081
|
+
[](int64_t, size_t)
|
|
2082
2082
|
{
|
|
2083
2083
|
return std::nullopt;
|
|
2084
2084
|
});
|
|
@@ -2095,12 +2095,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2095
2095
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
2096
2096
|
{ 13, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
2097
2097
|
{ 14, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
2098
|
-
|
|
2098
|
+
});
|
|
2099
2099
|
|
|
2100
2100
|
// Ack 12, and report an empty receiver window (the peer obviously has a
|
|
2101
2101
|
// tiny receive window).
|
|
2102
2102
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
2103
|
-
|
|
2103
|
+
nowUs,
|
|
2104
2104
|
createSackChunk(
|
|
2105
2105
|
9,
|
|
2106
2106
|
/*aRwnd*/ 0,
|
|
@@ -2120,7 +2120,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2120
2120
|
|
|
2121
2121
|
// Still rwnd=0, TSN 10 in-flight.
|
|
2122
2122
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
2123
|
-
|
|
2123
|
+
nowUs,
|
|
2124
2124
|
createSackChunk(
|
|
2125
2125
|
9,
|
|
2126
2126
|
/*aRwnd=*/0,
|
|
@@ -2131,11 +2131,11 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2131
2131
|
|
|
2132
2132
|
// There is in-flight data, so new data should not be allowed to be send since
|
|
2133
2133
|
// the receiver window is full.
|
|
2134
|
-
REQUIRE(retransmissionQueue.GetChunksToSend(
|
|
2134
|
+
REQUIRE(retransmissionQueue.GetChunksToSend(nowUs, mtu).empty());
|
|
2135
2135
|
|
|
2136
2136
|
// Ack TSN 10 (no more in-flight data), still rwnd=0.
|
|
2137
2137
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
2138
|
-
|
|
2138
|
+
nowUs,
|
|
2139
2139
|
createSackChunk(
|
|
2140
2140
|
10,
|
|
2141
2141
|
/*aRwnd=*/0,
|
|
@@ -2152,7 +2152,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2152
2152
|
|
|
2153
2153
|
// Ack and recover the receiver window
|
|
2154
2154
|
retransmissionQueue.HandleReceivedSackChunk(
|
|
2155
|
-
|
|
2155
|
+
nowUs, createSackChunk(12, static_cast<uint32_t>(5 * mtu)).get());
|
|
2156
2156
|
|
|
2157
2157
|
// Remaining TO_BE_RETRANSMITTED chunks can now be sent.
|
|
2158
2158
|
REQUIRE(getSentPacketTSNs(retransmissionQueue, mtu) == std::vector<uint32_t>{ 13 });
|
|
@@ -2174,7 +2174,7 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2174
2174
|
.WillProduceOnce(createDataToSend(1)) // TSN 11.
|
|
2175
2175
|
.WillProduceOnce(createDataToSend(2)) // TSN 12.
|
|
2176
2176
|
.WillProduceRepeatedly(
|
|
2177
|
-
[](
|
|
2177
|
+
[](int64_t, size_t)
|
|
2178
2178
|
{
|
|
2179
2179
|
return std::nullopt;
|
|
2180
2180
|
});
|
|
@@ -2187,12 +2187,12 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2187
2187
|
{ 10, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
2188
2188
|
{ 11, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
2189
2189
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
2190
|
-
|
|
2190
|
+
});
|
|
2191
2191
|
|
|
2192
2192
|
REQUIRE(retransmissionQueue.GetRwnd() == Arwnd - (PayloadSize * 3));
|
|
2193
2193
|
|
|
2194
2194
|
// Ack TSN 10, new aRwnd=1000.
|
|
2195
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
2195
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(10, 1000).get());
|
|
2196
2196
|
|
|
2197
2197
|
REQUIRE(
|
|
2198
2198
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
@@ -2200,18 +2200,18 @@ SCENARIO("SCTP RetransmissionQueue", "[sctp][retransmissionqueue]")
|
|
|
2200
2200
|
{ 10, RTC::SCTP::OutstandingData::State::ACKED },
|
|
2201
2201
|
{ 11, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
2202
2202
|
{ 12, RTC::SCTP::OutstandingData::State::IN_FLIGHT },
|
|
2203
|
-
|
|
2203
|
+
});
|
|
2204
2204
|
|
|
2205
2205
|
REQUIRE(retransmissionQueue.GetRwnd() == 1000 - (PayloadSize * 2));
|
|
2206
2206
|
|
|
2207
2207
|
// Ack everything, new aRwnd=2000.
|
|
2208
|
-
retransmissionQueue.HandleReceivedSackChunk(
|
|
2208
|
+
retransmissionQueue.HandleReceivedSackChunk(nowUs, createSackChunk(12, 2000).get());
|
|
2209
2209
|
|
|
2210
2210
|
REQUIRE(
|
|
2211
2211
|
retransmissionQueue.GetChunkStatesForTesting() ==
|
|
2212
2212
|
std::vector<std::pair<uint32_t /*tsn*/, RTC::SCTP::OutstandingData::State>>{
|
|
2213
2213
|
{ 12, RTC::SCTP::OutstandingData::State::ACKED },
|
|
2214
|
-
|
|
2214
|
+
});
|
|
2215
2215
|
|
|
2216
2216
|
REQUIRE(retransmissionQueue.GetRwnd() == 2000);
|
|
2217
2217
|
}
|