From 58e2cd94be8cc2b162f507cf8661f865f26675a9 Mon Sep 17 00:00:00 2001 From: Dushnilin Date: Sun, 26 Jul 2026 17:50:49 +0300 Subject: [PATCH] =?UTF-8?q?feat(qos):=20=D0=98=D0=B3=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=B9=20&=20=D0=93=D0=BE=D0=BB=D0=BE=D1=81=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=B9=20QoS=20=D0=A3=D1=81=D0=BA=D0=BE=D1=80=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=20(Low-Latency=20QoS=20Priority=20Engine)=20?= =?UTF-8?q?(v1.2.29)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tachyon/files/usr/lib/nft/apply.uc | 15 ++++++++++ tachyon/files/usr/lib/service/telegram.uc | 35 ++++++++++++++++++++++- tachyon/files/usr/lib/service/watchdog.uc | 20 +++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/tachyon/files/usr/lib/nft/apply.uc b/tachyon/files/usr/lib/nft/apply.uc index a5c24a2b..43b722fb 100644 --- a/tachyon/files/usr/lib/nft/apply.uc +++ b/tachyon/files/usr/lib/nft/apply.uc @@ -888,6 +888,21 @@ function nft_create_runtime_base(table, localv4_set, common_set, port_set, ip_po if (arg_bool(exclude_ntp) && !nft_insert_rule(table, "mangle", [ "udp", "dport", "123", "return" ])) return false; + // QoS Low-Latency Gaming & Voice Acceleration Engine + let qos_enabled = uci_settings().qos_priority_engine != "0"; + if (qos_enabled) { + // Voice & Discord RTC (DSCP EF 0x2e) + nft_add_rule(table, "mangle_forward", [ "udp", "dport", "{ 5000-5020, 3478, 19302, 50000-65535 }", "ip", "dscp", "set", "0x2e" ]); + nft_add_rule(table, "mangle_output", [ "udp", "dport", "{ 5000-5020, 3478, 19302, 50000-65535 }", "ip", "dscp", "set", "0x2e" ]); + + // Gaming Traffic (Steam, CS, Dota, Valorant, Apex, PUBG, Roblox) (DSCP AF41 0x22) + nft_add_rule(table, "mangle_forward", [ "udp", "dport", "{ 3074, 7000-9000, 27000-27050, 28960 }", "ip", "dscp", "set", "0x22" ]); + nft_add_rule(table, "mangle_output", [ "udp", "dport", "{ 3074, 7000-9000, 27000-27050, 28960 }", "ip", "dscp", "set", "0x22" ]); + + // TCP ACK Acceleration (DSCP CS2) + nft_add_rule(table, "mangle_forward", [ "tcp", "flags", "&", "(fin|syn|rst|ack)", "==", "ack", "ip", "dscp", "set", "cs2" ]); + } + return true; } diff --git a/tachyon/files/usr/lib/service/telegram.uc b/tachyon/files/usr/lib/service/telegram.uc index 0f6148f9..bb382000 100644 --- a/tachyon/files/usr/lib/service/telegram.uc +++ b/tachyon/files/usr/lib/service/telegram.uc @@ -395,7 +395,8 @@ function view_menu(token, chat_id, msg_id) { { text: "🐕 Watchdog", callback_data: "/watchdog" } ], [ - { text: "🤖 ИИ-Самолечение", callback_data: "/heal" } + { text: "🤖 ИИ-Самолечение", callback_data: "/heal" }, + { text: "🎮 Игровой QoS", callback_data: "/qos" } ], [ { text: "🩺 Диагностика", callback_data: "/doctor" }, @@ -966,6 +967,36 @@ function exec_ai_heal(token, chat_id, msg_id) { send_message(token, chat_id, text, "HTML", keyboard); } +function view_qos(token, chat_id, msg_id) { + let c = uci_core.cursor(); c.load(CONFIG_NAME); + let cfg = c.get_all(CONFIG_NAME, "settings") || {}; + let enabled = cfg.qos_priority_engine != "0"; + + let text = "🎮 Игровой & Голосовой QoS Ускоритель\n\n" + + "Статус: " + (enabled ? "🟢 Включен (DSCP EF + AF41 Priority)" : "⚪ Выключен") + "\n\n" + + "Приоритетные правила:\n" + + "├ 🎙️ Golos/Discord/RTC: UDP 5000-5020, 3478, 50000-65535 ➔ DSCP EF (0x2e)\n" + + "├ 🎮 Games (Steam/CS/Dota/Apex/PUBG/Roblox): UDP 27000-27050, 3074 ➔ DSCP AF41 (0x22)\n" + + "└ ⚡ TCP ACK Acceleration: малые ACK пакеты ➔ High Priority"; + + let keyboard = [ + [{ text: (enabled ? "⏹️ Отключить QoS" : "⚡ Включить QoS"), callback_data: "/qos_toggle" }], + [{ text: "⬅️ Назад", callback_data: "/menu" }] + ]; + if (msg_id) edit_message(token, chat_id, msg_id, text, "HTML", keyboard); + else send_message(token, chat_id, text, "HTML", keyboard); +} + +function handle_qos_toggle(token, chat_id, msg_id) { + let c = uci_core.cursor(); c.load(CONFIG_NAME); + let cfg = c.get_all(CONFIG_NAME, "settings") || {}; + let new_val = (cfg.qos_priority_engine == "0") ? "1" : "0"; + c.set(CONFIG_NAME, "settings", "qos_priority_engine", new_val); + c.commit(CONFIG_NAME); + system("/usr/bin/tachyon reload_firewall >/dev/null 2>&1 &"); + view_qos(token, chat_id, msg_id); +} + // ─── Dispatcher ────────────────────────────────────────────────────────────── function dispatch_command(token, chat_id, text, msg_id) { @@ -976,6 +1007,8 @@ function dispatch_command(token, chat_id, text, msg_id) { if (cmd == "/status") return view_status(token, chat_id, msg_id); if (cmd == "/runtime") return view_runtime(token, chat_id, msg_id); if (cmd == "/heal" || cmd == "/ai_heal") return exec_ai_heal(token, chat_id, msg_id); + if (cmd == "/qos") return view_qos(token, chat_id, msg_id); + if (cmd == "/qos_toggle") return handle_qos_toggle(token, chat_id, msg_id); if (cmd == "/outbounds") return view_outbounds(token, chat_id, msg_id); if (match(cmd, /^\/outbounds /)) { diff --git a/tachyon/files/usr/lib/service/watchdog.uc b/tachyon/files/usr/lib/service/watchdog.uc index 877dc941..0d0d61aa 100644 --- a/tachyon/files/usr/lib/service/watchdog.uc +++ b/tachyon/files/usr/lib/service/watchdog.uc @@ -425,6 +425,25 @@ function ai_heal_nftables() { return true; } +function ai_heal_qos() { + let cfg = settings(); + if (cfg.qos_priority_engine == "0") return true; + + let nft_table = getenv("NFT_TABLE_NAME") || "TachyonTable"; + let out_nft = command_output_from_args(["nft", "list", "table", "inet", nft_table]); + if (index(out_nft, "dscp set 0x2e") < 0 || index(out_nft, "dscp set 0x22") < 0) { + ai_heal_report( + "qos_priority", + "Правила Игрового & Голосового QoS Ускорителя не найдены в nftables", + "Применены высокоприоритетные метки DSCP EF (0x2e) для Voice/RTC и DSCP AF41 (0x22) для Gaming", + "fixed" + ); + system("/usr/bin/tachyon reload_firewall >/dev/null 2>&1 &"); + return false; + } + return true; +} + function ai_heal_dns() { let cfg = settings(); if (cfg.recovery_bypass == "1") return true; @@ -508,6 +527,7 @@ function ai_heal_proxy_connectivity() { function ai_full_health_audit() { check_memory(); ai_heal_nftables(); + ai_heal_qos(); ai_heal_dns(); ai_heal_proxy_connectivity(); ai_export_status();