From ae85423e39d8dc24dd843b6f74cbfc6fbe50448a Mon Sep 17 00:00:00 2001 From: evgeny Date: Sun, 25 Oct 2026 16:22:50 +0100 Subject: [PATCH] Add automatic socket protocol selector to desktop settings --- src/transport_layer/auto_socket.h | 5 ++-- tools/chatgui/src/networksettingspage.cpp | 33 ++++++++++++++++++++--- tools/chatgui/src/networksettingspage.h | 1 + 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/transport_layer/auto_socket.h b/src/transport_layer/auto_socket.h index 046d693e..f03408c3 100644 --- a/src/transport_layer/auto_socket.h +++ b/src/transport_layer/auto_socket.h @@ -1,6 +1,7 @@ /* auto_socket — создание UDP/TCP-сокетов и линков при появлении сетевых интерфейсов. * При auto_sockets=yes init сканирует интерфейсы и включает мониторинг Linux/BSD/Windows; - * адреса и набор сокетов затем обновляются автоматически. Порты сохраняются в SQLite для повторного использования. + * auto_socket_protocols выбирает TCP, UDP или TCP+UDP (по умолчанию); адреса и сокеты обновляются автоматически. + * Порты сохраняются в SQLite для повторного использования. * Destroy отключает мониторинг и удаляет созданные ресурсы. В режиме android сокеты приходят из конфигурации frontend. * Основной API — uasync-поток. Из другого потока вызывать только on_network_change, пока instance жив. * Add/remove_interface предназначены для платформенного мониторинга; смена сети сама не создаёт членство в группе. */ @@ -44,7 +45,7 @@ void auto_socket_reload_config(struct UTUN_INSTANCE* inst, struct utun_config* n // ─── Внутренний API платформенного мониторинга ─── /* - * Создать UDP+TCP сокеты для интерфейса и добавить разрешённые линки к активным NCD-транспортам вне FIN_WAIT. + * Создать выбранные auto_socket_protocols сокеты интерфейса и разрешённые линки к активным NCD-транспортам вне FIN_WAIT. * ifindex — индекс интерфейса (0 = автоопределение по ifname) * ifname — имя интерфейса для SO_BINDTODEVICE * has_v4 — есть ли IPv4 адреса на интерфейсе diff --git a/tools/chatgui/src/networksettingspage.cpp b/tools/chatgui/src/networksettingspage.cpp index da5e340c..80b3d32d 100644 --- a/tools/chatgui/src/networksettingspage.cpp +++ b/tools/chatgui/src/networksettingspage.cpp @@ -31,8 +31,19 @@ NetworkSettingsPage::NetworkSettingsPage(QWidget* parent) title->setStyleSheet("font-weight: bold; font-size: 13px;"); layout->addWidget(title); - m_autoSocketsCheck = new QCheckBox(QCoreApplication::translate("ChatGui", "Auto sockets (UDP+TCP from interfaces)"), this); + m_autoSocketsCheck = new QCheckBox(QCoreApplication::translate("ChatGui", "Auto sockets from interfaces"), this); layout->addWidget(m_autoSocketsCheck); + auto* autoProtocolsRow = new QHBoxLayout(); + autoProtocolsRow->addWidget(new QLabel(QCoreApplication::translate("ChatGui", "Socket protocols:"), this)); + m_autoProtocolsCombo = new QComboBox(this); + m_autoProtocolsCombo->setObjectName(QStringLiteral("autoSocketProtocols")); + m_autoProtocolsCombo->addItem(QStringLiteral("TCP"), QStringLiteral("tcp")); + m_autoProtocolsCombo->addItem(QStringLiteral("UDP"), QStringLiteral("udp")); + m_autoProtocolsCombo->addItem(QStringLiteral("TCP+UDP"), QStringLiteral("tcp+udp")); + m_autoProtocolsCombo->setCurrentIndex(2); + autoProtocolsRow->addWidget(m_autoProtocolsCombo); + autoProtocolsRow->addStretch(); + layout->addLayout(autoProtocolsRow); m_serverList = new QListWidget(this); m_serverList->setMinimumHeight(110); @@ -150,6 +161,7 @@ void NetworkSettingsPage::populateAddresses() { void NetworkSettingsPage::applyAutoSocketsState() { bool manual = !m_autoSocketsCheck->isChecked(); + m_autoProtocolsCombo->setEnabled(!manual); m_serverList->setEnabled(manual); m_addBtn->setEnabled(manual); m_removeBtn->setEnabled(manual); @@ -259,6 +271,7 @@ void NetworkSettingsPage::loadFromConfig(const QString& configPath) { /* auto_sockets из [global] */ bool autoSockets = false; + QString autoProtocols = QStringLiteral("tcp+udp"); struct chat_setting_state localSettings = {}; f.setFileName(configPath); if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -270,9 +283,11 @@ void NetworkSettingsPage::loadFromConfig(const QString& configPath) { section = line.mid(1, line.length() - 2); continue; } - if ((section == "global" || section.isEmpty()) && line.startsWith("auto_sockets=")) { - QString v = line.section('=', 1).trimmed(); - autoSockets = (v.compare("yes", Qt::CaseInsensitive) == 0 || v == "1"); + if ((section == "global" || section.isEmpty()) && line.contains('=')) { + QString key = line.section('=', 0, 0).trimmed(); + QString value = line.section('=', 1).section('#', 0, 0).section(';', 0, 0).trimmed().toLower(); + if (key == "auto_sockets") autoSockets = (value == "yes" || value == "1"); + else if (key == "auto_socket_protocols") autoProtocols = value; } if (section == "chatserver" && line.contains('=')) { QByteArray key = line.section('=', 0, 0).trimmed().toUtf8(); @@ -285,6 +300,13 @@ void NetworkSettingsPage::loadFromConfig(const QString& configPath) { f.close(); } m_autoSocketsCheck->setChecked(autoSockets); + int protocolsIndex = m_autoProtocolsCombo->findData(autoProtocols); + if (protocolsIndex < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "network settings: invalid auto_socket_protocols='%s' path=%s", + qPrintable(autoProtocols), qPrintable(configPath)); + protocolsIndex = 2; + } + m_autoProtocolsCombo->setCurrentIndex(protocolsIndex); m_localInvitesCheck->setChecked(chat_setting_get_int_state(&localSettings, "local_invites_enabled", 1) != 0); m_localBroadcastsCheck->setChecked(chat_setting_get_int_state(&localSettings, "local_broadcasts_enabled", 1) != 0); @@ -295,12 +317,15 @@ void NetworkSettingsPage::loadFromConfig(const QString& configPath) { bool NetworkSettingsPage::saveToConfig(const QString& configPath) const { if (!config_rewrite_servers(configPath, m_servers) || !config_update_option(configPath, "global", "auto_sockets", m_autoSocketsCheck->isChecked() ? "yes" : "no") || + !config_update_option(configPath, "global", "auto_socket_protocols", m_autoProtocolsCombo->currentData().toString()) || !config_update_option(configPath, "chatserver", "local_invites_enabled", localInvitesEnabled() ? "1" : "0") || !config_update_option(configPath, "chatserver", "local_broadcasts_enabled", localBroadcastsEnabled() ? "1" : "0")) { DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "network settings: saving failed path=%s", qPrintable(configPath)); return false; } DEBUG_INFO(DEBUG_CATEGORY_DISCOVERY, "LAN permissions saved receive_invites=%d broadcast=%d", localInvitesEnabled(), localBroadcastsEnabled()); + DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "Auto sockets saved enabled=%d protocols=%s; applies after restart", + m_autoSocketsCheck->isChecked(), qPrintable(m_autoProtocolsCombo->currentData().toString())); return true; } diff --git a/tools/chatgui/src/networksettingspage.h b/tools/chatgui/src/networksettingspage.h index 0cdea06e..447b1eba 100644 --- a/tools/chatgui/src/networksettingspage.h +++ b/tools/chatgui/src/networksettingspage.h @@ -42,6 +42,7 @@ private: void updateSelectedListItemText(); QCheckBox* m_autoSocketsCheck; + QComboBox* m_autoProtocolsCombo; // протоколы автосокетов: TCP, UDP, TCP+UDP QCheckBox* m_localInvitesCheck; // разрешение входящих LAN-приглашений QCheckBox* m_localBroadcastsCheck; // рассылка собственного присутствия в LAN QListWidget* m_serverList;