From 7d0df9b6ddee8db69ea0a511f031f32a4537a749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 23 Aug 2018 15:21:12 +0200 Subject: Disable the throttle limit if negative Also, invalid values result in -1 being set --- doc/biboumi.1.rst | 2 +- src/database/database.hpp | 4 ++-- src/irc/irc_client.cpp | 2 +- src/irc/irc_client.hpp | 2 +- src/utils/tokens_bucket.hpp | 12 ++++++++---- src/xmpp/biboumi_adhoc_commands.cpp | 6 +++++- tests/end_to_end/__main__.py | 5 +++++ 7 files changed, 23 insertions(+), 10 deletions(-) diff --git a/doc/biboumi.1.rst b/doc/biboumi.1.rst index 06d2d80..4508f7b 100644 --- a/doc/biboumi.1.rst +++ b/doc/biboumi.1.rst @@ -691,7 +691,7 @@ On a server JID (e.g on the JID chat.freenode.org@biboumi.example.com) are throttled, only one command per second is sent to the server. The default is 10. You can lower this value if you are ever kicked for excess flood. If the value is 0, all messages are throttled. To - disable this feature, just set a high value, like 999. + disable this feature, set it to a negative number, or an empty string. - get-irc-connection-info: Returns some information about the IRC server, for the executing user. It lets the user know if they are connected to diff --git a/src/database/database.hpp b/src/database/database.hpp index 5fabadd..4a413be 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -86,8 +86,8 @@ class Database struct Address: Column { static constexpr auto name = "address_"; }; - struct ThrottleLimit: Column { static constexpr auto name = "throttlelimit_"; - ThrottleLimit(): Column(10) {} }; + struct ThrottleLimit: Column { static constexpr auto name = "throttlelimit_"; + ThrottleLimit(): Column(10) {} }; using MucLogLineTable = Table; using MucLogLine = MucLogLineTable::RowType; diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 78d0fbf..2835a33 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -1291,7 +1291,7 @@ bool IrcClient::abort_on_invalid_cert() const } #endif -std::size_t IrcClient::get_throttle_limit() const +long int IrcClient::get_throttle_limit() const { #ifdef USE_DATABASE return Database::get_irc_server_options(this->bridge.get_bare_jid(), this->hostname).col(); diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index aa314f8..1653225 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -402,7 +402,7 @@ private: */ Resolver dns_resolver; TokensBucket tokens_bucket; - std::size_t get_throttle_limit() const; + long int get_throttle_limit() const; }; diff --git a/src/utils/tokens_bucket.hpp b/src/utils/tokens_bucket.hpp index 03af015..2992e21 100644 --- a/src/utils/tokens_bucket.hpp +++ b/src/utils/tokens_bucket.hpp @@ -17,7 +17,7 @@ class TokensBucket { public: - TokensBucket(std::size_t max_size, std::chrono::milliseconds fill_duration, std::function callback, std::string name): + TokensBucket(long int max_size, std::chrono::milliseconds fill_duration, std::function callback, std::string name): limit(max_size), tokens(limit), callback(std::move(callback)) @@ -29,6 +29,8 @@ public: bool use_token() { + if (this->limit < 0) + return true; if (this->tokens > 0) { this->tokens--; @@ -38,19 +40,21 @@ public: return false; } - void set_limit(std::size_t limit) + void set_limit(long int limit) { this->limit = limit; } private: - std::size_t limit; + long int limit; std::size_t tokens; std::function callback; void add_token() { - if (this->callback() && this->tokens != limit) + if (this->limit < 0) + return; + if (this->callback() && this->tokens != static_casttokens)>(this->limit)) this->tokens++; } }; diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index 45557aa..7c31f36 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -494,7 +494,11 @@ void ConfigureIrcServerStep2(XmppComponent& xmpp_component, AdhocSession& sessio else if (field->get_tag("var") == "throttle_limit" && value) { - options.col() = std::stoul(value->get_inner()); + try { + options.col() = std::stol(value->get_inner()); + } catch (const std::logic_error&) { + options.col() = -1; + } Bridge* bridge = biboumi_component.find_user_bridge(session.get_owner_jid()); if (bridge) { diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 6e254b0..24bc492 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -2973,6 +2973,7 @@ if __name__ == '__main__': "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6697']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='verify_cert']/dataform:value[text()='true']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='fingerprint']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='throttle_limit']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-private'][@var='pass']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='after_connect_commands']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='nick']", @@ -2995,6 +2996,7 @@ if __name__ == '__main__': "first commandsecond command" "my_nickname" "username" + "42" "realname" "UTF-8" "latin-1" @@ -3016,6 +3018,7 @@ if __name__ == '__main__': "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='after_connect_commands']/dataform:value[text()='second command']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='username']/dataform:value[text()='username']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='realname']/dataform:value[text()='realname']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='throttle_limit']/dataform:value[text()='42']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']/dataform:value[text()='latin-1']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='UTF-8']", "/iq/commands:command/commands:actions/commands:next", @@ -3037,6 +3040,7 @@ if __name__ == '__main__': "" "" "" + "" "" "" ""), @@ -3054,6 +3058,7 @@ if __name__ == '__main__': "!/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='encoding_in']/dataform:value", "!/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='encoding_out']/dataform:value", "/iq/commands:command/commands:actions/commands:next", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='throttle_limit']/dataform:value[text()='-1']", # An invalid value sets this field to -1, aka disabled ), after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid")) ), -- cgit v1.2.3