Example #1
0
////////////////////////////////////////////////////
// setCache 
// adds current packet to specified cache
void EQPacketStream::setCache(uint16_t serverArqSeq, EQProtocolPacket& packet)
{
   // check if the entry already exists in the cache
   EQPacketMap::iterator it = m_cache.find(serverArqSeq);

   if (it == m_cache.end())
   {
   // entry doesn't exist, so insert an entry into the cache

#ifdef PACKET_PROCESS_DIAG
      seqDebug("SEQ: Insert arq (%04x) stream %d into cache", serverArqSeq, m_streamid);
#endif

      m_cache.insert(EQPacketMap::value_type(serverArqSeq, 
         new EQProtocolPacket(packet, true)));
      emit cacheSize(m_cache.size(), (int)m_streamid);
   }
   else
   {
     // replacing an existing entry, make sure the new data is valid
#ifdef APPLY_CRC_CHECK
     if (! packet.hasCRC() || calculateCRC(packet) == packet.crc())
#endif
     {
#ifdef PACKET_PROCESS_DIAG
        seqDebug("SEQ: Update arq (%04x) stream %d in cache", serverArqSeq, m_streamid);
#endif

        // Free the old packet at this place and replace with the new one.
        delete it->second;
        it->second = new EQProtocolPacket(packet, true);
     }
#if defined(PACKET_PROCESS_DIAG) && defined(APPLY_CRC_CHECK)
     else
        seqDebug("SEQ: Not Updating arq (%04x) stream %d into cache, CRC error!",
               serverArqSeq, m_streamid);
#endif
   }

#ifdef PACKET_CACHE_DIAG
   if (m_cache.size() > m_maxCacheCount)
      m_maxCacheCount = m_cache.size();
#endif // PACKET_CACHE_DIAG
}
Example #2
0
////////////////////////////////////////////////////
// Cache processing
void EQPacketStream::processCache()
{
#if defined(PACKET_CACHE_DIAG)
  seqDebug("SEQ: START checking stream %s cache, arq %04x, cache count %04d",
         EQStreamStr[m_streamid], m_arqSeqExp, m_cache.size());
#endif
  EQPacketMap::iterator it;
  EQPacketMap::iterator eraseIt;
  EQProtocolPacket* packet;

  // check if the cache has grown large enough that we should give up
  // on seeing the current serverArqSeqExp
  // 
  // If people see this a lot, they either have pathetic network cards, or
  // are having problems keeping up with packets (slow computer? Too much
  // net traffic?). Some possible solutions to this are to turn on session
  // tracking to filter out more PF_PACKET packets from getting passed out of
  // the kernel and to up the socket receive buffer sizes. See FAQ for
  // more information.
  if (m_cache.size() >= m_arqSeqGiveUp)
  {
    // ok, if the expected server arq sequence isn't here yet, give up
    
    // attempt to find the current expencted arq seq
    it = m_cache.find(m_arqSeqExp);
    
    // keep trying to find a new serverArqSeqExp if we haven't found a good
    // one yet...
    while(it == m_cache.end())
    {
      seqWarn("SEQ: Giving up on finding arq %04x in stream %s cache, skipping!",
	     m_arqSeqExp, EQStreamStr[m_streamid]);
      
      // incremente the expected arq sequence number
      m_arqSeqExp++;
      emit seqExpect(m_arqSeqExp, (int)m_streamid);
      
      // attempt to find the new current expencted arq seq
      it = m_cache.find(m_arqSeqExp);
    }
  }
  else
  {
    // haven't given up yet, just try to find the current serverArqSeqExp
    // attempt to find the current expected ARQ seq
    it = m_cache.find(m_arqSeqExp);
  }


  // iterate over cache until we reach the end or run out of
  // immediate followers
  while (it != m_cache.end())
  {
    // get the PacketFormat for the iterator
    packet = it->second;
    
    // make sure this is the expected packet
    // (we might have incremented to the one after the one returned
    // by find above).
    if (packet->arqSeq() != m_arqSeqExp)
      break;
    
#ifdef PACKET_CACHE_DIAG
    seqDebug("SEQ: found next arq %04x in stream %s cache, cache count %04d",
	   m_arqSeqExp, EQStreamStr[m_streamid], m_cache.size());
#endif
    
    // validate the packet with a crc check. If the packet is for an old
    // session, we probably shouldn't be using it!
#ifdef APPLY_CRC_CHECK
    if (packet->hasCRC() && packet->crc() != calculateCRC(*packet))
    {
#if defined (PACKET_CACHE_DIAG)
      // Something's screwed up
      seqDebug("SEQ: INVALID PACKET: Bad CRC in packet in stream %s cache with arq %04x! Droping it, but leaving expected seq as %04x",
	    EQStreamStr[m_streamid], packet->arqSeq(), m_arqSeqExp);
#endif

      // Need to drop from the cache
      eraseIt = it;
        
      // increment the current position iterator
      it++;
        
      // erase the packet from the cache
      m_cache.erase(eraseIt);
      emit cacheSize(m_cache.size(), (int)m_streamid);
        
    #ifdef PACKET_CACHE_DIAG
      seqDebug("SEQ: REMOVING arq %04x from stream %s cache, cache count %04d",
         packet->arqSeq(), EQStreamStr[m_streamid], m_cache.size());
    #endif
      // delete the packet
      delete packet;

      // No sense looping some more.
      break;
    }
    else
#endif /* APPLY_CRC_CHECK */
    {
#if defined (PACKET_CACHE_DIAG) && (PACKET_CACHE_DIAG > 2)
      seqDebug("SEQ: Found next arq in stream %s cache, incrementing arq seq, %04x", 
	     EQStreamStr[m_streamid], packet->arqSeq());
#endif
    
      // Process the packet since it's next in the sequence and was just
      // received out of order
      processPacket(*packet, packet->isSubpacket());
      
      // Need to drop from the cache
      eraseIt = it;
      
      // increment the current position iterator
      it++;
      
      // erase the packet from the cache
      m_cache.erase(eraseIt);
      emit cacheSize(m_cache.size(), (int)m_streamid);
    
#ifdef PACKET_CACHE_DIAG
      seqDebug("SEQ: REMOVING arq %04x from stream %s cache, cache count %04d",
	     packet->arqSeq(), EQStreamStr[m_streamid], m_cache.size());
#endif
      // delete the packet
      delete packet;
  
      if (m_arqSeqExp == 0)
        it = m_cache.begin();
    }
  }
  
#ifdef PACKET_CACHE_DIAG
  seqDebug("SEQ: FINISHED checking stream %s cache, arq %04x, cache count %04d",
         EQStreamStr[m_streamid], m_arqSeqExp, m_cache.size());
#endif
}