Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mumble/CMakeLists.txt3
-rw-r--r--src/mumble/MainWindow.cpp134
-rw-r--r--src/mumble/ServerInformation.cpp199
-rw-r--r--src/mumble/ServerInformation.h37
-rw-r--r--src/mumble/ServerInformation.ui643
5 files changed, 885 insertions, 131 deletions
diff --git a/src/mumble/CMakeLists.txt b/src/mumble/CMakeLists.txt
index 96266ee8f..e90272181 100644
--- a/src/mumble/CMakeLists.txt
+++ b/src/mumble/CMakeLists.txt
@@ -176,6 +176,9 @@ set(MUMBLE_SOURCES
"Screen.h"
"ServerHandler.cpp"
"ServerHandler.h"
+ "ServerInformation.cpp"
+ "ServerInformation.h"
+ "ServerInformation.ui"
"Settings.cpp"
"Settings.h"
"SharedMemory.cpp"
diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp
index 1b7723ed4..6d955c9d6 100644
--- a/src/mumble/MainWindow.cpp
+++ b/src/mumble/MainWindow.cpp
@@ -39,6 +39,7 @@
#include "SSLCipherInfo.h"
#include "Screen.h"
#include "ServerHandler.h"
+#include "ServerInformation.h"
#include "Settings.h"
#include "SvgIcon.h"
#include "TalkingUI.h"
@@ -1403,138 +1404,9 @@ void MainWindow::on_qaServerUserList_triggered() {
}
}
-static const QString currentCodec() {
- if (Global::get().bOpus)
- return QLatin1String("Opus");
-
- int v = Global::get().bPreferAlpha ? Global::get().iCodecAlpha : Global::get().iCodecBeta;
- CELTCodec *cc = Global::get().qmCodecs.value(v);
- if (cc)
- return QString::fromLatin1("CELT %1").arg(cc->version());
- else
- return QString::fromLatin1("CELT %1").arg(QString::number(v, 16));
-}
-
void MainWindow::on_qaServerInformation_triggered() {
- ConnectionPtr c = Global::get().sh->cConnection;
-
- if (!c)
- return;
-
- QSslCipher qsc = Global::get().sh->qscCipher;
-
- QString qsVersion = tr("<h2>Version</h2><p>Protocol %1</p>").arg(MumbleVersion::toString(Global::get().sh->uiVersion));
-
- if (Global::get().sh->qsRelease.isEmpty() || Global::get().sh->qsOS.isEmpty() || Global::get().sh->qsOSVersion.isEmpty()) {
- qsVersion.append(tr("<p>No build information or OS version available</p>"));
- } else {
- qsVersion.append(
- tr("<p>%1 (%2)<br />%3</p>")
- .arg(Global::get().sh->qsRelease.toHtmlEscaped(), Global::get().sh->qsOS.toHtmlEscaped(), Global::get().sh->qsOSVersion.toHtmlEscaped()));
- }
-
- QString host, uname, pw;
- unsigned short port;
-
- Global::get().sh->getConnectionInfo(host, port, uname, pw);
-
- const SSLCipherInfo *ci = SSLCipherInfoLookupByOpenSSLName(qsc.name().toLatin1().constData());
-
- QString cipherDescription;
- if (ci && ci->message_authentication && ci->encryption && ci->key_exchange_verbose && ci->rfc_name) {
- if (QString::fromLatin1(ci->message_authentication) == QLatin1String("AEAD")) {
- // Authenticated Encryption with Associated Data
- // See https://en.wikipedia.org/wiki/Authenticated_encryption
- cipherDescription =
- tr("The connection is encrypted and authenticated "
- "using %1 and uses %2 as the key exchange mechanism (%3)")
- .arg(QString::fromLatin1(ci->encryption), QString::fromLatin1(ci->key_exchange_verbose),
- QString::fromLatin1(ci->rfc_name));
- } else {
- cipherDescription =
- tr("The connection is encrypted using %1, with %2 "
- "for message authentication and %3 as the key "
- "exchange mechanism (%4)")
- .arg(QString::fromLatin1(ci->encryption), QString::fromLatin1(ci->message_authentication),
- QString::fromLatin1(ci->key_exchange_verbose), QString::fromLatin1(ci->rfc_name));
- }
- }
- if (cipherDescription.isEmpty()) {
- cipherDescription =
- tr("The connection is secured by the cipher suite that OpenSSL identifies as %1").arg(qsc.name());
- }
-
- QString cipherPFSInfo;
- if (ci) {
- if (ci->forward_secret) {
- cipherPFSInfo = tr("<p>The connection provides perfect forward secrecy</p>");
- } else {
- cipherPFSInfo = tr("<p>The connection does not provide perfect forward secrecy</p>");
- }
- }
-
- QString qsControl =
- tr("<h2>Control channel</h2>"
- "<p>The connection uses %1</p>"
- "%2"
- "%3"
- "<p>%4 ms average latency (%5 deviation)</p>"
- "<p>Remote host %6 (port %7)</p>")
- .arg(c->sessionProtocolString().toHtmlEscaped(), cipherDescription, cipherPFSInfo,
- QString::fromLatin1("%1").arg(boost::accumulators::mean(Global::get().sh->accTCP), 0, 'f', 2),
- QString::fromLatin1("%1").arg(sqrt(boost::accumulators::variance(Global::get().sh->accTCP)), 0, 'f', 2),
- host.toHtmlEscaped(), QString::number(port));
- if (Global::get().uiMaxUsers) {
- qsControl += tr("<p>Connected users: %1/%2</p>").arg(ModelItem::c_qhUsers.count()).arg(Global::get().uiMaxUsers);
- }
-
- QString qsVoice, qsCrypt, qsAudio;
-
- if (NetworkConfig::TcpModeEnabled()) {
- qsVoice = tr("Voice channel is sent over control channel");
- } else {
- qsVoice = tr("<h2>Voice channel</h2><p>Encrypted with 128 bit OCB-AES128<br />%1 ms average latency (%4 "
- "deviation)</p>")
- .arg(boost::accumulators::mean(Global::get().sh->accUDP), 0, 'f', 2)
- .arg(sqrt(boost::accumulators::variance(Global::get().sh->accUDP)), 0, 'f', 2);
- qsCrypt = QString::fromLatin1("<h2>%1</h2><table><tr><th></th><th>%2</th><th>%3</th></tr>"
- "<tr><th>%4</th><td>%8</td><td>%12</td></tr>"
- "<tr><th>%5</th><td>%9</td><td>%13</td></tr>"
- "<tr><th>%6</th><td>%10</td><td>%14</td></tr>"
- "<tr><th>%7</th><td>%11</td><td>%15</td></tr>"
- "</table>")
- .arg(tr("UDP Statistics"))
- .arg(tr("To Server"))
- .arg(tr("From Server"))
- .arg(tr("Good"))
- .arg(tr("Late"))
- .arg(tr("Lost"))
- .arg(tr("Resync"))
- .arg(c->csCrypt->uiRemoteGood)
- .arg(c->csCrypt->uiRemoteLate)
- .arg(c->csCrypt->uiRemoteLost)
- .arg(c->csCrypt->uiRemoteResync)
- .arg(c->csCrypt->uiGood)
- .arg(c->csCrypt->uiLate)
- .arg(c->csCrypt->uiLost)
- .arg(c->csCrypt->uiResync);
- }
- qsAudio = tr("<h2>Audio bandwidth</h2><p>Maximum %1 kbit/s<br />Current %2 kbit/s<br />Codec: %3</p>")
- .arg(Global::get().iMaxBandwidth / 1000.0, 0, 'f', 1)
- .arg(Global::get().iAudioBandwidth / 1000.0, 0, 'f', 1)
- .arg(currentCodec());
-
- QMessageBox qmb(QMessageBox::Information, tr("Mumble Server Information"),
- qsVersion + qsControl + qsVoice + qsCrypt + qsAudio, QMessageBox::Ok, this);
- qmb.setDefaultButton(QMessageBox::Ok);
- qmb.setEscapeButton(QMessageBox::Ok);
-
- QPushButton *qp = qmb.addButton(tr("&View Certificate"), QMessageBox::ActionRole);
- int res = qmb.exec();
- if ((res == 0) && (qmb.clickedButton() == qp)) {
- ViewCert vc(Global::get().sh->qscCert, this);
- vc.exec();
- }
+ ServerInformation *infoDialog = new ServerInformation(this);
+ infoDialog->show();
}
void MainWindow::on_qaServerTexture_triggered() {
diff --git a/src/mumble/ServerInformation.cpp b/src/mumble/ServerInformation.cpp
new file mode 100644
index 000000000..dd8e41278
--- /dev/null
+++ b/src/mumble/ServerInformation.cpp
@@ -0,0 +1,199 @@
+// Copyright 2021 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 "CELTCodec.h"
+#include "Connection.h"
+#include "MainWindow.h"
+#include "NetworkConfig.h"
+#include "SSL.h"
+#include "SSLCipherInfo.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();
+}
+
+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(MumbleVersion::toString(Global::get().sh->uiVersion));
+ serverInfo_release->setText(release);
+ serverInfo_os->setText(os);
+}
+
+static const QString currentCodec() {
+ if (Global::get().bOpus)
+ return QLatin1String("Opus");
+
+ int v = Global::get().bPreferAlpha ? Global::get().iCodecAlpha : Global::get().iCodecBeta;
+ CELTCodec *cc = Global::get().qmCodecs.value(v);
+ if (cc)
+ return QString::fromLatin1("CELT %1").arg(cc->version());
+ else
+ return QString::fromLatin1("CELT %1").arg(QString::number(v, 16));
+}
+
+void ServerInformation::updateAudioBandwidth() {
+ // The bandwidths are in bit/s, so we divide by 1000 to get kBit/s
+ const float maxBandwidthAllowed = Global::get().iMaxBandwidth / 1000.0f;
+ const float currentBandwidth = 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());
+}
+
+QString getCipherID(const QSslCipher &cipher, const SSLCipherInfo *cipherInfo) {
+ if (cipherInfo && cipherInfo->rfc_name) {
+ return QString::fromUtf8(cipherInfo->rfc_name);
+ }
+
+ return cipher.name();
+}
+
+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 = boost::accumulators::mean(Global::get().sh->accUDP);
+ const float deviation = 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 = boost::accumulators::mean(Global::get().sh->accTCP);
+ const float deviation = std::sqrt(boost::accumulators::variance(Global::get().sh->accTCP));
+
+ QSslCipher cipher = Global::get().sh->qscCipher;
+ const SSLCipherInfo *cipherInfo = SSLCipherInfoLookupByOpenSSLName(cipher.name().toLatin1().constData());
+
+ const QString cipherID = getCipherID(cipher, cipherInfo);
+
+ 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(cipherID.isEmpty() ? m_unknownStr : cipherID);
+
+ if (cipherInfo) {
+ if (cipherInfo->forward_secret) {
+ connection_tcp_forwardSecrecy->setText(tr("The connection provides perfect forward secrecy."));
+ } else {
+ connection_tcp_forwardSecrecy->setText(tr("The connection does NOT provide perfect forward secrecy."));
+ }
+ } else {
+ connection_tcp_forwardSecrecy->setText(tr("No information about forward secrecy available."));
+ }
+}
+
+void ServerInformation::populateUDPStatistics(const Connection &connection) {
+ // statistics
+ constexpr int toServerCol = 0;
+ constexpr int fromServerCol = 1;
+ constexpr int goodRow = 0;
+ constexpr int lateRow = 1;
+ constexpr int lostRow = 2;
+ constexpr int resyncRow = 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(goodRow, toServerCol, toGoodItem);
+ connection_udp_statisticsTable->setItem(goodRow, fromServerCol, fromGoodItem);
+ connection_udp_statisticsTable->setItem(lateRow, toServerCol, toLateItem);
+ connection_udp_statisticsTable->setItem(lateRow, fromServerCol, fromLateItem);
+ connection_udp_statisticsTable->setItem(lostRow, toServerCol, toLostItem);
+ connection_udp_statisticsTable->setItem(lostRow, fromServerCol, fromLostItem);
+ connection_udp_statisticsTable->setItem(resyncRow, toServerCol, toResyncItem);
+ connection_udp_statisticsTable->setItem(resyncRow, fromServerCol, fromResyncItem);
+
+ connection_udp_statisticsTable->adjustSize();
+}
diff --git a/src/mumble/ServerInformation.h b/src/mumble/ServerInformation.h
new file mode 100644
index 000000000..41669b5d4
--- /dev/null
+++ b/src/mumble/ServerInformation.h
@@ -0,0 +1,37 @@
+// Copyright 2021 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>.
+
+#ifndef MUMBLE_MUMBLE_SERVERINFORMATION_H_
+#define MUMBLE_MUMBLE_SERVERINFORMATION_H_
+
+#include <QDialog>
+
+#include "ui_ServerInformation.h"
+
+class Connection;
+
+class ServerInformation : public QDialog, private Ui::ServerInformation {
+ Q_OBJECT;
+ Q_DISABLE_COPY(ServerInformation);
+
+public:
+ ServerInformation(QWidget *parent = nullptr);
+
+ void updateFields();
+
+public slots:
+ void on_okButton_clicked();
+ void on_viewCertButton_clicked();
+
+private:
+ static QString m_unknownStr;
+
+ void updateServerInformation();
+ void updateAudioBandwidth();
+ void updateConnectionDetails();
+ void populateUDPStatistics(const Connection &connection);
+};
+
+#endif // MUMBLE_MUMBLE_SERVERINFORMATION_H_
diff --git a/src/mumble/ServerInformation.ui b/src/mumble/ServerInformation.ui
new file mode 100644
index 000000000..ba274deda
--- /dev/null
+++ b/src/mumble/ServerInformation.ui
@@ -0,0 +1,643 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ServerInformation</class>
+ <widget class="QDialog" name="ServerInformation">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>578</width>
+ <height>585</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Server information</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>-203</y>
+ <width>541</width>
+ <height>731</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QGroupBox" name="qgbServerInformation">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Server Information</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>&lt;b&gt;Host:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="serverInfo_host">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;host&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Port:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="serverInfo_port">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;port&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>&lt;b&gt;Users&lt;/b&gt;:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="serverInfo_users">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;users&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Protocol:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="serverInfo_protocol">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;protocol&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Release:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="serverInfo_release">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;release&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;OS:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="serverInfo_os">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;os&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="qgbAudioBandwidth">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Audio</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout_4">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_31">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Allowed:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="audio_allowed">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;allowed&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_32">
+ <property name="text">
+ <string>&lt;b&gt;Current:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="audio_current">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;current&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_33">
+ <property name="text">
+ <string>&lt;b&gt;Codec:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="audio_codec">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;codec&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="qgbConnectionDetails">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Connection details</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="tabPosition">
+ <enum>QTabWidget::North</enum>
+ </property>
+ <property name="tabShape">
+ <enum>QTabWidget::Rounded</enum>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>UDP (Voice)</string>
+ </attribute>
+ <layout class="QFormLayout" name="formLayout_3">
+ <item row="1" column="0">
+ <widget class="QLabel" name="connection_udp_encryptionLabel">
+ <property name="text">
+ <string>&lt;b&gt;Encryption:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="connection_udp_encryption">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;encryption&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="connection_udp_latencyLabel">
+ <property name="text">
+ <string>&lt;b&gt;Avg. latency:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="connection_udp_latency">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;latency&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QGroupBox" name="connection_udp_statisticsGroup">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Statistics</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QTableWidget" name="connection_udp_statisticsTable">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="verticalScrollMode">
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
+ </property>
+ <property name="horizontalScrollMode">
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
+ </property>
+ <property name="showGrid">
+ <bool>true</bool>
+ </property>
+ <property name="cornerButtonEnabled">
+ <bool>false</bool>
+ </property>
+ <row>
+ <property name="text">
+ <string>Good</string>
+ </property>
+ </row>
+ <row>
+ <property name="text">
+ <string>Late</string>
+ </property>
+ </row>
+ <row>
+ <property name="text">
+ <string>Lost</string>
+ </property>
+ </row>
+ <row>
+ <property name="text">
+ <string>Resync</string>
+ </property>
+ </row>
+ <column>
+ <property name="text">
+ <string>Outgoing</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Incoming</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="connection_udp_infoMessage">
+ <property name="text">
+ <string>Voice packets is currently sent over TCP.</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>TCP (Control)</string>
+ </attribute>
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>&lt;b&gt;TLS version:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="connection_tcp_tls">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;TLS&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>&lt;b&gt;Cipher suite:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="connection_tcp_cipher">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;Cipher&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>&lt;b&gt;Avg. latency:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="connection_tcp_latency">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;latency&gt;</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QLabel" name="connection_tcp_forwardSecrecy">
+ <property name="text">
+ <string>&lt;forward secrecy&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Maximum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="viewCertButton">
+ <property name="text">
+ <string>&amp;View certificate</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>&amp;Ok</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>