X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcore%2Fcorenetwork.cpp;h=3ad9d7cb1982ffb5c2cc6836fa431444e4b605b0;hb=fdf6853d42bbd3279d5bc85df9006145382b0ea6;hp=6f2c285f71d0df01d3dd5f952eb25417c570b408;hpb=7d30b18136eecbdf2089e5d5877c7e41c6f4bcb6;p=quassel.git diff --git a/src/core/corenetwork.cpp b/src/core/corenetwork.cpp index 6f2c285f..3ad9d7cb 100644 --- a/src/core/corenetwork.cpp +++ b/src/core/corenetwork.cpp @@ -214,12 +214,16 @@ void CoreNetwork::connectToIrc(bool reconnecting) } else if (_previousConnectionAttemptFailed) { // cycle to next server if previous connection attempt failed + _previousConnectionAttemptFailed = false; displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Connection failed. Cycling to next Server")); if (++_lastUsedServerIndex >= serverList().size()) { _lastUsedServerIndex = 0; } } - _previousConnectionAttemptFailed = false; + else { + // Start out with the top server in the list + _lastUsedServerIndex = 0; + } Server server = usedServer(); displayStatusMsg(tr("Connecting to %1:%2...").arg(server.host).arg(server.port)); @@ -542,8 +546,13 @@ void CoreNetwork::socketInitialized() 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(); @@ -640,6 +649,10 @@ void CoreNetwork::networkInitialized() _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(); @@ -647,8 +660,11 @@ void CoreNetwork::networkInitialized() // restore away state QString awayMsg = Core::awayMessage(userId(), networkId()); - if (!awayMsg.isEmpty()) - userInputHandler()->handleAway(BufferInfo(), Core::awayMessage(userId(), networkId())); + if (!awayMsg.isEmpty()) { + // Don't re-apply any timestamp formatting in order to preserve escaped percent signs, e.g. + // '%%%%%%%%' -> '%%%%' If processed again, it'd result in '%%'. + userInputHandler()->handleAway(BufferInfo(), awayMsg, true); + } sendPerform(); @@ -931,12 +947,14 @@ void CoreNetwork::setPingInterval(int interval) /******** 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(); @@ -957,9 +975,10 @@ void CoreNetwork::updateRateLimiting() } // 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. @@ -984,12 +1003,12 @@ void CoreNetwork::updateRateLimiting() } 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 @@ -1041,7 +1060,7 @@ void CoreNetwork::serverCapAcknowledged(const QString &capability) // FIXME use event #ifdef HAVE_SSL if (!identityPtr()->sslCert().isNull()) { - if (IrcCap::SaslMech::maybeSupported(capValue(IrcCap::SASL), IrcCap::SaslMech::EXTERNAL)) { + if (saslMaybeSupports(IrcCap::SaslMech::EXTERNAL)) { // EXTERNAL authentication supported, send request putRawLine(serverEncode("AUTHENTICATE EXTERNAL")); } else { @@ -1051,7 +1070,7 @@ void CoreNetwork::serverCapAcknowledged(const QString &capability) } } else { #endif - if (IrcCap::SaslMech::maybeSupported(capValue(IrcCap::SASL), IrcCap::SaslMech::PLAIN)) { + if (saslMaybeSupports(IrcCap::SaslMech::PLAIN)) { // PLAIN authentication supported, send request // Only working with PLAIN atm, blowfish later putRawLine(serverEncode("AUTHENTICATE PLAIN"));