mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-11 15:22:26 +00:00
Send packet uncompressed if zlib deflates to a larger size than input
It's not guaranteed that deflate output will be smaller than the input. In some cases zlib-ng (Z_BEST_SPEED) compression is causing packets to increase in size and exceed m_max_packet_size. This results in the packets never being fully received by the client. Currently this is most reproducible in the spell_book section of the OP_PlayerProfile message. After using #scribespells this portion of the player profile has a lot of incrementing spellids which may be affecting the compression algorithm. The client never processes the player profile (MSG_SEND_PC) message and times out on zone entry. This isn't necessarily a bug with zlib-ng since it inflates back to the original input and normal zlib could do this too, but the current netcode doesn't handle this.
This commit is contained in:
parent
952fd43301
commit
ed09d4ae54
@ -1047,12 +1047,14 @@ void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t leng
|
|||||||
uint8_t new_buffer[2048] = { 0 };
|
uint8_t new_buffer[2048] = { 0 };
|
||||||
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
||||||
uint32_t new_length = 0;
|
uint32_t new_length = 0;
|
||||||
|
bool send_uncompressed = true;
|
||||||
|
|
||||||
if (length > 30) {
|
if (length > 30) {
|
||||||
new_length = Deflate(buffer, (uint32_t)length, new_buffer + 1, 2048) + 1;
|
new_length = Deflate(buffer, (uint32_t)length, new_buffer + 1, 2048) + 1;
|
||||||
new_buffer[0] = 0x5a;
|
new_buffer[0] = 0x5a;
|
||||||
|
send_uncompressed = (new_length > length);
|
||||||
}
|
}
|
||||||
else {
|
if (send_uncompressed) {
|
||||||
memcpy(new_buffer + 1, buffer, length);
|
memcpy(new_buffer + 1, buffer, length);
|
||||||
new_buffer[0] = 0xa5;
|
new_buffer[0] = 0xa5;
|
||||||
new_length = length + 1;
|
new_length = length + 1;
|
||||||
@ -1380,7 +1382,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto stream = &m_streams[stream_id];
|
auto stream = &m_streams[stream_id];
|
||||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size();
|
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size() - 1; // -1 for compress flag
|
||||||
size_t length = p.Length();
|
size_t length = p.Length();
|
||||||
if (length > max_raw_size) {
|
if (length > max_raw_size) {
|
||||||
DaybreakReliableFragmentHeader first_header;
|
DaybreakReliableFragmentHeader first_header;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user