proxy/README.md

78 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# vojo proxy
Нативный Android-клиент для прокси: **Shadowsocks**, **SOCKS5**, **HTTP**, **HTTPS**.
Per-app whitelist, минимальный расход батареи, маленький размер (release APK ≈ 2.4 МБ).
Дизайн — в стиле мессенджера vojo (Dawn/Fleet: тёмные поверхности, hairline-границы,
один фиолетовый акцент, monospace для технических данных).
> Для AI-агентов: карта кодовой базы, как собирать/тестировать и список инвариантов — в [`docs/`](docs/README.md).
## Стек
- **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:<port>
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 — версия закреплена в
`app/build.gradle.kts` (`ndkVersion`). Путь к 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.