diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 053339fafc..cbacc0f88e 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -49,6 +49,10 @@ static int32_t _pickup_peep_old_x = LOCATION_NULL; // with uint16_t and needs some spare room for other data in the packet. static constexpr uint32_t CHUNK_SIZE = 1024 * 63; +// If data is sent fast enough it would halt the entire server, process only a maximum amount. +// This limit is per connection, the current value was determined by tests with fuzzing. +static constexpr uint32_t MaxPacketsPerUpdate = 100; + # include "../Cheats.h" # include "../ParkImporter.h" # include "../Version.h" @@ -1654,8 +1658,11 @@ void NetworkBase::Server_Send_EVENT_PLAYER_DISCONNECTED(const char* playerName, bool NetworkBase::ProcessConnection(NetworkConnection& connection) { NetworkReadPacket packetStatus; + + uint32_t countProcessed = 0; do { + countProcessed++; packetStatus = connection.ReadPacket(); switch (packetStatus) { @@ -1681,7 +1688,7 @@ bool NetworkBase::ProcessConnection(NetworkConnection& connection) // could not read anything from socket break; } - } while (packetStatus == NetworkReadPacket::Success); + } while (packetStatus == NetworkReadPacket::Success && countProcessed < MaxPacketsPerUpdate); if (!connection.ReceivedPacketRecently()) { @@ -1698,13 +1705,21 @@ bool NetworkBase::ProcessConnection(NetworkConnection& connection) void NetworkBase::ProcessPacket(NetworkConnection& connection, NetworkPacket& packet) { const auto& handlerList = GetMode() == NETWORK_MODE_SERVER ? server_command_handlers : client_command_handlers; + auto it = handlerList.find(packet.GetCommand()); if (it != handlerList.end()) { auto commandHandler = it->second; if (connection.AuthStatus == NetworkAuth::Ok || !packet.CommandRequiresAuth()) { - (this->*commandHandler)(connection, packet); + try + { + (this->*commandHandler)(connection, packet); + } + catch (const std::exception& ex) + { + log_verbose("Exception during packet processing: %s", ex.what()); + } } }