Beispiel #1
0
////////////////////////////////////////////////////
// handle a new packet on the stream
void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet)
{
  emit numPacket(++m_packetCount, (int)m_streamid);

  // Only accept packets if we've been initialized unless they are
  // initialization packets!
  if (packet.getNetOpCode() != OP_SessionRequest &&
      packet.getNetOpCode() != OP_SessionResponse &&
      ! m_sessionKey)
  {
#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || defined(PACKET_SESSION_DIAG)
    seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Session not initialized. Need to zone to start picking up packets. Session tracking %s.",
      (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
      (const char*)packet.getIPv4DestA(), packet.getDestPort(),
      packet.getNetOpCode(), packet.payloadLength(),
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
    return;
  }

  emit rawPacket(packet.payload(), packet.payloadLength(), m_dir,
    packet.getNetOpCode());

  processPacket(packet, false); // false = isn't subpacket

  // if the cache isn't empty, then process it.
  if (!m_cache.empty()) 
    processCache();
}
Beispiel #2
0
////////////////////////////////////////////////////
// handle a new packet on the stream
void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet)
{
  emit numPacket(++m_packetCount, (int)m_streamid);

  // Only accept packets if we've been initialized unless they are
  // initialization packets!
  if (packet.getNetOpCode() != OP_SessionRequest &&
      packet.getNetOpCode() != OP_SessionResponse &&
      ! m_sessionKey)
  {
#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1)
    seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Session not initialized. Need to zone to start picking up packets. Session tracking %s.",
      (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
      (const char*)packet.getIPv4DestA(), packet.getDestPort(),
      packet.getNetOpCode(), packet.payloadLength(),
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
    return;
  }

  // Decode the packet first
  if (! packet.decode(m_maxLength))
  {
    seqWarn("Packet decode failed for stream %s (%d), op %04x, flags %02x packet dropped.",
      EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(),
      packet.getFlags());
    return;
  }
#ifdef PACKET_DECODE_DIAG
  else if (packet.hasFlags())
  {
    seqDebug("Successful decode for stream %s (%d), op %04x, flags %02x.",
        EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(),
        packet.getFlags());
  }
#endif

  // Raw packet
  emit rawPacket(packet.rawPayload(), packet.rawPayloadLength(), m_dir, 
    packet.getNetOpCode());

  processPacket(packet, false); // false = isn't subpacket

  // if the cache isn't empty, then process it.
  if (!m_cache.empty()) 
    processCache();
}
Beispiel #3
0
////////////////////////////////////////////////////
// handle a new packet on the stream
void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet)
{
  emit numPacket(++m_packetCount, (int)m_streamid);

  // Packet is ours now. Logging needs to know this later on.
  packet.setSessionKey(getSessionKey());

  // Only accept packets if we've been initialized unless they are
  // initialization packets!
  if (packet.getNetOpCode() != OP_SessionRequest &&
      packet.getNetOpCode() != OP_SessionResponse &&
      ! m_sessionKey)
  {
#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1)
    seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Session not initialized. Need to zone to start picking up packets. Session tracking %s.",
      (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
      (const char*)packet.getIPv4DestA(), packet.getDestPort(),
      packet.getNetOpCode(), packet.payloadLength(),
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
    return;
  }

  // Only accept packets that correspond to our latched client port, if
  // it is set. This helps filter out multiple sessions on the same physical
  // host when two eq clients zone at the same time. The first one will win.
  if (m_sessionClientPort != 0 &&
      ((dir() == DIR_Server && m_sessionClientPort != packet.getDestPort()) ||
       (dir() == DIR_Client && m_sessionClientPort != packet.getSourcePort())))
  {
#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1)
    seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Multiple sessions on the same box? Ignoring all but one of them. Latched client port %d. Session tracking %s.",
      (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
      (const char*)packet.getIPv4DestA(), packet.getDestPort(),
      packet.getNetOpCode(), packet.payloadLength(),
      m_sessionClientPort,
        (m_session_tracking_enabled == 2 ? "locked on" :
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
    return;
  }

  // Only accept packets that pass the EQ protocol-level CRC check. This helps
  // weed out non-EQ packets that we might see.
#ifdef APPLY_CRC_CHECK
  if (packet.hasCRC())
  {
    uint16_t calcedCRC = calculateCRC(packet);

    if (calcedCRC != packet.crc())
    {
      seqWarn("INVALID PACKET: Bad CRC [%s:%d -> %s:%d] netOp %04x seq %04x len %d crc (%04x != %04x)",
         (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
         (const char*)packet.getIPv4DestA(), packet.getDestPort(),
         packet.getNetOpCode(), packet.arqSeq(), packet.getUDPPayloadLength(),
         packet.crc(), calcedCRC);
      return;
    }
  }
#endif /* APPLY_CRC_CHECK */

  // Decode the packet first
  if (! packet.decode(m_maxLength))
  {
    seqWarn("Packet decode failed for stream %s (%d), op %04x, flags %02x packet dropped.",
      EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(),
      packet.getFlags());
    return;
  }
#ifdef PACKET_DECODE_DIAG
  else if (packet.hasFlags())
  {
    seqDebug("Successful decode for stream %s (%d), op %04x, flags %02x.",
        EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(),
        packet.getFlags());
  }
#endif

  // Raw packet
  emit rawPacket(packet.rawPayload(), packet.rawPayloadLength(), m_dir, 
    packet.getNetOpCode());

  processPacket(packet, false); // false = isn't subpacket

  // if the cache isn't empty, then process it.
  if (!m_cache.empty()) 
    processCache();
}
Beispiel #4
0
////////////////////////////////////////////////////
// handle a new packet on the stream
void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet)
{
  emit numPacket(++m_packetCount, (int)m_streamid);

  if (!packet.isARQ()) // process packets that don't have an arq sequence
  { 
    // we only handle packets with opcodes
    if (packet.payloadLength() < 2)
      return;
    
    // process the packets payload immediately
    processPayload(packet.payload(), packet.payloadLength());
  }
  else if (packet.isARQ()) // process ARQ sequences
  {
     uint16_t arqSeq = packet.arq();
     emit seqReceive(arqSeq, (int)m_streamid);
      
     /* this conditions should only be met once per zone/world, New Sequence */
     if (packet.isSEQStart() && !packet.isClosingLo() && 
	 (m_session_tracking_enabled < 2))
     {
#ifdef PACKET_PROCESS_DIAG
       seqDebug("EQPacket: SEQStart found, setting arq seq, %04x  stream %s",
	      arqSeq, EQStreamStr[m_streamid]);
#endif

       initDecode();
       
       // hey, a SEQStart, use it's packet to set ARQ
       m_arqSeqExp = arqSeq;
       m_arqSeqFound = true;
       emit seqExpect(m_arqSeqExp, (int)m_streamid);
       
       if ((m_streamid == zone2client) && m_session_tracking_enabled)
       {
	 m_session_tracking_enabled = 2;
	 
	 emit lockOnClient(packet.getSourcePort(),
			   packet.getDestPort());
	 
	 // notify that the client port has been latched
	 emit sessionTrackingChanged(m_session_tracking_enabled);
       }
     }
     else if (!m_arqSeqFound && m_session_tracking_enabled == 0 &&
              !packet.isClosingHi() && !packet.isClosingLo() && 
	      (m_streamid == zone2client))
     {
#ifdef PACKET_PROCESS_DIAG
       seqDebug("SEQ: new sequence found, setting arq seq, %04x  stream %s",
	      arqSeq, EQStreamStr[m_streamid]);
#endif
       m_arqSeqExp = arqSeq;
       m_arqSeqFound = true;
       emit seqExpect(m_arqSeqExp, (int)m_streamid);
     }
     // is this the currently expected sequence, if so, do something with it.
     if (m_arqSeqExp == arqSeq)
     {
       m_arqSeqExp = arqSeq + 1;
       emit seqExpect(m_arqSeqExp, (int)m_streamid);
       
#ifdef PACKET_PROCESS_DIAG
       seqDebug("SEQ: Found next arq in data stream %s, incrementing arq seq, %04x", 
	      EQStreamStr[m_streamid], arqSeq);
#endif

       if (!packet.isASQ() && !packet.isFragment() && !packet.isClosingHi())
       {
	 // seems to be a sort of ping from client to server, has ARQ
	 // but no ASQ, Flags look like 0x0201 (network byte order)
#ifdef PACKET_PROCESS_DIAG
	 seqDebug("SEQ: ARQ without ASQ from stream %s arq 0x%04x",
		EQStreamStr[m_streamid], arqSeq);
#endif
       }
       // since the servers do not care about client closing sequences, we won't either
       // Hey clients have rights too, or not! 
       else if (packet.isClosingHi() && packet.isClosingLo() && 
		(m_streamid == zone2client))
       {
	 if (m_session_tracking_enabled)
	   m_session_tracking_enabled = 1; 
	 
	 emit closing();
	 
	 return;
       } // if the packet is a fragment do appropriate processing
       else if (packet.isFragment())
	 processFragment(packet);
       else if (packet.payloadLength() >= 2) // has to have an opcode
	 processPayload(packet.payload(), packet.payloadLength());
     } // it's a packet from the future, add it to the cache
     else if ( ( (arqSeq > m_arqSeqExp) && 
                 (arqSeq < (uint32_t(m_arqSeqExp + arqSeqWrapCutoff))) ) || 
               (arqSeq < (int32_t(m_arqSeqExp) - arqSeqWrapCutoff)) ) 
     {
#ifdef PACKET_PROCESS_DIAG
       seqDebug("SEQ: out of order arq %04x stream %s, sending to cache, %04d",
	      arqSeq, EQStreamStr[m_streamid], m_cache.size());
#endif
       
       setCache(arqSeq, packet);
     }
     
     // if the cache isn't empty, then check for the expected ARQ sequence
     if (!m_cache.empty()) 
       processCache();
  } /* end ARQ processing */
}