public bool sameAs(ReConfigChunk other)
        {
            // we ignore other var types for now....
            bool ret = false; // assume the negative.

            if (other != null)
            {
                // if there are 2 params and both match
                if ((this.hasIncomingReset() && other.hasIncomingReset()) &&
                    (this.hasOutgoingReset() && other.hasOutgoingReset()))
                {
                    ret = this.getIncomingReset().sameAs(other.getIncomingReset()) &&
                          this.getOutgoingReset().sameAs(other.getOutgoingReset());
                }
                else
                {
                    // there is only one (of these) params
                    // that has to match too
                    if (this.hasIncomingReset() && other.hasIncomingReset())
                    {
                        ret = this.getIncomingReset().sameAs(other.getIncomingReset());
                    }
                    if (this.hasOutgoingReset() && other.hasOutgoingReset())
                    {
                        ret = this.getOutgoingReset().sameAs(other.getOutgoingReset());
                    }
                }
            }
            return(ret);
        }
示例#2
0
        private ReConfigChunk makeSSNResets()
        {
            ReConfigChunk reply = new ReConfigChunk(); // create a new thing
            //logger.LogDebug($"SCTP closing {listOfStreamsToReset.Count} stream.");
            List <int> streamsL = new List <int>();

            lock (listOfStreamsToReset)
            {
                foreach (var s in listOfStreamsToReset)
                {
                    if (s.InboundIsOpen())
                    {
                        streamsL.Add(s.getNum());
                    }
                }
            }

            int[] streams = streamsL.ToArray();
            if (streams.Length > 0)
            {
                OutgoingSSNResetRequestParameter rep =
                    new OutgoingSSNResetRequestParameter(nextNearNo(), farSeqno - 1, assoc.getNearTSN());
                rep.setStreams(streams);
                reply.addParam(rep);
            }

            streamsL.Clear();
            lock (listOfStreamsToReset)
            {
                foreach (var s in listOfStreamsToReset)
                {
                    if (s.OutboundIsOpen())
                    {
                        streamsL.Add(s.getNum());
                    }
                }
            }

            streams = streamsL.ToArray();
            if (streams.Length > 0)
            {
                IncomingSSNResetRequestParameter rep = new IncomingSSNResetRequestParameter(nextNearNo());
                rep.setStreams(streams);
                reply.addParam(rep);
            }

            //logger.LogDebug("reconfig chunk is " + reply.ToString());
            return(reply);
        }
示例#3
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.LogDebug($"SCTP closing stream {st}");
            st.setClosing(true);
            lock (listOfStreamsToReset)
            {
                listOfStreamsToReset.Enqueue(st);
            }
            if (!timerIsRunning())
            {
                ret = makeSSNResets();
            }
            return(ret);
        }
示例#4
0
        public static Chunk mkChunk(ByteBuffer pkt)
        {
            Chunk ret = null;

            if (pkt.remaining() >= 4)
            {
                ChunkType type   = (ChunkType)pkt.GetByte();
                byte      flags  = pkt.GetByte();
                int       length = pkt.GetUShort();
                switch (type)
                {
                case ChunkType.DATA:
                    ret = new DataChunk(flags, length, pkt);
                    break;

                case ChunkType.INIT:
                    ret = new InitChunk(type, flags, length, pkt);
                    break;

                case ChunkType.SACK:
                    ret = new SackChunk(type, flags, length, pkt);
                    break;

                case ChunkType.INITACK:
                    ret = new InitAckChunk(type, flags, length, pkt);
                    break;

                case ChunkType.COOKIE_ECHO:
                    ret = new CookieEchoChunk(type, flags, length, pkt);
                    break;

                case ChunkType.COOKIE_ACK:
                    ret = new CookieAckChunk(type, flags, length, pkt);
                    break;

                case ChunkType.ABORT:
                    ret = new AbortChunk(type, flags, length, pkt);
                    break;

                case ChunkType.HEARTBEAT:
                    ret = new HeartBeatChunk(type, flags, length, pkt);
                    break;

                case ChunkType.RE_CONFIG:
                    ret = new ReConfigChunk(type, flags, length, pkt);
                    break;

                case ChunkType.ERROR:
                    ret = new ErrorChunk(type, flags, length, pkt);
                    break;

                default:
                    logger.LogWarning($"SCTP unknown chunk type received {type}.");
                    ret = new FailChunk(type, flags, length, pkt);
                    break;
                }
                if (ret != null)
                {
                    if (pkt.hasRemaining())
                    {
                        int mod = ret.getLength() % 4;
                        if (mod != 0)
                        {
                            for (int pad = mod; pad < 4; pad++)
                            {
                                pkt.GetByte();
                            }
                        }
                    }
                }
            }
            return(ret);
        }
示例#5
0
        /*
         * https://tools.ietf.org/html/rfc6525
         */
        public Chunk[] deal(ReConfigChunk rconf)
        {
            Chunk[]       ret   = new Chunk[1];
            ReConfigChunk reply = null;

            //logger.LogDebug("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 until we catch up.
                    if (oreset.getLastAssignedTSN() > assoc.getCumAckPt())
                    {
                        //logger.LogDebug("Last assigned > farTSN " + oreset.getLastAssignedTSN() + " v " + assoc.getCumAckPt());
                        foreach (int s in streams)
                        {
                            SCTPStream defstr = assoc.getStream(s);
                            // AC: All this call did was set an unused local variable. Removed for now.
                            //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.LogDebug("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.LogError("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.LogDebug("Ireset " + ireset);
                }
            }
            if (reply.hasParam())
            {
                ret[0] = reply;
                // todo should add sack here
                //logger.LogDebug("about to reply with " + reply.ToString());
            }
            else
            {
                ret = null;
            }
            return(ret);
        }
示例#6
0
 private void markAsAcked(ReConfigChunk rconf)
 {
     // ooh, what does this button do ??? To Do
 }
示例#7
0
 private ReConfigChunk getPrevious(ReConfigChunk rconf)
 {
     return(rconf.sameAs(recentInbound) ? sentReply : null);
 }
示例#8
0
 private bool haveSeen(ReConfigChunk rconf)
 {
     return(rconf.sameAs(recentInbound));
 }