Пустых catch в кодовой базе около полусотни, и они не одинаковые. Большинство
выражает намерение: fs.unlink бросает на ENOENT, а вызывающий говорит «пусть
этого файла не будет», и отсутствующий файл это условие уже выполняет; разбор
json в цикле пропускает мусорную строку и берёт следующую. Такие места теперь
несут пояснение, почему пустое тело здесь и есть правильный ответ.
Семь мест к этому классу не относились: там сбой означал потерю состояния, а
дальше код шёл так, будто всё получилось.
Watchdog писал через пустой catch файл лока перезапуска прокси, шкалу
GOMEMLIMIT после OOM, бэкап конфига и метку keepalive. Не лёгший лок означает,
что следующий тик перезапустит прокси заново, а счётчик rate-limit об этом не
узнает; не записанная метка keepalive заставляет init.d считать watchdog мёртвым
и перезапускать его. Все четыре теперь идут через write_state_file, который
логирует отказ. Метка пишется на каждом тике uloop, поэтому безусловная строка
залила бы syslog именно при переполненной файловой системе — там, где лог нужнее
всего; вместо этого каждый путь сообщает о первом отказе и молчит до следующего
успеха, что заодно делает видимым восстановление.
Контроллер разбирал /etc/sing-box/config.json ради портов http и tproxy и при
неудаче молча брал 4534 и 4530. Watchdog после этого опрашивает не тот порт,
вечно считает прокси нерабочим и лечит его по кругу — при том, что в логе нет
ничего, что связало бы это с конфигом. Разбор вынесен в общую функцию, которая
сообщает о непарсящемся конфиге один раз на процесс.
Telegram молча терял карту callback-токенов: токен уже вшит в клавиатуру к
моменту записи, поэтому провал отдаёт пользователю кнопку, которая на нажатие
ответит «кнопка устарела». Обновление списков молча теряло маркер отложенного
применения nft — списки обновлены на диске и до nftables не доехали никогда,
а строкой выше в лог написано, что маркер сохраняется. urltest молча выкидывал
битое регулярное выражение из конфига пользователя, отчего группа тихо
подхватывала меньше outbound-ов, чем сказано в конфиге.
tests/heal_escalation.sh проверял порядок строк по литералу fs.writefile для
лока и обновлён под новый вызов.
- wget: remove -t flag incompatible with BusyBox 25.12+, add curl-first fallback
in download_to_file() with wget as fallback
- startup/reload speedup (5 improvements):
- cut sing-box verification timeout from 45 iterations to 15
- remove redundant second stability wait for sing-box process
- batch requirement check + runtime validation into single ucode fork
- replace dnsmasq full restart with procd reload (config-conditional bounce)
- move telegram and watchdog runtime start to background
- telegram: fix "API failure" spam - empty result[] from getUpdates is now
treated as a successful idle poll, not an error that triggers backoff
- watchdog SmartDetect: extract domain from proxy and VPN URLs for DNS
health check, use real domains (google.com/example.com) instead of
provider-specific endpoints that trigger false alerts
- tests: new invariants for wget -t prohibition, telegram empty-result
handling, DNS apply reload-vs-restart, and combined validation mode ownership
Дашборд:
- Добавлены карточки статуса Zapret, Zapret2, ByeDpi на панель мониторинга
- Показывают статус (работает/остановлен), количество перезапусков, предупреждения
- Баг: API возвращает boolean а не число — исправлено сравнение
Секция Hosts:
- Перенесены опции hosts из глобальных настроек в отдельный тип секции (action=hosts)
- Опции: пользовательские DNS записи, удалённые списки хостов, автообновление, интервал
- Миграция: автоматический перенос глобальных настроек hosts в секцию
- Вкладка «Условия» скрыта для секций типа Hosts (hosts записи применяются глобально)
- Возвращена кнопка «Import Hosts File» с модальным окном загрузки из файла
- Убраны неиспользуемые опции из settings.js (~280 строк)
Локализация:
- Переведены 6 новых строк для превью импорта hosts
generator.uc: try/catch around hosts cache file read with guaranteed close
hosts.uc: try/catch around parse_hosts_file with guaranteed close
migration.uc: try/catch around remove_cache_path, checked unlink in remove_legacy
runtime.uc: cleanup stale temp config files on init_config startup
lifecycle.uc: log warning on nft table delete failure in stop_main
migration.uc:
- try/catch around migration.run() with error logging
- try/catch around apply_operations() with error logging
- Error checking for UCI cursor operations in apply_operations
- Checked fs.writefile return values in ensure_runtime_cache_format
updates.uc:
- Write pending marker on lock acquisition failure for next retry
Ключевые изменения:
1. core/helpers.uc: file_is_usable(path, min_bytes) + file_size_value(path)
для единообразной проверки файлов (минимальный размер порог).
2. singbox/dns.uc: WAN fallback DNS серверы (fallback_wan_main) теперь
используют прямой UDP без detour — исправлена петля когда
DNS шёл через мёртвую прокси-секцию.
Health probes для ВСЕХ DNS серверов (включая DoH) идут direct —
failover может определить доступность DNS серверов.
3. watchdog.uc: ai_heal_empty_sections() — автообнаружение пустых
proxy-секций с подписками → запуск subscription_update_async.
ai_heal_dns_loop() — при обнаружении DNS-петли (dead proxy +
dead DNS) → временно отключает DNS detour → загружает подписку →
восстанавливает настройки.
4. Единая file_is_usable: nft/apply.uc, generator_routes.uc,
components/{updates,action}.uc, config/validator.uc,
subscription/cache.uc — все используют helpers.file_is_usable.
5. Тест tests/file_usable.sh для проверки helpers CLI.
6. Исправлен components_updater_job.sh mock lib — добавлен core/helpers.uc
1. Добавлен встроенный установщик Tor через LuCI-попап с поддержкой opkg и apk.
2. Маршрутизация скрытых сетей (.onion / .i2p) интегрирована на уровень backend (route.uc, generator.uc).
3. Добавлена прозрачная поддержка форка sing-box lx: UI и генераторы теперь корректно включают 'extended' фичи для lx.
4. Проведен полный аудит и восстановление отсутствующих переводов в fe-app-tachyon и luci-app-tachyon.
Resolves merge conflicts:
- install.sh, build.sh, .github/workflows/build.yml: Reverted to Dushnilin's versions to avoid installing SourceForge mirrors.
- fe-app-tachyon: Resolved type, formatting and copyOutbound conflicts, keeping both Dushnilin's custom features and ushan0v's frontend performance optimizations.
- backend: Kept Dushnilin's ucode refactorings, Telegram bot integration, and release repository URL (Dushnilin/tachyon) while merging updates.uc cache format v8 & persistent cache format v7.
- tests: Merged tests from both branches, preserving ucode -L wrappers for local test execution.
- Вынесена логика вызова команд shell в core.common
- Удалено дублирование реализации чтения stdin и извлечения параметров UCI
- Громоздкие циклы парсинга URL в helpers.uc переписаны на регулярные выражения
- Проверка IPv4/IPv6 упрощена до использования регулярных выражений вместо построчного разбора
- Использованы встроенные функции ucode (lc, length) вместо ручных аналогов
- Очистка фронтенда: удален функционал мониторинга прямого трафика и лишняя колонка 'Add to' из UI таблиц