From 1578c7cf6fbd56ba6149e70a33e56a0091680da9 Mon Sep 17 00:00:00 2001 From: Hartmnt Date: Fri, 10 Jan 2025 19:23:41 +0000 Subject: [PATCH] FEAT(server): Add setting for rolling packet stats time window This commit adds a new option to mumble_server.ini which allows the server operator to specify the time window in which rolling packet stats are collected for each client. --- auxiliary_files/mumble-server.ini | 6 ++++++ src/crypto/CryptState.cpp | 4 ++++ src/crypto/CryptState.h | 1 + src/murmur/Meta.cpp | 4 ++++ src/murmur/Meta.h | 3 +++ src/murmur/Server.cpp | 13 +++++++++++++ src/murmur/Server.h | 1 + 7 files changed, 32 insertions(+) diff --git a/auxiliary_files/mumble-server.ini b/auxiliary_files/mumble-server.ini index c7d0dbc0610..8ea2af0d9a2 100644 --- a/auxiliary_files/mumble-server.ini +++ b/auxiliary_files/mumble-server.ini @@ -396,6 +396,12 @@ allowping=true ; ; allowRecording=true +; The time frame in seconds the server will keep rolling packet stats for each client. +; The default is 5 minutes = 300 seconds. Minimum window is 10 seconds. Set to 0 to +; disable rolling packet stats. This option has been introduced with 1.6.0 +; +; rollingStatsWindow=300 + ; The amount of allowed listener proxies in a single channel. It defaults to -1 ; meaning that there is no limit. Set to 0 to disable Channel Listeners altogether. ; This option has been introduced with 1.4.0. diff --git a/src/crypto/CryptState.cpp b/src/crypto/CryptState.cpp index c30bed5936a..82f9756b3cd 100644 --- a/src/crypto/CryptState.cpp +++ b/src/crypto/CryptState.cpp @@ -6,6 +6,10 @@ #include "CryptState.h" void CryptState::updateRollingStats() { + if (!m_rollingStatsEnabled) { + return; + } + std::chrono::time_point< std::chrono::steady_clock > now = std::chrono::steady_clock::now(); // Update no more than every few seconds diff --git a/src/crypto/CryptState.h b/src/crypto/CryptState.h index 17f1c14bb04..fd27c524c61 100644 --- a/src/crypto/CryptState.h +++ b/src/crypto/CryptState.h @@ -42,6 +42,7 @@ class CryptState { PacketStats m_statsLocalRolling = {}; PacketStats m_statsRemoteRolling = {}; + bool m_rollingStatsEnabled = false; /// This is the packet statistics sliding time window size in seconds std::chrono::duriation< unsigned int, std::ratio< 1 > > m_rollingWindow = std::chrono::minutes(5); diff --git a/src/murmur/Meta.cpp b/src/murmur/Meta.cpp index ef750b54734..29eaec97d8b 100644 --- a/src/murmur/Meta.cpp +++ b/src/murmur/Meta.cpp @@ -112,6 +112,8 @@ MetaParams::MetaParams() { allowRecording = true; + rollingStatsWindow = 300; + qsSettings = nullptr; } @@ -329,6 +331,8 @@ void MetaParams::read(QString fname) { allowRecording = typeCheckedFromSettings("allowRecording", allowRecording); + rollingStatsWindow = typeCheckedFromSettings("rollingStatsWindow", rollingStatsWindow); + iOpusThreshold = typeCheckedFromSettings("opusthreshold", iOpusThreshold); iChannelNestingLimit = typeCheckedFromSettings("channelnestinglimit", iChannelNestingLimit); diff --git a/src/murmur/Meta.h b/src/murmur/Meta.h index 4a151506e74..4cf47dbe096 100644 --- a/src/murmur/Meta.h +++ b/src/murmur/Meta.h @@ -151,6 +151,9 @@ class MetaParams { /// A flag indicating whether recording is allowed on this server bool allowRecording; + /// The number of seconds to keep rolling stats for per client + unsigned int rollingStatsWindow; + /// qsAbsSettingsFilePath is the absolute path to /// the murmur.ini used by this Meta instance. QString qsAbsSettingsFilePath; diff --git a/src/murmur/Server.cpp b/src/murmur/Server.cpp index 17800b3c667..af7d8f6b14a 100644 --- a/src/murmur/Server.cpp +++ b/src/murmur/Server.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #ifdef Q_OS_WIN @@ -346,6 +347,7 @@ void Server::readParams() { bBonjour = Meta::mp.bBonjour; bAllowPing = Meta::mp.bAllowPing; allowRecording = Meta::mp.allowRecording; + rollingStatsWindow = Meta::mp.rollingStatsWindow; bCertRequired = Meta::mp.bCertRequired; bForceExternalAuth = Meta::mp.bForceExternalAuth; qrUserName = Meta::mp.qrUserName; @@ -445,6 +447,7 @@ void Server::readParams() { iChannelNestingLimit = getConf("channelnestinglimit", iChannelNestingLimit).toInt(); iChannelCountLimit = getConf("channelcountlimit", iChannelCountLimit).toInt(); + rollingStatsWindow = getConf("rollingStatsWindow", rollingStatsWindow).toUInt(); qrUserName = decltype(qrUserName)(QRegularExpression::anchoredPattern(getConf("username", qrUserName.pattern()).toString())); @@ -577,6 +580,8 @@ void Server::setLiveConf(const QString &key, const QString &value) { bAllowPing = !v.isNull() ? QVariant(v).toBool() : Meta::mp.bAllowPing; else if (key == "allowrecording") allowRecording = !v.isNull() ? QVariant(v).toBool() : Meta::mp.allowRecording; + else if (key == "rollingStatsWindow") + rollingStatsWindow = i ? static_cast< unsigned int >(i) : Meta::mp.rollingStatsWindow; else if (key == "username") qrUserName = !v.isNull() ? QRegularExpression(v) : Meta::mp.qrUserName; else if (key == "channelname") @@ -1437,6 +1442,14 @@ void Server::newClient() { u->haAddress = ha; HostAddress(sock->localAddress()).toSockaddr(&u->saiTcpLocalAddress); + if (rollingStatsWindow >= 10) { + // Note: We use a minimum rolling window of 10 seconds. + // Anything lower would be pretty meaningless anyway and + // probably increase server load significantly. + u->csCrypt->m_rollingStatsEnabled = true; + u->csCrypt->m_rollingWindow = std::chrono::seconds(rollingStatsWindow); + } + connect(u, &ServerUser::connectionClosed, this, &Server::connectionClosed); connect(u, SIGNAL(message(Mumble::Protocol::TCPMessageType, const QByteArray &)), this, SLOT(message(Mumble::Protocol::TCPMessageType, const QByteArray &))); diff --git a/src/murmur/Server.h b/src/murmur/Server.h index e55e6a8d497..031e0fa33be 100644 --- a/src/murmur/Server.h +++ b/src/murmur/Server.h @@ -137,6 +137,7 @@ class Server : public QThread { bool bBonjour; bool bAllowPing; bool allowRecording; + unsigned int rollingStatsWindow; QRegularExpression qrUserName; QRegularExpression qrChannelName;