/// <summary>
        /// Process the next message in the queue.
        /// </summary>
        /// <param name="action"></param>
        public void ProcessNextMessage(SCTPSocket socket, Action <SCTPMessageReceivedEventArgs> action)
        {
            if (Interlocked.CompareExchange(ref this.signalMessageReceivedLock, 1, 0) == 0)
            {
                Task.Run(
                    () =>
                {
                    bool more = false;

                    try
                    {
                        SCTPMessage message = this.DequeueNextMessage(socket);
                        if (message != null)
                        {
                            socket.PeerReceiveWindowSize += (uint)message.Length;
                            more = true;

                            action(new SCTPMessageReceivedEventArgs(message));
                        }
                    }
                    finally
                    {
                        Interlocked.Exchange(ref this.signalMessageReceivedLock, 0);
                    }

                    if (more == true)
                    {
                        this.ProcessNextMessage(socket, action);
                    }
                });
            }
        }
Exemple #2
0
        /// <summary>
        /// Initialises a new instance of the <see cref="TCB"/> class.
        /// </summary>
        /// <param name="socket">The owning SCTP socket.</param>
        /// <param name="localEndPoint">The local end point.</param>
        /// <param name="peerInitialTSN">The peers initial TSN.</param>
        public TCB(SCTPSocket socket, IPEndPoint localEndPoint)
        {
            this.socket            = socket;
            this.State             = SCTPSocketState.Closed;
            this.CreationTime      = DateTime.UtcNow;
            this.Lifetime          = SCTPConstants.ValidCookieLifetime;
            this.SourceEndPoint    = localEndPoint;
            this.streams           = new ConcurrentDictionary <ushort, SCTPStream>();
            this.sequenceGenerator = new StreamSequenceGenerator();
            this.ReceiveWindowSize = SCTPConstants.DefaultReceiverWindowSize;

            Random rnd  = new Random();
            uint   itag = (uint)rnd.Next(int.MinValue, int.MaxValue);

            this.LocalVerificationTag = itag;
            this.initialTSN           = itag;
            this.nextTSN = this.initialTSN;
            this.LastCumulativeTSNAcked = Convert.ToUInt32(this.nextTSN - 1);

            this.socket.WriteConsole(string.Format("Initial TSN {0}", this.initialTSN));
        }
        /// <summary>
        /// Dequeues the next message from the queue.
        /// </summary>
        /// <returns>A message; otherwise null.</returns>
        private SCTPMessage DequeueNextMessage(SCTPSocket socket)
        {
            lock (this.queue)
            {
                SCTPMessage message = null;

                if (this.queue.Count > 0)
                {
                    KeyValuePair <int, SCTPMessage> item = this.queue.First();

                    if (item.Value.StreamSequenceNo == this.lastMessageSeqNo + 1 &&
                        item.Value.IsMessageComplete() == true)
                    {
                        this.lastMessageSeqNo = item.Value.StreamSequenceNo;
                        message = item.Value;
                        this.queue.RemoveAt(0);
                    }
                }

                return(message);
            }
        }
Exemple #4
0
        static void Main(string[] args)
        {
            try
            {
                IPAddress address = GetFirstActiveAddress();

                SCTPSocket local = new SCTPSocket(9100);
                local.Bind(address);
                Console.WriteLine("[{0}] Local", local.GetHashCode());


                SCTPSocket remote = new SCTPSocket(9200);
                remote.Bind(address);
                remote.MessageReceived += Remote_MessageReceived;
                Console.WriteLine("[{0}] Remote", remote.GetHashCode());

                streams = new StreamStat[100];
                for (int i = 0; i < streams.Length; i++)
                {
                    streams[i] = new StreamStat()
                    {
                        StreamId = i + 1
                    };
                }

                while (true)
                {
                    string[] cmd = Console.ReadLine().Split(' ');
                    if (cmd[0] == "q")
                    {
                        break;
                    }
                    else if (cmd[0] == "c")
                    {
                        if (local.Connect(address, 9200) == true)
                        {
                            Console.WriteLine("Local Connected: {0}", local.Connected);
                            Console.WriteLine("Remote Connected: {0}", remote.Connected);
                        }
                    }
                    else if (cmd[0].StartsWith("s"))
                    {
                        string streamStr = cmd[0].Substring(1);
                        int    streamId  = string.IsNullOrEmpty(streamStr) == false?Convert.ToInt32(streamStr) : 1;

                        int count = cmd.Length > 1 ? Convert.ToInt32(cmd[1]) : 1;

                        for (int i = 0; i < count; i++)
                        {
                            streams[streamId - 1].IncrementCounter();

                            var model = new TestModel
                            {
                                Data = $"Hello World-{streams[streamId - 1].Counter}"
                            };

                            model.Hash = Convert.ToBase64String(SHA1.Create().ComputeHash(UTF8Encoding.UTF8.GetBytes(model.Data)));
                            var json = JsonConvert.SerializeObject(model);

                            local.SendMessageAsync(streamId, UTF8Encoding.UTF8.GetBytes(json)).Wait();
                        }
                    }
                    else if (cmd[0].StartsWith("a"))
                    {
                        string streamStr = cmd[0].Substring(1);
                        int    streamId  = string.IsNullOrEmpty(streamStr) == false?Convert.ToInt32(streamStr) : 1;

                        int count = cmd.Length > 1 ? Convert.ToInt32(cmd[1]) : 1;

                        streams[streamId - 1].IncrementCounter();

                        var model = new TestModel();

                        for (int i = 0; i < count; i++)
                        {
                            model.Data += "Hello World";
                        }

                        model.Data += $"-{streams[streamId-1].Counter}";
                        model.Hash  = Convert.ToBase64String(SHA1.Create().ComputeHash(UTF8Encoding.UTF8.GetBytes(model.Data)));

                        var json = JsonConvert.SerializeObject(model);
                        local.SendMessageAsync(streamId, UTF8Encoding.UTF8.GetBytes(json)).Wait();
                    }
                    else if (cmd[0] == "d")
                    {
                        local.Shutdown();

                        Console.WriteLine("Local Connected: {0}", local.Connected);
                        Console.WriteLine("Remote Connected: {0}", remote.Connected);
                    }
                    else if (cmd[0] == "ua")
                    {
                        var chunks = local.GetUnackedChunks();
                        foreach (var chunk in chunks)
                        {
                            Console.WriteLine("Unacked Chunk: {0}", chunk.TSN);
                        }
                    }
                    else if (cmd[0] == "prws")
                    {
                        Console.WriteLine("Peer Receive Window Size: {0}", local.PeerReceiveWindowSize);
                    }
                    else if (cmd[0] == "mtu")
                    {
                        Console.WriteLine("Path MTU Size: {0}", local.MTUSize);
                    }
                }

                local.Dispose();
                remote.Dispose();

                Console.WriteLine("Local Connected: {0}", local.Connected);
                Console.WriteLine("Remote Connected: {0}", remote.Connected);
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Error: {0}", ex.ToString());
                Console.ResetColor();
            }
        }
Exemple #5
0
 /// <summary>
 /// Initialises a new instance of the <see cref="SCTPEndPoint"/> class.
 /// </summary>
 /// <param name="sctpSocket"></param>
 /// <param name="endPoint"></param>
 internal SCTPEndPoint(SCTPSocket sctpSocket, IPEndPoint endPoint)
 {
     this.sctpSocket = sctpSocket;
     this.EndPoint   = endPoint;
 }