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();
_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();
/******** 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)
+ // Verify and apply custom rate limiting options, always resetting the delay and burst size
+ // (safe-guarding against accidentally starting the timer), but don't reset the token bucket as
+ // this may be called while connected to a server.
- 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();
}
// 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();
+ // If we're here, either useCustomMessageRate or forceUnlimited is true. Thus, the logic is
+ // _skipMessageRates = ((useCustomMessageRate && unlimitedMessageRate) || forceUnlimited)
+ // Override user preferences if called with force unlimited, only used during connect.
+ _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.
} else {
// Custom message rates disabled. Go for the default.
- _skipMessageRates = false; // Enable rate-limiting by default
- // TokenBucket to avoid sending too much at once
- _messageDelay = 2200; // This seems to be a safe value (2.2 seconds delay)
- _burstSize = 5; // 5 messages at once
+ _skipMessageRates = false; // Enable rate-limiting by default
+ _messageDelay = 2200; // This seems to be a safe value (2.2 seconds delay)
+ _burstSize = 5; // 5 messages at once
if (_tokenBucket > _burstSize) {
- // Don't let the token bucket exceed the maximum
+ // TokenBucket to avoid sending too much at once. Don't let the token bucket exceed the
+ // maximum.
_tokenBucket = _burstSize;
// To fill up the token bucket, use resetRateLimiting(). Don't do that here, otherwise
// changing the rate-limit settings while connected to a server will incorrectly reset