示例#1
0
        private Chunk[] dataDeal(DataChunk dc)
        {
            List <Chunk> rep        = new List <Chunk>();
            List <uint>  duplicates = new List <uint>();

            uint tsn = dc.getTsn();

            if (tsn > _farTSN)
            {
                // put it in the pen.
                Logger.Trace("TSN:::" + tsn);
                DataChunk dup;
                if (_holdingPen.TryGetValue(tsn, out dup))
                {
                    duplicates.Add(tsn);
                }
                else
                {
                    _holdingPen.Add(tsn, dc);
                }
                // now see if we can deliver anything new to the streams
                bool gap = false;
                for (uint t = _farTSN + 1; !gap; t++)
                {
                    if (_holdingPen.TryGetValue(t, out dc))
                    {
                        _holdingPen.Remove(t);
                        ingest(dc, rep);
                    }
                    else
                    {
                        Logger.Trace("gap in inbound tsns at " + t);
                        gap = true;
                    }
                }
            }
            else
            {
                // probably wrong now..
                Logger.Warn("Already seen . " + tsn + " expecting " + (_farTSN));
                duplicates.Add(tsn);
            }
            List <uint> l = new List <uint>();

            l.AddRange(_holdingPen.Keys);
            l.Sort();

            SackChunk sack = mkSack(l, duplicates);

            rep.Add(sack);
            return(rep.ToArray());
        }
示例#2
0
        private SackChunk mkSack(List <uint> pen, List <uint> dups)
        {
            SackChunk ret = new SackChunk();

            ret.setCumuTSNAck(_farTSN);
            int stashcap = calcStashCap();

            ret.setArWin((uint)(MAXBUFF - stashcap));
            ret.setGaps(pen);
            ret.setDuplicates(dups);
            Logger.Debug("made SACK " + ret.ToString());
            return(ret);
        }
示例#3
0
 protected override Chunk[] sackDeal(SackChunk sackChunk)
 {
     throw new Exception("[UnsupportedOperationException] Not supported yet.");                 //To change body of generated methods, choose Tools | Templates.
 }
示例#4
0
        /*
         *
         * D) Any time a SACK arrives, the endpoint performs the following:
         *
         * ...
         *
         * ToDo :
         *
         * iii) If the SACK is missing a TSN that was previously acknowledged
         * via a Gap Ack Block (e.g., the data receiver reneged on the
         * data), then consider the corresponding DATA that might be
         * possibly missing: Count one miss indication towards Fast
         * Retransmit as described in Section 7.2.4, and if no
         * retransmit timer is running for the destination address to
         * which the DATA chunk was originally transmitted, then T3-rtx
         * is started for that destination address.
         *
         * iv) If the Cumulative TSN Ack matches or exceeds the Fast
         * Recovery exitpoint (Section 7.2.4), Fast Recovery is exited.
         *
         */

        protected override Chunk[] sackDeal(SackChunk sack)
        {
            Chunk[] ret = { };

            /*
             * i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
             * Point, then drop the SACK.  Since Cumulative TSN Ack is
             * monotonically increasing, a SACK whose Cumulative TSN Ack is
             * less than the Cumulative TSN Ack Point indicates an out-of-
             * order SACK.
             */
            if (sack.getCumuTSNAck() >= this._lastCumuTSNAck)
            {
                long ackedTo    = sack.getCumuTSNAck();
                int  totalAcked = 0;
                long now        = Time.CurrentTimeMillis();
                // interesting SACK
                // process acks
                lock (_inFlight) {
                    List <long> removals = new List <long>();
                    foreach (var kvp in _inFlight)
                    {
                        if (kvp.Key <= ackedTo)
                        {
                            removals.Add(kvp.Key);
                        }
                    }
                    foreach (long k in removals)
                    {
                        DataChunk d = _inFlight[k];
                        _inFlight.Remove(k);
                        totalAcked += d.getDataSize();

                        /*
                         * todo     IMPLEMENTATION NOTE: RTT measurements should only be made using
                         * a chunk with TSN r if no chunk with TSN less than or equal to r
                         * is retransmitted since r is first sent.
                         */
                        setRTO(now - d.getSentTime());
                        try {
                            int        sid    = d.getStreamId();
                            SCTPStream stream = getStream(sid);
                            if (stream != null)
                            {
                                stream.delivered(d);
                            }
                            lock (_freeBlocks) {
                                _freeBlocks.Enqueue(d);
                            }
                        }
                        catch (Exception ex) {
                            Logger.Error("eek - can't replace free block on list!?!");
                            Logger.Error(ex.ToString());
                        }
                    }
                }

                /*
                 * Gap Ack Blocks:
                 *
                 * These fields contain the Gap Ack Blocks.  They are repeated for
                 * each Gap Ack Block up to the number of Gap Ack Blocks defined in
                 * the Number of Gap Ack Blocks field.  All DATA chunks with TSNs
                 * greater than or equal to (Cumulative TSN Ack + Gap Ack Block
                 * Start) and less than or equal to (Cumulative TSN Ack + Gap Ack
                 * Block End) of each Gap Ack Block are assumed to have been received
                 * correctly.
                 */
                foreach (SackChunk.GapBlock gb in sack.getGaps())
                {
                    long ts = gb.getStart() + ackedTo;
                    long te = gb.getEnd() + ackedTo;
                    lock (_inFlight) {
                        for (long t = ts; t <= te; t++)
                        {
                            Logger.Trace("gap block says far end has seen " + t);
                            DataChunk d;
                            if (_inFlight.TryGetValue(t, out d))
                            {
                                d.setGapAck(true);
                                totalAcked += d.getDataSize();
                            }
                            else
                            {
                                Logger.Debug("Huh? gap for something not inFlight ?!? " + t);
                            }
                        }
                    }
                }

                /*
                 * ii) Set rwnd equal to the newly received a_rwnd minus the number
                 * of bytes still outstanding after processing the Cumulative
                 * TSN Ack and the Gap Ack Blocks.
                 */
                int totalDataInFlight = 0;
                lock (_inFlight) {
                    foreach (var kvp in _inFlight)
                    {
                        DataChunk d = kvp.Value;
                        long      k = kvp.Key;
                        if (!d.getGapAck())
                        {
                            totalDataInFlight += d.getDataSize();
                        }
                    }
                }
                _rwnd = sack.getArWin() - totalDataInFlight;
                Logger.Debug("Setting rwnd to " + _rwnd);
                bool advanced = (_lastCumuTSNAck < ackedTo);
                adjustCwind(advanced, totalDataInFlight, totalAcked);
                _lastCumuTSNAck = ackedTo;
            }
            else
            {
                Logger.Debug("Dumping Sack - already seen later sack.");
            }
            return(ret);
        }
示例#5
0
 abstract protected Chunk[] sackDeal(SackChunk sackChunk);