Пример #1
0
        public void FragmentWithTSNWrap()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, uint.MaxValue - 2);

            SctpDataChunk chunk1 = new SctpDataChunk(false, true, false, uint.MaxValue - 2, 0, 0, 0, new byte[] { 0x00 });
            SctpDataChunk chunk2 = new SctpDataChunk(false, false, false, uint.MaxValue - 1, 0, 0, 0, new byte[] { 0x01 });
            SctpDataChunk chunk3 = new SctpDataChunk(false, false, false, uint.MaxValue, 0, 0, 0, new byte[] { 0x02 });
            SctpDataChunk chunk4 = new SctpDataChunk(false, false, false, 0, 0, 0, 0, new byte[] { 0x03 });
            SctpDataChunk chunk5 = new SctpDataChunk(false, false, true, 1, 0, 0, 0, new byte[] { 0x04 });

            var sFrames1 = receiver.OnDataChunk(chunk1);

            Assert.Equal(uint.MaxValue - 2, receiver.CumulativeAckTSN);
            var sFrames2 = receiver.OnDataChunk(chunk2);

            Assert.Equal(uint.MaxValue - 1, receiver.CumulativeAckTSN);
            var sFrames3 = receiver.OnDataChunk(chunk3);

            Assert.Equal(uint.MaxValue, receiver.CumulativeAckTSN);
            var sFrames4 = receiver.OnDataChunk(chunk4);

            Assert.Equal(0U, receiver.CumulativeAckTSN);
            var sFrames5 = receiver.OnDataChunk(chunk5);

            Assert.Equal(1U, receiver.CumulativeAckTSN);

            Assert.Empty(sFrames1);
            Assert.Empty(sFrames2);
            Assert.Empty(sFrames3);
            Assert.Empty(sFrames4);
            Assert.Single(sFrames5);
            Assert.Equal("0001020304", sFrames5.Single().UserData.HexStr());
            Assert.Equal(0, receiver.ForwardTSNCount);
        }
Пример #2
0
        public void InitialChunkTwoChunkDelay()
        {
            uint   arwnd      = 131072;
            ushort mtu        = 1400;
            uint   initialTSN = Crypto.GetRandomUInt(true);

            SctpDataReceiver receiver = new SctpDataReceiver(arwnd, mtu, initialTSN);

            // Skip initial DATA chunk.
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN + 1, 0, 0, 0, new byte[] { 0x44 }));
            Assert.Null(receiver.CumulativeAckTSN);
            Assert.Null(receiver.GetSackChunk());

            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN + 2, 0, 0, 0, new byte[] { 0x44 }));
            Assert.Null(receiver.CumulativeAckTSN);
            Assert.Null(receiver.GetSackChunk());

            // Give the receiver the initial DATA chunk.
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN, 0, 0, 0, new byte[] { 0x44 }));
            Assert.Equal(initialTSN + 2, receiver.CumulativeAckTSN);

            var sack = receiver.GetSackChunk();

            Assert.NotNull(sack);
            Assert.Empty(sack.GapAckBlocks);
        }
Пример #3
0
 public void CheckGetDistance()
 {
     Assert.Equal(55U, SctpDataReceiver.GetDistance(95, 150));
     Assert.Equal(1U, SctpDataReceiver.GetDistance(0, uint.MaxValue));
     Assert.Equal(1U, SctpDataReceiver.GetDistance(uint.MaxValue, 0));
     Assert.Equal(11U, SctpDataReceiver.GetDistance(5, uint.MaxValue - 5));
     Assert.Equal(11U, SctpDataReceiver.GetDistance(uint.MaxValue - 5, 5));
     Assert.Equal(50U, SctpDataReceiver.GetDistance(100, 50));
 }
        public async Task MaxBufferSendWithRandomDrops()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(1000, 1400, 0);
            SctpDataSender   sender   = new SctpDataSender("dummy", null, 1400, 0, 1000);

            sender._burstPeriodMilliseconds = 1;
            sender._rtoInitialMilliseconds  = 1;
            sender._rtoMinimumMilliseconds  = 1;
            sender.StartSending();

            SctpDataFrame        frame      = SctpDataFrame.Empty;
            ManualResetEventSlim frameReady = new ManualResetEventSlim(false);

            // This local function replicates a data chunk being sent from a data
            // sender to the receiver of a remote peer and the return of the SACK.
            Action <SctpDataChunk> doSend = async(chunk) =>
            {
                if (chunk.SendCount == 1 && Crypto.GetRandomInt(0, 99) % 5 == 0)
                {
                    logger.LogDebug($"Data chunk {chunk.TSN} dropped.");
                }
                else
                {
                    logger.LogDebug($"Data chunk {chunk.TSN} provided to receiver.");
                    var frames = receiver.OnDataChunk(chunk);
                    sender.GotSack(receiver.GetSackChunk());

                    if (frames.Count > 0)
                    {
                        logger.LogDebug($"Receiver got frame of length {frames.First().UserData?.Length}.");
                        frame = frames.First();
                        frameReady.Set();
                    }
                }

                await Task.Delay(1);
            };

            sender._sendDataChunk = doSend;

            byte[] buffer = new byte[RTCSctpTransport.SCTP_DEFAULT_MAX_MESSAGE_SIZE];
            //byte[] buffer = new byte[2000];
            Crypto.GetRandomBytes(buffer);
            string hash = Crypto.GetSHA256Hash(buffer);

            logger.LogDebug($"Max buffer hash {hash}.");

            await Task.Delay(50);

            sender.SendData(0, 0, buffer);

            frameReady.WaitHandle.WaitOne(10000, true);

            Assert.False(frame.IsEmpty());
            Assert.Equal(buffer.Length, frame.UserData.Length);
            Assert.Equal(hash, Crypto.GetSHA256Hash(frame.UserData));
        }
Пример #5
0
        public void GetSackForInitialChunkMissing()
        {
            uint   arwnd      = 131072;
            ushort mtu        = 1400;
            uint   initialTSN = Crypto.GetRandomUInt(true);

            SctpDataReceiver receiver = new SctpDataReceiver(arwnd, mtu, initialTSN);

            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN + 1, 0, 0, 0, new byte[] { 0x44 }));
            Assert.Null(receiver.CumulativeAckTSN);
            Assert.Null(receiver.GetSackChunk());
        }
Пример #6
0
        public void SinglePacketFrame()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, 0);

            SctpDataChunk chunk = new SctpDataChunk(false, true, true, 0, 0, 0, 0, new byte[] { 0x00 });

            var sortedFrames = receiver.OnDataChunk(chunk);

            Assert.Single(sortedFrames);
            Assert.Equal("00", sortedFrames.Single().UserData.HexStr());
            Assert.Equal(0U, receiver.CumulativeAckTSN);
            Assert.Equal(0, receiver.ForwardTSNCount);
        }
        public async Task InitialDataChunkDropped()
        {
            uint   arwnd      = 131072;
            ushort mtu        = 1400;
            uint   initialTSN = Crypto.GetRandomUInt(true);

            SctpDataReceiver receiver = new SctpDataReceiver(arwnd, mtu, initialTSN);
            SctpDataSender   sender   = new SctpDataSender("dummy", null, mtu, initialTSN, arwnd);

            sender.StartSending();

            // This local function replicates a data chunk being sent from a data
            // sender to the receiver of a remote peer and the return of the SACK.
            Action <SctpDataChunk> doSend = (chunk) =>
            {
                if (chunk.TSN == initialTSN && chunk.SendCount == 1)
                {
                    logger.LogDebug($"Data chunk {chunk.TSN} dropped.");
                }
                else
                {
                    receiver.OnDataChunk(chunk);
                    sender.GotSack(receiver.GetSackChunk());
                }
            };

            sender._sendDataChunk = doSend;

            sender.SendData(0, 0, new byte[] { 0x55 });
            Assert.Equal(initialTSN + 1, sender.TSN);
            await Task.Delay(250);

            Assert.Null(receiver.CumulativeAckTSN);

            await Task.Delay(500);

            sender.SendData(0, 0, new byte[] { 0x55 });
            Assert.Equal(initialTSN + 2, sender.TSN);
            await Task.Delay(1250);

            Assert.Equal(initialTSN + 1, receiver.CumulativeAckTSN);

            await Task.Delay(500);

            sender.SendData(0, 0, new byte[] { 0x55 });
            Assert.Equal(initialTSN + 3, sender.TSN);
            await Task.Delay(250);

            Assert.Equal(initialTSN + 2, receiver.CumulativeAckTSN);
        }
Пример #8
0
        public void GetTwoGapReports()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, 15005);

            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 15005, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 15007, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 15008, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 15010, 0, 0, 0, new byte[] { 0x33 }));

            var gapReports = receiver.GetForwardTSNGaps();

            Assert.Equal(2, gapReports.Count);
            Assert.True(gapReports[0].Start == 2 && gapReports[0].End == 3);
            Assert.True(gapReports[1].Start == 5 && gapReports[1].End == 5);
        }
Пример #9
0
        public void GetSingleGapReport()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, 25);

            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 25, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 30, 0, 0, 0, new byte[] { 0x33 }));

            var gapReports = receiver.GetForwardTSNGaps();

            Assert.Single(gapReports);

            var report = gapReports.Single();

            Assert.Equal(5, report.Start);
            Assert.Equal(5, report.End);
        }
Пример #10
0
        public void GeGapReportWithDuplicateForwardTSN()
        {
            uint             initialTSN = Crypto.GetRandomUInt(true);
            SctpDataReceiver receiver   = new SctpDataReceiver(0, 0, initialTSN);

            // Forward TSN.
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN + 1, 0, 0, 0, new byte[] { 0x33 }));
            // Initial expected TSN.
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN, 0, 0, 0, new byte[] { 0x33 }));
            // Duplicate of first received TSN.
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN + 1, 0, 0, 0, new byte[] { 0x33 }));

            var gapReports = receiver.GetForwardTSNGaps();

            Assert.Empty(gapReports);
        }
Пример #11
0
        public void GetSingleGapReportWithWrap()
        {
            uint             initialTSN = uint.MaxValue - 2;
            SctpDataReceiver receiver   = new SctpDataReceiver(0, 0, initialTSN);

            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 2, 0, 0, 0, new byte[] { 0x33 }));

            var gapReports = receiver.GetForwardTSNGaps();

            Assert.Single(gapReports);

            var report = gapReports.Single();

            Assert.Equal(5, report.Start);
            Assert.Equal(5, report.End);
        }
Пример #12
0
        public void FragmentWithTSNWrapAndOutOfOrder()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, uint.MaxValue - 2);

            SctpDataChunk chunk1 = new SctpDataChunk(true, true, false, uint.MaxValue - 2, 0, 0, 0, new byte[] { 0x00 });
            SctpDataChunk chunk2 = new SctpDataChunk(true, false, false, uint.MaxValue - 1, 0, 0, 0, new byte[] { 0x01 });
            SctpDataChunk chunk3 = new SctpDataChunk(true, false, false, uint.MaxValue, 0, 0, 0, new byte[] { 0x02 });
            SctpDataChunk chunk4 = new SctpDataChunk(true, false, false, 0, 0, 0, 0, new byte[] { 0x03 });
            SctpDataChunk chunk5 = new SctpDataChunk(true, false, true, 1, 0, 0, 0, new byte[] { 0x04 });

            // Intersperse a couple of full chunks in the middle of the fragmented chunk.
            SctpDataChunk chunk6 = new SctpDataChunk(true, true, true, 6, 0, 0, 0, new byte[] { 0x06 });
            SctpDataChunk chunk9 = new SctpDataChunk(true, true, true, 9, 0, 0, 0, new byte[] { 0x09 });

            var sframes9 = receiver.OnDataChunk(chunk9);

            Assert.Null(receiver.CumulativeAckTSN);
            var sframes1 = receiver.OnDataChunk(chunk1);

            Assert.Equal(uint.MaxValue - 2, receiver.CumulativeAckTSN);
            var sframes2 = receiver.OnDataChunk(chunk2);

            Assert.Equal(uint.MaxValue - 1, receiver.CumulativeAckTSN);
            var sframes3 = receiver.OnDataChunk(chunk3);

            Assert.Equal(uint.MaxValue, receiver.CumulativeAckTSN);
            var sframes6 = receiver.OnDataChunk(chunk6);

            Assert.Equal(uint.MaxValue, receiver.CumulativeAckTSN);
            var sframes4 = receiver.OnDataChunk(chunk4);

            Assert.Equal(0U, receiver.CumulativeAckTSN);
            var sframes5 = receiver.OnDataChunk(chunk5);

            Assert.Equal(1U, receiver.CumulativeAckTSN);

            Assert.Empty(sframes1);
            Assert.Empty(sframes2);
            Assert.Empty(sframes3);
            Assert.Empty(sframes4);
            Assert.Single(sframes6);
            Assert.Single(sframes9);
            Assert.Single(sframes5);
            Assert.Equal("0001020304", sframes5.Single().UserData.HexStr());
            Assert.Equal(2, receiver.ForwardTSNCount);
        }
        public async Task SACKChunkRetransmit()
        {
            uint   arwnd      = 131072;
            ushort mtu        = 1400;
            uint   initialTSN = Crypto.GetRandomUInt(true);

            SctpDataReceiver receiver = new SctpDataReceiver(arwnd, mtu, initialTSN);
            SctpDataSender   sender   = new SctpDataSender("dummy", null, mtu, initialTSN, arwnd);

            sender.StartSending();

            // This local function replicates a data chunk being sent from a data
            // sender to the receiver of a remote peer and the return of the SACK.
            Action <SctpDataChunk> doSend = (chunk) =>
            {
                receiver.OnDataChunk(chunk);
                sender.GotSack(receiver.GetSackChunk());
            };

            Action <SctpDataChunk> dontSend = (chunk) => { };

            sender._sendDataChunk = doSend;
            sender.SendData(0, 0, new byte[] { 0x00, 0x01, 0x02 });
            Assert.Equal(initialTSN + 1, sender.TSN);
            await Task.Delay(250);

            Assert.Equal(initialTSN, receiver.CumulativeAckTSN);

            // This send to the receiver is blocked so the receivers ACK TSN should stay the same.
            sender._sendDataChunk = dontSend;
            sender.SendData(0, 0, new byte[] { 0x00, 0x01, 0x02 });
            Assert.Equal(initialTSN + 2, sender.TSN);
            await Task.Delay(250);

            Assert.Equal(initialTSN, receiver.CumulativeAckTSN);

            // Unblock. Receiver's ACK TSN should not advance as it has a missing chunk.
            sender._sendDataChunk = doSend;
            sender.SendData(0, 0, new byte[] { 0x00, 0x01, 0x02 });
            Assert.Equal(initialTSN + 3, sender.TSN);
            await Task.Delay(250);

            Assert.Equal(initialTSN + 2, receiver.CumulativeAckTSN);
        }
        public void MaxBufferSend()
        {
            uint             arwnd    = SctpAssociation.DEFAULT_ADVERTISED_RECEIVE_WINDOW;
            SctpDataReceiver receiver = new SctpDataReceiver(arwnd, 1400, 0);
            SctpDataSender   sender   = new SctpDataSender("dummy", null, 1400, 0, arwnd);

            sender.StartSending();

            SctpDataFrame        frame      = SctpDataFrame.Empty;
            ManualResetEventSlim frameReady = new ManualResetEventSlim(false);

            // This local function replicates a data chunk being sent from a data
            // sender to the receiver of a remote peer and the return of the SACK.
            Action <SctpDataChunk> doSend = (chunk) =>
            {
                logger.LogDebug($"Data chunk {chunk.TSN} provided to receiver.");
                var frames = receiver.OnDataChunk(chunk);
                sender.GotSack(receiver.GetSackChunk());

                if (frames.Count > 0)
                {
                    logger.LogDebug($"Receiver got frame of length {frames.First().UserData?.Length}.");
                    frame = frames.First();
                    frameReady.Set();
                }
            };

            sender._sendDataChunk = doSend;

            byte[] buffer = new byte[RTCSctpTransport.SCTP_DEFAULT_MAX_MESSAGE_SIZE];
            Crypto.GetRandomBytes(buffer);
            string hash = Crypto.GetSHA256Hash(buffer);

            logger.LogDebug($"Max buffer hash {hash}.");

            sender.SendData(0, 0, buffer);

            frameReady.WaitHandle.WaitOne(10000, true);

            Assert.False(frame.IsEmpty());
            Assert.Equal(RTCSctpTransport.SCTP_DEFAULT_MAX_MESSAGE_SIZE, (uint)frame.UserData.Length);
            Assert.Equal(hash, Crypto.GetSHA256Hash(frame.UserData));
        }
Пример #15
0
        public void CheckIsCurrent()
        {
            Assert.True(SctpDataReceiver.IsNewer(0, 1));
            Assert.True(SctpDataReceiver.IsNewerOrEqual(0, 0));
            Assert.True(SctpDataReceiver.IsNewerOrEqual(1, 1));
            Assert.True(SctpDataReceiver.IsNewerOrEqual(uint.MaxValue, uint.MaxValue));
            Assert.True(SctpDataReceiver.IsNewerOrEqual(uint.MaxValue - 1, uint.MaxValue - 1));
            Assert.True(SctpDataReceiver.IsNewer(uint.MaxValue, 0));
            Assert.True(SctpDataReceiver.IsNewer(uint.MaxValue, 1));
            Assert.True(SctpDataReceiver.IsNewer(uint.MaxValue - 1, uint.MaxValue));
            Assert.True(SctpDataReceiver.IsNewer(uint.MaxValue - 1, 0));
            Assert.True(SctpDataReceiver.IsNewer(103040, 232933));

            Assert.False(SctpDataReceiver.IsNewer(uint.MaxValue, uint.MaxValue - 1));
            Assert.False(SctpDataReceiver.IsNewer(0, uint.MaxValue));
            Assert.False(SctpDataReceiver.IsNewer(1, uint.MaxValue));
            Assert.False(SctpDataReceiver.IsNewer(0, uint.MaxValue - 1));
            Assert.False(SctpDataReceiver.IsNewer(1, uint.MaxValue - 1));
        }
Пример #16
0
        public void GetThreeGapReports()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, 3);

            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 3, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 7, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 8, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 9, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 11, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 12, 0, 0, 0, new byte[] { 0x33 }));
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, 14, 0, 0, 0, new byte[] { 0x33 }));

            var gapReports = receiver.GetForwardTSNGaps();

            Assert.Equal(3, gapReports.Count);
            Assert.True(gapReports[0].Start == 4 && gapReports[0].End == 6);
            Assert.True(gapReports[1].Start == 8 && gapReports[1].End == 9);
            Assert.True(gapReports[2].Start == 11 && gapReports[2].End == 11);
        }
Пример #17
0
        public void CheckExpiryWithSinglePacketChunksUnordered()
        {
            uint             tsn           = uint.MaxValue - 3;
            uint             receiveWindow = 8;
            uint             mtu           = 1;
            SctpDataReceiver receiver      = new SctpDataReceiver(receiveWindow, mtu, tsn);

            for (int i = 0; i < 50; i++)
            {
                SctpDataChunk chunk = new SctpDataChunk(true, true, true, tsn++, 0, 0, 0, new byte[] { 0x55 });

                var sortedFrames = receiver.OnDataChunk(chunk);

                Assert.Single(sortedFrames);
                Assert.Equal("55", sortedFrames.Single().UserData.HexStr());
                Assert.Equal(0, receiver.ForwardTSNCount);
                Assert.Equal(tsn - 1, receiver.CumulativeAckTSN);
            }
        }
        public void MediumBufferSend()
        {
            ushort           mtu      = 1400;
            SctpDataReceiver receiver = new SctpDataReceiver(1000, mtu, 0);
            SctpDataSender   sender   = new SctpDataSender("dummy", null, mtu, 0, 1000);

            sender.StartSending();

            SctpDataFrame        frame      = SctpDataFrame.Empty;
            ManualResetEventSlim frameReady = new ManualResetEventSlim(false);

            // This local function replicates a data chunk being sent from a data
            // sender to the receiver of a remote peer and the return of the SACK.
            Action <SctpDataChunk> doSend = (chunk) =>
            {
                logger.LogDebug($"Data chunk {chunk.TSN} provided to receiver.");
                var frames = receiver.OnDataChunk(chunk);
                sender.GotSack(receiver.GetSackChunk());

                if (frames.Count > 0)
                {
                    logger.LogDebug($"Receiver got frame of length {frames.First().UserData?.Length}.");
                    frame = frames.First();
                    frameReady.Set();
                }
            };

            sender._sendDataChunk = doSend;

            byte[] buffer = new byte[10 * mtu];
            Crypto.GetRandomBytes(buffer);
            string hash = Crypto.GetSHA256Hash(buffer);

            logger.LogDebug($"Medium buffer hash {hash}.");

            sender.SendData(0, 0, buffer);

            frameReady.WaitHandle.WaitOne(5000, true);

            Assert.False(frame.IsEmpty());
            Assert.Equal(buffer.Length, frame.UserData.Length);
            Assert.Equal(hash, Crypto.GetSHA256Hash(frame.UserData));
        }
Пример #19
0
        public void GetSackForSingleMissingChunk()
        {
            uint   arwnd      = 131072;
            ushort mtu        = 1400;
            uint   initialTSN = Crypto.GetRandomUInt(true);

            SctpDataReceiver receiver = new SctpDataReceiver(arwnd, mtu, initialTSN);

            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN, 0, 0, 0, new byte[] { 0x44 }));
            Assert.Equal(initialTSN, receiver.CumulativeAckTSN);

            // Simulate a missing chunk by incrementing the TSN by 2.
            receiver.OnDataChunk(new SctpDataChunk(true, true, true, initialTSN + 2, 0, 0, 0, new byte[] { 0x44 }));
            Assert.Equal(initialTSN, receiver.CumulativeAckTSN);

            var sack = receiver.GetSackChunk();

            Assert.Equal(initialTSN, sack.CumulativeTsnAck);
            Assert.Single(sack.GapAckBlocks);
            Assert.Equal(2, sack.GapAckBlocks[0].Start);
            Assert.Equal(2, sack.GapAckBlocks[0].End);
        }
Пример #20
0
        public async Task IncreaseCongestionWindowSlowStart()
        {
            uint   arwnd      = SctpAssociation.DEFAULT_ADVERTISED_RECEIVE_WINDOW;
            ushort mtu        = 1400;
            uint   initialTSN = 0;

            SctpDataReceiver receiver = new SctpDataReceiver(arwnd, mtu, initialTSN);
            SctpDataSender   sender   = new SctpDataSender("dummy", null, mtu, initialTSN, arwnd);

            sender._burstPeriodMilliseconds = 1;
            sender._rtoInitialMilliseconds  = 1;
            sender._rtoMinimumMilliseconds  = 1;

            Action <SctpDataChunk> reluctantSender = (chunk) =>
            {
                if (chunk.TSN % 10 == 0)
                {
                    receiver.OnDataChunk(chunk);
                    sender.GotSack(receiver.GetSackChunk());
                }
            };

            sender._sendDataChunk = reluctantSender;
            sender.StartSending();

            Assert.Equal(SctpDataSender.CONGESTION_WINDOW_FACTOR, sender._congestionWindow);

            var buffer = new byte[mtu];

            for (int i = 0; i <= 10; i++)
            {
                sender.SendData(0, 0, buffer);
            }

            await Task.Delay(500);

            Assert.Equal(SctpDataSender.CONGESTION_WINDOW_FACTOR + mtu, sender._congestionWindow);
        }
Пример #21
0
        public void ThreeStreamPackets()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, 0);

            SctpDataChunk chunk1 = new SctpDataChunk(false, true, true, 0, 0, 0, 0, new byte[] { 0x00 });
            SctpDataChunk chunk2 = new SctpDataChunk(false, true, true, 1, 0, 1, 0, new byte[] { 0x01 });
            SctpDataChunk chunk3 = new SctpDataChunk(false, true, true, 2, 0, 2, 0, new byte[] { 0x02 });

            var sortFrames1 = receiver.OnDataChunk(chunk1);
            var sortFrames2 = receiver.OnDataChunk(chunk2);
            var sortFrames3 = receiver.OnDataChunk(chunk3);

            Assert.Single(sortFrames1);
            Assert.Equal(0, sortFrames1.Single().StreamSeqNum);
            Assert.Equal("00", sortFrames1.Single().UserData.HexStr());
            Assert.Single(sortFrames2);
            Assert.Equal(1, sortFrames2.Single().StreamSeqNum);
            Assert.Equal("01", sortFrames2.Single().UserData.HexStr());
            Assert.Single(sortFrames3);
            Assert.Equal(2, sortFrames3.Single().StreamSeqNum);
            Assert.Equal("02", sortFrames3.Single().UserData.HexStr());
            Assert.Equal(0, receiver.ForwardTSNCount);
        }
Пример #22
0
        public void ThreeFragmentsOutOfOrder()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, 0);

            SctpDataChunk chunk1 = new SctpDataChunk(false, true, false, 0, 0, 0, 0, new byte[] { 0x00 });
            SctpDataChunk chunk2 = new SctpDataChunk(false, false, false, 1, 0, 0, 0, new byte[] { 0x01 });
            SctpDataChunk chunk3 = new SctpDataChunk(false, false, true, 2, 0, 0, 0, new byte[] { 0x02 });

            var sortFrames1 = receiver.OnDataChunk(chunk1);

            Assert.Equal(0U, receiver.CumulativeAckTSN);
            var sortFrames2 = receiver.OnDataChunk(chunk3);

            Assert.Equal(0U, receiver.CumulativeAckTSN);
            var sortFrames3 = receiver.OnDataChunk(chunk2);

            Assert.Equal(2U, receiver.CumulativeAckTSN);

            Assert.Empty(sortFrames1);
            Assert.Empty(sortFrames2);
            Assert.Single(sortFrames3);
            Assert.Equal("000102", sortFrames3.Single().UserData.HexStr());
            Assert.Equal(0, receiver.ForwardTSNCount);
        }
Пример #23
0
        public void StreamPacketsReceviedOutOfOrder()
        {
            SctpDataReceiver receiver = new SctpDataReceiver(0, 0, uint.MaxValue);

            SctpDataChunk chunk0 = new SctpDataChunk(false, true, true, uint.MaxValue, 0, ushort.MaxValue, 0, new byte[] { 0x00 });
            SctpDataChunk chunk1 = new SctpDataChunk(false, true, true, 0, 0, 0, 0, new byte[] { 0x00 });
            SctpDataChunk chunk2 = new SctpDataChunk(false, true, true, 1, 0, 1, 0, new byte[] { 0x01 });
            SctpDataChunk chunk3 = new SctpDataChunk(false, true, true, 2, 0, 2, 0, new byte[] { 0x02 });

            var sortFrames0 = receiver.OnDataChunk(chunk0);
            var sortFrames1 = receiver.OnDataChunk(chunk3);
            var sortFrames2 = receiver.OnDataChunk(chunk2);
            var sortFrames3 = receiver.OnDataChunk(chunk1);

            Assert.Single(sortFrames0);
            Assert.Empty(sortFrames1);
            Assert.Empty(sortFrames2);
            Assert.Equal(3, sortFrames3.Count);
            Assert.Equal(0, sortFrames3.First().StreamSeqNum);
            Assert.Equal("00", sortFrames3.First().UserData.HexStr());
            Assert.Equal(2, sortFrames3.Last().StreamSeqNum);
            Assert.Equal("02", sortFrames3.Last().UserData.HexStr());
            Assert.Equal(0, receiver.ForwardTSNCount);
        }