예제 #1
0
        public void setUp()
        {
            DatagramTransport _fakedt = new DatagramTransportImpl();

            _fakeAssociation = new AssociationImpl(_fakedt, null);
            _fakeStream      = new SCTPStreamImpl(_fakeAssociation, 22);
        }
예제 #2
0
        public SCTPMessage(SCTPStream s, SortedArray <DataChunk> chunks)
        {
            _stream = s;
            int tot = 0;

            if ((chunks.First.getFlags() & DataChunk.BEGINFLAG) == 0)
            {
                throw new Exception("[IllegalArgumentException] must start with 'start' chunk");
            }
            if ((chunks.Last.getFlags() & DataChunk.ENDFLAG) == 0)
            {
                throw new Exception("[IllegalArgumentException] must end with 'end' chunk");
            }
            _pPid = chunks.First.getPpid();
            foreach (DataChunk dc in chunks)
            {
                tot += dc.getDataSize();
                if (_pPid != dc.getPpid())
                {
                    // aaagh
                    throw new Exception("[IllegalArgumentException] chunk has wrong ppid" + dc.getPpid() + " vs " + _pPid);
                }
            }
            _data = new byte[tot];
            int offs = 0;

            foreach (DataChunk dc in chunks)
            {
                Array.Copy(dc.getData(), 0, _data, offs, dc.getDataSize());
                offs += dc.getDataSize();
            }
        }
예제 #3
0
 public void closeStream(SCTPStream st)
 {
     Chunk[] cs = new Chunk[1];
     if (canSend())
     {
         Logger.Debug("due to reconfig stream " + st);
         cs[0] = reconfigState.makeClose(st);
     }
     this.send(cs);
 }
예제 #4
0
        public SCTPMessage(SCTPStream s, DataChunk singleChunk)
        {
            _stream = s;
            int flags = singleChunk.getFlags();

            if ((flags & DataChunk.SINGLEFLAG) > 0)
            {
                _data = singleChunk.getData();
                _pPid = singleChunk.getPpid();
            }
            else
            {
                throw new Exception("[IllegalArgumentException] must use a 'single' chunk");
            }
        }
예제 #5
0
        /* we can only demand they close their outbound streams */
        /* we can request they start to close inbound (ie ask us to shut our outbound */
        /* DCEP treats streams as bi-directional - so this is somewhat of an inpedance mis-match */
        /* resulting in a temporary 'half closed' state */
        /* mull this over.... */
        public ReConfigChunk makeClose(SCTPStream st)
        {
            ReConfigChunk ret = null;

            Logger.Debug("building reconfig so close stream " + st);
            st.setClosing(true);
            lock (listOfStreamsToReset) {
                listOfStreamsToReset.Enqueue(st);
            }
            if (!timerIsRunning())
            {
                ret = makeSSNResets();
            }
            return(ret);
        }
예제 #6
0
        // todo should be in a behave block
        // then we wouldn't be messing with stream seq numbers.

        private Chunk[] dcepDeal(SCTPStream s, DataChunk dc, DCOpen dcep)
        {
            Chunk[] rep = null;
            Logger.Debug("dealing with a decp for stream " + dc.getDataAsString());
            if (!dcep.isAck())
            {
                Logger.Debug("decp is not an ack... ");

                SCTPStreamBehaviour behave = dcep.mkStreamBehaviour();
                s.setBehave(behave);
                s.setLabel(dcep.getLabel());
                lock (s) {
                    int seqIn = s.getNextMessageSeqIn();
                    s.setNextMessageSeqIn(seqIn + 1);
                    int seqOut = s.getNextMessageSeqOut();
                    s.setNextMessageSeqOut(seqOut + 1);
                }
                rep = new Chunk[1];
                DataChunk ack = dc.mkAck(dcep);
                s.outbound(ack);
                ack.setTsn(_nearTSN++);
                // check rollover - will break at maxint.
                rep[0] = ack;
            }
            else
            {
                Logger.Debug("got a dcep ack for " + s.getLabel());
                SCTPStreamBehaviour behave = dcep.mkStreamBehaviour();
                s.setBehave(behave);
                lock (s) {
                    int seqIn = s.getNextMessageSeqIn();
                    s.setNextMessageSeqIn(seqIn + 1);
                    int seqOut = s.getNextMessageSeqOut();
                    s.setNextMessageSeqOut(seqOut + 1);
                }
            }
            return(rep);
        }
예제 #7
0
 public SCTPMessage(string data, SCTPStream s)
 {
     _data   = (data.Length > 0) ? System.Text.Encoding.ASCII.GetBytes(data) : new byte[1];
     _stream = s;
     _pPid   = (data.Length > 0) ? DataChunk.WEBRTCstring : DataChunk.WEBRTCstringEMPTY;
 }
예제 #8
0
 /**
  * Outbound message - note that we assume no one will mess with data between
  * calls to fill()
  *
  * @param data
  * @param s
  */
 public SCTPMessage(byte[] data, SCTPStream s)
 {
     _data   = (data.Length > 0) ? data : new byte[1];
     _stream = s;
     _pPid   = (data.Length > 0) ? DataChunk.WEBRTCBINARY : DataChunk.WEBRTCBINARYEMPTY;
 }
예제 #9
0
        /*
         * https://tools.ietf.org/html/rfc6525
         */
        public Chunk[] deal(ReConfigChunk rconf)
        {
            Chunk[]       ret   = new Chunk[1];
            ReConfigChunk reply = null;

            Logger.Debug("Got a reconfig message to deal with");
            if (haveSeen(rconf))
            {
                // if not - is this a repeat
                reply = getPrevious(rconf);                 // then send the same reply
            }
            if (reply == null)
            {
                // not a repeat then
                reply = new ReConfigChunk();                 // create a new thing
                if (rconf.hasOutgoingReset())
                {
                    OutgoingSSNResetRequestParameter oreset = rconf.getOutgoingReset();
                    int[] streams = oreset.getStreams();
                    if (streams.Length == 0)
                    {
                        streams = assoc.allStreams();
                    }
                    if (timerIsRunning())
                    {
                        markAsAcked(rconf);
                    }
                    // if we are behind, we are supposed to wait untill we catch up.
                    if (oreset.getLastAssignedTSN() > assoc.getCumAckPt())
                    {
                        Logger.Debug("Last assigned > farTSN " + oreset.getLastAssignedTSN() + " v " + assoc.getCumAckPt());
                        foreach (int s in streams)
                        {
                            SCTPStream defstr = assoc.getStream(s);
                            defstr.setDeferred(true);
                        }
                        ReconfigurationResponseParameter rep = new ReconfigurationResponseParameter();
                        rep.setSeq(oreset.getReqSeqNo());
                        rep.setResult(ReconfigurationResponseParameter.IN_PROGRESS);
                        reply.addParam(rep);
                    }
                    else
                    {
                        // somehow invoke this when TSN catches up ?!?! ToDo
                        Logger.Debug("we are up-to-date ");
                        ReconfigurationResponseParameter rep = new ReconfigurationResponseParameter();
                        rep.setSeq(oreset.getReqSeqNo());
                        int result = streams.Length > 0 ? ReconfigurationResponseParameter.SUCCESS_PERFORMED : ReconfigurationResponseParameter.SUCCESS_NOTHING_TO_DO;
                        rep.setResult((uint)result);                          // assume all good
                        foreach (int s in streams)
                        {
                            SCTPStream cstrm = assoc.delStream(s);
                            if (cstrm == null)
                            {
                                Logger.Error("Close a non existant stream");
                                rep.setResult(ReconfigurationResponseParameter.ERROR_WRONG_SSN);
                                break;
                                // bidriectional might be a problem here...
                            }
                            else
                            {
                                cstrm.reset();
                            }
                        }
                        reply.addParam(rep);
                    }
                }
                // ponder putting this in a second chunk ?
                if (rconf.hasIncomingReset())
                {
                    IncomingSSNResetRequestParameter ireset = rconf.getIncomingReset();

                    /*The Re-configuration
                     * Response Sequence Number of the Outgoing SSN Reset Request
                     * Parameter MUST be the Re-configuration Request Sequence Number
                     * of the Incoming SSN Reset Request Parameter. */
                    OutgoingSSNResetRequestParameter rep = new OutgoingSSNResetRequestParameter(nextNearNo(), ireset.getReqNo(), assoc.getNearTSN());
                    int[] streams = ireset.getStreams();
                    rep.setStreams(streams);
                    if (streams.Length == 0)
                    {
                        streams = assoc.allStreams();
                    }
                    foreach (int s in streams)
                    {
                        SCTPStream st = assoc.getStream(s);
                        if (st != null)
                        {
                            st.setClosing(true);
                        }
                    }
                    reply.addParam(rep);
                    // set outbound timer running here ???
                    Logger.Debug("Ireset " + ireset);
                }
            }
            if (reply.hasParam())
            {
                ret[0] = reply;
                // todo should add sack here
                Logger.Debug("about to reply with " + reply.ToString());
            }
            else
            {
                ret = null;
            }
            return(ret);
        }
예제 #10
0
 public ReConfigChunk addToCloseList(SCTPStream st)
 {
     return(reconfigState.makeClose(st));
 }