X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fcorenetwork.cpp;h=8506dea2a6df9840527a4fc689fce2bf3231bff2;hp=d7215a4638ac12fb5cfcec9c9f98203bddff3194;hb=HEAD;hpb=cc6e7c08709c4e761e2fd9c2e322751015497003 diff --git a/src/core/corenetwork.cpp b/src/core/corenetwork.cpp index d7215a46..618aaaec 100644 --- a/src/core/corenetwork.cpp +++ b/src/core/corenetwork.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2019 by the Quassel Project * + * Copyright (C) 2005-2022 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -20,33 +20,33 @@ #include "corenetwork.h" +#include + #include #include +#include #include "core.h" #include "coreidentity.h" #include "corenetworkconfig.h" #include "coresession.h" #include "coreuserinputhandler.h" -#include "networkevent.h" - -// IRCv3 capabilities +#include "ircencoder.h" #include "irccap.h" +#include "irctag.h" +#include "networkevent.h" CoreNetwork::CoreNetwork(const NetworkId& networkid, CoreSession* session) : Network(networkid, session) , _coreSession(session) , _userInputHandler(new CoreUserInputHandler(this)) + , _metricsServer(Core::instance()->metricsServer()) , _autoReconnectCount(0) , _quitRequested(false) , _disconnectExpected(false) - , - - _previousConnectionAttemptFailed(false) + , _previousConnectionAttemptFailed(false) , _lastUsedServerIndex(0) - , - - _requestedUserModes('-') + , _requestedUserModes('-') { // Check if raw IRC logging is enabled _debugLogRawIrc = (Quassel::isOptionSet("debug-irc") || Quassel::isOptionSet("debug-irc-id")); @@ -62,12 +62,12 @@ CoreNetwork::CoreNetwork(const NetworkId& networkid, CoreSession* session) setAutoWhoInterval(networkConfig()->autoWhoInterval()); QHash channels = coreSession()->persistentChannels(networkId()); - foreach (QString chan, channels.keys()) { + for (const QString& chan : channels.keys()) { _channelKeys[chan.toLower()] = channels[chan]; } QHash bufferCiphers = coreSession()->bufferCiphers(networkId()); - foreach (QString buffer, bufferCiphers.keys()) { + for (const QString& buffer : bufferCiphers.keys()) { storeChannelCipherKey(buffer.toLower(), bufferCiphers[buffer]); } @@ -86,10 +86,8 @@ CoreNetwork::CoreNetwork(const NetworkId& networkid, CoreSession* session) connect(&socket, selectOverload(&QAbstractSocket::error), this, &CoreNetwork::onSocketError); connect(&socket, &QAbstractSocket::stateChanged, this, &CoreNetwork::onSocketStateChanged); connect(&socket, &QIODevice::readyRead, this, &CoreNetwork::onSocketHasData); -#ifdef HAVE_SSL connect(&socket, &QSslSocket::encrypted, this, &CoreNetwork::onSocketInitialized); connect(&socket, selectOverload&>(&QSslSocket::sslErrors), this, &CoreNetwork::onSslErrors); -#endif connect(this, &CoreNetwork::newEvent, coreSession()->eventManager(), &EventManager::postEvent); // Custom rate limiting @@ -122,9 +120,9 @@ CoreNetwork::~CoreNetwork() disconnect(&socket, nullptr, this, nullptr); if (!forceDisconnect()) { qWarning() << QString{"Could not disconnect from network %1 (network ID: %2, user ID: %3)"} - .arg(networkName()) - .arg(networkId().toInt()) - .arg(userId().toInt()); + .arg(networkName()) + .arg(networkId().toInt()) + .arg(userId().toInt()); } } @@ -188,6 +186,10 @@ void CoreNetwork::connectToIrc(bool reconnecting) _socketId = Core::instance()->identServer()->addWaitingSocket(); } + if (_metricsServer) { + _metricsServer->addNetwork(userId()); + } + if (!reconnecting && useAutoReconnect() && _autoReconnectCount == 0) { _autoReconnectTimer.setInterval(autoReconnectInterval() * 1000); if (unlimitedReconnectRetries()) @@ -222,7 +224,12 @@ void CoreNetwork::connectToIrc(bool reconnecting) else if (_previousConnectionAttemptFailed) { // cycle to next server if previous connection attempt failed _previousConnectionAttemptFailed = false; - showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Connection failed. Cycling to next Server")); + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Connection failed. Cycling to next server...") + )); if (++_lastUsedServerIndex >= serverList().size()) { _lastUsedServerIndex = 0; } @@ -234,10 +241,15 @@ void CoreNetwork::connectToIrc(bool reconnecting) Server server = usedServer(); displayStatusMsg(tr("Connecting to %1:%2...").arg(server.host).arg(server.port)); - showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Connecting to %1:%2...").arg(server.host).arg(server.port)); + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Connecting to %1:%2...").arg(server.host).arg(server.port) + )); if (server.useProxy) { - QNetworkProxy proxy((QNetworkProxy::ProxyType)server.proxyType, server.proxyHost, server.proxyPort, server.proxyUser, server.proxyPass); + QNetworkProxy proxy((QNetworkProxy::ProxyType) server.proxyType, server.proxyHost, server.proxyPort, server.proxyUser, server.proxyPass); socket.setProxy(proxy); } else { @@ -256,7 +268,6 @@ void CoreNetwork::connectToIrc(bool reconnecting) // hostname of the server. Qt's DNS cache also isn't used by the proxy so we don't need to refresh the entry. QHostInfo::fromName(server.host); } -#ifdef HAVE_SSL if (server.useSsl) { CoreIdentity* identity = identityPtr(); if (identity) { @@ -268,9 +279,6 @@ void CoreNetwork::connectToIrc(bool reconnecting) else { socket.connectToHost(server.host, server.port); } -#else - socket.connectToHost(server.host, server.port); -#endif } void CoreNetwork::disconnectFromIrc(bool requested, const QString& reason, bool withReconnect) @@ -284,6 +292,9 @@ void CoreNetwork::disconnectFromIrc(bool requested, const QString& reason, bool } disablePingTimeout(); _msgQueue.clear(); + if (_metricsServer) { + _metricsServer->messageQueue(userId(), 0); + } IrcUser* me_ = me(); if (me_) { @@ -298,10 +309,12 @@ void CoreNetwork::disconnectFromIrc(bool requested, const QString& reason, bool else _quitReason = reason; - showMessage(Message::Server, - BufferInfo::StatusBuffer, - "", - tr("Disconnecting. (%1)").arg((!requested && !withReconnect) ? tr("Core Shutdown") : _quitReason)); + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Disconnecting. (%1)").arg((!requested && !withReconnect) ? tr("Core Shutdown") : _quitReason) + )); if (socket.state() == QAbstractSocket::UnconnectedState) { onSocketDisconnected(); } @@ -323,9 +336,9 @@ void CoreNetwork::disconnectFromIrc(bool requested, const QString& reason, bool void CoreNetwork::onSocketCloseTimeout() { qWarning() << QString{"Timed out quitting network %1 (network ID: %2, user ID: %3)"} - .arg(networkName()) - .arg(networkId().toInt()) - .arg(userId().toInt()); + .arg(networkName()) + .arg(networkId().toInt()) + .arg(userId().toInt()); socket.abort(); } @@ -358,35 +371,23 @@ void CoreNetwork::putRawLine(const QByteArray& s, bool prepend) // Add to back, waiting in order _msgQueue.append(s); } + if (_metricsServer) { + _metricsServer->messageQueue(userId(), _msgQueue.size()); + } } } -void CoreNetwork::putCmd(const QString& cmd, const QList& params, const QByteArray& prefix, const bool prepend) +void CoreNetwork::putCmd(const QString& cmd, const QList& params, const QByteArray& prefix, const QHash& tags, bool prepend) { - QByteArray msg; - - if (!prefix.isEmpty()) - msg += ":" + prefix + " "; - msg += cmd.toUpper().toLatin1(); - - for (int i = 0; i < params.size(); i++) { - msg += " "; - - if (i == params.size() - 1 && (params[i].contains(' ') || (!params[i].isEmpty() && params[i][0] == ':'))) - msg += ":"; - - msg += params[i]; - } - - putRawLine(msg, prepend); + putRawLine(IrcEncoder::writeMessage(tags, prefix, cmd, params), prepend); } -void CoreNetwork::putCmd(const QString& cmd, const QList>& params, const QByteArray& prefix, const bool prependAll) +void CoreNetwork::putCmd(const QString& cmd, const QList>& params, const QByteArray& prefix, const QHash& tags, bool prependAll) { QListIterator> i(params); while (i.hasNext()) { QList msg = i.next(); - putCmd(cmd, msg, prefix, prependAll); + putCmd(cmd, msg, prefix, tags, prependAll); } } @@ -512,6 +513,9 @@ void CoreNetwork::onSocketHasData() { while (socket.canReadLine()) { QByteArray s = socket.readLine(); + if (_metricsServer) { + _metricsServer->receiveDataNetwork(userId(), s.size()); + } if (s.endsWith("\r\n")) s.chop(2); else if (s.endsWith("\n")) @@ -532,7 +536,12 @@ void CoreNetwork::onSocketError(QAbstractSocket::SocketError error) _previousConnectionAttemptFailed = true; qWarning() << qPrintable(tr("Could not connect to %1 (%2)").arg(networkName(), socket.errorString())); emit connectionError(socket.errorString()); - showMessage(Message::Error, BufferInfo::StatusBuffer, "", tr("Connection failure: %1").arg(socket.errorString())); + showMessage(NetworkInternalMessage( + Message::Error, + BufferInfo::StatusBuffer, + "", + tr("Connection failure: %1").arg(socket.errorString()) + )); emitConnectionError(socket.errorString()); if (socket.state() < QAbstractSocket::ConnectedState) { onSocketDisconnected(); @@ -550,7 +559,6 @@ void CoreNetwork::onSocketInitialized() Server server = usedServer(); -#ifdef HAVE_SSL // Non-SSL connections enter here only once, always emit socketInitialized(...) in these cases // SSL connections call socketInitialized() twice, only emit socketInitialized(...) on the first (not yet encrypted) run if (!server.useSsl || !socket.isEncrypted()) { @@ -561,9 +569,6 @@ void CoreNetwork::onSocketInitialized() // We'll finish setup once we're encrypted, and called again return; } -#else - emit socketInitialized(identity, localAddress(), localPort(), peerAddress(), peerPort(), _socketId); -#endif socket.setSocketOption(QAbstractSocket::KeepAliveOption, true); @@ -579,7 +584,12 @@ void CoreNetwork::onSocketInitialized() // Request capabilities as per IRCv3.2 specifications // Older servers should ignore this; newer servers won't downgrade to RFC1459 - showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Requesting capability list...")); + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Requesting capability list...") + )); putRawLine(serverEncode(QString("CAP LS 302"))); if (!server.password.isEmpty()) { @@ -602,6 +612,9 @@ void CoreNetwork::onSocketDisconnected() { disablePingTimeout(); _msgQueue.clear(); + if (_metricsServer) { + _metricsServer->messageQueue(userId(), 0); + } _autoWhoCycleTimer.stop(); _autoWhoTimer.stop(); @@ -614,8 +627,14 @@ void CoreNetwork::onSocketDisconnected() IrcUser* me_ = me(); if (me_) { - foreach (QString channel, me_->channels()) - showMessage(Message::Quit, BufferInfo::ChannelBuffer, channel, _quitReason, me_->hostmask()); + for (const QString& channel : me_->channels()) { + showMessage(NetworkInternalMessage( + Message::Quit, + BufferInfo::ChannelBuffer, + channel, + _quitReason, me_->hostmask() + )); + } } setConnected(false); @@ -635,6 +654,10 @@ void CoreNetwork::onSocketDisconnected() else _autoReconnectTimer.start(); } + + if (_metricsServer) { + _metricsServer->removeNetwork(userId()); + } } void CoreNetwork::onSocketStateChanged(QAbstractSocket::SocketState socketState) @@ -721,7 +744,7 @@ void CoreNetwork::sendPerform() } // send perform list - foreach (QString line, perform()) { + for (const QString& line : perform()) { if (!line.isEmpty()) userInput(statusBuf, line); } @@ -729,7 +752,7 @@ void CoreNetwork::sendPerform() // rejoin channels we've been in if (rejoinChannels()) { QStringList channels, keys; - foreach (QString chan, coreSession()->persistentChannels(networkId()).keys()) { + for (const QString& chan : coreSession()->persistentChannels(networkId()).keys()) { QString key = channelKey(chan); if (!key.isEmpty()) { channels.prepend(chan); @@ -913,7 +936,7 @@ void CoreNetwork::sendPing() qDebug() << "UserId:" << userId() << "Network:" << networkName() << "missed" << _pingCount << "pings." << "BA:" << socket.bytesAvailable() << "BTW:" << socket.bytesToWrite(); } - if ((int)_pingCount >= networkConfig()->maxPingCount() && (now - _lastPingTime) <= (_pingTimer.interval() + (1 * 1000))) { + if ((int) _pingCount >= networkConfig()->maxPingCount() && (now - _lastPingTime) <= (_pingTimer.interval() + (1 * 1000))) { // In transitioning to 64-bit time, the interval no longer needs converted down to seconds. // However, to reduce the risk of breaking things by changing past behavior, we still allow // up to 1 second missed instead of enforcing a stricter 1 millisecond allowance. @@ -970,7 +993,7 @@ void CoreNetwork::setPongTimestampValid(bool validTimestamp) /******** Custom Rate Limiting ********/ -void CoreNetwork::updateRateLimiting(const bool forceUnlimited) +void CoreNetwork::updateRateLimiting(bool forceUnlimited) { // 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 @@ -1054,12 +1077,18 @@ void CoreNetwork::resetTokenBucket() void CoreNetwork::serverCapAdded(const QString& capability) { + // Exclude skipped capabilities + if (skipCaps().contains(capability)) { + return; + } + // Check if it's a known capability; if so, add it to the list // Handle special cases first if (capability == IrcCap::SASL) { // Only request SASL if it's enabled - if (networkInfo().useSasl) + if (useSasl()) { queueCap(capability); + } } else if (IrcCap::knownCaps.contains(capability)) { // Handling for general known capabilities @@ -1078,36 +1107,42 @@ void CoreNetwork::serverCapAcknowledged(const QString& capability) } // Handle capabilities that require further messages sent to the IRC server - // If you change this list, ALSO change the list in CoreNetwork::capsRequiringServerMessages + // If you change this list, ALSO change the list in CoreNetwork::capsRequiringConfiguration if (capability == IrcCap::SASL) { // If SASL mechanisms specified, limit to what's accepted for authentication // if the current identity has a cert set, use SASL EXTERNAL // FIXME use event -#ifdef HAVE_SSL if (!identityPtr()->sslCert().isNull()) { if (saslMaybeSupports(IrcCap::SaslMech::EXTERNAL)) { // EXTERNAL authentication supported, send request putRawLine(serverEncode("AUTHENTICATE EXTERNAL")); } else { - showMessage(Message::Error, BufferInfo::StatusBuffer, "", tr("SASL EXTERNAL authentication not supported")); + showMessage(NetworkInternalMessage( + Message::Error, + BufferInfo::StatusBuffer, + "", + tr("SASL EXTERNAL authentication not supported") + )); sendNextCap(); } } else { -#endif if (saslMaybeSupports(IrcCap::SaslMech::PLAIN)) { // PLAIN authentication supported, send request // Only working with PLAIN atm, blowfish later putRawLine(serverEncode("AUTHENTICATE PLAIN")); } else { - showMessage(Message::Error, BufferInfo::StatusBuffer, "", tr("SASL PLAIN authentication not supported")); + showMessage(NetworkInternalMessage( + Message::Error, + BufferInfo::StatusBuffer, + "", + tr("SASL PLAIN authentication not supported") + )); sendNextCap(); } -#ifdef HAVE_SSL } -#endif } } @@ -1211,10 +1246,12 @@ void CoreNetwork::retryCapsIndividually() // Add most recently tried capability set to individual list, re-requesting them one at a time _capsQueuedIndividual.append(_capsQueuedLastBundle); // Warn of this issue to explain the slower login. Servers usually shouldn't trigger this. - showMessage(Message::Server, - BufferInfo::StatusBuffer, - "", - tr("Could not negotiate some capabilities, retrying individually (%1)...").arg(_capsQueuedLastBundle.join(", "))); + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Could not negotiate some capabilities, retrying individually (%1)...").arg(_capsQueuedLastBundle.join(", ")) + )); // Capabilities are already removed from the capability bundle queue via takeQueuedCaps(), no // need to remove them here. // Clear the most recently tried set to reduce risk that mistakes elsewhere causes retrying @@ -1224,45 +1261,128 @@ void CoreNetwork::retryCapsIndividually() void CoreNetwork::beginCapNegotiation() { - // Don't begin negotiation if no capabilities are queued to request - if (!capNegotiationInProgress()) { - // If the server doesn't have any capabilities, but supports CAP LS, continue on with the - // normal connection. - showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("No capabilities available")); + // Check if any available capabilities have been disabled + QStringList capsSkipped; + if (!skipCaps().isEmpty() && !caps().isEmpty()) { + // Find the entries that are common to skipCaps() and caps(). This represents any + // capabilities supported by the server that were skipped. + + // Both skipCaps() and caps() are already lowercase + // std::set_intersection requires sorted lists, and we can't modify the original lists. + // + // skipCaps() should already be sorted. caps() is intentionally not sorted elsewhere so + // Quassel can show the capabilities in the order transmitted by the network. + auto sortedCaps = caps(); + sortedCaps.sort(); + + // Find the intersection between skipped caps and server-supplied caps + std::set_intersection(skipCaps().cbegin(), skipCaps().cend(), + sortedCaps.cbegin(), sortedCaps.cend(), + std::back_inserter(capsSkipped)); + } + + if (!capsPendingNegotiation()) { + // No capabilities are queued for request, determine the reason why + QString capStatusMsg; + if (caps().empty()) { + // The server doesn't provide any capabilities, but supports CAP LS + capStatusMsg = tr("No capabilities available"); + } + else if (capsEnabled().empty()) { + // The server supports capabilities (caps() is not empty) but Quassel doesn't support + // anything offered. This should be uncommon. + capStatusMsg = + tr("None of the capabilities provided by the server are supported (found: %1)") + .arg(caps().join(", ")); + } + else { + // Quassel has enabled some capabilities, but there are no further capabilities that can + // be negotiated. + // (E.g. the user has manually run "/cap ls 302" after initial negotiation.) + capStatusMsg = + tr("No additional capabilities are supported (found: %1; currently enabled: %2)") + .arg(caps().join(", "), capsEnabled().join(", ")); + } + // Inform the user of the situation + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + capStatusMsg + )); + + if (!capsSkipped.isEmpty()) { + // Mention that some capabilities are skipped + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Quassel is configured to ignore some capabilities (skipped: %1)").arg(capsSkipped.join(", ")) + )); + } + + // End any ongoing capability negotiation, allowing connection to continue endCapNegotiation(); return; } _capNegotiationActive = true; - showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Ready to negotiate (found: %1)").arg(caps().join(", "))); + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Ready to negotiate (found: %1)").arg(caps().join(", ")) + )); + + if (!capsSkipped.isEmpty()) { + // Mention that some capabilities are skipped + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Quassel is configured to ignore some capabilities (skipped: %1)").arg(capsSkipped.join(", ")) + )); + } // Build a list of queued capabilities, starting with individual, then bundled, only adding the // comma separator between the two if needed (both individual and bundled caps exist). QString queuedCapsDisplay = _capsQueuedIndividual.join(", ") + ((!_capsQueuedIndividual.empty() && !_capsQueuedBundled.empty()) ? ", " : "") + _capsQueuedBundled.join(", "); - showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Negotiating capabilities (requesting: %1)...").arg(queuedCapsDisplay)); + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Negotiating capabilities (requesting: %1)...").arg(queuedCapsDisplay) + )); sendNextCap(); } void CoreNetwork::sendNextCap() { - if (capNegotiationInProgress()) { + if (capsPendingNegotiation()) { // Request the next set of capabilities and remove them from the list putRawLine(serverEncode(QString("CAP REQ :%1").arg(takeQueuedCaps()))); } else { // No pending desired capabilities, capability negotiation finished // If SASL requested but not available, print a warning - if (networkInfo().useSasl && !capEnabled(IrcCap::SASL)) - showMessage(Message::Error, BufferInfo::StatusBuffer, "", tr("SASL authentication currently not supported by server")); + if (useSasl() && !capEnabled(IrcCap::SASL)) + showMessage(NetworkInternalMessage( + Message::Error, + BufferInfo::StatusBuffer, + "", + tr("SASL authentication currently not supported by server") + )); if (_capNegotiationActive) { - showMessage(Message::Server, - BufferInfo::StatusBuffer, - "", - tr("Capability negotiation finished (enabled: %1)").arg(capsEnabled().join(", "))); + showMessage(NetworkInternalMessage( + Message::Server, + BufferInfo::StatusBuffer, + "", + tr("Capability negotiation finished (enabled: %1)").arg(capsEnabled().join(", ")) + )); _capNegotiationActive = false; } @@ -1362,7 +1482,9 @@ void CoreNetwork::sendAutoWho() // And https://github.com/quakenet/snircd/blob/master/doc/readme.who // And https://github.com/hexchat/hexchat/blob/57478b65758e6b697b1d82ce21075e74aa475efc/src/common/proto-irc.c#L752 putRawLine(serverEncode( - QString("WHO %1 n%chtsunfra,%2").arg(serverEncode(chanOrNick), QString::number(IrcCap::ACCOUNT_NOTIFY_WHOX_NUM)))); + QString("WHO %1 n%chtsunfra,%2") + .arg(chanOrNick, QString::number(IrcCap::ACCOUNT_NOTIFY_WHOX_NUM)) + )); } else { // Fall back to normal WHO @@ -1388,7 +1510,6 @@ void CoreNetwork::sendAutoWho() } } -#ifdef HAVE_SSL void CoreNetwork::onSslErrors(const QList& sslErrors) { Server server = usedServer(); @@ -1400,7 +1521,12 @@ void CoreNetwork::onSslErrors(const QList& sslErrors) // Add the error reason if known sslErrorMessage.append(tr(" (Reason: %1)").arg(sslErrors.first().errorString())); } - showMessage(Message::Error, BufferInfo::StatusBuffer, "", sslErrorMessage); + showMessage(NetworkInternalMessage( + Message::Error, + BufferInfo::StatusBuffer, + "", + sslErrorMessage + )); // Disconnect, triggering a reconnect in case it's a temporary issue with certificate // validity, network trouble, etc. @@ -1414,19 +1540,22 @@ void CoreNetwork::onSslErrors(const QList& sslErrors) // Add the error reason if known sslErrorMessage.append(tr(" (Reason: %1)").arg(sslErrors.first().errorString())); } - showMessage(Message::Info, BufferInfo::StatusBuffer, "", sslErrorMessage); + showMessage(NetworkInternalMessage( + Message::Info, + BufferInfo::StatusBuffer, + "", + sslErrorMessage + )); // Proceed with the connection socket.ignoreSslErrors(); } } -#endif // HAVE_SSL - void CoreNetwork::checkTokenBucket() { if (_skipMessageRates) { - if (_msgQueue.size() == 0) { + if (_msgQueue.empty()) { // Message queue emptied; stop the timer and bail out _tokenBucketTimer.stop(); return; @@ -1446,8 +1575,11 @@ void CoreNetwork::fillBucketAndProcessQueue() } // As long as there's tokens available and messages remaining, sending messages from the queue - while (_msgQueue.size() > 0 && _tokenBucket > 0) { + while (!_msgQueue.empty() && _tokenBucket > 0) { writeToSocket(_msgQueue.takeFirst()); + if (_metricsServer) { + _metricsServer->messageQueue(userId(), _msgQueue.size()); + } } } @@ -1460,6 +1592,9 @@ void CoreNetwork::writeToSocket(const QByteArray& data) } socket.write(data); socket.write("\r\n"); + if (_metricsServer) { + _metricsServer->transmitDataNetwork(userId(), data.size() + 2); + } if (!_skipMessageRates) { // Only subtract from the token bucket if message rate limiting is enabled _tokenBucket--;