getLength() public method

public getLength ( ) : int
return int
Exemplo n.º 1
0
        // Functionality:
        //    Send out a packet to a given address.
        // Parameters:
        //    1) [in] addr: destination address
        //    2) [in] packet: packet to be sent out
        // Returned value:
        //    Size of data sent out.

        public int sendto(IPEndPoint addr, CPacket packet)
        {
            // send out the packet immediately (high priority), this is a control packet
            m_pChannel.sendto(addr, packet);

            return packet.getLength();
        }
Exemplo n.º 2
0
        // Functionality:
        //    Receive a packet from the channel and record the source address.
        // Parameters:
        //    0) [in] addr: pointer to the source address.
        //    1) [in] packet: reference to a CPacket entity.
        // Returned value:
        //    Actual size of data received.

        public int recvfrom(IPAddress addr, CPacket packet)
{
      DWORD size = CPacket.m_iPktHdrSize + packet.getLength();
      DWORD flag = 0;
      int addrsize = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);

      int res = WSARecvFrom(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, &flag, addr, &addrsize, null, null);
      res = (0 == res) ? size : -1;

   if (res <= 0)
   {
      packet.setLength(-1);
      return -1;
   }

   packet.setLength(res - CPacket.m_iPktHdrSize);

   // convert back into local host order
   //for (int i = 0; i < 4; ++ i)
   //   packet.m_nHeader[i] = ntohl(packet.m_nHeader[i]);
   uint* p = packet.m_nHeader;
   for (int i = 0; i < 4; ++ i)
   {
      *p = ntohl(*p);
      ++ p;
   }

   if (packet.getFlag())
      for (int j = 0, n = packet.getLength() / 4; j < n; ++ j)
         *((uint *)packet.m_pcData + j) = ntohl(*((uint *)packet.m_pcData + j));

   return packet.getLength();
        }
Exemplo n.º 3
0
        // Functionality:
        //    Read a packet for a specific UDT socket id.
        // Parameters:
        //    1) [in] id: Socket ID
        //    2) [out] packet: received packet
        // Returned value:
        //    Data size of the packet

        public int recvfrom(int id, ref CPacket packet)
        {
            packet = null;

            CGuard bufferlock = new CGuard(m_PassLock);

            // Try to find a packet for the specified
            // socket ID
            CPacket workPacket;
            if (!m_mBuffer.TryGetValue(id, out workPacket))
            {
                // If we didn't find the packet waiting already
                // Then wait around until a packet arrives
                m_PassLock.ReleaseMutex();
                m_PassCond.WaitOne(1000);
                m_PassLock.WaitOne(-1);

                // Try to find it again
                if (!m_Buffer.TryGetValue(id, out workPacket))
                {
                    packet.setLength(-1);
                    return -1;
                }
            }

            if (packet.getLength() < i.second.getLength())
            {
                packet.setLength(-1);
                return -1;
            }

            workPacket.m_nHeader.CopyTo(packet.m_nHeader, 0);
            workPacket.m_pcData.CopyTo(packet.m_pcData, 0);
            packet.setLength(workPacket.getLength());

            m_mBuffer.Remove(i);

            return packet.getLength();
        }
Exemplo n.º 4
0
        // Functionality:
        //    Send a packet to the given address.
        // Parameters:
        //    0) [in] addr: pointer to the destination address.
        //    1) [in] packet: reference to a CPacket entity.
        // Returned value:
        //    Actual size of data sent.

        public int sendto(IPEndPoint addr, CPacket packet)
{
   // convert control information into network order
   if (packet.getFlag() > 0)
      for (int i = 0, n = packet.getLength() / 4; i < n; ++ i)
         *((uint *)packet.m_pcData + i) = htonl(*((uint *)packet.m_pcData + i));

   // convert packet header into network order
   //for (int j = 0; j < 4; ++ j)
   //   packet.m_nHeader[j] = htonl(packet.m_nHeader[j]);
   uint* p = packet.m_nHeader;
   for (int j = 0; j < 4; ++ j)
   {
      *p = htonl(*p);
      ++ p;
   }

      DWORD size = CPacket.m_iPktHdrSize + packet.getLength();
      //int addrsize = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
      //int res = WSASendTo(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, 0, addr, addrsize, null, null);
      //int res = m_iSocket.SendTo(Buffer, addr);
      int res = m_iSocket.SendTo(Buffer, 0, size, SocketFlags.None, addr);

      res = (0 == res) ? size : -1;

   // convert back into local host order
   //for (int k = 0; k < 4; ++ k)
   //   packet.m_nHeader[k] = ntohl(packet.m_nHeader[k]);
   p = packet.m_nHeader;
   for (int k = 0; k < 4; ++ k)
   {
      *p = ntohl(*p);
       ++ p;
   }

   if (packet.getFlag() > 0)
      for (int l = 0, n = packet.getLength() / 4; l < n; ++ l)
         packet.m_pcData[l] = ntohl(packet.m_pcData[l]);

   return res;
}
Exemplo n.º 5
0
void processCtrl(CPacket ctrlpkt)
{
   // Just heard from the peer, reset the expiration count.
   m_iEXPCount = 1;
   if ((CSeqNo.incseq(m_iSndCurrSeqNo) == m_iSndLastAck) || (2 == ctrlpkt.getType()) || (3 == ctrlpkt.getType()))
   {
      m_ullEXPInt = m_ullMinEXPInt;
      CClock.rdtsc(out m_ullNextEXPTime);
      m_ullNextEXPTime += m_ullEXPInt;
   }

   switch (ctrlpkt.getType())
   {
   case 2: //010 - Acknowledgement
      {
      Int32 ack;

      // process a lite ACK
      if (4 == ctrlpkt.getLength())
      {
         ack = *(Int32 *)ctrlpkt.m_pcData;
         if (CSeqNo.seqcmp(ack, (Int32)(m_iSndLastAck)) >= 0)
         {
            m_iFlowWindowSize -= CSeqNo.seqoff((Int32)(m_iSndLastAck), ack);
            m_iSndLastAck = ack;
         }

         break;
      }

       // read ACK seq. no.
      ack = ctrlpkt.getAckSeqNo();

      // send ACK acknowledgement
      // ACK2 can be much less than ACK
      Int64 currtime = CClock.getTime();
      if ((currtime - m_ullSndLastAck2Time > (Int64)m_iSYNInterval) || (ack == m_iSndLastAck2))
      {
         sendCtrl(6, &ack);
         m_iSndLastAck2 = ack;
         m_ullSndLastAck2Time = currtime;
      }

      // Got data ACK
      ack = *(Int32 *)ctrlpkt.m_pcData;

      // check the validation of the ack
      if (CSeqNo.seqcmp(ack, CSeqNo.incseq(m_iSndCurrSeqNo)) > 0)
      {
         //this should not happen: attack or bug
         m_bBroken = true;
         m_iBrokenCounter = 0;
         break;
      }

      if (CSeqNo.seqcmp(ack, (Int32)(m_iSndLastAck)) >= 0)
      {
         // Update Flow Window Size, must update before and together with m_iSndLastAck
         m_iFlowWindowSize = *((Int32 *)ctrlpkt.m_pcData + 3);
         m_iSndLastAck = ack;
      }

      // protect packet retransmission
      CGuard.enterCS(m_AckLock);

      int offset = CSeqNo.seqoff((Int32)m_iSndLastDataAck, ack);
      if (offset <= 0)
      {
         // discard it if it is a repeated ACK
         CGuard.leaveCS(m_AckLock);
         break;
      }

      // acknowledge the sending buffer
      m_pSndBuffer.ackData(offset);

      // record total time used for sending
      m_llSndDuration += currtime - m_llSndDurationCounter;
      m_llSndDurationTotal += currtime - m_llSndDurationCounter;
      m_llSndDurationCounter = currtime;

      // update sending variables
      m_iSndLastDataAck = ack;
      m_pSndLossList.remove(CSeqNo.decseq((Int32)m_iSndLastDataAck));

      CGuard.leaveCS(m_AckLock);

         if (m_bSynSending)
            SetEvent(m_SendBlockCond);

      // insert this socket to snd list if it is not on the list yet
      m_pSndQueue.m_pSndUList.update(this, false);

      // Update RTT
      //m_iRTT = *((Int32 *)ctrlpkt.m_pcData + 1);
      //m_iRTTVar = *((Int32 *)ctrlpkt.m_pcData + 2);
      int rtt = *((Int32 *)ctrlpkt.m_pcData + 1);
      m_iRTTVar = (m_iRTTVar * 3 + abs(rtt - m_iRTT)) >> 2;
      m_iRTT = (m_iRTT * 7 + rtt) >> 3;

      m_pCC.setRTT(m_iRTT);

      m_ullMinEXPInt = (m_iRTT + 4 * m_iRTTVar) * m_ullCPUFrequency + m_ullSYNInt;
      if (m_ullMinEXPInt < 100000 * m_ullCPUFrequency)
          m_ullMinEXPInt = 100000 * m_ullCPUFrequency;

      if (ctrlpkt.getLength() > 16)
      {
         // Update Estimated Bandwidth and packet delivery rate
         if (*((Int32 *)ctrlpkt.m_pcData + 4) > 0)
            m_iDeliveryRate = (m_iDeliveryRate * 7 + *((Int32 *)ctrlpkt.m_pcData + 4)) >> 3;

         if (*((Int32 *)ctrlpkt.m_pcData + 5) > 0)
            m_iBandwidth = (m_iBandwidth * 7 + *((Int32 *)ctrlpkt.m_pcData + 5)) >> 3;

         m_pCC.setRcvRate(m_iDeliveryRate);
         m_pCC.setBandwidth(m_iBandwidth);
      }

      m_pCC.onACK(ack);
      // update CC parameters
      m_ullInterval = (Int64)(m_pCC.m_dPktSndPeriod * m_ullCPUFrequency);
      m_dCongestionWindow = m_pCC.m_dCWndSize;

      ++ m_iRecvACK;
      ++ m_iRecvACKTotal;

      break;
      }

   case 6: //110 - Acknowledgement of Acknowledgement
      {
      Int32 ack;
      int rtt = -1;

      // update RTT
      rtt = m_pACKWindow.acknowledge(ctrlpkt.getAckSeqNo(), ack);

      if (rtt <= 0)
         break;

      //if increasing delay detected...
      //   sendCtrl(4);

      // RTT EWMA
      m_iRTTVar = (m_iRTTVar * 3 + abs(rtt - m_iRTT)) >> 2;
      m_iRTT = (m_iRTT * 7 + rtt) >> 3;

      m_pCC.setRTT(m_iRTT);

      m_ullMinEXPInt = (m_iRTT + 4 * m_iRTTVar) * m_ullCPUFrequency + m_ullSYNInt;
      if (m_ullMinEXPInt < 100000 * m_ullCPUFrequency)
          m_ullMinEXPInt = 100000 * m_ullCPUFrequency;

      // update last ACK that has been received by the sender
      if (CSeqNo.seqcmp(ack, m_iRcvLastAckAck) > 0)
         m_iRcvLastAckAck = ack;

      break;
      }

   case 3: //011 - Loss Report
      {
      Int32* losslist = (Int32 *)(ctrlpkt.m_pcData);

      m_pCC.onLoss(losslist, ctrlpkt.getLength() / 4);
      // update CC parameters
      m_ullInterval = (Int64)(m_pCC.m_dPktSndPeriod * m_ullCPUFrequency);
      m_dCongestionWindow = m_pCC.m_dCWndSize;

      bool secure = true;

      // decode loss list message and insert loss into the sender loss list
      for (int i = 0, n = (int)(ctrlpkt.getLength() / 4); i < n; ++ i)
      {
         if (0 != (losslist[i] & 0x80000000))
         {
            if ((CSeqNo.seqcmp(losslist[i] & 0x7FFFFFFF, losslist[i + 1]) > 0) || (CSeqNo.seqcmp(losslist[i + 1], (Int32)(m_iSndCurrSeqNo)) > 0))
            {
               // seq_a must not be greater than seq_b; seq_b must not be greater than the most recent sent seq
               secure = false;
               break;
            }

            int num = 0;
            if (CSeqNo.seqcmp(losslist[i] & 0x7FFFFFFF, (Int32)(m_iSndLastAck)) >= 0)
               num = m_pSndLossList.insert(losslist[i] & 0x7FFFFFFF, losslist[i + 1]);
            else if (CSeqNo.seqcmp(losslist[i + 1], (Int32)(m_iSndLastAck)) >= 0)
               num = m_pSndLossList.insert((Int32)(m_iSndLastAck), losslist[i + 1]);

            m_iTraceSndLoss += num;
            m_iSndLossTotal += num;

            ++ i;
         }
         else if (CSeqNo.seqcmp(losslist[i], (Int32)(m_iSndLastAck)) >= 0)
         {
            if (CSeqNo.seqcmp(losslist[i], (Int32)(m_iSndCurrSeqNo)) > 0)
            {
               //seq_a must not be greater than the most recent sent seq
               secure = false;
               break;
            }

            int num = m_pSndLossList.insert(losslist[i], losslist[i]);

            m_iTraceSndLoss += num;
            m_iSndLossTotal += num;
         }
      }

      if (!secure)
      {
         //this should not happen: attack or bug
         m_bBroken = true;
         m_iBrokenCounter = 0;
         break;
      }

      // the lost packet (retransmission) should be sent out immediately
      m_pSndQueue.m_pSndUList.update(this);

      ++ m_iRecvNAK;
      ++ m_iRecvNAKTotal;

      break;
      }

   case 4: //100 - Delay Warning
      // One way packet delay is increasing, so decrease the sending rate
      m_ullInterval = (Int64)ceil(m_ullInterval * 1.125);
      m_iLastDecSeq = m_iSndCurrSeqNo;

      break;

   case 1: //001 - Keep-alive
      // The only purpose of keep-alive packet is to tell that the peer is still alive
      // nothing needs to be done.

      break;

   case 0: //000 - Handshake
      if ((((CHandShake*)(ctrlpkt.m_pcData)).m_iReqType > 0) || (m_bRendezvous && (((CHandShake*)(ctrlpkt.m_pcData)).m_iReqType != -2)))
      {
         // The peer side has not received the handshake message, so it keeps querying
         // resend the handshake packet

         CHandShake initdata;
         initdata.m_iISN = m_iISN;
         initdata.m_iMSS = m_iMSS;
         initdata.m_iFlightFlagSize = m_iFlightFlagSize;
         initdata.m_iReqType = (!m_bRendezvous) ? -1 : -2;
         initdata.m_iID = m_SocketID;
         sendCtrl(0, null, (char *)&initdata, sizeof(CHandShake));
      }

      break;

   case 5: //101 - Shutdown
      m_bShutdown = true;
      m_bClosing = true;
      m_bBroken = true;
      m_iBrokenCounter = 60;

      // Signal the sender and recver if they are waiting for data.
      releaseSynch();

      CClock.triggerEvent();

      break;

   case 7: //111 - Msg drop request
      m_pRcvBuffer.dropMsg(ctrlpkt.getMsgSeq());
      m_pRcvLossList.remove(*(Int32*)ctrlpkt.m_pcData, *(Int32*)(ctrlpkt.m_pcData + 4));

      break;

   case 32767: //0x7FFF - reserved and user defined messages
      m_pCC.processCustomMsg(&ctrlpkt);
      // update CC parameters
      m_ullInterval = (Int64)(m_pCC.m_dPktSndPeriod * m_ullCPUFrequency);
      m_dCongestionWindow = m_pCC.m_dCWndSize;

      break;

   default:
      break;
   }
}