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); } }
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); }
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); } }
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); } }
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"); }
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); } }
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"); } }
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); } }
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); } }
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)); }); }
internal override void deliverMessage(SCTPMessage message) { message.run(); }
internal override void deliverMessage(SCTPMessage message) { throw new NotImplementedException(); }
internal override void deliverMessage(SCTPMessage message) { ThreadPool.QueueUserWorkItem((obj) => { message.run(); }); }