//////////////////////////////////////////////////// // 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(); }
//////////////////////////////////////////////////// // 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 */ }