/// <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();
        }