Skip to content
Permalink
Browse files

Merge PR #3517: Make Rate limiter configurable

  • Loading branch information...
davidebeatrici committed Sep 8, 2018
2 parents f7221c1 + 73a0b2f commit b44b1f2172a8fa489697cd78d2cc92254c968283
Showing with 49 additions and 3 deletions.
  1. +12 −0 scripts/murmur.ini
  2. +6 −0 src/murmur/Meta.cpp
  3. +3 −0 src/murmur/Meta.h
  4. +22 −0 src/murmur/Server.cpp
  5. +3 −0 src/murmur/Server.h
  6. +2 −2 src/murmur/ServerUser.cpp
  7. +1 −1 src/murmur/ServerUser.h
@@ -136,6 +136,18 @@ bandwidth=72000
; Maximum number of concurrent clients allowed.
users=100

; Per-user rate limiting
;
; These two settings allow to configure the per-user rate limiter for some
; command messages sent from the client to the server. The messageburst setting
; specifies an amount of messages which are allowed in short bursts. The
; messagelimit setting specifies the number of messages per second allowed over
; a longer period. If a user hits the rate limit, his packages are then ignored
; for some time. Both of these settings have a minimum of 1 as setting either to
; 0 could render the server unusable.
messageburst=5
messagelimit=1

; Respond to UDP ping packets.
;
; Setting to true exposes the current user count, the maximum user count, and
@@ -74,6 +74,9 @@ MetaParams::MetaParams() {
qrUserName = QRegExp(QLatin1String("[-=\\w\\[\\]\\{\\}\\(\\)\\@\\|\\.]+"));
qrChannelName = QRegExp(QLatin1String("[ \\-=\\w\\#\\[\\]\\{\\}\\(\\)\\@\\|]+"));

iMessageLimit = 1;
iMessageBurst = 5;

qsCiphers = MumbleSSL::defaultOpenSSLCipherString();

qsSettings = NULL;
@@ -369,6 +372,9 @@ void MetaParams::read(QString fname) {
qrUserName = QRegExp(typeCheckedFromSettings("username", qrUserName.pattern()));
qrChannelName = QRegExp(typeCheckedFromSettings("channelname", qrChannelName.pattern()));

iMessageLimit = typeCheckedFromSettings("messagelimit", 1);
iMessageBurst = typeCheckedFromSettings("messageburst", 5);

bool bObfuscate = typeCheckedFromSettings("obfuscate", false);
if (bObfuscate) {
qWarning("IP address obfuscation enabled.");
@@ -94,6 +94,9 @@ class MetaParams {
QRegExp qrUserName;
QRegExp qrChannelName;

unsigned int iMessageLimit;
unsigned int iMessageBurst;

QSslCertificate qscCert;
QSslKey qskKey;

@@ -392,6 +392,8 @@ void Server::readParams() {
bForceExternalAuth = Meta::mp.bForceExternalAuth;
qrUserName = Meta::mp.qrUserName;
qrChannelName = Meta::mp.qrChannelName;
iMessageLimit = Meta::mp.iMessageLimit;
iMessageBurst = Meta::mp.iMessageBurst;
qvSuggestVersion = Meta::mp.qvSuggestVersion;
qvSuggestPositional = Meta::mp.qvSuggestPositional;
qvSuggestPushToTalk = Meta::mp.qvSuggestPushToTalk;
@@ -468,6 +470,15 @@ void Server::readParams() {

qrUserName=QRegExp(getConf("username", qrUserName.pattern()).toString());
qrChannelName=QRegExp(getConf("channelname", qrChannelName.pattern()).toString());

iMessageLimit=getConf("messagelimit", iMessageLimit).toUInt();
if (iMessageLimit < 1) { // Prevent disabling messages entirely
iMessageLimit = 1;
}
iMessageBurst=getConf("messageburst", iMessageBurst).toUInt();
if (iMessageBurst < 1) { // Prevent disabling messages entirely
iMessageBurst = 1;
}
}

void Server::setLiveConf(const QString &key, const QString &value) {
@@ -586,6 +597,17 @@ void Server::setLiveConf(const QString &key, const QString &value) {
iChannelNestingLimit = (i >= 0 && !v.isNull()) ? i : Meta::mp.iChannelNestingLimit;
else if (key == "channelcountlimit")
iChannelCountLimit = (i >= 0 && !v.isNull()) ? i : Meta::mp.iChannelCountLimit;
else if (key == "messagelimit") {
iMessageLimit = (!v.isNull()) ? v.toUInt() : Meta::mp.iMessageLimit;
if (iMessageLimit < 1) {
iMessageLimit = 1;
}
} else if (key == "messageburst") {
iMessageBurst = (!v.isNull()) ? v.toUInt() : Meta::mp.iMessageBurst;
if (iMessageBurst < 1) {
iMessageBurst = 1;
}
}
}

#ifdef USE_BONJOUR
@@ -128,6 +128,9 @@ class Server : public QThread {
QRegExp qrUserName;
QRegExp qrChannelName;

unsigned int iMessageLimit;
unsigned int iMessageBurst;

QVariant qvSuggestVersion;
QVariant qvSuggestPositional;
QVariant qvSuggestPushToTalk;
@@ -9,7 +9,7 @@
#include "ServerUser.h"
#include "Meta.h"

ServerUser::ServerUser(Server *p, QSslSocket *socket) : Connection(p, socket), User(), s(NULL) {
ServerUser::ServerUser(Server *p, QSslSocket *socket) : Connection(p, socket), User(), s(NULL), leakyBucket(p->iMessageLimit, p->iMessageBurst) {
sState = ServerUser::Connected;
sUdpSocket = INVALID_SOCKET;

@@ -139,7 +139,7 @@ unsigned long millisecondsBetween(time_point start, time_point end) {
#endif

// Rate limiting: burst up to 5, 1 message per sec limit over longer time
LeakyBucket::LeakyBucket() : tokensPerSec(1), maxTokens(5), currentTokens(0) {
LeakyBucket::LeakyBucket(unsigned int tokensPerSec, unsigned int maxTokens) : tokensPerSec(tokensPerSec), maxTokens(maxTokens), currentTokens(0) {
lastUpdate = now();
}

@@ -79,7 +79,7 @@ class LeakyBucket {
// Returns true if packets should be dropped
bool ratelimit(int tokens);

LeakyBucket();
LeakyBucket(unsigned int tokensPerSec, unsigned int maxTokens);
};

class ServerUser : public Connection, public User {

0 comments on commit b44b1f2

Please sign in to comment.
You can’t perform that action at this time.