mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 13:30:06 +00:00
Do not dynamically allocate memory in CNSocket::sendPacket()
Also reorder the rapid fire check in MobManager::pcAttackNpcs(), so the output packet validation happens immediately before the buffer is initialized, for clarity.
This commit is contained in:
parent
29dbe83a0b
commit
da8dde9818
@ -118,42 +118,39 @@ void CNSocket::kill() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't own buf, TODO: queue packets up to send in step()
|
|
||||||
void CNSocket::sendPacket(void* buf, uint32_t type, size_t size) {
|
void CNSocket::sendPacket(void* buf, uint32_t type, size_t size) {
|
||||||
if (!alive)
|
if (!alive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
size_t bodysize = size + sizeof(uint32_t);
|
uint8_t fullpkt[CN_PACKET_BUFFER_SIZE]; // length, type, body
|
||||||
uint8_t* fullpkt = (uint8_t*)xmalloc(bodysize+4);
|
uint8_t* body = fullpkt + 4; // packet without length (type, body)
|
||||||
uint8_t* body = fullpkt+4;
|
size_t bodysize = size + 4;
|
||||||
|
|
||||||
|
// set packet length
|
||||||
memcpy(fullpkt, (void*)&bodysize, 4);
|
memcpy(fullpkt, (void*)&bodysize, 4);
|
||||||
|
|
||||||
// copy packet type to the front of the buffer & then the actual buffer
|
// copy packet type to the front of the buffer & then the actual buffer
|
||||||
memcpy(body, (void*)&type, sizeof(uint32_t));
|
memcpy(body, (void*)&type, 4);
|
||||||
memcpy(body+sizeof(uint32_t), buf, size);
|
memcpy(body+4, buf, size);
|
||||||
|
|
||||||
// encrypt the packet
|
// encrypt the packet
|
||||||
switch (activeKey) {
|
switch (activeKey) {
|
||||||
case SOCKETKEY_E:
|
case SOCKETKEY_E:
|
||||||
CNSocketEncryption::encryptData((uint8_t*)body, (uint8_t*)(&EKey), bodysize);
|
CNSocketEncryption::encryptData((uint8_t*)body, (uint8_t*)(&EKey), bodysize);
|
||||||
break;
|
break;
|
||||||
case SOCKETKEY_FE:
|
case SOCKETKEY_FE:
|
||||||
CNSocketEncryption::encryptData((uint8_t*)body, (uint8_t*)(&FEKey), bodysize);
|
CNSocketEncryption::encryptData((uint8_t*)body, (uint8_t*)(&FEKey), bodysize);
|
||||||
break;
|
break;
|
||||||
default: {
|
default:
|
||||||
free(fullpkt);
|
DEBUGLOG(
|
||||||
DEBUGLOG(
|
std::cout << "[WARN]: UNSET KEYTYPE FOR SOCKET!! ABORTING SEND" << std::endl;
|
||||||
std::cout << "[WARN]: UNSET KEYTYPE FOR SOCKET!! ABORTING SEND" << std::endl;
|
)
|
||||||
)
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// send packet data!
|
// send packet data!
|
||||||
if (alive && !sendData(fullpkt, bodysize+4))
|
if (alive && !sendData(fullpkt, bodysize+4))
|
||||||
kill();
|
kill();
|
||||||
|
|
||||||
free(fullpkt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNSocket::setActiveKey(ACTIVEKEY key) {
|
void CNSocket::setActiveKey(ACTIVEKEY key) {
|
||||||
|
@ -52,16 +52,6 @@ void MobManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) {
|
|||||||
|
|
||||||
int32_t *pktdata = (int32_t*)((uint8_t*)data->buf + sizeof(sP_CL2FE_REQ_PC_ATTACK_NPCs));
|
int32_t *pktdata = (int32_t*)((uint8_t*)data->buf + sizeof(sP_CL2FE_REQ_PC_ATTACK_NPCs));
|
||||||
|
|
||||||
/*
|
|
||||||
* Due to the possibility of multiplication overflow (and regular buffer overflow),
|
|
||||||
* both incoming and outgoing variable-length packets must be validated, at least if
|
|
||||||
* the number of trailing structs isn't well known (ie. it's from the client).
|
|
||||||
*/
|
|
||||||
if (!validOutVarPacket(sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC), pkt->iNPCCnt, sizeof(sAttackResult))) {
|
|
||||||
std::cout << "[WARN] bad sP_FE2CL_PC_ATTACK_NPCs_SUCC packet size\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rapid fire anti-cheat
|
// rapid fire anti-cheat
|
||||||
time_t currTime = getTime();
|
time_t currTime = getTime();
|
||||||
if (currTime - plr->lastShot < plr->fireRate * 80)
|
if (currTime - plr->lastShot < plr->fireRate * 80)
|
||||||
@ -77,6 +67,16 @@ void MobManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) {
|
|||||||
if (plr->suspicionRating > 10000) // kill the socket when the player is too suspicious
|
if (plr->suspicionRating > 10000) // kill the socket when the player is too suspicious
|
||||||
sock->kill();
|
sock->kill();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Due to the possibility of multiplication overflow (and regular buffer overflow),
|
||||||
|
* both incoming and outgoing variable-length packets must be validated, at least if
|
||||||
|
* the number of trailing structs isn't well known (ie. it's from the client).
|
||||||
|
*/
|
||||||
|
if (!validOutVarPacket(sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC), pkt->iNPCCnt, sizeof(sAttackResult))) {
|
||||||
|
std::cout << "[WARN] bad sP_FE2CL_PC_ATTACK_NPCs_SUCC packet size\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// initialize response struct
|
// initialize response struct
|
||||||
size_t resplen = sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC) + pkt->iNPCCnt * sizeof(sAttackResult);
|
size_t resplen = sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC) + pkt->iNPCCnt * sizeof(sAttackResult);
|
||||||
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
||||||
|
Loading…
Reference in New Issue
Block a user