Disable message rate limit during nick registration and capability
negotiation (Network::Initializing). Once network initialization
is complete (Network::Initialized), re-apply configured rate limits.
Helps fix connection timeouts during login on servers with SASL
enabled, multiple capabilities negotiated, and a strict 10s login
time.
Add flag 'forceUnlimited' to updateRateLimiting() which temporarily
overrides user preferences to skip all rate limiting. User
preferences can be applied afterwards by calling updateRateLimiting()
without setting 'forceUnlimited'.
Resolves GH-236.
socket.setSocketOption(QAbstractSocket::KeepAliveOption, true);
socket.setSocketOption(QAbstractSocket::KeepAliveOption, true);
- // Update the TokenBucket with specified rate-limiting settings
- updateRateLimiting();
+ // Update the TokenBucket, force-enabling unlimited message rates for initial registration and
+ // capability negotiation. networkInitialized() will call updateRateLimiting() without the
+ // force flag to apply user preferences. When making changes, ensure that this still happens!
+ // As Quassel waits for CAP ACK/NAK and AUTHENTICATE replies, this shouldn't ever fill the IRC
+ // server receive queue and cause a kill. "Shouldn't" being the operative word; the real world
+ // is a scary place.
+ updateRateLimiting(true);
// Fill up the token bucket as we're connecting from scratch
resetTokenBucket();
// Fill up the token bucket as we're connecting from scratch
resetTokenBucket();
_disconnectExpected = false;
_quitRequested = false;
_disconnectExpected = false;
_quitRequested = false;
+ // Update the TokenBucket with specified rate-limiting settings, removing the force-unlimited
+ // flag used for initial registration and capability negotiation.
+ updateRateLimiting();
+
if (useAutoReconnect()) {
// reset counter
_autoReconnectCount = unlimitedReconnectRetries() ? -1 : autoReconnectRetries();
if (useAutoReconnect()) {
// reset counter
_autoReconnectCount = unlimitedReconnectRetries() ? -1 : autoReconnectRetries();
/******** Custom Rate Limiting ********/
/******** Custom Rate Limiting ********/
-void CoreNetwork::updateRateLimiting()
+void CoreNetwork::updateRateLimiting(const bool forceUnlimited)
{
// Always reset the delay and token bucket (safe-guard against accidentally starting the timer)
{
// Always reset the delay and token bucket (safe-guard against accidentally starting the timer)
- if (useCustomMessageRate()) {
- // Custom message rates enabled. Let's go for it!
+ if (useCustomMessageRate() || forceUnlimited) {
+ // Custom message rates enabled, or chosen by means of forcing unlimited. Let's go for it!
_messageDelay = messageRateDelay();
_messageDelay = messageRateDelay();
// Toggle the timer according to whether or not rate limiting is enabled
// If we're here, useCustomMessageRate is true. Thus, the logic becomes
// Toggle the timer according to whether or not rate limiting is enabled
// If we're here, useCustomMessageRate is true. Thus, the logic becomes
- // _skipMessageRates = (useCustomMessageRate && unlimitedMessageRate)
- _skipMessageRates = unlimitedMessageRate();
+ // _skipMessageRates = (useCustomMessageRate && (unlimitedMessageRate || forceUnlimited))
+ // Override user preferences if called with force unlimited
+ _skipMessageRates = (unlimitedMessageRate() || forceUnlimited);
if (_skipMessageRates) {
// If the message queue already contains messages, they need sent before disabling the
// timer. Set the timer to a rapid pace and let it disable itself.
if (_skipMessageRates) {
// If the message queue already contains messages, they need sent before disabling the
// timer. Set the timer to a rapid pace and let it disable itself.
* @see Network::messageRateBurstSize()
* @see Network::messageRateDelay()
* @see Network::unlimitedMessageRate()
* @see Network::messageRateBurstSize()
* @see Network::messageRateDelay()
* @see Network::unlimitedMessageRate()
+ *
+ * @param[in] forceUnlimited
+ * @parmblock
+ * If true, override user settings to disable message rate limiting, otherwise apply rate limits
+ * set by the user. Use with caution and remember to re-enable configured limits when done.
+ * @endparmblock
- void updateRateLimiting();
+ void updateRateLimiting(const bool forceUnlimited = false);
/**
* Resets the token bucket up to the maximum
/**
* Resets the token bucket up to the maximum