chat flood protection (yet untested)

This commit is contained in:
Max-Wilhelm Bruker 2011-03-02 19:39:38 +01:00
parent 3bb1d9a1de
commit 6145d6d524
8 changed files with 49 additions and 1 deletions

View file

@ -268,6 +268,7 @@ void ProtocolResponse::initializeHash()
responseHash.insert("user_level_too_low", RespUserLevelTooLow); responseHash.insert("user_level_too_low", RespUserLevelTooLow);
responseHash.insert("in_ignore_list", RespInIgnoreList); responseHash.insert("in_ignore_list", RespInIgnoreList);
responseHash.insert("would_overwrite_old_session", RespWouldOverwriteOldSession); responseHash.insert("would_overwrite_old_session", RespWouldOverwriteOldSession);
responseHash.insert("chat_flood", RespChatFlood);
} }
Response_JoinRoom::Response_JoinRoom(int _cmdId, ResponseCode _responseCode, ServerInfo_Room *_roomInfo) Response_JoinRoom::Response_JoinRoom(int _cmdId, ResponseCode _responseCode, ServerInfo_Room *_roomInfo)

View file

@ -8,7 +8,7 @@
class DeckList; class DeckList;
enum ResponseCode { RespNothing, RespOk, RespInternalError, RespInvalidCommand, RespInvalidData, RespNameNotFound, RespLoginNeeded, RespFunctionNotAllowed, RespGameNotStarted, RespGameFull, RespContextError, RespWrongPassword, RespSpectatorsNotAllowed, RespOnlyBuddies, RespUserLevelTooLow, RespInIgnoreList, RespWouldOverwriteOldSession }; enum ResponseCode { RespNothing, RespOk, RespInternalError, RespInvalidCommand, RespInvalidData, RespNameNotFound, RespLoginNeeded, RespFunctionNotAllowed, RespGameNotStarted, RespGameFull, RespContextError, RespWrongPassword, RespSpectatorsNotAllowed, RespOnlyBuddies, RespUserLevelTooLow, RespInIgnoreList, RespWouldOverwriteOldSession, RespChatFlood };
// PrivateZone: Contents of the zone are always visible to the owner, // PrivateZone: Contents of the zone are always visible to the owner,
// but not to anyone else. // but not to anyone else.

View file

@ -38,6 +38,9 @@ public:
virtual bool getGameShouldPing() const = 0; virtual bool getGameShouldPing() const = 0;
virtual int getMaxGameInactivityTime() const = 0; virtual int getMaxGameInactivityTime() const = 0;
virtual int getMaxPlayerInactivityTime() const = 0; virtual int getMaxPlayerInactivityTime() const = 0;
virtual int getMessageCountingInterval() const { return 0; }
virtual int getMaxMessageCountPerInterval() const { return 0; }
virtual int getMaxMessageSizePerInterval() const { return 0; }
virtual QMap<QString, ServerInfo_User *> getBuddyList(const QString &name) = 0; virtual QMap<QString, ServerInfo_User *> getBuddyList(const QString &name) = 0;
virtual QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name) = 0; virtual QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name) = 0;

View file

@ -208,6 +208,16 @@ void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont)
void Server_ProtocolHandler::pingClockTimeout() void Server_ProtocolHandler::pingClockTimeout()
{ {
int interval = server->getMessageCountingInterval();
if (interval > 0) {
messageSizeOverTime.prepend(0);
if (messageSizeOverTime.size() > server->getMessageCountingInterval())
messageSizeOverTime.removeLast();
messageCountOverTime.prepend(0);
if (messageCountOverTime.size() > server->getMessageCountingInterval())
messageCountOverTime.removeLast();
}
if (lastCommandTime.secsTo(QDateTime::currentDateTime()) > server->getMaxPlayerInactivityTime()) if (lastCommandTime.secsTo(QDateTime::currentDateTime()) > server->getMaxPlayerInactivityTime())
deleteLater(); deleteLater();
} }
@ -355,6 +365,26 @@ ResponseCode Server_ProtocolHandler::cmdLeaveRoom(Command_LeaveRoom * /*cmd*/, C
ResponseCode Server_ProtocolHandler::cmdRoomSay(Command_RoomSay *cmd, CommandContainer * /*cont*/, Server_Room *room) ResponseCode Server_ProtocolHandler::cmdRoomSay(Command_RoomSay *cmd, CommandContainer * /*cont*/, Server_Room *room)
{ {
QString msg = cmd->getMessage();
if (server->getMessageCountingInterval() > 0) {
int totalSize = 0, totalCount = 0;
if (messageSizeOverTime.isEmpty())
messageSizeOverTime.prepend(0);
messageSizeOverTime[0] += msg.size();
for (int i = 0; i < messageSizeOverTime.size(); ++i)
totalSize += messageSizeOverTime[i];
if (messageCountOverTime.isEmpty())
messageCountOverTime.prepend(0);
++messageCountOverTime[0];
for (int i = 0; i < messageCountOverTime.size(); ++i)
totalCount += messageCountOverTime[i];
if ((totalSize > server->getMaxMessageSizePerInterval()) || (totalCount > server->getMaxMessageCountPerInterval()))
return RespChatFlood;
}
room->say(this, cmd->getMessage()); room->say(this, cmd->getMessage());
return RespOk; return RespOk;
} }

View file

@ -30,6 +30,7 @@ protected:
QMap<QString, ServerInfo_User *> buddyList, ignoreList; QMap<QString, ServerInfo_User *> buddyList, ignoreList;
private: private:
QList<ProtocolItem *> itemQueue; QList<ProtocolItem *> itemQueue;
QList<int> messageSizeOverTime, messageCountOverTime;
QDateTime lastCommandTime; QDateTime lastCommandTime;
QTimer *pingClock; QTimer *pingClock;

View file

@ -27,3 +27,8 @@ size=1
[game] [game]
max_game_inactivity_time=120 max_game_inactivity_time=120
max_player_inactivity_time=15 max_player_inactivity_time=15
[security]
message_counting_interval=10
max_message_size_per_interval=1000
max_message_count_per_interval=10

View file

@ -84,6 +84,10 @@ Servatrice::Servatrice(QObject *parent)
maxGameInactivityTime = settings->value("game/max_game_inactivity_time").toInt(); maxGameInactivityTime = settings->value("game/max_game_inactivity_time").toInt();
maxPlayerInactivityTime = settings->value("game/max_player_inactivity_time").toInt(); maxPlayerInactivityTime = settings->value("game/max_player_inactivity_time").toInt();
messageCountingInterval = settings->value("security/message_counting_interval").toInt();
maxMessageCountPerInterval = settings->value("security/max_message_count_per_interval").toInt();
maxMessageSizePerInterval = settings->value("security/max_message_size_per_interval").toInt();
} }
Servatrice::~Servatrice() Servatrice::~Servatrice()

View file

@ -45,6 +45,9 @@ public:
bool getGameShouldPing() const { return true; } bool getGameShouldPing() const { return true; }
int getMaxGameInactivityTime() const { return maxGameInactivityTime; } int getMaxGameInactivityTime() const { return maxGameInactivityTime; }
int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; } int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; }
int getMessageCountingInterval() const { return messageCountingInterval; }
int getMaxMessageCountPerInterval() const { return maxMessageCountPerInterval; }
int getMaxMessageSizePerInterval() const { return maxMessageSizePerInterval; }
QString getDbPrefix() const { return dbPrefix; } QString getDbPrefix() const { return dbPrefix; }
void updateLoginMessage(); void updateLoginMessage();
ServerInfo_User *getUserData(const QString &name); ServerInfo_User *getUserData(const QString &name);
@ -62,6 +65,7 @@ private:
int uptime; int uptime;
int maxGameInactivityTime; int maxGameInactivityTime;
int maxPlayerInactivityTime; int maxPlayerInactivityTime;
int messageCountingInterval, maxMessageCountPerInterval, maxMessageSizePerInterval;
ServerInfo_User *evalUserQueryResult(const QSqlQuery &query, bool complete); ServerInfo_User *evalUserQueryResult(const QSqlQuery &query, bool complete);
}; };