void CInputProcessor::Handshake(LPDESC d, const char * c_pData) { TPacketCGHandshake * p = (TPacketCGHandshake *) c_pData; if (d->GetHandshake() != p->dwHandshake) { sys_err("Invalid Handshake on %d", d->GetSocket()); d->SetPhase(PHASE_CLOSE); } else { if (d->IsPhase(PHASE_HANDSHAKE)) { if (d->HandshakeProcess(p->dwTime, p->lDelta, false)) { #ifdef _IMPROVED_PACKET_ENCRYPTION_ d->SendKeyAgreement(); #else if (g_bAuthServer) d->SetPhase(PHASE_AUTH); else d->SetPhase(PHASE_LOGIN); #endif // #ifdef _IMPROVED_PACKET_ENCRYPTION_ } } else d->HandshakeProcess(p->dwTime, p->lDelta, true); } }
bool CInputProcessor::Process(LPDESC lpDesc, const void * c_pvOrig, int iBytes, int & r_iBytesProceed) { const char * c_pData = (const char *) c_pvOrig; BYTE bLastHeader = 0; int iLastPacketLen = 0; int iPacketLen; if (!m_pPacketInfo) { sys_err("No packet info has been binded to"); return true; } for (m_iBufferLeft = iBytes; m_iBufferLeft > 0;) { BYTE bHeader = (BYTE) *(c_pData); const char * c_pszName; if (bHeader == 0) // 암호화 처리가 있으므로 0번 헤더는 스킵한다. iPacketLen = 1; else if (!m_pPacketInfo->Get(bHeader, &iPacketLen, &c_pszName)) { sys_err("UNKNOWN HEADER: %d, LAST HEADER: %d(%d), REMAIN BYTES: %d, fd: %d", bHeader, bLastHeader, iLastPacketLen, m_iBufferLeft, lpDesc->GetSocket()); //printdata((BYTE *) c_pvOrig, m_iBufferLeft); lpDesc->SetPhase(PHASE_CLOSE); return true; } if (m_iBufferLeft < iPacketLen) return true; if (bHeader) { if (test_server && bHeader != HEADER_CG_MOVE) sys_log(0, "Packet Analyze [Header %d][bufferLeft %d] ", bHeader, m_iBufferLeft); m_pPacketInfo->Start(); int iExtraPacketSize = Analyze(lpDesc, bHeader, c_pData); if (iExtraPacketSize < 0) return true; iPacketLen += iExtraPacketSize; lpDesc->Log("%s %d", c_pszName, iPacketLen); m_pPacketInfo->End(); } // TRAFFIC_PROFILER if (g_bTrafficProfileOn) TrafficProfiler::instance().Report(TrafficProfiler::IODIR_INPUT, bHeader, iPacketLen); // END_OF_TRAFFIC_PROFILER if (bHeader == HEADER_CG_PONG) sys_log(0, "PONG! %u %u", m_pPacketInfo->IsSequence(bHeader), *(BYTE *) (c_pData + iPacketLen - sizeof(BYTE))); if (m_pPacketInfo->IsSequence(bHeader)) { BYTE bSeq = lpDesc->GetSequence(); BYTE bSeqReceived = *(BYTE *) (c_pData + iPacketLen - sizeof(BYTE)); if (bSeq != bSeqReceived) { sys_err("SEQUENCE %x mismatch 0x%x != 0x%x header %u", get_pointer(lpDesc), bSeq, bSeqReceived, bHeader); LPCHARACTER ch = lpDesc->GetCharacter(); char buf[1024]; int offset, len; offset = snprintf(buf, sizeof(buf), "SEQUENCE_LOG [%s]-------------\n", ch ? ch->GetName() : "UNKNOWN"); if (offset < 0 || offset >= (int) sizeof(buf)) offset = sizeof(buf) - 1; for (size_t i = 0; i < lpDesc->m_seq_vector.size(); ++i) { len = snprintf(buf + offset, sizeof(buf) - offset, "\t[%03d : 0x%x]\n", lpDesc->m_seq_vector[i].hdr, lpDesc->m_seq_vector[i].seq); if (len < 0 || len >= (int) sizeof(buf) - offset) offset += (sizeof(buf) - offset) - 1; else offset += len; } snprintf(buf + offset, sizeof(buf) - offset, "\t[%03d : 0x%x]\n", bHeader, bSeq); sys_err("%s", buf); lpDesc->SetPhase(PHASE_CLOSE); return true; } else { lpDesc->push_seq(bHeader, bSeq); lpDesc->SetNextSequence(); //sys_err("SEQUENCE %x match %u next %u header %u", lpDesc, bSeq, lpDesc->GetSequence(), bHeader); } } c_pData += iPacketLen; m_iBufferLeft -= iPacketLen; r_iBytesProceed += iPacketLen; iLastPacketLen = iPacketLen; bLastHeader = bHeader; if (GetType() != lpDesc->GetInputProcessor()->GetType()) return false; } return true; }
int io_loop(LPFDWATCH fdw) { LPDESC d; int num_events, event_idx; DESC_MANAGER::instance().DestroyClosed(); // PHASE_CLOSEАО БўјУµйА» ІчѕоБШґЩ. DESC_MANAGER::instance().TryConnect(); if ((num_events = fdwatch(fdw, 0)) < 0) return 0; for (event_idx = 0; event_idx < num_events; ++event_idx) { d = (LPDESC) fdwatch_get_client_data(fdw, event_idx); if (!d) { if (FDW_READ == fdwatch_check_event(fdw, tcp_socket, event_idx)) { DESC_MANAGER::instance().AcceptDesc(fdw, tcp_socket); fdwatch_clear_event(fdw, tcp_socket, event_idx); } else if (FDW_READ == fdwatch_check_event(fdw, p2p_socket, event_idx)) { DESC_MANAGER::instance().AcceptP2PDesc(fdw, p2p_socket); fdwatch_clear_event(fdw, p2p_socket, event_idx); } /* else if (FDW_READ == fdwatch_check_event(fdw, udp_socket, event_idx)) { char buf[256]; struct sockaddr_in cliaddr; socklen_t socklen = sizeof(cliaddr); int iBytesRead; if ((iBytesRead = socket_udp_read(udp_socket, buf, 256, (struct sockaddr *) &cliaddr, &socklen)) > 0) { static CInputUDP s_inputUDP; s_inputUDP.SetSockAddr(cliaddr); int iBytesProceed; s_inputUDP.Process(NULL, buf, iBytesRead, iBytesProceed); } fdwatch_clear_event(fdw, udp_socket, event_idx); } */ continue; } int iRet = fdwatch_check_event(fdw, d->GetSocket(), event_idx); switch (iRet) { case FDW_READ: if (db_clientdesc == d) { int size = d->ProcessInput(); if (size) sys_log(1, "DB_BYTES_READ: %d", size); if (size < 0) { d->SetPhase(PHASE_CLOSE); } } else if (d->ProcessInput() < 0) { d->SetPhase(PHASE_CLOSE); } break; case FDW_WRITE: if (db_clientdesc == d) { int buf_size = buffer_size(d->GetOutputBuffer()); int sock_buf_size = fdwatch_get_buffer_size(fdw, d->GetSocket()); int ret = d->ProcessOutput(); if (ret < 0) { d->SetPhase(PHASE_CLOSE); } if (buf_size) sys_log(1, "DB_BYTES_WRITE: size %d sock_buf %d ret %d", buf_size, sock_buf_size, ret); } else if (d->ProcessOutput() < 0) { d->SetPhase(PHASE_CLOSE); } else if (g_TeenDesc==d) { int buf_size = buffer_size(d->GetOutputBuffer()); int sock_buf_size = fdwatch_get_buffer_size(fdw, d->GetSocket()); int ret = d->ProcessOutput(); if (ret < 0) { d->SetPhase(PHASE_CLOSE); } if (buf_size) sys_log(0, "TEEN::Send(size %d sock_buf %d ret %d)", buf_size, sock_buf_size, ret); } break; case FDW_EOF: { d->SetPhase(PHASE_CLOSE); } break; default: sys_err("fdwatch_check_event returned unknown %d", iRet); d->SetPhase(PHASE_CLOSE); break; } } return 1; }