mumble-voip_mumble/src/mumble/ServerInformation.cpp

193 lines
7.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2021-2023 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#include "ServerInformation.h"
#include "Connection.h"
#include "MainWindow.h"
#include "NetworkConfig.h"
#include "SSL.h"
#include "ServerHandler.h"
#include "UserModel.h"
#include "Version.h"
#include "ViewCert.h"
#include "Global.h"
#include <QTableWidgetItem>
#include <boost/accumulators/accumulators.hpp>
#include <cmath>
QString ServerInformation::m_unknownStr = tr("Unknown");
ServerInformation::ServerInformation(QWidget *parent) : QDialog(parent) {
setupUi(this);
updateFields();
// Labels are not initialized properly here. We need to wait a tiny bit
// to make sure its contents are actually read.
QTimer::singleShot(0, [this]() {
qgbServerInformation->updateAccessibleText();
qgbAudioBandwidth->updateAccessibleText();
qgbTCPParameters->updateAccessibleText();
});
}
void ServerInformation::updateFields() {
updateServerInformation();
updateAudioBandwidth();
updateConnectionDetails();
}
void ServerInformation::on_okButton_clicked() {
accept();
}
void ServerInformation::on_viewCertButton_clicked() {
hide();
ViewCert certViewer(Global::get().sh->qscCert, this);
certViewer.exec();
accept();
}
void ServerInformation::updateServerInformation() {
QString host, userName, password;
unsigned short port;
Global::get().sh->getConnectionInfo(host, port, userName, password);
const int userCount = ModelItem::c_qhUsers.count();
const unsigned int maxUserCount = Global::get().uiMaxUsers;
QString release = Global::get().sh->qsRelease;
if (release.isEmpty()) {
release = m_unknownStr;
}
QString os = Global::get().sh->qsOS;
if (os.isEmpty()) {
os = m_unknownStr;
} else if (!Global::get().sh->qsOSVersion.isEmpty()) {
os += QString::fromLatin1(" (%1)").arg(Global::get().sh->qsOSVersion);
}
serverInfo_host->setText(host);
serverInfo_port->setText(QString::number(port));
serverInfo_users->setText(QString::fromLatin1("%1 / %2").arg(userCount).arg(maxUserCount));
serverInfo_protocol->setText(Version::toString(Global::get().sh->m_version));
serverInfo_release->setText(release);
serverInfo_os->setText(os);
qgbServerInformation->updateAccessibleText();
}
static const QString currentCodec() {
// We now always use Opus
return "Opus";
}
void ServerInformation::updateAudioBandwidth() {
// The bandwidths are in bit/s, so we divide by 1000 to get kBit/s
const float maxBandwidthAllowed = static_cast< float >(Global::get().iMaxBandwidth) / 1000.0f;
const float currentBandwidth = static_cast< float >(Global::get().iAudioBandwidth) / 1000.0f;
audio_current->setText(QString::fromLatin1("%1 kBit/s").arg(currentBandwidth, 0, 'f', 1));
audio_allowed->setText(QString::fromLatin1("%1 kBit/s").arg(maxBandwidthAllowed, 0, 'f', 1));
audio_codec->setText(currentCodec());
qgbAudioBandwidth->updateAccessibleText();
}
void ServerInformation::updateConnectionDetails() {
QString latencyString = QString::fromUtf8("%1 ms (σ = %2 ms)");
const ConnectionPtr connection = Global::get().sh->cConnection;
if (!connection) {
return;
}
// UDP
if (NetworkConfig::TcpModeEnabled()) {
connection_udp_infoMessage->show();
connection_udp_encryption->hide();
connection_udp_encryptionLabel->hide();
connection_udp_latency->hide();
connection_udp_latencyLabel->hide();
connection_udp_statisticsGroup->hide();
} else {
connection_udp_infoMessage->hide();
connection_udp_encryption->show();
connection_udp_encryptionLabel->show();
connection_udp_latency->show();
connection_udp_latencyLabel->show();
connection_udp_statisticsGroup->show();
// Actually fill in data
const float latency = static_cast< float >(boost::accumulators::mean(Global::get().sh->accUDP));
const float deviation =
static_cast< float >(std::sqrt(boost::accumulators::variance(Global::get().sh->accUDP)));
connection_udp_encryption->setText("128 bit OCB-AES128");
connection_udp_latency->setText(latencyString.arg(latency, 0, 'f', 1).arg(deviation, 0, 'f', 1));
populateUDPStatistics(*connection);
}
// TCP
const float latency = static_cast< float >(boost::accumulators::mean(Global::get().sh->accTCP));
const float deviation = static_cast< float >(std::sqrt(boost::accumulators::variance(Global::get().sh->accTCP)));
QSslCipher cipher = Global::get().sh->qscCipher;
connection_tcp_tls->setText(MumbleSSL::protocolToString(connection->sessionProtocol()).toHtmlEscaped());
connection_tcp_latency->setText(latencyString.arg(latency, 0, 'f', 1).arg(deviation, 0, 'f', 1));
connection_tcp_cipher->setText(cipher.name().isEmpty() ? m_unknownStr : cipher.name());
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
connection_tcp_forwardSecrecy->setText(Global::get().sh->connectionUsesPerfectForwardSecrecy ? tr("Yes")
: tr("No"));
#else
// The Qt function we use to query for PFS inside ServerHandler is only available since Qt 5.7 and if it is
// unavailable, the respective boolean flag is never touched and is therefore meaningless.
connection_tcp_forwardSecrecy->setText(tr("Unknown"));
#endif
qgbTCPParameters->updateAccessibleText();
}
void ServerInformation::populateUDPStatistics(const Connection &connection) {
// statistics
constexpr int TO_SERVER_COL = 0;
constexpr int FROM_SERVER_COL = 1;
constexpr int GOOD_ROW = 0;
constexpr int LATE_ROW = 1;
constexpr int LOST_ROW = 2;
constexpr int RESYNC_ROW = 3;
QTableWidgetItem *toGoodItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiRemoteGood));
QTableWidgetItem *fromGoodItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiGood));
QTableWidgetItem *toLateItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiRemoteLate));
QTableWidgetItem *fromLateItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiLate));
QTableWidgetItem *toLostItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiRemoteLost));
QTableWidgetItem *fromLostItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiLost));
QTableWidgetItem *toResyncItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiRemoteResync));
QTableWidgetItem *fromResyncItem = new QTableWidgetItem(QString::number(connection.csCrypt->uiResync));
connection_udp_statisticsTable->setItem(GOOD_ROW, TO_SERVER_COL, toGoodItem);
connection_udp_statisticsTable->setItem(GOOD_ROW, FROM_SERVER_COL, fromGoodItem);
connection_udp_statisticsTable->setItem(LATE_ROW, TO_SERVER_COL, toLateItem);
connection_udp_statisticsTable->setItem(LATE_ROW, FROM_SERVER_COL, fromLateItem);
connection_udp_statisticsTable->setItem(LOST_ROW, TO_SERVER_COL, toLostItem);
connection_udp_statisticsTable->setItem(LOST_ROW, FROM_SERVER_COL, fromLostItem);
connection_udp_statisticsTable->setItem(RESYNC_ROW, TO_SERVER_COL, toResyncItem);
connection_udp_statisticsTable->setItem(RESYNC_ROW, FROM_SERVER_COL, fromResyncItem);
connection_udp_statisticsTable->adjustSize();
}