# vojo proxy Нативный Android-клиент для прокси: **Shadowsocks**, **SOCKS5**, **HTTP**, **HTTPS**. Per-app whitelist, минимальный расход батареи, маленький размер (release APK ≈ 2.4 МБ). Дизайн — в стиле мессенджера vojo (Dawn/Fleet: тёмные поверхности, hairline-границы, один фиолетовый акцент, monospace для технических данных). ## Стек - **Kotlin + Jetpack Compose + Material3**, Coroutines, DataStore, kotlinx.serialization. - **VpnService** для создания tun-интерфейса и per-app whitelist (`addAllowedApplication`). - **tun2socks**: нативный движок [`hev-socks5-tunnel`](https://github.com/heiher/hev-socks5-tunnel) (C, event-loop, ~320 КБ) — самый экономичный по CPU/батарее способ конвертировать IP-пакеты из tun в потоки. - minSdk 28, targetSdk 35, только `arm64-v8a` (Samsung S23). ## Архитектура потока данных ``` Выбранные приложения │ (per-app whitelist через VpnService.addAllowedApplication) ▼ tun-интерфейс ──fd──► hev-socks5-tunnel (нативный, JNI) │ говорит SOCKS5 на 127.0.0.1: ▼ LocalSocks5Server (Kotlin, loopback) │ мост на нужный апстрим ┌─────────────────────┼─────────────────────┬───────────────┐ ▼ ▼ ▼ ▼ Shadowsocks SOCKS5 HTTP CONNECT HTTPS CONNECT (AEAD SIP004) (RFC 1928/1929) (RFC 7231) (TLS + CONNECT) ``` - **TCP** проксируется для всех 4 протоколов. Цель приходит уже как IP/домен в SOCKS5-форме. - **UDP/DNS**: `hev` отдаёт UDP через SOCKS5 UDP ASSOCIATE. Для SS/SOCKS5 — полноценный UDP-релей; для HTTP/HTTPS (UDP не поддерживается протоколом) — DNS-over-TCP fallback (порт 53). - Все апстрим-сокеты защищены `VpnService.protect()`, чтобы не зацикливаться обратно в tun. ## Ключевые модули | Путь | Назначение | |------|-----------| | `core/Tun2Socks.kt`, `jni/tun2socks.c` | JNI-мост к нативному движку | | `core/crypto/ShadowsocksCrypto.kt`, `ShadowsocksStream.kt` | AEAD (HKDF-SHA1, AES-GCM, ChaCha20-Poly1305), TCP-framing, UDP seal/open | | `core/socks/LocalSocks5Server.kt` | Локальный SOCKS5-сервер: CONNECT + UDP ASSOCIATE | | `core/upstream/*` | Апстримы SS / SOCKS5 / HTTP(S) | | `service/ProxyVpnService.kt` | VpnService, whitelist, foreground-уведомление, статистика, журнал событий | | `service/ProxyTileService.kt` | Тайл быстрых настроек (вкл/выкл из шторки) | | `data/ConfigStore.kt`, `AppRepository.kt` | Персист конфигов (DataStore) и список приложений | | `core/ConfigImport.kt` | Импорт ссылок `ss://` (SIP002/legacy), `socks5://`, `http(s)://` | | `ui/*` | Compose-экраны: Туннель (журнал событий на timeline rail), Серверы, Приложения, Опции | ## Сборка ```bash ./gradlew :app:assembleRelease # → app/build/outputs/apk/release/app-release.apk (~2.4 МБ) ./gradlew :app:assembleDebug ``` Требуется Android SDK (platform-35, build-tools 35), NDK 27.2.x. Путь к SDK — в `local.properties`. ## Оптимизация батареи - Нативный event-loop tun2socks вместо userspace TCP/IP-стека на JVM (нет GC-давления на пакет). - Блокирующий I/O на эластичном пуле потоков — простаивающие соединения паркуют поток (0% CPU). - `setUnderlyingNetworks` + отслеживание смены сети, `setMetered(false)`. - Низкоприоритетное foreground-уведомление, поллинг статистики раз в 2 с (без wakelock). - Секундный тикер UI работает только при CONNECTED и только пока активити RESUMED. ## Безопасность / ограничения - Не реализованы VLESS/Reality (намеренно). - Shadowsocks: AEAD-шифры (`aes-128-gcm`, `aes-256-gcm`, `chacha20-ietf-poly1305`). Legacy stream-шифры и SS-2022 не поддерживаются. - HTTP/HTTPS-прокси не могут передавать UDP — для них работает только DNS-over-TCP.