Ejemplo n.º 1
0
private int processData(CUnit unit)
{
   CPacket packet = unit.m_Packet;

   // Just heard from the peer, reset the expiration count.
   m_iEXPCount = 1;
   m_ullEXPInt = m_ullMinEXPInt;

   if (CSeqNo.incseq(m_iSndCurrSeqNo) == m_iSndLastAck)
   {
      CClock.rdtsc(m_ullNextEXPTime);
      if (!m_pCC.m_bUserDefinedRTO)
         m_ullNextEXPTime += m_ullEXPInt;
      else
         m_ullNextEXPTime += m_pCC.m_iRTO * m_ullCPUFrequency;
   }

   m_pCC.onPktReceived(&packet);

   ++ m_iPktCount;

   // update time information
   m_pRcvTimeWindow.onPktArrival();

   // check if it is probing packet pair
   if (0 == (packet.m_iSeqNo & 0xF))
      m_pRcvTimeWindow.probe1Arrival();
   else if (1 == (packet.m_iSeqNo & 0xF))
      m_pRcvTimeWindow.probe2Arrival();

   ++ m_llTraceRecv;
   ++ m_llRecvTotal;

   Int32 offset = CSeqNo.seqoff(m_iRcvLastAck, packet.m_iSeqNo);
   if ((offset < 0) || (offset >= m_pRcvBuffer.getAvailBufSize()))
      return -1;

   if (m_pRcvBuffer.addData(unit, offset) < 0)
      return -1;

   // Loss detection.
   if (CSeqNo.seqcmp(packet.m_iSeqNo, CSeqNo.incseq(m_iRcvCurrSeqNo)) > 0)
   {
      // If loss found, insert them to the receiver loss list
      m_pRcvLossList.insert(CSeqNo.incseq(m_iRcvCurrSeqNo), CSeqNo.decseq(packet.m_iSeqNo));

      // pack loss list for NAK
      Int32[] lossdata = new int[2];
      lossdata[0] = CSeqNo.incseq(m_iRcvCurrSeqNo) | 0x80000000;
      lossdata[1] = CSeqNo.decseq(packet.m_iSeqNo);

      // Generate loss report immediately.
      sendCtrl(3, null, lossdata, (CSeqNo.incseq(m_iRcvCurrSeqNo) == CSeqNo.decseq(packet.m_iSeqNo)) ? 1 : 2);

      m_iTraceRcvLoss += CSeqNo.seqlen(m_iRcvCurrSeqNo, packet.m_iSeqNo) - 2;
   }

   // This is not a regular fixed size packet...   
   //an irregular sized packet usually indicates the end of a message, so send an ACK immediately   
   if (packet.getLength() != m_iPayloadSize)   
      CClock.rdtsc(m_ullNextACKTime); 

   // Update the current largest sequence number that has been received.
   // Or it is a retransmitted packet, remove it from receiver loss list.
   if (CSeqNo.seqcmp(packet.m_iSeqNo, m_iRcvCurrSeqNo) > 0)
      m_iRcvCurrSeqNo = packet.m_iSeqNo;
   else
      m_pRcvLossList.remove(packet.m_iSeqNo);

   return 0;
}   
Ejemplo n.º 2
0
        // Functionality:
        //    Increase (double) the unit queue size.
        // Parameters:
        //    None.
        // Returned value:
        //    0: success, -1: failure.

        public int increase()
        {
            // adjust/correct m_iCount
            int real_count = 0;
            CQEntry p = m_pQEntry;
            while (p != null)
            {
                CUnit u = p.m_pUnit;
                for (CUnit end = u + p.m_iSize; u != end; ++u)
                    if (u.m_iFlag != 0)
                        ++real_count;

                if (p == m_pLastQueue)
                    p = null;
                else
                    p = p.m_pNext;
            }
            m_iCount = real_count;
            if ((double)(m_iCount) / m_iSize < 0.9)
                return -1;

            CQEntry tempq = null;
            CUnit tempu = null;
            IntPtr tempb = IntPtr.Zero;

            // all queues have the same size
            int size = m_pQEntry.m_iSize;

            try
            {
                tempq = new CQEntry();
                tempu = new CUnit[size];
                tempb = new char[size * m_iMSS];
            }
            catch (Exception e)
            {
                tempq.Dispose();
                tempu.Dispose();
                tempb.Dispose();
                //delete tempq;
                //delete [] tempu;
                //delete [] tempb;

                return -1;
            }

            for (int i = 0; i < size; ++i)
            {
                tempu[i].m_iFlag = 0;
                tempu[i].m_Packet.m_pcData = tempb + i * m_iMSS;
            }
            tempq.m_pUnit = tempu;
            tempq.m_pBuffer = tempb;
            tempq.m_iSize = size;

            m_pLastQueue.m_pNext = tempq;
            m_pLastQueue = tempq;
            m_pLastQueue.m_pNext = m_pQEntry;

            m_iSize += size;

            return 0;
        }
Ejemplo n.º 3
0
        // Functionality:
        //    find an available unit for incoming packet.
        // Parameters:
        //    None.
        // Returned value:
        //    Pointer to the available unit, null if not found.

        public CUnit getNextAvailUnit()
        {
            if (m_iCount * 10 > m_iSize * 9)
                increase();

            if (m_iCount >= m_iSize)
                return null;

            CQEntry entrance = m_pCurrQueue;

            do
            {
                for (CUnit sentinel = m_pCurrQueue.m_pUnit + m_pCurrQueue.m_iSize - 1; m_pAvailUnit != sentinel; ++m_pAvailUnit)
                    if (m_pAvailUnit.m_iFlag == 0)
                        return m_pAvailUnit;

                if (m_pCurrQueue.m_pUnit.m_iFlag == 0)
                {
                    m_pAvailUnit = m_pCurrQueue.m_pUnit;
                    return m_pAvailUnit;
                }

                m_pCurrQueue = m_pCurrQueue.m_pNext;
                m_pAvailUnit = m_pCurrQueue.m_pUnit;
            } while (m_pCurrQueue != entrance);

            increase();

            return null;
        }
Ejemplo n.º 4
0
        public AddressFamily m_iIPversion;		// IP version

        #region Constructor - Destructor
        //public CUnitQueue()
        //{
        //}

        //~CUnitQueue()
        //{
        //    CQEntry p = m_pQEntry;

        //    while (p != null)
        //    {
        //        CQEntry q = p;
        //        if (p == m_pLastQueue)
        //            p = null;
        //        else
        //            p = p.m_pNext;

        //        q.Dispose();
        //    }
        //}
        #endregion

        // Functionality:
        //    Initialize the unit queue.
        // Parameters:
        //    1) [in] size: queue size
        //    2) [in] mss: maximum segment size
        //    3) [in] version: IP version
        // Returned value:
        //    0: success, -1: failure.

        public int init(int size, int mss, AddressFamily version)
        {
            CQEntry tempq = null;
            CUnit tempu = null;
            IntPtr tempb = IntPtr.Zero;

            try
            {
                tempq = new CQEntry();
                tempu = new CUnit[size];
                tempb = new char[size * mss];
            }
            catch (Exception e)
            {
                //tempq.Dispose();
                // tempu.Dispose();
                // tempb.Dispose();

                return -1;
            }

            for (int i = 0; i < size; ++i)
            {
                tempu[i].m_iFlag = 0;
                tempu[i].m_Packet.m_pcData = tempb + i * mss;
            }
            tempq.m_pUnit = tempu;
            tempq.m_pBuffer = tempb;
            tempq.m_iSize = size;

            m_pQEntry = m_pCurrQueue = m_pLastQueue = tempq;
            m_pQEntry.m_pNext = m_pQEntry;

            m_pAvailUnit = m_pCurrQueue.m_pUnit;

            m_iSize = size;
            m_iMSS = mss;
            m_iIPversion = version;

            return 0;
        }