Example #1
0
        public async Task SmallBufferSend()
        {
            BlockingCollection <byte[]> inStm  = new BlockingCollection <byte[]>();
            BlockingCollection <byte[]> outStm = new BlockingCollection <byte[]>();
            var             mockTransport      = new MockB2BSctpTransport(outStm, inStm);
            SctpAssociation assoc = new SctpAssociation(mockTransport, null, 5000, 5000, 1400, 0);

            SctpDataSender sender = new SctpDataSender("dummy", assoc.SendChunk, 1400, 0, 1000);

            sender.StartSending();
            sender.SendData(0, 0, new byte[] { 0x00, 0x01, 0x02 });

            await Task.Delay(100);

            Assert.Single(outStm);

            byte[]     sendBuffer = outStm.Single();
            SctpPacket pkt        = SctpPacket.Parse(sendBuffer, 0, sendBuffer.Length);

            Assert.NotNull(pkt);
            Assert.NotNull(pkt.Chunks.Single() as SctpDataChunk);

            var datachunk = pkt.Chunks.Single() as SctpDataChunk;

            Assert.Equal("000102", datachunk.UserData.HexStr());
        }
        /// <summary>
        /// Helper method to create two SCTP associations and do the 4 way handshake to connect them.
        /// </summary>
        /// <returns>A task that will complete once the two associations are connected.</returns>
        internal static (SctpAssociation a, SctpAssociation b) GetConnectedAssociations(ILogger logger, ushort mtu)
        {
            BlockingCollection <byte[]> _aOut = new BlockingCollection <byte[]>();
            BlockingCollection <byte[]> _bOut = new BlockingCollection <byte[]>();

            var aTransport = new MockB2BSctpTransport(_aOut, _bOut);
            var aAssoc     = new SctpAssociation(aTransport, null, 5000, 5000, mtu, 0);

            aTransport.OnSctpPacket += aAssoc.OnPacketReceived;
            var aAssocTcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            aAssoc.OnAborted += (reason) => logger.LogError($"Association A aborted with {reason}.");
            aAssoc.OnAssociationStateChanged += (state) =>
            {
                logger.LogDebug($"Association A changed to state {state}.");
                if (state == SctpAssociationState.Established)
                {
                    aAssocTcs.TrySetResult(true);
                }
            };
            _ = Task.Run(aTransport.Listen);

            var bTransport = new MockB2BSctpTransport(_bOut, _aOut);
            var bAssoc     = new SctpAssociation(bTransport, null, 5000, 5000, mtu, 0);

            bTransport.OnSctpPacket += bAssoc.OnPacketReceived;
            bTransport.OnCookieEcho += bAssoc.GotCookie;
            var bAssocTcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            bAssoc.OnAborted += (reason) => logger.LogError($"Association B aborted with {reason}.");
            bAssoc.OnAssociationStateChanged += (state) =>
            {
                logger.LogDebug($"Association B changed to state {state}.");
                if (state == SctpAssociationState.Established)
                {
                    bAssocTcs.TrySetResult(true);
                }
            };
            _ = Task.Run(bTransport.Listen);

            aAssoc.Init();

            Task.WaitAll(new Task[] { aAssocTcs.Task, bAssocTcs.Task }, 5000);

            if (aAssoc.State == SctpAssociationState.Established &&
                bAssoc.State == SctpAssociationState.Established)
            {
                return(aAssoc, bAssoc);
            }
            else
            {
                throw new ApplicationException("GetConnectedAssociations failed to connect associations.");
            }
        }
        public void ConnectAssociations()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            BlockingCollection <byte[]> _aOut = new BlockingCollection <byte[]>();
            BlockingCollection <byte[]> _bOut = new BlockingCollection <byte[]>();

            var aTransport = new MockB2BSctpTransport(_aOut, _bOut);
            var aAssoc     = new SctpAssociation(aTransport, null, 5000, 5000, 1400, 0);

            aTransport.OnSctpPacket += aAssoc.OnPacketReceived;
            var aAssocTcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            aAssoc.OnAssociationStateChanged += (state) =>
            {
                if (state == SctpAssociationState.Established)
                {
                    aAssocTcs.TrySetResult(true);
                }
            };
            _ = Task.Run(aTransport.Listen);

            var bTransport = new MockB2BSctpTransport(_bOut, _aOut);
            var bAssoc     = new SctpAssociation(bTransport, null, 5000, 5000, 1400, 0);

            bTransport.OnSctpPacket += bAssoc.OnPacketReceived;
            bTransport.OnCookieEcho += bAssoc.GotCookie;
            var bAssocTcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            bAssoc.OnAssociationStateChanged += (state) =>
            {
                if (state == SctpAssociationState.Established)
                {
                    bAssocTcs.TrySetResult(true);
                }
            };
            _ = Task.Run(bTransport.Listen);

            aAssoc.Init();

            Task.WaitAll(new Task[] { aAssocTcs.Task, bAssocTcs.Task }, 5000);

            Assert.Equal(SctpAssociationState.Established, aAssoc.State);
            Assert.Equal(SctpAssociationState.Established, bAssoc.State);

            aTransport.Close();
            bTransport.Close();
        }