Commit Graph
2117 Commits
Author SHA1 Message Date
Dushnilin 9927c04a6f fix: resolve crash on geoip_country selection and harden hosts list download (1.3.20) 2026-09-04 17:46:48 +03:00
Dushnilin 2f83954255 fix(updates): resolve service restart timeout and LuCI session drop on upgrade (1.3.20) 2026-09-04 17:15:52 +03:00
Dushnilin 0cfc351d5a fix: restore zapret2 worker startup, fast doctor check, and dnsmasq sync (1.3.20) 2026-09-04 16:47:08 +03:00
Dushnilin 6bedef4c77 fix: zapret2 daemon privileges and lua loader, dnsmasq reload auto-repair (1.3.20) 2026-09-04 14:45:01 +03:00
Dushnilin e901f9d41a fix: zapret2 startup, dnsmasq fakeip rebind protection, dns detour routes (1.3.19) 2026-09-04 13:56:48 +03:00
Dushnilin 196782b18d feat: variant badges, live RSS RAM tracking, sysctl network tuning, telegram updates (1.3.18) 2026-09-03 23:23:39 +03:00
Dushnilin 875c483b37 fix(dns): eliminate invalid non-capturing regex in nslookup fallback parser 2026-09-03 23:05:31 +03:00
Dushnilin 4c69a98c27 fix(singbox): fix Leadaxe (lx) version parsing regex and AWG startup on OpenWrt
- In action.uc: replace broken PCRE non-capturing regex in extract_sing_box_version_from_output with token-based field splitting. ucode POSIX regex engine threw 'Repetition not preceded by valid expression', crashing component_action during binary validation.
- In telegram.uc: replace non-capturing group (?:outbounds|server|servers) with standard capturing group for POSIX regex compatibility.
- In generator_outbounds.uc and servers.uc: enhance is_lx detection to check sing-box-version file in addition to sing-box-variant, ensuring AWG 2.0 root schema is generated even if variant file is desynced.
- In runtime.uc: add fallback recovery in sing_box_check retry loop for endpoints (auto-flattening amnezia sub-objects) and outbounds unknown fields.
2026-09-03 21:11:00 +03:00
Dushnilin a2cd11a74c fix(dns): fix 2.5s DNS benchmark and diagnostic probe latency on OpenWrt
- In benchmark.uc and service_check.uc, pass -timeout=2 -type=a to nslookup
- Prevents BusyBox nslookup from sending simultaneous A and AAAA queries across WAN, which causes a 2.5-second retransmit timeout bug on dual-stack/IPv4 routers
- Reduces measured latency from ~2534ms down to true round-trip ping time (~8-15ms)
- Cache tool lookups in has_tool() to avoid spawning redundant child processes
2026-09-03 19:39:57 +03:00
Dushnilin 1c48422511 fix(luci): ensure Tachyon menu item reliably appears in LuCI
- Remove 'uci: { tachyon: true }' dependency from menu.d/luci-app-tachyon.json so LuCI does not hide the menu node if UCI config is uncommitted/reloading
- Add portable timeout normalization in install.sh ucode to handle Busybox timeout and systems without timeout applet
- Ensure luci_postinst is called directly in IPK postinst (build.sh) and after install in install.sh
- Restart uhttpd alongside rpcd and purge LuCI caches in post-install and uninstaller
- Fix uninstall.sh to remove packages individually with lock retry and omit non-existent luci-i18n-tachyon-en
- In install_ui_packages, verify that menu.d/luci-app-tachyon.json actually exists on disk before proceeding
2026-09-03 19:14:22 +03:00
Dushnilin 5c7aa58669 fix(updates): force reinstall and robust validation for sing-box-extended package
- Pass force_reinstall=true to opkg when installing sing-box-extended packages to prevent opkg from silently skipping file extraction on up-to-date packages after the binary backup was moved
- Ensure chmod 0755 on /usr/bin/sing-box after package extraction and before validation
- Include /lib in LD_LIBRARY_PATH when library_dir is set to prevent dynamic linker failures
- Robustly match 'version <tag>' from binary output in read_sing_box_binary_version and log diagnostic details on failure
2026-09-03 07:52:30 +03:00
Dushnilin abaa891dd3 fix(updates): resolve component update hang and multiple page reload loop
- action.uc: sweep stuck flock 1000 processes before tachyon restart, bound service restart with 25s timeout, and prevent worker lockup
- shell/index.ts: add 15-minute general hard timeout for non-Tachyon components to prevent infinite modal spin; allow same-version confirmation for both install and reinstall
- package.uc: remove disruptive uhttpd restart from luci_postinst to prevent active socket drops
- ui.uc: refresh stale PID state before checking value.running in action_ack so dead jobs can always be acknowledged
- initController.ts & sessionJobs.ts: persist handled job IDs across reloads in sessionStorage, eliminate redundant modal popups on page reload, and guard against concurrent reloads with safeReloadPage
- renderUpdateProgressModal.ts: record active job before reload and poll readiness with fast health check instead of blind 5s freeze
2026-09-03 07:36:30 +03:00
Dushnilin 36fe7ef312 fix(package): preserve managed sing-box on package upgrade 2026-09-03 07:22:05 +03:00
Dushnilin 43eafd8655 fix(singbox): filter dummy subscription nodes and handle empty binary rulesets on boot 2026-09-03 06:26:39 +03:00
Dushnilin b3358f77a3 fix(stability): optimize Go memory tiers, prevent nftables degradation deadlock, harden NTP & process supervision
- singbox/runtime.uc: add dynamic 4-tier GOMEMLIMIT and GOGC limits based on RAM, enforce /etc/tachyon/mem_scale, and install managed init script across all binary variants
- service/event_controller.uc: guard probe_nftables() with recovery_bypass and native_internet_restored checks to prevent 5-minute network drop deadlock
- service/watchdog.uc: reduce Telegram worker heartbeat timeout from 900s to 300s and add nslookup fallback to Zero-RTT prefetcher
- diagnostics/runtime.uc & service/lifecycle.uc: use direct-IP NTP pool to eliminate circular DNS/TLS deadlocks, and step clock forward on cold boot if RTC desynced
- service/failover.uc & diagnostics/runtime.uc: flush conntrack states on proxy group switch so client connections immediately migrate
2026-09-03 06:13:30 +03:00
Dushnilin ea85164646 docs: expand README.md and README.en.md with comprehensive feature set
- add DPI Fuzzer Engine section (PAWS TCP timestamp spoofing, authentic blobs, seqovl, TCP SYN data, target suites, Netfilter queue isolation)
- add Smart DNS & Failover section (FakeIP pool, DoH/DoT/DoQ/H3, DNS Failover daemon, anti-hijack redirection, DNS Benchmark & Autotune)
- add Parental Controls, Quotas & Smart QoS section (per-device schedules, bandwidth quotas, DSCP packet marking in nftables)
- expand Telegram bot features (real-time connection monitor, quiet hours, live section editor, resilient dual-transport, 64-byte payload protection)
- add MCP (Model Context Protocol) server documentation and WARP / AmneziaWG generator
- expand CLI reference with complete practical command table
2026-09-03 05:14:55 +03:00
Dushnilin f2d846515c chore(deps): upgrade @humanfs/node to 0.16.8 to resolve dependabot alert 2026-09-03 05:02:57 +03:00
Dushnilin 9c80cb4442 fix(telegram): eliminate hang bugs, button payload limit, and sync reload lifecycle
- wrap /sw callback data in cb_data() to strictly enforce 64-byte limit and prevent BUTTON_DATA_INVALID API rejections
- sync telegram daemon in lifecycle reload() so LuCI Save & Apply starts/reloads bot automatically without router reboot
- cleanly stop telegram worker in stop_main() to prevent orphaned background polling processes
- reduce interactive curl timeout in tg_request_via from 35s to 12s, preventing 70s worker freeze on proxy stalls
- close open HTML tags on message truncation and add fallback to plain text if Telegram entity parsing fails
- reduce watchdog telegram worker restart cooldown from 3600s to 120s
- fix nftables check in /test to inspect TachyonTable instead of legacy ip tachyon
- add command aliases /server, /servers, /rules, /ai_doctor and fix integer division in /connections pagination
2026-09-03 05:00:40 +03:00
Dushnilin cce9e026a2 fix(fuzzer): eliminate nfq_create_queue race conditions, rogue daemon leaks and fix modal badge rendering 2026-09-02 21:58:43 +03:00
Dushnilin 13bd69cef9 feat(fuzzer): god-tier strategy generator with PAWS timestamp spoofing, real TLS blobs, and 280+ combinatorial matrix 2026-09-02 20:27:26 +03:00
Dushnilin 963185569e fix(fuzzer): support .lua.gz scripts and correct zapret2 desync function names 2026-09-02 19:37:13 +03:00
Dushnilin fd629555c7 feat(dns): recommend multiple diverse servers for primary DoH, bootstrap, and fallback DNS 2026-09-02 18:38:30 +03:00
Dushnilin 5f4bfc7caf fix(dns): optimize benchmark probing with host caching and strict timeouts 2026-09-02 18:19:37 +03:00
Dushnilin de691c61ab feat(dns): prioritize encrypted DoH as primary DNS with verified UDP bootstrap resolution 2026-09-02 17:29:51 +03:00
Dushnilin 4a46d78e60 fix(singbox): restore strict unusable outbounds rejection while preserving country filter fallback 2026-09-02 16:52:00 +03:00
Dushnilin e8932d3f2d fix(core): prevent ruleset download_detour crash, resilient selector fallback, and clean legacy migration 2026-09-02 16:49:10 +03:00
Dushnilin ad960a173a fix(dns): two-phase cascade benchmark with verified bootstrap DNS resolution 2026-09-02 16:25:58 +03:00
Dushnilin d72e381018 fix(dns): probe DoH with RFC 8484 wireformat and direct IP resolution 2026-09-02 16:18:31 +03:00
Dushnilin 2e094a5c15 fix(tests): update applied_migrations expected fixtures in config_migration.sh 2026-09-02 15:58:07 +03:00
Dushnilin fa38422260 fix(tests): supply isolated cache dirs in config_migration dns tests 2026-09-02 15:54:30 +03:00
Dushnilin de61450e91 ci: include luci-app-tachyon and locales in backend-ci triggers 2026-09-02 15:45:03 +03:00
Dushnilin 8e1d613959 chore(locales): synchronize source and packaged Russian PO catalogs 2026-09-02 15:42:08 +03:00
Dushnilin f3b1feba31 chore(release): bump version to 1.3.14 2026-09-02 15:38:47 +03:00
Dushnilin 6b92b12135 fix(singbox): supply default /dns-query path and SNI for DoH/DoT IP addresses
- When users configure plain IP addresses (e.g. 8.8.8.8, 1.1.1.1, 77.88.8.8) with DoH (https in sing-box), sing-box requires a non-empty HTTP path (defaulting to /dns-query) and proper TLS SNI (server_name) matching the provider certificate.
- Added default /dns-query path fallback in server_from_options().
- Added KNOWN_DNS_SERVER_NAMES mapping for Google, Cloudflare, Yandex, Quad9, AdGuard, Mullvad, Control D, AliDNS, OpenDNS, DNS.SB to provide correct TLS SNI when connecting to raw DNS IPs.
- Added comprehensive DoH/DoT unit tests in tests/dns_failover.sh.
2026-09-02 15:34:27 +03:00
Dushnilin 84658d84dc feat(dns): add intelligent DNS Benchmark, Auto-Tuner & clean defaults
- Implement ucode module dns/benchmark.uc:
  * Probes major DNS servers (Yandex, Cloudflare, Google, Quad9, AdGuard, Comss, Mullvad, Control D) across UDP 53 and DoH.
  * Measures latency, packet loss, and detects ISP DNS poisoning/hijacking.
  * Intelligent recommendation engine computes optimal primary DNS (prefers encrypted DoH if fast), bootstrap plain UDP, fallback plain UDP from independent provider, and upstream mode (sequential/parallel).
  * Supports CLI execution (tachyon dns_benchmark, tachyon dns_autotune --apply) and background async worker mode for LuCI UI.
- LuCI Web UI modal (renderDnsBenchmarkModal.ts):
  * Real-time progress bar, responsive results table with latency rating badges.
  * Recommendation summary card with one-click 'Apply Recommended DNS' action.
  * Added '⚡ Auto-Tune & Benchmark DNS' button in Settings -> DNS tab.
- Added comprehensive unit tests in vitest (538/538 passed) and tests/dns_benchmark.sh.
- Added Russian PO translations.
2026-09-02 15:28:23 +03:00
Dushnilin a2eaf25c90 fix(runtime): auto-detect listen IP via ubus interface dump on x86/64
On x86/64 the LAN interface is often named 'eth1', 'enp2s0', etc.
in UCI - not 'lan' or 'br-lan'. The two-tier probe both fail,
producing 'Failed to determine the listening IP address' on startup.

Add a third-tier fallback using ubus network.interface dump:
- is_private_ipv4(): RFC-1918 address check
- network_interface_dump_first_private_ipv4(): iterates all UCI
  interfaces, skips wan/wan6/loopback, returns first private IPv4

Workaround (no update needed):
  uci set tachyon.settings.service_listen_address='192.168.x.x'
  uci commit tachyon && /etc/init.d/tachyon restart
2026-09-02 15:16:15 +03:00
Dushnilin 557058c772 fix(ui): reject DoH URLs and path-style DoH in dns_fallback_server field
Mirror the backend validator.uc checks in the LuCI settings UI.
Previously the validate function used validateDNS() which accepts
DoH path format (e.g. 'cloudflare-dns.com/dns-query'); now we gate
before that call with explicit checks matching the backend:
  - '://' → DoH/DoT URL (e.g. 'https://cloudflare-dns.com/...')
  - '/'   → path-style DoH (e.g. 'cloudflare-dns.com/dns-query')

Also add Russian translations for both new error messages.
2026-09-02 14:20:33 +03:00
Dushnilin 6b8e143d0b fix(validator): also reject path-style DoH in dns_fallback_server
A value like 'cloudflare-dns.com/dns-query' is the sing-box DoH
path format. The previous check only caught 'https://' URLs.
dns_server_value_valid() accepts it because it validates only the
host part — so 'cloudflare-dns.com' passed as a valid hostname.

Fallback servers are plain UDP only; any '/' in the value is the
DoH path separator and must be rejected.

Changes:
- validator.uc: add index(value, '/') >= 0 check before the
  dns_server_value_valid call
- config_validator_runtime.sh: add regression test for path-style
  DoH ('cloudflare-dns.com/dns-query') in dns_fallback_server
2026-09-02 14:18:32 +03:00
Dushnilin 6e45ecab6a fix(validator): validate dns_fallback_server entries, reject URL schemes
Fallback servers must be plain UDP (IP or IP:port). Before this fix a
user could accidentally enter a DoH URL (https://...) as a fallback
server — the validator passed it through, and it silently failed at
runtime because dns_failover treats all fallback entries as UDP.

Changes:
- validator.uc: after main/bootstrap validation, check all
  dns_fallback_server values: reject entries containing '://'
  (protocol URL scheme) with a clear error, then validate each
  with dns_server_value_valid for format correctness
- config_validator_runtime.sh: assert_rejects for a DoH URL in
  dns_fallback_server
2026-09-02 14:09:28 +03:00
Dushnilin b82a151c87 fix: inject DNS defaults on forkop->tachyon migration, add LuCI E2E check
Fixes Tachyon startup abort when migrated config has no dns_server or
bootstrap_dns_server (forkop/podkop did not require these fields).

Changes:
- migration.uc: add ensure_dns_server_defaults migration that injects
  77.88.8.8 as fallback when either dns list is empty
- default config: pre-mark orphan_section_interface_cleanup and
  ensure_dns_server_defaults as applied so fresh installs skip them
- tests/config_migration.sh: regression tests for both missing-DNS cases
  and stable named-marker assertion for the new migration
- tests/package_contract.sh: enforce that default config ships both new
  migration IDs in applied_migrations
- tests/docker_e2e_test.sh: also install luci-app-tachyon and verify
  menu.d + acl.d files are present after install (LuCI menu bug class)
2026-09-02 14:00:54 +03:00
Dushnilin 0f0eb90cdc fix: add missing command_status_from_args alias in singbox/runtime.uc
Fixes crash-loop introduced in 1.3.13. The function was called on lines
494-495 (stop/disable conflicting forkop/podkop services at startup) but
the alias was never declared, unlike command_success_from_args on line 48.
This caused a 'Type error: left-hand side is not a function' crash in
configure_service(), sending Tachyon into a 75-second crash loop.

Fixes #44
2026-09-02 13:20:19 +03:00
Dushnilin 60cd0d155a fix(subscription): eliminate forward-reference crashes in runtime_cache_missing
Remove helper functions section_cache_has_outbounds and section_has_source_cache
which called source_json_path (line 513), subscription_cache_is_usable (line 507)
and object_key_count (line 1115) — all defined AFTER their call site at line 334.
ucode has no function hoisting, so these caused 'left-hand side is not a function'.

Inline the logic directly in runtime_cache_missing using only primitives
available before line 334:
- read_json (line 59)
- object_or_empty, fs.stat, source_id (line 251)
- subscription_source_count (line 300)
- TMP_SUBSCRIPTION_FOLDER (line 30)
- for-in loop to check empty object (no object_key_count needed)
2026-09-02 08:09:37 +03:00
Dushnilin b03f4d8d5c fix(subscription): fix read_json_file -> read_json in section_cache_has_outbounds
Incorrect function name caused a Type error crash in CI:
  'left-hand side is not a function'

Also replace for-in early-return trick with object_key_count() which
already exists in this file (see line 1145).
2026-09-02 08:05:19 +03:00
Dushnilin 6dc6ed9486 fix(subscription): rebuild sing-box when section-cache empty but source data available
When a new subscription section is added that shares the same URL as an
existing section, the following race occurs:

1. Sing-box config is generated — source cache doesn't exist yet for the
   new section, so it is added with zero outbounds; section-cache file is
   written (empty outboundMetadata.names).
2. Background subscription download runs — content is identical to the
   existing section, so result is 'unchanged' (return 2), updated=0.
3. reload-service is triggered — runtime_cache_missing returns false
   because the section-cache file exists, so sing-box is NOT reloaded.
4. Servers from the new section never appear in the UI.

Fix: runtime_cache_missing now also returns true when a section-cache file
exists but contains no outbounds (names={}) while the source subscription
cache is already available in TMP_SUBSCRIPTION_FOLDER. This causes the
next reload cycle to regenerate sing-box config with the actual servers.
2026-09-02 08:01:38 +03:00
Dushnilin cc4ad5855a feat(dns): expand DNS server presets for UDP, DoH, DoT, DoQ and Bootstrap 2026-09-01 22:00:04 +03:00
Dushnilin 8b3c3e365f feat(dns): upstream mode (sequential/parallel) & explicit fallback DNS servers, bump 1.3.13 2026-09-01 20:49:21 +03:00
Dushnilin f55f37f804 fix(ui): добавить load() в EntryPoint — UCI не загружался до render(), tab_order всегда был default 2026-09-01 19:36:44 +03:00
Dushnilin 79a4d477db fix(ui): заменить input[checkbox] на button-тогл в виджете порядка вкладок (починить кликабельность) 2026-09-01 19:21:06 +03:00
Dushnilin 416a15a805 fix(parental): не устанавливать cron-джоб если нет расписаний с квотами (убирает cron.err spam) 2026-09-01 18:50:13 +03:00
Dushnilin 324569aa53 fix(ui): исправить чекбоксы виджета порядка вкладок (DummyValue→renderWidget) 2026-09-01 18:46:07 +03:00