Skip to content

Releases: eleutherifer/LxBox

LxBox v2.25.9

Choose a tag to compare

@eleutherifer eleutherifer released this 29 Sep 21:39
d73fad7

L×Box v2.25.9

A patch on top of v2.25.8.

Core v1.14.2-lx.11: Tailscale nodes pass traffic to peers over a direct path
again and reach the coordination server over port 443 from the start. Repeats
of one server in a subscription are merged with a note on the node that stays.
Preset rules follow the template contract more strictly: a rule written
without conditions is kept, a rule that lost its conditions is dropped. Xray
JSON arrays with a balancer name pool servers by selector. Protocol contract
1.1.107.

Патч поверх v2.25.8.

Ядро v1.14.2-lx.11: узлы Tailscale снова передают трафик пирам по прямому
пути и с первого соединения ходят к серверу координации через порт 443.
Повторы одного сервера в подписке схлопываются с пометкой на оставшемся узле.
Правила пресетов строже следуют контракту шаблонов: правило, написанное без
условий, остаётся, правило, потерявшее условия, выпадает. Xray JSON-массивы с
балансировщиком собирают пул по selector. Контракт протоколов 1.1.107.


🇬🇧 English

🔄 Changed

  • Core v1.14.2-lx.11. Two Tailscale fixes. A node that found a direct UDP
    path to a peer (for example, both on the same Wi-Fi) could see and ping the
    peer, but TCP connections to it timed out; traffic now goes over the direct
    path, and WireGuard and AmneziaWG nodes send the same bytes as before. The
    channel to the Tailscale coordination server now always uses HTTPS on port
    443: behind DPI that freezes port 80, a node no longer loses the
    coordination server for about 15 minutes after every start.
    Synced with sing-box stable: stricter checks of incoming protocol data
    (sniffers, FakeIP, the TUN stack, transports), and a UDP checksum that
    comes out as 0 is written as 0xffff, so such packets are no longer
    dropped.

  • Repeated servers in a subscription. Providers often list one server many
    times under different names. The app keeps one node, as before, and now
    marks it with an info note «Repeats of this server in the subscription: N»
    that names the merged entries. The subscription summary shows «M duplicates
    merged into K nodes» on its own line; «entries dropped» no longer counts
    them.

  • Preset rules without conditions. A route or DNS rule of a preset that
    the author wrote without conditions (for example, a bare
    {"action": "sniff"}) now goes into the config, with the build warning
    «Rule from … matches everything». A rule whose conditions were removed by a
    failure is still dropped with «Entry … left out»: a variable without a value,
    an undeclared variable name, or rule sets none of which made it into the
    config. The same applies to sub-rules of a logical rule at any depth: one
    sub-rule that lost its conditions drops the whole logical rule.

  • Rule sets that were not downloaded. Your own DNS rule whose every
    rule_set points to a set missing from the config (for example, a remote
    .srs that was not downloaded) is left out with a build warning instead of
    going to the core without its condition. A missing name next to live ones
    is removed from the list. A DNS rule by an .srs file without a cached
    copy is reported the same way instead of being skipped silently.

  • Preset variables are optional by default. A variable without required
    is no longer required, as in the launcher. The built-in template marks its
    required variables explicitly, so presets behave as before.

  • Xray JSON arrays with a balancer. The group keeps the element's
    remarks; each server of the pool is named remarks tag. A name already
    taken in the element (by the group or by an earlier server) gets the
    server's number in the pool: pool p, pool p 2, pool 3. Pool members
    are the servers the balancer's selector picks by tag prefix; a server it
    does not pick stays a separate node. leastLoad without expected selects
    the fastest server. When one server of the element is merged with another,
    the group points to the node that stays.

🔧 Under the hood

  • Contract with the launcher: 1.1.107. Its copy is now in the repository, so
    CI checks the parsing corpus and the schemas on every push.
  • Feature specifications rewritten from the code (EN+RU).

🇷🇺 Русский

🔄 Изменено

  • Ядро v1.14.2-lx.11. Два исправления Tailscale. Узел, нашедший прямой
    UDP-путь к пиру (например, оба в одной Wi-Fi), видел и пинговал пира, но
    TCP-соединения к нему обрывались по таймауту; теперь трафик идёт по прямому
    пути, а узлы WireGuard и AmneziaWG отправляют те же байты, что и раньше.
    Канал к серверу координации Tailscale теперь всегда идёт по HTTPS на порт
    443: за DPI, который замораживает порт 80, узел больше не теряет
    координатора примерно на 15 минут после каждого старта.
    Синхронизировано со stable sing-box: строже проверка входящих данных
    протоколов (сниферы, FakeIP, TUN-стек, транспорты), а контрольная сумма
    UDP, равная 0, пишется как 0xffff, и такие пакеты больше не
    отбрасываются.

  • Повторы сервера в подписке. Провайдеры часто кладут один сервер много
    раз под разными именами. Приложение, как и раньше, оставляет один узел и
    теперь ставит на нём info-пометку «Повторов этого сервера в подписке: N» с
    именами схлопнутых записей. Сводка подписки показывает «M duplicates merged
    into K nodes» отдельной строкой; «entries dropped» их больше не считает.

  • Правила пресетов без условий. Правило маршрута или DNS из пресета,
    которое автор написал без условий (например, голый {"action": "sniff"}),
    теперь попадает в конфиг с предупреждением сборки «Rule from … matches
    everything». Правило, условия которого снял сбой, по-прежнему выпадает с
    «Entry … left out»: переменная без значения, необъявленное имя переменной
    или наборы правил, ни один из которых не попал в конфиг. То же для
    под-правил логического правила на любой глубине: одно под-правило,
    потерявшее условия, снимает всё логическое правило.

  • Нескачанные наборы правил. Своё DNS-правило, все rule_set которого
    указывают на наборы, не попавшие в конфиг (например, нескачанный remote
    .srs), не включается в конфиг и даёт предупреждение сборки, а не уходит в
    ядро без условия. Отсутствующее имя рядом с живыми убирается из списка.
    DNS-правило по файлу .srs без скачанной копии отмечается так же, а не
    пропускается молча.

  • Переменные пресета по умолчанию необязательны. Переменная без
    required больше не обязательна, как в лаунчере. Встроенный шаблон помечает
    обязательные переменные явно, поэтому пресеты ведут себя как прежде.

  • Xray JSON-массивы с балансировщиком. Группа сохраняет remarks
    элемента, каждый сервер пула называется remarks tag. Имя, уже занятое в
    элементе (группой или предыдущим сервером), получает номер сервера в пуле:
    pool p, pool p 2, pool 3. Члены пула — серверы, которые selector
    балансировщика выбирает по префиксу тега; невыбранный сервер остаётся
    отдельным узлом. leastLoad без expected выбирает самый быстрый сервер.
    Когда сервер элемента схлопнут с другим, группа ссылается на оставшийся
    узел.

🔧 Под капотом

  • Контракт с лаунчером: 1.1.107. Его копия теперь в репозитории, и CI
    проверяет корпус разбора и схемы на каждом push.
  • Спецификации фич переписаны по коду (EN+RU).

Install / Установка

adb install -r LxBox-v2.25.9-arm64-v8a.apk

Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся.

No uninstall needed — install over the existing one. Settings and subscriptions
are preserved.


Previous release / Предыдущий релиз: v2.25.8.

LxBox v2.25.8

Choose a tag to compare

@eleutherifer eleutherifer released this 28 Sep 19:44
33bdd26

L×Box v2.25.8

A patch on top of v2.25.7.

Tailscale is now served by a routing preset instead of per-node sections, and a
Tailscale node gets a Network tab with devices and exit node switching on the
fly. Home lists Tailscale nodes without an exit under NETWORKS. A node
written by hand as sing-box JSON goes to the core as written; nodes of a type
the app does not know and openvpn-client endpoints are accepted. The DNS
screen gets cache settings. Core v1.14.2-lx.8, protocol contract 1.1.99.

Google Play last shipped v2.25.5: the section «Since v2.25.5» at the end of
each language lists what v2.25.6 and v2.25.7 brought.

Патч поверх v2.25.7.

Tailscale теперь обслуживает пресет маршрутизации, а не секции узла; у узла
Tailscale появилась вкладка Network с устройствами и сменой exit node на ходу.
Главный экран показывает узлы Tailscale без выхода в NETWORKS. Узел,
записанный вручную как sing-box JSON, уходит в ядро как написан; узлы
незнакомого приложению типа и endpoint openvpn-client принимаются. На экране
DNS появились настройки кэша. Ядро v1.14.2-lx.8, контракт протоколов 1.1.99.

В Google Play последней была v2.25.5: раздел «С v2.25.5» в конце каждого языка
перечисляет, что принесли v2.25.6 и v2.25.7.


🇬🇧 English

⚠️ Read before updating

  • Node sections are gone. A node no longer carries route rules or DNS
    records of its own. The Tailscale bundle that used to live in a node is now
    the Tailscale networks preset, added once to existing installs and on by
    default. A record or a backup with a leftover sections field loads without
    error; the field is dropped
    (§575).
  • A hand-written node is no longer fixed by the app. A sing-box JSON node
    saved as your own server or a folder member goes to the core as written: an
    extra key, an AmneziaWG mtu above 1280, a tls.fragment next to a detour
    stay. The node card still lists each rule, says nothing was changed and what
    to do. Rules the core cannot start with (an unsupported flow, an invalid
    port, TLS fields naive does not take) are still applied
    (§577).
  • A node's source keeps the node only. Saving a sing-box document or an
    array in the node editor keeps the first node and says once that the rest is
    not kept; a document with no node is refused. Records saved earlier this way
    are read as the node's body, the config does not change
    (§576).

✨ Added

  • Tailscale preset. Tailscale networks serves every Tailscale node in
    the config, subscription nodes included: tailnet names go to the node's own
    DNS, addresses and names the node claims (preferred_by) go through the
    node. Deleting the preset keeps it deleted. The preset row on the Routing and
    DNS screens lists the nodes it serves
    (§578).
  • Skip presets on a node. A server or a folder member can opt out of
    presets that serve nodes one by one: the Skip presets switch on the node
    screen, stored in the record and in backups. It shows only when the template
    has such a preset for the node's type.
  • Tailscale node: Network tab. Node state, sign in and log out, this
    device, the network's devices with a ping, and the exit node list. Picking an
    exit node switches it on the fly without touching the node; Save choice
    writes it into the node. From NETWORKS the node opens on this tab
    (task 581).
  • NETWORKS on Home. While the VPN is on, Tailscale nodes without an exit
    node are listed under NETWORKS, the last entry of the Direction list.
    Instead of a delay the row shows the node state: running,
    sign-in needed, stopped or starting
    (task 579).
  • DNS cache settings. Next to Clear DNS cache: DNS cache size (1024 to
    65535 entries, default 4000), Serve stale answers (on by default) and
    Keep DNS cache after restart (on by default). The settings travel in
    backups (task 580).
  • Nodes of a type the app does not know. A sing-box node added by hand
    (Add server, paste, file, folder member, node editor) is accepted even if the
    app has no model for its type; it goes to the core as written with one info
    notice. Subscriptions still drop such entries. Pasted JSON with // and
    /* */ comments is accepted; the comments are removed
    (task 585).
  • OpenVPN endpoints as sing-box JSON. openvpn-client is a known type: it
    is accepted as your own record, inside a document and from a subscription, and
    goes to the core as written. There is no form and no .ovpn import
    (task 586).
  • Home: press back twice to exit. The first press shows
    «Press back again to exit», a second press within 2 seconds closes the app.
    An open menu, dialog or sheet closes on back as before
    (task 583).
  • Template language. A preset can repeat its rules and DNS servers for
    every matching node with for_each, and read the node's tag, record and body
    through @node and #tpl.

🔄 Changed

  • Core v1.14.2-lx.8. Synced with sing-box stable. Idle connections of
    nodes and DNS servers nothing refers to any more are closed, also when the
    device pauses. WireGuard, AmneziaWG and MASQUE inside another tunnel really
    allow fragmentation of the outer UDP datagram on Android; before, oversized
    datagrams were dropped. Hysteria, Hysteria2 and TUIC no longer allow it by
    default, QUIC finds the path MTU itself.
  • MASQUE no longer hangs without an error. vhttp: auto goes back to h3
    when the remembered h2 stops working (before, only a restart helped);
    closing an h2 tunnel does not wait minutes for a stalled write; an h3
    endpoint that never answers no longer holds every dial of the node.
  • XHTTP without xmux. An XHTTP node without an xmux section (or with an
    empty one) keeps at most three connections to the server and shares them
    between streams. Before, every stream opened its own TLS connection: dozens
    to hundreds of parallel connections to one IP, a pattern reported to be cut
    on mobile networks in Russia. An xmux section with any field set is taken as
    written.
  • A hand-written node the core would reject is dropped. A TUIC node with a
    uuid that is not a UUID, or a WireGuard node with invalid peer
    allowed_ips, is dropped with the reason in the list of dropped nodes. A
    REALITY short_id longer than 16 characters is removed; a REALITY block with
    an invalid public_key is removed whole. A MASQUE body without keys is read
    instead of being rejected
    (task 582).
  • Default emoji of a Tailscale node is 🕸️ (was 🪢). Existing node tags do
    not change.

🩹 Fixes

  • Bottom sheet and padding rules in the new screens; waiting for MASQUE
    parsing.

🔧 Under the hood

  • Contract with the launcher: 1.1.99. Which types are endpoints now comes from
    the contract registry.

📦 Since v2.25.5 (for Google Play users)

v2.25.7

  • TLS fragmentation from Xray finalmask.tcp; these fields used to be ignored
    (§573).
  • A node that goes through another node (a chain or a subscription detour) no
    longer carries TLS fragmentation
    (§574).
  • Node notifications with the same code are grouped into one entry; Xray nodes
    show fewer «field not read» notices
    (§572).

v2.25.6

  • Turn a WireGuard/AmneziaWG node off and on without restarting the tunnel
    (§557).
  • Replace a folder or a subscription with a group: Manual, Auto or Both
    (§568).
  • A selector group from a subscription or a backup stays manual and keeps
    its chosen server
    (§565).
  • Wi-Fi rules read the network name the way Android 12+ expects and say why
    the name cannot be read (approximate location, Location off)
    (§567,
    §569).
  • Imported nodes keep what the provider sent: multiplex, udp_over_tcp,
    dial options, WireGuard workers and more
    (§560).
  • A preset rule left without conditions is dropped instead of matching all
    traffic (§571).
  • Dropped subscription entries show in the subscription summary, not on a
    working node (§561).
  • A chain with a REALITY hop saves when uTLS is stripped; links to a chain
    open the chain
    (§556,
    §558).
  • A vpn:// line gives every WireGuard/AmneziaWG container of the profile;
    template variables with a list of values are chips with an optional own value
    (§570).

Full lists: v2.25.6,
v2.25.7.

🇷🇺 Русский

⚠️ Прочтите до обновления

  • Секций узла больше нет. Узел не несёт собственных правил маршрутов и
    записей DNS. Связка Tailscale, которая раньше...
Read more

LxBox v2.25.7

Choose a tag to compare

@eleutherifer eleutherifer released this 27 Sep 11:50
af54323

L×Box v2.25.7

A patch on top of v2.25.6.

Xray nodes that set TLS fragmentation in finalmask.tcp now get the core's
fragmentation; before, these fields were ignored. A node that goes through
another node (a chain or a subscription detour) no longer carries TLS
fragmentation. Xray nodes show fewer "field not read" notifications, and
notifications with the same code are grouped into one entry. The parser and the
config build follow the protocol contract 1.1.84.

Патч поверх v2.25.6.

Узлы Xray, у которых фрагментация TLS задана в finalmask.tcp, получают
фрагментацию ядра; раньше эти поля не читались. Узел, который идёт через другой
узел (цепочка или detour подписки), больше не несёт фрагментацию TLS. У узлов
Xray меньше уведомлений «field not read», а уведомления с одним кодом собраны в
одну запись. Парсер и сборка конфига следуют контракту протоколов 1.1.84.


🇬🇧 English

⚠️ Read before updating

  • TLS fragmentation is removed from a node that goes through another node.
    When the build sends a node through a hop (a chain, or a subscription's
    detour), tls.fragment is taken off that node and the node shows an info
    notice. This also applies to nodes whose sing-box JSON sets tls.fragment.
    Under a hop fragmentation does not help: the core pauses 500 ms after every
    segment and turns off its own protection against a lost large ClientHello.
    A detour written in the
    sing-box JSON itself does not count, since it never reaches the core
    (§574).

✨ Added

  • TLS fragmentation from Xray subscriptions. An Xray node that sets
    ClientHello fragmentation in streamSettings.finalmask.tcp (an item with
    type: fragment) now gets the core's tls.fragment. These fields used to be
    ignored, and the node went out without fragmentation. The Xray parameters
    (length, delay, maxSplit) are not carried over: the core splits the
    ClientHello at the domain labels of the SNI. The older form (a freedom
    outbound through dialerProxy) worked before and is unchanged
    (§573).

🔄 Changed

  • Node notifications are grouped by code. Several notifications with the
    same code within a level are shown as one entry with a count, the list of
    fields and a single explanation. A code that occurs once is shown as before
    (§572).
  • TLS fragmentation with a system TLS engine. With tls.engine set to
    apple or windows, fragmentation is removed with a warning instead of the
    config failing to start; the engine stays. These engines are not used on
    Android (§574).

🩹 Fixes

  • Fewer "field not read" notifications on Xray nodes. An empty
    tcpSettings and the mode / path / host fields inside
    xhttpSettings.extra no longer produce a notification. Xray always replaces
    those three with the outer values, so there is nothing to report
    (§573).

🔧 Under the hood

  • Contract with the launcher: 1.1.84.
  • GitHub Actions moved to Node 24.

🇷🇺 Русский

⚠️ Прочтите до обновления

  • С узла, который идёт через другой узел, снимается фрагментация TLS. Если
    сборка пускает узел через промежуточный (цепочка или detour подписки),
    tls.fragment с него снимается, и узел показывает информационное
    уведомление. Это касается и узлов, у которых tls.fragment прописан в
    sing-box JSON. Через промежуточный узел фрагментация не помогает: ядро
    выжидает 500 мс после каждого сегмента и отключает собственную защиту от
    потери большого ClientHello. detour, записанный в самом sing-box JSON, не
    считается: до ядра он не доходит (§574).

✨ Добавлено

  • Фрагментация TLS из Xray-подписок. Узел Xray, у которого фрагментация
    ClientHello задана в streamSettings.finalmask.tcp (элемент с
    type: fragment), получает фрагментацию ядра tls.fragment. Раньше эти поля
    не читались, и узел работал без фрагментации. Параметры Xray (length,
    delay, maxSplit) не переносятся: ядро режет ClientHello по меткам домена
    в SNI. Старая форма (outbound freedom через dialerProxy) работала и
    раньше и не менялась
    (§573).

🔄 Изменено

  • Уведомления узла сгруппированы по коду. Несколько уведомлений одного
    уровня с одинаковым кодом показываются одной записью: счётчик, список полей
    и один общий разбор. Код, который встречается один раз, выглядит как раньше
    (§572).
  • Фрагментация TLS и системный TLS-движок. При tls.engine = apple или
    windows фрагментация снимается с предупреждением, а не роняет старт
    конфига; движок остаётся. На Android такие движки не используются
    (§574).

🩹 Исправления

  • Меньше уведомлений «field not read» у узлов Xray. Пустой tcpSettings и
    поля mode / path / host внутри xhttpSettings.extra больше не дают
    уведомлений. Xray всегда заменяет эти три поля внешними значениями, так что
    сообщать не о чем
    (§573).

🔧 Под капотом

  • Контракт с лаунчером: 1.1.84.
  • GitHub Actions переведены на Node 24.

Install / Установка

adb install -r LxBox-v2.25.7-arm64-v8a.apk

Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся.

No uninstall needed — install over the existing one. Settings and subscriptions
are preserved.


Previous release / Предыдущий релиз: v2.25.6.

LxBox v2.25.6

Choose a tag to compare

@eleutherifer eleutherifer released this 27 Sep 02:28
af54323
Merge branch 'Leadaxe:main' into main

LxBox v2.25.5

Choose a tag to compare

@eleutherifer eleutherifer released this 27 Sep 01:52
af54323
Merge branch 'Leadaxe:main' into main

LxBox v2.25.4

Choose a tag to compare

@eleutherifer eleutherifer released this 25 Sep 03:57
c4edb89

L×Box v2.25.4

A patch on top of v2.25.3.

The core moves to v1.14.2-lx.1. WireGuard and AmneziaWG servers no longer hold
memory until traffic actually goes through them, and two new settings control
this. The Ru internet segment preset now routes Russian apps by package name.
The server list uses two columns on a tablet. A subscription that repeats the
same server no longer shows it twice.

Патч поверх v2.25.3.

Ядро обновлено до v1.14.2-lx.1. Серверы WireGuard и AmneziaWG больше не
держат память, пока через них не пошёл трафик, и этим управляют две новые
настройки. Пресет «Ru internet segment» теперь ведёт российские приложения
по имени пакета. На планшете список серверов идёт в две колонки. Подписка,
повторяющая один и тот же сервер, больше не показывает его дважды.


🇬🇧 English

⚠️ Read before updating

  • Duplicate servers in one subscription are collapsed. If a subscription
    lists the same server several times under different names, the list keeps
    one server per configuration (the first one). The rest are skipped and
    marked duplicate with a “Duplicate of ” note. Only entries inside one
    subscription or one import are compared.
  • At most 5 WireGuard/AmneziaWG tunnels are kept built at a time by default.
    A server over the limit may show ERR on a latency check while it waits for
    a free slot, and the selected server may be torn down to free a slot.
    VPN Settings → System → WireGuard connections → Built tunnels limit →
    0 (no limit) removes the cap.

✨ Added

  • Russian apps by package in the Ru internet segment preset. A fourth rule
    set, ru-app-list (by legiz-ru), matches a connection by the Android package
    name rather than by domain or IP. Banking and government apps that go through
    third-party CDNs or by bare IP used to miss both the domain and the IP sets and
    ended up in the tunnel; now they go direct. The checkbox Russian apps by
    package
    is on by default; the set is downloaded when first enabled.
    Unchecking it leaves domains and IPs as they are
    (#116).
  • Two columns of servers on wide screens. From 600 dp of window width the
    server list on the home screen goes into two columns; narrower screens keep
    one. The layout follows rotation and split screen on the fly. Manual sort
    stays in one column, since drag and drop only works there
    (#134).
  • Appearance tab in App Settings. Theme, language and Allow rotation
    moved here from General. The Layout section also has Two columns on wide
    screens
    (on by default). Changes apply immediately and are included in the
    backup.
  • Per-app summary in the log with Verbose on. When Verbose (TRACE/DEBUG) is
    enabled on the Diagnostics tab, each tunnel start writes one per-app: line
    to Logs: allow or deny mode, allow_bypass, the packages applied and the ones
    not installed on the device.
  • Lazy tunnel build and Built tunnels limit. VPN Settings → System →
    WireGuard connections. Lazy tunnel build (on by default) builds a
    WireGuard/AmneziaWG tunnel on first use. Built tunnels limit sets how many
    stay built at once: 0 (no limit), 3, 5, 8, 12; default 5. Both need
    Suspend idle tunnels on; the limit also needs lazy build. Applied on the
    next connect.

🔄 Changed

  • Core v1.14.2-lx.1. A network change (Wi-Fi ↔ mobile) no longer resets the
    tunnel on every system notification, only on a real interface change: fewer
    drops on the move. The disabled UDP GSO lines that filled the log of a
    working AmneziaWG server are gone; connectivity was never affected
    (#95).
  • WireGuard/AmneziaWG servers take no memory until used. Previously every
    WG/AWG server in storage got a device with about 17.5 MB of receive buffers at
    tunnel start. Now a server starts unbuilt and is built on first use. On a test
    setup with eleven AWG servers the core's live memory fell from 113 MB to
    53 MB. The cost is half a second to a second on the first switch to a server.
    The Auto group probes all its members at start and builds them, so there the
    saving comes from the limit.
  • WireGuard/AmneziaWG server state in one word. The server row shows up,
    sleep or down instead of “Node asleep” / “Node not built yet”. The full
    core state and idle time are in Endpoint state on the Details screen from
    the server menu.
  • Copy link follows the common scheme format. VLESS always carries
    security, including security=reality (other Xray clients read its absence
    as “no encryption”). NaiveProxy keeps port 443. AnyTLS writes insecure
    instead of allowInsecure. Shadowsocks has no trailing =. VLESS drops the
    default fp=random; other fingerprints are kept. TUIC writes
    reduce_rtt=true instead of reduce_rtt=1. Reading has not changed: links
    saved earlier or received from other clients parse as before.
  • The preset “Russian domains & IPs” is renamed “Ru internet segment”. The
    preset id is the same, saved rules expand as before.

🩹 Fixes

  • Proxy mode no longer asks about another active VPN. In Proxy mode (local
    port only, no tunnel) Start showed “Another VPN is active. Switch to L×Box?”,
    although the other VPN is not revoked in this mode. The question now appears
    only in VPN and VPN+Proxy modes
    (#126).
  • Duplicate servers in one subscription. A subscription sent the same AWG
    server twice, as an amneziawg:// line and as a vpn:// link, and the list
    showed two identical servers. See the warning above.
  • An unchecked rule set in the Ru internet segment preset no longer switches
    off the whole rule.
    The GeoIP IP-range fallback and Russian apps by
    package
    checkboxes were only honoured by config build; the Routing screen,
    download and background update ignored them. An unchecked set was still
    downloaded, and if its file was missing, opening Routing switched off the
    whole preset rule. Now all of them follow the checkbox. A rule already
    switched off by the old behaviour stays off — turn it on once.
  • Xray subscriptions parse closer to Xray itself. WebSocket ed/eh fields
    that Xray does not declare there are no longer read; the proxy address is no
    longer put into the TLS server name when the author did not set one; the
    WebSocket host written as a separate field is no longer lost; negative
    keep-alive intervals are read as Xray reads them. An Xray element with a
    foreign protocol version no longer yields a server the provider did not send.
  • VMess Copy link without a transport lost the server address; fixed.
  • proxy-https://…?security=none no longer keeps a TLS block and goes out as
    a plain HTTP proxy, including in Copy link.

🔧 Under the hood

  • Contract with the launcher: 1.1.53. The protocol registry engine runs three
    primitives exactly as the reference does; server bodies and identities did not
    change.
  • Debug API /state returns endpoint_states.

🇷🇺 Русский

⚠️ Прочтите до обновления

  • Повторы сервера в одной подписке схлопываются. Если подписка перечисляет
    один и тот же сервер несколько раз под разными именами, в списке остаётся
    по одному серверу на конфигурацию (первый). Остальные отбрасываются и
    помечаются duplicate с пояснением «Duplicate of <имя>». Сравниваются только
    записи внутри одной подписки или одного импорта.
  • По умолчанию собранными держатся не больше 5 туннелей WireGuard/AmneziaWG.
    Сервер сверх лимита, ожидающий слота, может показать ERR при проверке
    задержки, а выбранный сервер может быть разобран ради слота.
    VPN Settings → System → WireGuard connections → Built tunnels limit →
    0 (no limit) снимает потолок.

✨ Добавлено

  • Российские приложения по имени пакета в пресете «Ru internet segment».
    Четвёртый набор правил, ru-app-list (автор legiz-ru), сопоставляет
    соединение с именем Android-пакета, а не с доменом или IP. Банковские и
    государственные приложения, которые ходят через сторонние CDN или по голому
    IP, промахивались мимо наборов доменов и IP и уходили в туннель; теперь идут
    напрямую. Галка Russian apps by package по умолчанию включена, набор
    скачивается при первом включении. Снятая галка не трогает домены и IP
    (#116).
  • Две колонки серверов на широком экране. От 600 dp ширины окна список
    серверов на главном экране идёт в две колонки, уже — в одну. Раскладка
    меняется на лету при повороте и split-screen. Ручная сортировка остаётся в
    одну колонку: перетаскивание работает только в ней
    (#134).
  • Вкладка Appearance в App Settings. Тема, язык и Allow rotation
    переехали сюда из General. В секции Layout там же Two columns on wide
    screens
    (по умолчанию включено). Применяется сразу и попадает в бэкап.
  • Сводка per-app в логе при Verbose. При включённом Verbose (TRACE/DEBUG)
    на вкладке Diagnostics каждый подъём туннеля пишет в Logs одну строку
    per-app:: режим белого или чёрного списка, allow_bypass, применённые
    пакеты и те, что не установлены на устройстве.
  • Lazy tunnel build и Built tunnels limit. VPN Settings → System →
    WireGuard connections. Lazy tunnel build (по умолчанию включён) собирает
    туннель WireGuard/AmneziaWG при первом использовании. Built tunnels limit
    задаёт, сколько туннелей держать собранными одновременно: 0 (no limit), 3,
    5, 8, 12; по умолчанию 5. Оба пункта требуют включённого Suspend idle
    tunnels
    , лимит — ещё и ленивой сборки. Применяется при следующем
    подключении.

🔄 Изменено

  • ...
Read more

LxBox v2.25.3

Choose a tag to compare

@eleutherifer eleutherifer released this 24 Sep 16:45
ba5dbba

L×Box v2.25.3

A patch on top of v2.25.2.
The main body of changes is in
v2.25.0 — one parsing
engine shared with
singbox-launcher 2.0.0,
and the Start insurance when the core refuses a server. Read those first;
this patch does not repeat them.

This patch is mostly about the core and about connecting. Diagnostics on a
NaiveProxy server no longer closes the app. A WireGuard or AmneziaWG server whose
address is a name rather than an IP connects in about a second instead of five.
A tunnel built from several such servers is no longer switched off by its own
safety net fifteen seconds in. And the Servers screen finally keeps one list:
servers, subscriptions, folders and chains are entries of one kind, in one order.

Патч поверх v2.25.2.
Основной корпус изменений — в
v2.25.0: один движок
разбора с
лаунчером 2.0.0
и страховка кнопки Start, когда ядро отказывается от сервера. Сначала
читайте их — этот патч их не повторяет.

Этот патч в основном про ядро и про подключение. Диагностика узла NaiveProxy
больше не закрывает приложение. Сервер WireGuard или AmneziaWG, чей адрес задан
именем, а не IP, соединяется примерно за секунду вместо пяти. Туннель из
нескольких таких серверов больше не гасится собственной страховкой через
пятнадцать секунд. А экран Servers наконец держит один список: серверы,
подписки, папки и цепочки — записи одного рода, в одном порядке.


🇬🇧 English

🩹 Fixes

The core — v1.14.1-lx.10

  • Diagnostics on a NaiveProxy server no longer closes the app. With the
    tunnel up, opening Diagnostics on a naive server shut the app down on the
    spot: the core read the connection's address, which a connection of that kind
    does not have. Diagnostics now returns status, response and timing for such a
    server like any other, and the address field stays empty — which is how it
    should be. Traffic through those servers and the latency check were never
    affected.
  • WireGuard and AmneziaWG servers addressed by name connect in a second
    instead of five.
    When the server address is a domain rather than an IP, the
    first handshake used to be lost and the connection took an extra five seconds.
    It now goes through on the first attempt.
  • XHTTP connections are no longer marked as failed when you switch servers.
    When you changed server, or the core closed an XHTTP connection it no longer
    needed, it took its own closure for a break from the server's side: a line
    about a closed response body landed in the log on every request, and a
    perfectly good XMUX session was marked unusable and rebuilt from scratch. A
    local cancellation is now recognised for what it is — the log of a working
    XHTTP server is clean, and switching servers costs no extra session rebuild. A
    real break on the server's side is still reported as before
    (#148).
  • Synced with upstream sing-box — fixes around DNS, IPv6 and shutdown.

The config schema, the set of fields and the behaviour of other servers did not
change.

Connecting

  • A VPN built from several WireGuard/AmneziaWG servers no longer switches
    itself off after 15 seconds.
    The core brings such servers up one at a time,
    7–9 seconds each, while the safety net against a stuck start waited a fixed 15
    seconds for any configuration. On four servers or more it managed to kill a
    connection that was already established: the handshake had happened, the
    tunnel was up — and immediately put out. No reason was visible either; from the
    outside it looked like "I pressed Connect and nothing happened". The allowance
    now grows with the number of such servers, and if the safety net does fire it
    names the reason and the threshold instead of switching off in silence. For
    configurations without WireGuard servers the threshold is unchanged.

Servers screen

  • One list of entries of every kind. Servers, subscriptions, folders and
    chains are now a single ordered list rather than three different mechanisms:
    the screen used to assemble the list from three separate places on every
    frame, and one drag wrote the settings twice. Deleting and dragging are now one
    entry, one record.
  • Chains travel with servers in a backup. In the export a chain used to be
    ticked under Routing — together with routing rules rather than with the
    servers it stands next to in the list. It now goes under "Server lists". Older
    archives where chains were exported as Routing still read as before; restore
    those with the Routing tick.
  • The Debug API sees every kind. GET /subs now returns the same list you
    see on screen, chains included.

The settings file, the backup format and the settings themselves did not change;
servers, routes and list order stay as they were.

Config editor

  • The Cut/Copy/Paste menu no longer piles up or hangs around after you clear
    the selection.
    Several menus could end up on screen at once — two or three
    stacked, the last one clipped by the screen edge — and tapping an empty spot to
    clear the selection did not dismiss them. The editor was rebuilding the menu's
    controlling object on every repaint of the screen, leaving an already-shown
    menu with no owner and nobody to close it. The editor now keeps one such object
    for the lifetime of the screen, and the menu closes when the selection is
    cleared, when you tap away, when you scroll, and when you leave the screen.
    Tapping the menu's own buttons still does not drop the selection: what gets
    copied is exactly what you selected.

DNS

  • DNS preset Shield: the Yandex server over DoT really takes part in the
    group.
    It used to drop out silently — it was listed as a member, but the
    server entry itself was missing from the template, so on every config build the
    member disappeared with a warning and the "shield" polled five providers
    instead of six. This was most visible to people behind a whitelist: Yandex
    answers on such a network and the other members do not, so resolution did not
    work at all. The server is now declared: Yandex over DNS-over-TLS, direct,
    outside the tunnel — so it works even when the tunnel is down, and queries
    still go encrypted, with no leak into plain UDP. Existing configurations are
    not migrated: the group's membership is taken from the template on the next
    config build.

Stability

  • "Check all servers" no longer runs out of memory on lists with several
    WireGuard/AmneziaWG servers.
    The check starts the core, and the core reserves
    buffers in advance for every WireGuard server in the configuration rather than
    only the one being measured: around 17 MB per server, so close to 200 MB on a
    dozen. The check broke the memory limit and the app closed instead of showing
    the latencies. Such servers are now checked four at a time: between batches the
    core restarts and the buffers are released. Every server is still measured and
    the list order does not change — the check simply takes a little longer. Lists
    with no WireGuard servers work as before.
  • The diagnostic report on server problems no longer skips servers with
    identical names.
    Providers often call every server the same thing — plainly
    proxy, say — and one and the same server can arrive twice under different
    protocols with a shared name. In the parsing problem report such servers
    overlaid one another: only the last survived and the notes on the rest
    vanished. There was no way to notice, because the server count shown next to
    them was right: twelve servers, eight lines of notes. Namesake servers are now
    told apart the same way they are in the server list, and no note is lost.

🔧 Under the hood

A corpus of real public subscriptions now guards the parser: snapshots of 68
public lists — about 74,000 servers as text, exactly as the sources hand them
over — plus the machinery to run parsing across them. Every change to the
protocol registry is checked against a reference: if the number of parsed servers
drops or the rejection codes change, it shows immediately and per subscription
rather than after a complaint. The run only reads text — not one server from the
corpus is connected to or checked for reachability, no config is built and the
core is never started. Contract 1.1.52 (unchanged). Core v1.14.1-lx.10.

🧪 Tests

The release gate is CI checks (analyze, the full test set, four l10n checkers,
docs parity). Added by this patch: the start threshold against the number of
WireGuard endpoints, namesake servers in the warnings report, the config editor
menu against duplicate overlays and every dismissal path, the single sources[]
list round-trip, the dns_shield preset membership, and probe batching on
WireGuard servers.

📚 Documentation

The trial methodology for the public-subscriptions corpus is written down, along
with the specs for this patch's changes. The Debug API reference records that
GET /subs returns every kind of entry.

🇷🇺 Русский

🩹 Исправления

Ядро — v1.14.1-lx.10

  • Диагностика узла NaiveProxy больше не закрывает приложение. При живом
    туннеле Диагностика узла naive закрывала приложение сразу же: ядро читало
    адрес соединения, которого у соединения этого типа нет. Теперь Диагностика
    такого узла отдаёт статус, ответ и время, как у любого другого, а поле адреса
    остаётся пустым — так и должно быть. Трафик через такие узлы и проверка
    задержки не страдали и раньше.
  • **Серверы WireGuard и AmneziaWG с адресом по имени подключаются за секунду
    вместо пяти...
Read more

LxBox v2.25.2

Choose a tag to compare

@eleutherifer eleutherifer released this 24 Sep 04:19
0feb6fd

L×Box v2.25.2

A patch on top of v2.25.1.
The main body of changes is in
v2.25.0 — one parsing
engine shared with
singbox-launcher 2.0.0,
and the Start insurance when the core refuses a server. Read those first;
this patch does not repeat them.

This patch is about subscriptions that used to come back short — and about not
being left in the dark when they do. Links providers actually write are read
instead of silently vanishing; a line the app cannot use says why. A decoy
banner from an expired subscription is no longer offered as a server, and a
transport the core does not speak is refused honestly instead of connecting to
nothing.

Патч поверх v2.25.1.
Основной корпус изменений — в
v2.25.0: один движок
разбора с
лаунчером 2.0.0
и страховка кнопки Start, когда ядро отказывается от сервера. Сначала
читайте их — этот патч их не повторяет.

Этот патч про подписки, которые приезжали короче, чем есть, — и про то, чтобы
не оставлять в тишине, когда так вышло. Ссылки в том написании, в котором их
пишут провайдеры, читаются, а не исчезают молча; строка, которую приложение не
может использовать, называет причину. Баннер-обманка истёкшей подписки больше
не выдаётся за сервер, а транспорт, которого ядро не знает, честно
отбраковывается вместо соединения в никуда.


🇬🇧 English

🩹 Fixes

Subscriptions and links

  • amneziawg:// links no longer disappear. Panels spell the AmneziaWG
    scheme out in full, and lines written that way used to vanish whole — every
    field in them was already readable, but the list of known schemes lived in the
    code as literals and did not include the long spelling.
  • A vpn:// link holding a plain WireGuard config gives a server. Under the
    wrapper there may be not only an Amnezia profile but the wg-quick /
    AmneziaWG config itself. Such a link used to yield zero servers with a message
    about zlib that sent you looking for a fault that was not there.
  • A subscription that is a single Xray configuration — one object rather
    than a list — is read as one server instead of yielding nothing.
  • Hysteria2 keeps its bandwidth and its Salamander obfuscation. A speed
    written as a string with a unit ("100mbps") was dropped without a word, and
    the obfuscation was lost together with its password, so the server arrived and
    would not come up. The up / down spelling the official client uses now
    arrives too.
  • A provider panel's decoy banner is no longer taken for a server. When a
    subscription has expired, panels return not an empty body but a
    syntactically valid link to nowhere (0.0.0.0:1, 127.0.0.1:1080) with the
    explanation in the remark after # — and when the traffic quota is used up,
    that entry can be the only one. What is judged now is the destination: an
    entry whose address cannot belong to a server stays out of the list, and the
    provider's own text reaches you as the reason.
  • A transport the core does not speak is refused instead of being swapped
    out.
    network: kcp / quic used to reach the core verbatim, the sanitiser
    stripped the transport silently, and the server came out as working plain TCP
    — a server expecting mKCP will not accept that connection, and you saw no
    reason why.
  • TCP header obfuscation (headerType=http) refuses the server. It used to
    be carried over into the http transport, which for the core means HTTP/2 —
    a different protocol on the wire: a server expecting camouflage received an
    h2 handshake and dropped the connection. The server looked healthy and did not
    work. Real http transport (spelled out as type=http) is unaffected.
  • A socks password is no longer lost. v2rayN always writes a socks link as
    base64("user:pass"), and parsing split the string on a : that is not there:
    the name became the whole base64 string and the password vanished silently.
  • wireguard, socks and http elements inside an Xray configuration are no
    longer dropped.
    No section recognised them and the server disappeared
    entirely, even though the core has every field they need.
  • ALPN from an Xray configuration reaches the server. It is part of the
    handshake: a server with nothing to pick from what was offered drops the
    connection, so a node facing an h2-only server simply did not work.
  • A number in alpn or server_ports no longer takes down the whole
    configuration.
    A node from sing-box JSON with "alpn": [443, "h2"] reached
    the core as written and the core refused to start at all. A non-string element
    is now removed with a warning on that server, and its valid neighbours stay.
  • "No servers found" no longer keeps the reason to itself. A subscription
    line whose protocol the app does not know, a link over the allowed length, and
    a body that could not be read at all now each name their reason in the
    notifications list, with the protocol spelled out instead of an empty list.
    An unknown scheme and an unreadable body no longer both report themselves as
    "protocol" — each has its own reason now.
  • Service lines that provider panels add are skipped quietly. Routing
    commands addressed to neighbouring clients (incy://routing/…,
    happ://routing/…) are not servers: a healthy subscription used to show five
    refusals alongside working servers.

Workspaces

  • Switching a workspace no longer overwrites the subscriptions in all of
    them.
    If a subscription refresh was in flight at the moment of the switch —
    by hand from ⟳, on the hourly timer, on return from the background, or after
    the VPN was turned off — the outgoing workspace's screen would write its own
    subscriptions into the workspace that had just loaded. Every workspace was
    left with a single subscription, the last one refreshed, and the loss was
    committed to disk. A refresh is now halted before the switch, and a write from
    the outgoing workspace is rejected. Workspaces already overwritten are not
    restored by this fix — only a backup can do that.

Start insurance

  • Servers with the same name no longer cut the run short. Two unusable
    servers sharing a name were being switched off one per press: after the first
    went off its name passed to the second, the state machine read that as "the
    same server again", and the VPN never came up. A repeat is now recognised by
    the server itself, not by its name.
  • Stop during a server check no longer brings the VPN back. A stop that did
    not come from the main screen's button — Debug API, the Quick Settings tile,
    the Intent API, Tasker/Locale — left the check running, and a few seconds
    later the insurance raised the tunnel by itself. Any Stop now cancels it.
  • The "disabled by insurance" list opens the server you tapped. When several
    servers shared a refusal reason, or two servers in a folder shared a name,
    tapping a row could open a different server's screen.

Servers screen

  • Deleting a row no longer shifts its neighbours. From a list of
    u1, c1, u2, c2 you would delete the chain c1 and get u1, c2, u2: a
    record of the same kind slid into the freed slot and jumped over a server.
    Slots are now matched by key, not by position.
  • Drag works when the storage holds a record the app cannot read. Any drag
    used to roll back silently — the row jumped home. The visible records now
    reorder, and the unreadable one keeps its slot.
  • A new row at the end of a long list is no longer hidden under the
    SnackBar.
    A new record is appended at the tail, and the tail only scrolled
    as far as the bottom padding, so the "New" row was covered by the
    config-rebuild message. The list now keeps room below.
  • The highlight on a new row is dropped when the row is deleted. Deleting
    within the seven seconds after adding — from the menu, or on a subscription
    refresh — left the highlight bound to a dead record, and the screen kept
    accumulating keys of deleted rows until it was closed.
  • LX Backup: importing keeps the source order from the file. A hop chain
    sitting between servers in the file moved to the head of the list after
    import, because chains and sources were written separately. New records now
    take the file's order.

Config editor and DNS

  • Config editor: a selection no longer collapses when the menu appears. A
    long tap on the text opened the menu through a modal route, which took focus
    away from the editor: the selection collapsed to a caret, and Copy put the
    line under the caret into the clipboard instead of the fragment you had
    selected. The menu now lives in an overlay bound to the editor — the selection
    survives while the menu is on screen, and Cut / Copy / Paste / Select all work
    on the real range. Both screens with an editor are covered: the shared config
    and the add-server wizard.
  • The dns_shield DNS preset no longer resolves in the clear. The group was
    set to mode: fastest — the query goes to every member at once, and plain UDP
    with no TLS handshake almost always wins the race against DoH/DoT: the
    "shield" regularly answered from an open resolver, and the UDP query was
    visible to an observer even when an encrypted member won. google_udp,
    cloudflare_udp, opendns_udp and yandex_udp are out of the group; the
    first three already had an encrypted twin there, and an opendns_doh entry
    was added for OpenDNS. The *_udp servers themselves stay in the list —
    hints and resolver defaults point at them and you can still pick them.
    Existing configurations are not rewritten automatically: the new compositio...
Read more

LxBox v2.25.1

Choose a tag to compare

@eleutherifer eleutherifer released this 20 Sep 22:38
99d112e

L×Box v2.25.1

Three fixes on top of v2.25.0.
That release is the main body of changes: one parsing engine with
singbox-launcher 2.0.0
(contract 1.1.46), and the Start insurance when the core refuses a server
(#147). Read it first — this
patch does not repeat it.

This patch: Stats → Memory breakdown shows PSS figures again; XHTTP extra keeps
sessionIDPlacement / sessionIDKey; a hop chain on Servers stays between the
rows you drop it among.

Три правки поверх v2.25.0.
Основной корпус изменений — там: один движок разбора с
лаунчером 2.0.0
(контракт 1.1.46) и страховка кнопки Start, когда ядро отказывается от
сервера (#147). Сначала читайте
2.25.0 — этот патч его не повторяет.

В этом патче: в Stats → Memory разбивка PSS снова с цифрами; XHTTP extra
сохраняет sessionIDPlacement / sessionIDKey; цепочка на Servers остаётся
между строками, куда её поставили.


🇬🇧 English

🩹 Fixes

§ Before Now
507 After v2.25.0 the Stats → Memory sheet still showed RSS and native-heap malloc counters, but the Breakdown section (Java / Native / Graphics / Code / Stack / System / Other) was all 0 B. Debug.getMemoryInfo no longer fills summary.* PSS categories on Android 10+ The snapshot comes from ActivityManager.getProcessMemoryInfo. If AMS is empty, the old call is the fallback; empty summary.* categories fall back to dalvikPss / nativePss / otherPss / totalPss
508 A live vless+xhttp link parsed, and seqPlacement from extra arrived, but Xray proto names sessionIDPlacement / sessionIDKey were dropped. The core then put the session id in the path (its default), while the server looked for a cookie with a custom key Those aliases map to session_placement / session_key (in extra and as flat query params). Canonical names still win. sessionIDLength / sessionIDTable are not mapped — "0" without a table means unset. Overlay until the launcher registry takes the alias (launcher #131)
509 Servers draws subscriptions, servers, folders and hop chains in one list, but a drop wrote two blocks: chains were saved at the tail of sources[] and jumped back down A mixed drag writes the array as shown. Chain records keep their slots among the other kinds. The “a hop may only point at a chain above” rule is unchanged — it is computed over the chains’ mutual order

🧪 Tests

CI checks (analyze, the full test suite, four l10n checkers, docs parity) is
the release gate. Locally: xhttp_test for the proto aliases, chains_storage_test
and lx_backup_test for mixed sources[] order.

🇷🇺 Русский

🩹 Исправления

§ Было Стало
507 После v2.25.0 шторка Stats → Memory по-прежнему показывала RSS и malloc-счётчики native heap, а секция Breakdown (Java / Native / Graphics / Code / Stack / System / Other) была сплошными 0 B. Debug.getMemoryInfo на Android 10+ больше не заполняет категории PSS summary.* Снимок берётся у ActivityManager.getProcessMemoryInfo. Если AMS пуст — запасной прежний вызов; пустые summary.* подставляют dalvikPss / nativePss / otherPss / totalPss
508 Живая vless+xhttp ссылка разбиралась, seqPlacement из extra доезжал, а proto-имена Xray sessionIDPlacement / sessionIDKey терялись. Ядро клало session id в path (свой дефолт), сервер искал cookie с кастомным ключом Алиасы мапятся в session_placement / session_key (в extra и в плоском query). Канон сильнее proto-имени. sessionIDLength / sessionIDTable не мапятся: "0" без таблицы — «не задано». Оверлей, пока реестр лаунчера не заберёт алиас (лаунчер #131)
509 Servers рисует подписки, серверы, папки и цепочки одним списком, но drop писал два блока: цепочки сохранялись хвостом sources[] и возвращались вниз Смешанный drag пишет массив как на экране. Записи цепочек держат свои слоты среди остальных родов. Инвариант «хоп ссылается только на цепочку выше» не менялся — он считается по взаимному порядку цепочек

🧪 Тесты

Релизный гейт — CI checks (analyze, полный набор тестов, четыре l10n-чекера,
паритет доков). Локально: xhttp_test на proto-алиасы, chains_storage_test и
lx_backup_test на смешанный порядок sources[].


Install / Установка

adb install -r LxBox-v2.25.1-arm64-v8a.apk

Без uninstall! Поверх существующей установки. Настройки и подписки сохранятся.

No uninstall needed — install over the existing one. Settings and subscriptions
are preserved.


Previous release / Предыдущий релиз: v2.25.0.
The main body of changes is there / Основной корпус изменений — там:
GitHub Release v2.25.0.

LxBox v2.25.0

Choose a tag to compare

@eleutherifer eleutherifer released this 20 Sep 06:44
1cf6112

L×Box v2.25.0

One parsing engine with the desktop launcher 2.0.0. The desktop
singbox-launcher 2.0.0
and L×Box now share one protocol registry (contract 1.1.46). Share links,
Xray JSON, WireGuard .conf files and Copy link are parsed and built by the
same table-driven engine on both sides; the handwritten per-protocol parsers
are gone. Warning texts come from the same registry too. If one app could read a
node, the other reads it the same way. Core: v1.14.1-lx.8.

Second: when you press Start and the core refuses because of one bad
server, that server is disabled automatically with the core's reason
(#147); the VPN comes up on the
rest.

Десктопный лаунчер 2.0.0 и телефон — один движок разбора. У обоих
приложений теперь общий реестр протоколов (контракт 1.1.46). Ссылки,
Xray-JSON, WireGuard .conf и Copy link разбираются и собираются одной
таблицей на обеих сторонах; рукописные парсеры сняты. Тексты предупреждений —
из того же реестра. Узел, который прочитала одна сторона, читает и другая
одинаково. Ядро: v1.14.1-lx.8.

Второе: по кнопке Start, если ядро отказывается стартовать из‑за одного
негодного сервера, этот сервер выключается сам с причиной от ядра
(#147); VPN поднимается на
остальных.


🇬🇧 English

🔗 Parsing aligned with singbox-launcher 2.0.0

Before Now
Thirteen handwritten link parsers, a separate Xray parser, a separate WireGuard INI parser and a separate link builder One registry-driven engine for all schemes
A fix on the phone did not reach the desktop until someone patched both sides Rules live in the shared registry; both apps pick them up from the same table
Warning texts for some codes lived only in the app All warning titles, explanations and advice come from warnings.json in the registry
A node read on one side could differ on the other after Copy link Parse and emit use the same table

WireGuard and AmneziaWG .conf files are a first-class input (not converted to an
internal wireguard:// link first). Invalid WireGuard keys, masked panel keys
and overlapping AmneziaWG magic headers are no longer dropped silently — the node
gets a named warning or is rejected with a reason.

socks4:// and socks4a:// links are recognised; the scheme carries the SOCKS
version.

A few schemes still differ from the desktop on Copy link (Shadowsocks padding,
some XHTTP / VMess spellings). Those remaining overlays are tracked, not silent
phone-only patches.

🛡 Core rejection insurance (#147)

Before Now
One bad server in a large subscription blocked the whole VPN; the core message named an index, not a node you recognise Start parses the core's refusal, finds the named server and disables it — the same switch you would use yourself
No way to see which servers were turned off After a clean start, a banner shows how many were disabled; Show lists each with the core's text; a tap opens that node's Diagnostics (notifications at the bottom)
A disabled-by-core server stayed disabled after a subscription refresh even if the provider fixed it When the node's body changes on refresh, it is enabled again for a new check
— Up to ten silent checks of the remaining servers before the app asks whether to continue; Start turns into Stop while the cycle runs

Servers you disabled yourself are never touched. Updating the core alone does not
clear a core verdict — toggle the switch or refresh the subscription. The banner
on the home screen goes away after Stop (the verdicts on the nodes stay).

This automatic disable runs on the Start button. Quick Settings, boot
auto-start and the watchdog raise the last saved config as before.

🩹 Visible fixes (parsing and Copy link)

Situation Before Now
Xray JSON pasted as a single outbound, a full config with outbounds, an array of outbounds, or an array of configs Only an array of configs was accepted; preview showed zero nodes All four shapes are accepted; preview shows the real count
Base64 subscription text pasted from the clipboard Worked only as a URL The wrapper is stripped on paste too
type=splithttp in a share link Node was built with no transport — dead TCP on an HTTP port, silently Read as xhttp; same node as the canonical name
Hysteria2 mport with a port range Server address landed in the port list → core fatal «bad port range», whole VPN down Only a number pair is a port-range element; a lone port stays on the server
REALITY pbk in standard base64 (not URL-safe) Whole config refused to start Key is rewritten to the alphabet the core expects — same key, different spelling
naive+quic:// after Copy link Scheme fell back to naive+https://; QUIC was lost naive+quic:// survives the round-trip
VMess over gRPC (Copy link) gRPC service name from v2rayN (path in the JSON container) was lost on copy Emitted back with serviceName mapped from path
TUIC link with empty password (tuic://uuid:@host) Node disappeared or passed silently Node stays; a warning marks the empty password
Xray outbound element without port App silently used 443 or 1080 Element is dropped, as in Xray-core — no fake node
Unknown query parameter on a link Dropped with a generic message or silently Named by the parameter
WireGuard [Peer] without Endpoint Became a node with nowhere to connect Rejected
Disabled TLS object tls: {"enabled": false} in a JSON body Could crash the core on first dial Removed on input on every path, like links already were
Invalid CIDR on a WireGuard address Whole VPN failed to start Bad prefix is stripped from that node
Fractional port in JSON (443.9) Truncated to 443 Node is rejected
Xray dialerProxy pointing at a freedom fragment outbound Whole node dropped as a bad hop Node stays direct; TLS fragment is set
Naive link password@host (no colon in userinfo) Read as a username with an empty password — auth failed Read as the password, same as NekoBox / NaiveGUI

📋 Notifications and the lists

Before Now
One long warning line under a node; info drowned real problems Error ✖ / warning ⚠ show text; info ⓘ is an icon only — tap opens the full list
No structured explanation Expandable cards What happened / Why it happens / What you can do; Details opens offline contract docs
Home screen and a cold start hid badges that Servers already showed The same badge (highest level) on the home node list, including after a cold start and on a standalone server
A rejected paste on Servers was a red line under the field The red line stays; a sheet with the same card opens at once
A new source on Servers was easy to miss The list scrolls to the new row and highlights it as New for a few seconds
Probe bar labelled «Test servers» Bulk switch sits with the row toggles; no extra label when idle

In node details the cards live at the bottom of Diagnostics, under the live
Check / Run output. The Diagnostics tab shows a yellow dot when there is
something to read (red on error). There is no separate Notifications tab.

Copy link on a node whose link carries a private key (SSH, WireGuard/AWG,
MASQUE) now asks with Link contains a private key / Copy anyway, instead
of refusing or copying silently.

⚙️ Core

v1.14.1-lx.4 → v1.14.1-lx.8. A REALITY short_id that is too long is an
error, not a process panic. Init errors name the record type and tag — Start
uses that to find the bad server. A gRPC service_name is passed through as
written.

⚠️ What may change for you

Situation What happens
Xray subscription element with no port that used to appear as port 443 or 1080 The element is dropped — it is not turned into a node anymore
REALITY public key in URL-safe base64 (pbk with - and _) Rewritten to standard base64 in the link the app stores and emits — the key bytes are the same; re-import on another client may show a different spelling
Donate Boosty is removed; crypto addresses are unchanged

🧪 Tests

CI checks (analyze, the full test suite, four l10n checkers, docs parity)
is the release gate.

🇷🇺 Русский

🔗 Сближение с singbox-launcher 2.0.0

Было Стало
Тринадцать рукописных разборщиков ссылок, отдельный разбор Xray, отдельный разбор WireGuard INI и отдельная сборка ссылки Один движок по таблицам общего реестра для всех схем
Починка на телефоне не доезжала до десктопа, пока не правили обе стороны Правила живут в общем реестре; оба приложения читают одну таблицу
Тексты части предупреждений держались только в коде приложения Заголовки, объяснения и советы — из warnings.json реестра
Узел после Copy link на одной стороне мог отличаться на другой Разбор и сборка — одна таблица

Файлы WireGuard и AmneziaWG .conf — полноценный вход (без перевода во
внутреннюю ссылку wireguard://). Негодные ключи WireGuard, замаскированные
панелью ключи и пересекающиеся magic-заголовки AmneziaWG больше не исчезают
молча — узел получает названное предупреждение или отбраковывается с причиной.

Ссылки socks4:// и socks4a:// распознаются; версию протокола несёт схема.

На части схем Copy link всё ещё расходится с десктопом (паддинг Shadowsocks,
некоторые написания XHTTP / VMess). Это учтённые оверлеи, а не тихие заплаты
только на телефоне.

🛡 Страховка от отказа ядра (#147)

Было Стало
Один негодный се...
Read more