// Copyright 2005-2019 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 . #include "mumble_pch.hpp" #include "NetworkConfig.h" #include "MainWindow.h" #include "OSInfo.h" // We define a global macro called 'g'. This can lead to issues when included code uses 'g' as a type or parameter name (like protobuf 3.7 does). As such, for now, we have to make this our last include. #include "Global.h" static ConfigWidget *NetworkConfigNew(Settings &st) { return new NetworkConfig(st); } static ConfigRegistrar registrar(1300, NetworkConfigNew); NetworkConfig::NetworkConfig(Settings &st) : ConfigWidget(st) { setupUi(this); #ifdef NO_UPDATE_CHECK qcbAutoUpdate->hide(); qcbPluginUpdate->hide(); #endif } QString NetworkConfig::title() const { return tr("Network"); } QIcon NetworkConfig::icon() const { return QIcon(QLatin1String("skin:config_network.png")); } void NetworkConfig::load(const Settings &r) { loadCheckBox(qcbTcpMode, s.bTCPCompat); loadCheckBox(qcbQoS, s.bQoS); loadCheckBox(qcbAutoReconnect, s.bReconnect); loadCheckBox(qcbAutoConnect, s.bAutoConnect); loadCheckBox(qcbSuppressIdentity, s.bSuppressIdentity); loadComboBox(qcbType, s.ptProxyType); qleHostname->setText(r.qsProxyHost); if (r.usProxyPort > 0) { QString port; port.setNum(r.usProxyPort); qlePort->setText(port); } else qlePort->setText(QString()); qleUsername->setText(r.qsProxyUsername); qlePassword->setText(r.qsProxyPassword); loadCheckBox(qcbHideOS, s.bHideOS); loadCheckBox(qcbAutoUpdate, r.bUpdateCheck); loadCheckBox(qcbPluginUpdate, r.bPluginCheck); loadCheckBox(qcbUsage, r.bUsage); #if defined(SNAPSHOT_BUILD) && defined(QT_NO_DEBUG) qcbAutoUpdate->setEnabled(false); qcbAutoUpdate->setToolTip(tr("Updates are mandatory when using snapshot releases.")); #endif } void NetworkConfig::save() const { s.bTCPCompat = qcbTcpMode->isChecked(); s.bQoS = qcbQoS->isChecked(); s.bReconnect = qcbAutoReconnect->isChecked(); s.bAutoConnect = qcbAutoConnect->isChecked(); s.bSuppressIdentity = qcbSuppressIdentity->isChecked(); s.bHideOS = qcbHideOS->isChecked(); s.ptProxyType = static_cast(qcbType->currentIndex()); s.qsProxyHost = qleHostname->text(); s.usProxyPort = qlePort->text().toUShort(); s.qsProxyUsername = qleUsername->text(); s.qsProxyPassword = qlePassword->text(); s.bUpdateCheck=qcbAutoUpdate->isChecked(); s.bPluginCheck=qcbPluginUpdate->isChecked(); s.bUsage=qcbUsage->isChecked(); } static QNetworkProxy::ProxyType local_to_qt_proxy(Settings::ProxyType pt) { switch (pt) { case Settings::NoProxy: return QNetworkProxy::NoProxy; case Settings::HttpProxy: return QNetworkProxy::HttpProxy; case Settings::Socks5Proxy: return QNetworkProxy::Socks5Proxy; } return QNetworkProxy::NoProxy; } void NetworkConfig::SetupProxy() { QNetworkProxy proxy; proxy.setType(local_to_qt_proxy(g.s.ptProxyType)); proxy.setHostName(g.s.qsProxyHost); proxy.setPort(g.s.usProxyPort); proxy.setUser(g.s.qsProxyUsername); proxy.setPassword(g.s.qsProxyPassword); QNetworkProxy::setApplicationProxy(proxy); } bool NetworkConfig::TcpModeEnabled() { /* * We force TCP mode for both HTTP and SOCKS5 proxies, even though SOCKS5 supports UDP. * * This is because Qt's automatic application-wide proxying fails when we're in UDP * mode since the datagram transmission code assumes that its socket is created in its * own thread. Due to the automatic proxying, this assumption is incorrect, because of * Qt's behind-the-scenes magic. * * However, TCP mode uses Qt events to make sure packets are sent off from the right * thread, and this is what we utilize here. * * This is probably not even something that should even be taken care of, as proxying * itself already is a potential latency killer. */ return g.s.ptProxyType != Settings::NoProxy || g.s.bTCPCompat; } void NetworkConfig::accept() const { NetworkConfig::SetupProxy(); } void NetworkConfig::on_qcbType_currentIndexChanged(int v) { Settings::ProxyType pt = static_cast(v); qleHostname->setEnabled(pt != Settings::NoProxy); qlePort->setEnabled(pt != Settings::NoProxy); qleUsername->setEnabled(pt != Settings::NoProxy); qlePassword->setEnabled(pt != Settings::NoProxy); qcbTcpMode->setEnabled(pt == Settings::NoProxy); s.ptProxyType = pt; } QNetworkReply *Network::get(const QUrl &url) { QNetworkRequest req(url); prepareRequest(req); return g.nam->get(req); } void Network::prepareRequest(QNetworkRequest &req) { req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); // Do not send OS information if the corresponding privacy setting is enabled if (g.s.bHideOS) { req.setRawHeader(QString::fromLatin1("User-Agent").toUtf8(), QString::fromLatin1("Mozilla/5.0 Mumble/%1 %2").arg(QLatin1String(MUMTEXT(MUMBLE_VERSION_STRING)), QLatin1String(MUMBLE_RELEASE)).toUtf8()); } else { req.setRawHeader(QString::fromLatin1("User-Agent").toUtf8(), QString::fromLatin1("Mozilla/5.0 (%1; %2) Mumble/%3 %4").arg(OSInfo::getOS(), OSInfo::getOSVersion(), QLatin1String(MUMTEXT(MUMBLE_VERSION_STRING)), QLatin1String(MUMBLE_RELEASE)).toUtf8()); } }