- Прокидываем sni (decoy-хост) по обновлённому UDL через весь стек: guest-js -> Tauri-команда -> desktop/mobile -> Kotlin spawnSession. Список серверов пока статичный (backend еще не отдает sni), но логика похода в реальный /api/v1/nodes оставлена под флагом на будущее. - Бандлим wintun.dll в Windows-инсталлятор через bundle.resources в tauri.windows.conf.json - раньше он копировался только для локального cargo run/tauri dev, но не попадал в NSIS/MSI. - Чиним падение мобильной сборки: гитигнорённые UniFFI Kotlin-биндинги отстали от обновленного UDL (не хватало параметра sni). - Флаги стран - локальные SVG вместо react-country-flag в CDN-режиме: тот бился об CSP и не грузился офлайн. - Добавляем дерево README.md по структуре проекта и точечные комментарии в неочевидных местах кода. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4.1 KiB
Android-часть плагина
Нативный Kotlin-код, к которому обращается src/mobile.rs через
PluginHandle::run_mobile_plugin. Отдельный Gradle-модуль (com.android.library),
подключается в gen/android как :tauri-plugin-vpn — см.
android/settings.gradle.
src/main/java/.../VpnPlugin.kt
Файл содержит два класса:
TunVpnService(android.net.VpnService) — foreground-сервис, который реально держит туннель: строитVpnService.Builder(адрес/DNS/MTU), сплит-туннелинг (allow-list для Telegram sandbox-режима или disallow-list для обычного режима — взаимоисключающе), отдаётfdсозданного TUN-интерфейса вSessionManager.spawnSession(...), крутит цикл статистики и рассылает статус/трафик черезsendBroadcast. Вибро-фидбек при подключении/отключении.VpnPlugin(@TauriPlugin) — мост Tauri-команд к сервису:startVpnзапрашивает системное разрешение VPN (VpnService.prepare) перед стартом,stopVpn/checkActualVpnStatus/getInstalledApps/launchApp. Транслирует broadcast отTunVpnServiceв Tauri-события (trigger("status-change" / "traffic-stats", ...)), которые ловитguest-jsна JS-стороне.
AndroidManifest.xml — разрешения INTERNET, FOREGROUND_SERVICE
(specialUse), POST_NOTIFICATIONS, VIBRATE; <queries> для обнаружения
установленных приложений (нужно для сплит-туннелинга).
⚠️ Обязательно прочитать до правок
SessionManager.spawnSession(...) — не обычный Kotlin-класс, а UniFFI-биндинг
поверх нативной .so-библиотеки. Три вещи должны совпадать между собой
всегда, иначе сборка падает (или, хуже, крашится в рантайме):
- Сигнатура
spawn_sessionв.udl/lib.rsкрейтаnetrunner_client(репозиторийnetrunner-proxy/netrunner-core). android/src/main/java/uniffi/netrunner_client/netrunner_client.kt— сгенерированные Kotlin-биндинги.android/src/main/jniLibs/<abi>/libnetrunner_client.so— скомпилированная нативная библиотека.
Все три файла из пп. 2–3 гитигнорены (*uniffi, *jniLibs в
.gitignore плагина) — они не часть репозитория, их нужно вручную
регенерировать/копировать при каждом изменении .udl в netrunner-core:
# в репозитории netrunner-proxy
make build-android # пересобирает .so под все ABI + генерит Kotlin-биндинги
# (tools/bindgen — обёртка над uniffi_bindgen_main)
# результат: gen/uniffi/netrunner_client/netrunner_client.kt
# gen/<abi>/libnetrunner_client.so
# скопировать в netrunner-app:
cp gen/uniffi/netrunner_client/netrunner_client.kt \
<netrunner-app>/src-tauri/src/plugins/vpn-plugin/android/src/main/java/uniffi/netrunner_client/
cp gen/<abi>/libnetrunner_client.so \
<netrunner-app>/src-tauri/src/plugins/vpn-plugin/android/src/main/jniLibs/<abi>/
Забытый шаг копирования — уже реальная причина падения сборки (Kotlin
компилятор ругается на несовпадение сигнатуры spawnSession, если .kt
отстал от .so/UDL). Если сборка падает быстро (~секунды, до NDK-этапа) —
проверяйте это в первую очередь.