- Fix#50: Discord community subnets hijacking Cloudflare Anycast traffic:
* Filter broad Cloudflare shared subnets (104.16.0.0/12, 172.64.0.0/13, etc.) for Discord preset in generator_routes.uc, nft/apply.uc, and updates.uc.
* Add tachyon resolve_domain CLI and runtime.uc helper for DNS queries with rpcd ACL support.
* Update LuCI Routing Rule Tracer to resolve queried domains against section subnets/CIDRs (including community subnets) and show shared CDN/Anycast warnings.
* Add unit tests in tests/community_subnets_sanitization.sh.
- Fix#51: Telegram bot spamming WAN up/down notifications on hotplug:
* Check enable_badwan_interface_monitoring, telegram.enabled, and badwan_monitored_interfaces list in 99-tachyon-wan-monitor.
* Add background debounce with atomic directory locking and ubus interface status verification.
* Implement state transition tracking to only notify on actual UP->DOWN and DOWN->UP changes without duplicates.
* Preserve retry_start_on_wan_up behavior on ifup.
* Add comprehensive integration test suite in tests/wan_monitor_hotplug.sh.
UI (section.js):
- showUrlTestSettingsModal и showPriorityLevelSettingsModal: предзагрузка
кэша outbound-имён до открытия модала — CBINamedSection.render() не
вызывает section.load(), из-за чего DynamicList рендерился без данных
- renderStackedJsonSettingsModal: вызов map.load() перед map.render()
LuCI ACL (luci-app-tachyon.json):
- Добавлены пути /tmp/run/tachyon/... наряду с /var/run/tachyon/...
На OpenWrt /var — симлинк на /tmp; rpcd резолвит симлинки перед
проверкой ACL, поэтому /var/run/... никогда не давал прав чтения
и fs.read() возвращал PermissionError
Postinstall (50_luci-tachyon):
- Добавлен перезапуск rpcd после установки пакета, чтобы новые ACL
вступали в силу без ручного logout/login в LuCI
Telegram-бот (telegram.uc):
- handle_toggle_mac(): блокировка/разблокировка устройств теперь
через правила firewall (fw4), а не через UCI blocked_macs
- /cb команда: разрешение токенизированных коллбэков для oversized
inline-клавиатур (лимит Telegram 64 байта на callback_data)
- /qh_start, /qh_end: интерактивная настройка часов тихого режима
- in_quiet_hours() и daily report: исправлен localtime(time())
вместо clock() — clock() возвращает [сек, мксек], а не tm-структуру
- Уведомления об обновлениях: current_version вместо installed_version
- Описание команды /restart исправлено
Backend (api.uc, state.uc):
- http_probe(): выделена функция с проверкой HTTP-статуса
(curl выходит 0 даже при 4xx/5xx — теперь проверяем код явно)
- run_speedtest(): учёт curl exit status
- Math.random() заменён на clock()[1] (Math недоступен без import)
- current_year(): убрано +1900 — localtime().year уже полный год
- Дашборд: Добавлена таблица 'Активные клиенты' с отображением имен устройств, IP, соединений и трафика.
- Дашборд: Исправлена ширина интерфейса при свернутом блоке подписки.
- Дашборд: В заголовке свернутой подписки теперь отображается пинг выбранного сервера.
- Дашборд: Для AWG и VPN соединений в таблице отображается пинг вместо статуса 'Connected'.
- Диагностика: Исправлена кнопка генерации отчета об ошибках (bugreport) и добавлена маскировка приватных данных.
- Локализация: Обновлены файлы переводов .po, исправлен парсинг кавычек в генераторе.