Beispiel #1
0
        public void testMakeMessage_string_BlockingSCTPStream()
        {
            Console.WriteLine("---->makeMessage string");

            StringBuilder      rightout = new StringBuilder();
            SCTPStreamListener rsl      = new ASCTPStreamListenerImpl(rightout);

            DatagramTransport[]     trans         = mkMockTransports();
            MockAssociationListener listenLeft    = new MockAssociationListener();
            MockAssociationListener listenRight   = new MockAssociationListenerImpl(rsl);
            ThreadedAssociation     instanceLeft  = new ThreadedAssociation(trans[0], listenLeft);
            ThreadedAssociation     instanceRight = new ThreadedAssociation(trans[1], listenRight);

            instanceLeft.associate();
            lock (listenLeft) {
                Monitor.Wait(listenLeft, 2000);
                Assert.IsTrue(listenLeft.associated);
                Assert.IsTrue(listenRight.associated);
            }
            int        id = 10;
            SCTPStream s  = instanceLeft.mkStream(id);

            Assert.IsTrue(typeof(BlockingSCTPStream).IsAssignableFrom(s.GetType()));
            string      test = "Test message";
            SCTPMessage m    = instanceLeft.makeMessage(test, (BlockingSCTPStream)s);

            instanceLeft.sendAndBlock(m);
            lock (rightout) {
                Monitor.Wait(rightout, 2000);
                Assert.AreEqual(rightout.ToString(), test);
            }
        }
Beispiel #2
0
        internal override SCTPMessage makeMessage(string bytes, BlockingSCTPStream s)
        {
            SCTPMessage m = null;

            if (base.canSend())
            {
                if (bytes.Length < this.maxMessageSize())
                {
                    m = new SCTPMessage(bytes, s);
                    lock (s) {
                        int mseq = s.getNextMessageSeqOut();
                        s.setNextMessageSeqOut(mseq + 1);
                        m.setSeq(mseq);
                    }
                }
                else
                {
                    Logger.Warn("Message too long " + bytes.Length + " > " + this.maxMessageSize());
                }
            }
            else
            {
                Logger.Warn("Can't send a message right now");
            }
            return(m);
        }
Beispiel #3
0
 public override void send(byte[] message)
 {
     lock (this) {
         Association a = base.getAssociation();
         SCTPMessage m = a.makeMessage(message, this);
         undeliveredOutboundMessages.Add(m.getSeq(), m);
         a.sendAndBlock(m);
     }
 }
Beispiel #4
0
 public override void send(string message)
 {
     lock (this) {
         Association a = base.getAssociation();
         SCTPMessage m = a.makeMessage(message, this);
         if (m == null)
         {
             Logger.Error("SCTPMessage cannot be null, but it is");
         }
         a.sendAndBlock(m);
     }
 }
Beispiel #5
0
        public void testMessFillSingle()
        {
            // assume capacity > 52
            SCTPMessage      m      = new SCTPMessage(data, stream);
            List <DataChunk> chunks = new List <DataChunk>();

            while (m.hasMoreData())
            {
                DataChunk dc = new DataChunk();
                m.fill(dc);
                chunks.Add(dc);
            }
            Console.WriteLine("chunks " + chunks.Count);
            Assert.AreEqual(chunks.Count, 1, "Wrong number of chunks");

            Assert.AreEqual(chunks[0].getFlags(), DataChunk.SINGLEFLAG, "First (and only) chunk should have single flag set");
        }
Beispiel #6
0
 internal override SCTPMessage makeMessage(byte[] bytes, BlockingSCTPStream s)
 {
     lock (this) {
         SCTPMessage m = null;
         if (base.canSend())
         {
             if (bytes.Length < this.maxMessageSize())
             {
                 m = new SCTPMessage(bytes, s);
                 lock (s) {
                     int mseq = s.getNextMessageSeqOut();
                     s.setNextMessageSeqOut(mseq + 1);
                     m.setSeq(mseq);
                 }
             }
         }
         return(m);
     }
 }
Beispiel #7
0
        public void testMessFill1()
        {
            SCTPMessage      m      = new SCTPMessage(data, stream);
            List <DataChunk> chunks = new List <DataChunk>();

            while (m.hasMoreData())
            {
                DataChunk dc = new DataChunkImpl();
                m.fill(dc);
                chunks.Add(dc);
            }
            Console.WriteLine("chunks " + chunks.Count);
            Assert.AreEqual(chunks.Count, data.Length, "Wrong number of chunks");

            Assert.AreEqual(chunks[0].getFlags(), DataChunk.BEGINFLAG, "Start chunk should have start flag set");
            Assert.AreEqual(chunks[data.Length - 1].getFlags(), DataChunk.ENDFLAG, "End chunk should have end flag set");
            for (int i = 1; i < data.Length - 1; i++)
            {
                Assert.AreEqual(chunks[i].getFlags(), 0, "middle chunk should have no flag set");
                Assert.AreEqual(chunks[i].getDataAsString(), data[i].ToString(), "middle data should match input");
            }
        }
Beispiel #8
0
        internal override void sendAndBlock(SCTPMessage m)
        {
            while (m.hasMoreData())
            {
                DataChunk dc;
                lock (_freeBlocks) {
                    dc = _freeBlocks.Count > 0 ? _freeBlocks.Dequeue() : new DataChunk();
                }
                m.fill(dc);
                Logger.Trace("thinking about waiting for congestion " + dc.getTsn());

                lock (_congestion) {
                    Logger.Trace("In congestion sync block ");
                    while (!this.maySend(dc.getDataSize()))
                    {
                        Logger.Trace("about to wait for congestion for " + this.getT3());
                        Monitor.Wait(_congestion, (int)this.getT3());                         // wholly wrong
                    }
                }
                // todo check rollover - will break at maxint.
                enqueue(dc);
            }
        }
Beispiel #9
0
        public void testMakeMessage_byteArr_BlockingSCTPStream()
        {
            Console.WriteLine("---->makeMessage bytes");

            ByteBuffer             rightout = new ByteBuffer(new byte[10000]);
            StringBuilder          empty    = new StringBuilder();
            SCTPByteStreamListener rsl      = new SCTPByteStreamListenerImpl(empty, rightout);

            DatagramTransport[]     trans         = mkMockTransports();
            MockAssociationListener listenLeft    = new MockAssociationListener();
            MockAssociationListener listenRight   = new MockAssociationListenerImpl(rsl);
            ThreadedAssociation     instanceLeft  = new ThreadedAssociation(trans[0], listenLeft);
            ThreadedAssociation     instanceRight = new ThreadedAssociation(trans[1], listenRight);

            instanceLeft.associate();
            lock (listenLeft) {
                Monitor.Wait(listenLeft, 2000);
                Assert.IsTrue(listenLeft.associated);
                Assert.IsTrue(listenRight.associated);
            }
            int        id = 10;
            SCTPStream s  = instanceLeft.mkStream(id);

            Assert.IsTrue(typeof(BlockingSCTPStream).IsAssignableFrom(s.GetType()));
            string      test = "Test message";
            SCTPMessage m    = instanceLeft.makeMessage(test.getBytes(), (BlockingSCTPStream)s);

            instanceLeft.sendAndBlock(m);
            lock (rightout) {
                Monitor.Wait(rightout, 2000);
                int    l   = rightout.Position;
                string res = rightout.Data.getString(0, l);
                Assert.AreEqual(res, test);
                Assert.AreEqual(empty.Length, 0);
            }
        }
Beispiel #10
0
        public void deliver(SCTPStream s, SortedArray <DataChunk> stash, SCTPStreamListener l)
        {
            //stash is the list of all DataChunks that have not yet been turned into whole messages
            //we assume that it is sorted by stream sequence number.
            List <DataChunk>        delivered = new List <DataChunk>();
            SortedArray <DataChunk> message   = null;

            if (stash.Count == 0)
            {
                return;                              // I'm not fond of these early returns
            }
            long expectedTsn = stash.First.getTsn(); // This ignores gaps - but _hopefully_ messageNo will catch any

            // gaps we care about - ie gaps in the sequence for _this_ stream
            // we can deliver ordered messages on this stream even if earlier messages from other streams are missing
            // - this does assume that the tsn's of a message are contiguous -which is odd.


            foreach (DataChunk dc in stash)
            {
                int messageNo = s.getNextMessageSeqIn();

                int  flags = dc.getFlags() & DataChunk.SINGLEFLAG;                // mask to the bits we want
                long tsn   = dc.getTsn();
                bool lookingForOrderedMessages = _ordered || (message != null);
                // which is to say for unordered messages we can tolerate gaps _between_ messages
                // but not within them
                if (lookingForOrderedMessages && (tsn != expectedTsn))
                {
                    Logger.Debug("Hole in chunk sequence  " + tsn + " expected " + expectedTsn);
                    break;
                }
                switch (flags)
                {
                case DataChunk.SINGLEFLAG:
                    // singles are easy - just dispatch.
                    if (_ordered && (messageNo != dc.getSSeqNo()))
                    {
                        Logger.Debug("Hole (single) in message sequence  " + dc.getSSeqNo() + " expected " + messageNo);
                        break;                                 // not the message we are looking for...
                    }
                    SCTPMessage single = new SCTPMessage(s, dc);
                    if (single.deliver(l))
                    {
                        delivered.Add(dc);
                        messageNo++;
                        s.setNextMessageSeqIn(messageNo);
                    }
                    break;

                case DataChunk.BEGINFLAG:
                    if (_ordered && (messageNo != dc.getSSeqNo()))
                    {
                        Logger.Debug("Hole (begin) in message sequence  " + dc.getSSeqNo() + " expected " + messageNo);
                        break;                                 // not the message we are looking for...
                    }
                    message = new SortedArray <DataChunk>();
                    message.Add(dc);
                    Logger.Trace("new message no" + dc.getSSeqNo() + " starts with  " + dc.getTsn());
                    break;

                case 0:                         // middle
                    if (message != null)
                    {
                        message.Add(dc);
                        Logger.Trace("continued message no" + dc.getSSeqNo() + " with  " + dc.getTsn());
                    }
                    else
                    {
                        // perhaps check sno ?
                        Logger.Debug("Middle with no start" + dc.getSSeqNo() + " tsn " + dc.getTsn());
                    }
                    break;

                case DataChunk.ENDFLAG:
                    if (message != null)
                    {
                        message.Add(dc);
                        Logger.Trace("finished message no" + dc.getSSeqNo() + " with  " + dc.getTsn());
                        SCTPMessage deliverable = new SCTPMessage(s, message);
                        if (deliverable.deliver(l))
                        {
                            message.AddToList(delivered);
                            messageNo++;
                            s.setNextMessageSeqIn(messageNo);
                        }
                        message = null;
                    }
                    else
                    {
                        Logger.Debug("End with no start" + dc.getSSeqNo() + " tsn " + dc.getTsn());
                        message = null;
                    }
                    break;

                default:
                    throw new Exception("[IllegalStateException] Impossible value in stream logic");
                }
                expectedTsn = tsn + 1;
            }
            stash.RemoveWhere((dc) => { return(delivered.Contains(dc)); });
        }
Beispiel #11
0
 internal override void deliverMessage(SCTPMessage message)
 {
     message.run();
 }
Beispiel #12
0
 internal override void deliverMessage(SCTPMessage message)
 {
     throw new NotImplementedException();
 }
Beispiel #13
0
 internal override void deliverMessage(SCTPMessage message)
 {
     ThreadPool.QueueUserWorkItem((obj) => { message.run(); });
 }