Commit Graph

35 Commits

Author SHA1 Message Date
samosvalishe acbd90f52e refactor(captcha): вынести ручной flow в internal/client/captcha/manual
- cmd/vk-turn-client/manual_captcha.go (875 строк, был в package main) →
  internal/client/captcha/manual/manual.go как отдельный пакет. Экспортирует
  SolveViaProxy и SolveViaHTTP (переименованы из solveCaptchaViaProxy/
  solveCaptchaViaHTTP). Остальное package-private.

- Глобал isDebug, который ручной flow читал из main, заменён на manual.Debug
  (package var). cmd/vk-turn-client/main.go ставит manualcaptcha.Debug =
  cfg.Debug рядом с существующим isDebug = cfg.Debug.

- Тестовый файл перенесён с кодом; пакет переключён с main на manual.
  TestRewriteProxyRedirectLocation по-прежнему зовёт package-private rewriter
  изнутри пакета.

- План предлагал дробить manual.go дальше (server.go/browser.go/proxy.go/
  rewrite_html.go). Пропущено: лишний churn без выгоды, раз файл живёт в
  своём пакете. Можно сделать позже.
2026-05-19 17:21:07 +03:00
samosvalishe 2167ba990b refactor(layout): переезд в cmd/, свернуть client/internal в internal/client
- server/main.go → cmd/vk-turn-server/main.go. Несёт остаточные правки сервера
  (drop параметра useBond, убрано поле startup-лога).
- client/internal/{browserprofile,captcha,dnsdial,namegen,vkauth} →
  internal/client/* (единая иерархия internal/; параллельное дерево
  client/internal/ убрано). Все Go import-пути обновлены.
- .github/workflows/{ci,release}.yml, Dockerfile, README.md — пути сборки
  переключены на ./cmd/vk-turn-client и ./cmd/vk-turn-server.
- README: убран устаревший пример "server -vless-bond" (флаг удалён ранее);
  добавлены рецепты сборки .so для Android arm64 + Linux arm64/amd64 под
  ручную упаковку для мобилок.
- internal/proxy/udp/udp.go, internal/config/config.go: обновлены устаревшие
  ссылки client/internal/* в doc-комментариях.
- notes/GLOSSARY.md (новый, ~20 терминов): фиксирует DTLS-как-обфускацию,
  wrap=AEAD-не-XOR, четыре значения "client", три значения "stream", пять
  ортогональных переключателей "mode", заметки по сборке libvkturn.so, iSH,
  хрупкость init globalBondRegistry и удаления флагов.

cmd/vk-turn-client/ намеренно оставлен вне этого коммита; сворачивается вместе
с извлечением ручной captcha в следующем коммите, т.к. переименование и правки
импортов manualcaptcha.* попадают в один файл.

Wire-форматы не тронуты. Поведение не изменено кроме уже закоммиченных
удалений CLI.
2026-05-19 17:20:26 +03:00
samosvalishe 5b68683d41 refactor(config): убрать флаги -no-dtls и серверный -vless-bond
Чистка CLI (breaking):

- Клиент: убран -no-dtls (был помечен DO NOT USE; VK content-filter дропает
  payload без DTLS-handshake, так что прямой путь в проде не работал). Поле
  config.Client.Direct, guard диспатчера в main и TestParseClient_WrapDirectConflict
  удалены.

- Сервер: убран -vless-bond. Сервер уже автоопределяет bond по magic-префиксу
  на первом smux-стриме (bond-autodetect=true), флаг был избыточен. Поле
  config.Server.VLESSBond, параметр useBond у handleVLESSConnection и
  ветка-предупреждение "non-bond stream while bond enabled" удалены.

- Клиентский -vless-bond остаётся — он по-прежнему управляет страйпингом на
  стороне клиента.

Wire-форматы не тронуты. Оба удаления флагов — breaking CLI-изменения.
2026-05-19 17:19:44 +03:00
samosvalishe 817def3e01 refactor: вынести разбор CLI в internal/config
ParseClient/ParseServer возвращают валидированные структуры; main становится
связкой. Валидация без сайд-эффектов (без DNS/сети); main держит ResolveUDPAddr,
установки dnsdial.* и вывод gen-wrap-key. Сервер теперь переиспользует
wrap.GenKeyHex/wrap.DecodeKey вместо своего hex+rand пути.

client/main.go: 319 → 272. server/main.go: 424 → 402.
19 тестов покрывают дефолты, санитизацию vk-link, отсутствующие флаги,
валидацию -dns, конфликт wrap+no-dtls, декод wrap-key, положительность
streams-per-cred, clamp n, split dns-servers и short-circuit gen-wrap-key.

Флаги CLI, дефолты и поведение не изменены. Две строки ошибок
("Need peer address!" / "Need vk-link!") переведены в нижний регистр под
revive; не часть wire-контракта.
2026-05-19 16:26:36 +03:00
samosvalishe 75471c6fdc test(bond/server): покрыть reorder, pending drain, lane churn
Добавляет server_test.go с 6 юнит-тестами для registry bond-сервера: reorder
data-фреймов не по порядку в backend, drain pending-map при приходе пропущенного
seq, round-robin запись по lane, lane churn (сбойный lane выкинут, выживший
продолжает), all-lanes-fail возвращает исходную ошибку, dedup + cleanup registry.

Вводит небольшой интерфейс laneStream (io.Reader+Writer+SetDeadline) на
serverLane, чтобы тесты инжектили in-memory фейки без запуска реальной
smux-сессии. *smux.Stream его удовлетворяет, так что HandleStreamAfterMagic и
on-wire поведение не изменены.
2026-05-19 16:14:40 +03:00
samosvalishe dc2e4135aa refactor: вынести bond-сервер в internal/bond/server 2026-05-19 16:03:20 +03:00
samosvalishe 29771b1e27 refactor: вынести bond-клиент в internal/bond/client 2026-05-19 11:37:16 +03:00
samosvalishe 09096568ff refactor: вынести VLESS-режим в internal/proxy/vless
Переносит runVLESSMode/maintainVLESSSession/createSmuxSession/pipe и sessionPool
в internal/proxy/vless. Клиентская половина bond (handleBondedTCP, copyTCPToBond,
copyBondToTCP, bondClientLane) остаётся в client/main.go до этапа 5.1 —
инжектится в vless через Deps.BondHandler.

sessionPool/pooledSession экспортированы как SessionPool/PooledSession, чтобы
половина bond работала со счётчиками lane (ID/Sess/Opened/Active/Closed/
ToSession/FromSession).

Также дедуплицирует iSH (linux/386) listener-shim в новый пакет internal/ish;
client/manual_captcha.go и internal/proxy/vless импортируют его через
ish.WrapListener.

client/main.go: 895 → 552 (-343). Wire-формат и CLI не изменены.
2026-05-19 11:21:48 +03:00
samosvalishe 82f231d5e0 refactor: вынести UDP proxy-цикл в internal/proxy/udp
Переносит oneDtlsConnection/oneTurnConnection и их retry-циклы из client/main.go
в internal/proxy/udp, за интерфейс AuthHandler, чтобы пакет оставался вне
client/internal/. UDPPacket/packetPool становятся udp.Packet/udp.Pool. Глобал
globalAppCancel убран в пользу Deps.AppCancel. turnParams пока остаётся в
client/main.go, т.к. vless ещё его использует; переедет с этапом 4.2.

client/main.go: 1195 → 895. Wire-формат и CLI не изменены.
2026-05-19 10:37:21 +03:00
samosvalishe bc1aea625b refactor: вынести turnpipe и dtlsdial в internal/
Переносит общий пайплайн TURN dial+allocate в internal/turnpipe и DTLS-настройку
клиента в internal/dtlsdial. И oneTurnConnection, и createSmuxSession теперь
используют одни строительные блоки, убирая ~140 строк дублированной настройки.

Глобал handshakeSem убран, заменён двумя сконфигурированными dtlsdial.Dialer:
udpDtlsDialer (timeout 20s, sem cap=3) и vlessDtlsDialer (timeout 30s, без
gate). Поведение идентично прежним путям.

client/main.go: 1380 → 1195. Импорты netadapt, pion/dtls, selfsign,
pion/logging и pion/turn вынесены из client/main.go в новые пакеты.
2026-05-19 10:05:31 +03:00
samosvalishe 5bf6dd0399 refactor: вынести VK-авторизацию в client/internal/vkauth
Этап 2 плана рефакторинга. Выносит слой VK credentials/captcha/throttle/
lockout из client/main.go в отдельный пакет с инжектируемым хуком token-chain
для тестов.

Интерфейс:
- vkauth.Client{GetCredentials, HandleAuthError, ResetErrors, LockoutUntilUnix}
- vkauth.IsAuthError (package-level)
- vkauth.DefaultAutoSolve / AutoSolveFunc / ManualSolveFunc

Wire-формат и флаги CLI не изменены. client/main.go: 1967 → 1380.
2026-05-19 09:48:55 +03:00
samosvalishe 322e8db4fa refactor: вынести wrap в internal/wrap
Объединяет client/wrap.go + server/wrap.go в internal/wrap с экспортируемым
API: State (общий AEAD), Conn (per-stream RTP-состояние), WrapInto/Unwrap,
Listen (серверный PacketListener), RelayPacketConn (клиентская обёртка
TURN-relay), хелперы GenKeyHex/DecodeKey. Wire-формат сохранён побитово.

relayPacketConn переезжает из client/main.go в пакет wrap как RelayPacketConn
(его единственный осмысленный дом — он владеет *wrap.Conn).

-573 строки (client/wrap.go, server/wrap.go, client/wrap_test.go удалены).
2026-05-19 09:28:24 +03:00
samosvalishe ada0c746aa refactor: вынести stats, netadapt, bond в internal/
- internal/stats: throughputStats/countingConn/форматтеры, общие для клиента
  и сервера
- internal/netadapt: DirectNet, ConnectedUDPConn, SplitFirstWriteConn
- internal/bond: wire-кодек (Frame/Hello, Read/Write, CloseWrite)

Убирает дублирование между client/main.go и server/main.go. Wire-формат и
поведение CLI не изменены; round-trip кодека покрыт тестами.
2026-05-19 00:29:47 +03:00
samosvalishe 948108a33a chore: исправить замечания golangci-lint в wrap_test
errcheck на возврате wrapInto и govet shadow на err в
TestUnwrapRejectsTamperedPacket.
2026-05-18 22:53:59 +03:00
samosvalishe 085b719be7 perf(bond): убрать аллокацию на чанк в copyTCPToBond
writeBondFrame пишет синхронно через w.Write, поэтому слайс буфера чтения
безопасно передавать напрямую. Убирает одну аллокацию+копию на TCP-чанк на
горячем пути upload.
2026-05-18 22:51:41 +03:00
samosvalishe d0dabeec67 fix(bond): ограничить pending-map в copyBondToTCP против OOM
Чанки не по порядку с постоянной потерей вызывали неограниченный рост.
Лимит 1024 записи, закрытие соединения при переполнении.
2026-05-18 22:51:24 +03:00
samosvalishe 729557d00d refactor(wrap): перейти на мимикрию под SRTP в обход content-фильтра VK TURN
Wire-формат noise-AEAD (1b7cb4c) был реализован верно, но перестал доставлять
трафик через VK TURN после auth: ChannelData payload, не похожий по форме на
SRTP/DTLS, похоже, дропается VK TURN после недавнего изменения на стороне
сервера.

Новый wire-формат мимикрирует под SRTP (RFC 3550 / RFC 7714 AEAD-профиль):

  [12B RTP header | 12B nonce | AEAD ciphertext | 16B tag]

RTP header:
  byte 0:   0x80          V=2, P=0, X=0, CC=0
  byte 1:   0x6F          M=0, PT=111 (opus, частый VK voice PT)
  byte 2-3: seq16 BE      монотонный, init random
  byte 4-7: ts32 BE       монотонный +960 на пакет (20ms @ 48kHz)
  byte 8-11: SSRC         случайный на conn, MSB кодирует направление

Nonce = 4B sessionID (MSB=направление) || 8B counter (init random).
AAD = первые 24 байта, так что любое искажение RTP-заголовка ломает Open.

Overhead 40 B/пакет против 36 у noise-AEAD и 12 у исходного XOR. Если VK TURN
форвардит SRTP-образный трафик по быстрому пути, повышенный overhead окупается
отсутствием медленного shaping.

Тесты: round-trip, прогрессия RTP-полей, бит направления, искажение AAD.
2026-05-18 20:56:24 +03:00
samosvalishe 1506dafe3c chore: исправить замечания golangci-lint
- wrap_test.go: проверять ошибки newWrapConn/wrapInto во всех тестах
- server/wrap.go: nolint на type assertion bufPool (pool New всегда
  возвращает *[]byte)
- captcha/slider.go: обосновать пустой импорт image/jpeg
- namegen_test.go: применить закон Де Моргана к условию цикла
2026-05-18 20:35:20 +03:00
samosvalishe e2dd09a729 refactor(wrap): заменить DTLS-мимикрию на noise-only AEAD
Фейковый DTLS wire-формат (0202b9b) был fingerprintable по содержимому:
фиксированный content_type=0x17, нет handshake-записей, размеры пакетов
кластеризовались в 6 фиксированных корзин padding. Throughput на shaped
TURN-путях совпадал с wrap-off.

Новый wire-формат неотличим от случайного после первого байта:

  [1B header | (prefix_len-1)B random | 12B nonce | AEAD ct | 16B tag]

где prefix_len = 1 + (header & 0x07). Байт 0 распределён равномерно по
0..255, длина префикса закодирована в младших 3 битах.

Nonce = 4B sessionID || 8B counter (BE). MSB sessionID кодирует направление
(0 клиент, 1 сервер), чтобы клиент и сервер не коллизировали под одним
ключом. counter стартует со случайного uint64 против reuse nonce между
перезапусками процесса. AAD = nonce; случайный префикс — неаутентифицированный
шум.

Padding по фиксированным корзинам убран полностью. Усиление в 2-4x мелких
ACK/keepalive-пакетов было вероятной причиной регрессии throughput.

Overhead: 29..36 B на пакет (против 31..47 в DTLS-мимикрии, 12 в pre-AEAD
XOR). Целостность обеспечивает Poly1305.
2026-05-18 20:26:54 +03:00
samosvalishe 369ba1e43c feat: поддержка refactor-коммитов в release-workflow 2026-05-18 19:42:50 +03:00
samosvalishe e64ec077f6 chore: go fmt 2026-05-18 19:40:18 +03:00
samosvalishe 39f95a8e0c refactor(wrap): переписать как мимикрию под DTLS 1.2 ApplicationData с AEAD
Заменяет наивный wire-формат [12B nonce | ChaCha20-XOR] на фейковый
заголовок DTLS 1.2 record, проходящий DPI-инспекцию:

  [content_type=0x17 | version=0xFEFD | epoch | seq | length | AEAD ciphertext | tag]

Ключевые изменения:
- ChaCha20-Poly1305 AEAD вместо неаутентифицированного ChaCha20 XOR
- Padding длины по фиксированным корзинам {128..1300} ломает fingerprint
  по размеру
- Direction-safe epochs (MSB=0 клиент, MSB=1 сервер) предотвращают reuse nonce
- Nonce выводится из XOR(SHA-256(key), поля заголовка), без константного
  префикса
- Горячий путь сервера использует sync.Pool, убирая аллокацию на пакет

Пользовательские флаги (-wrap, -wrap-key, -gen-wrap-key) не изменены.
2026-05-18 19:32:59 +03:00
samosvalishe b3f81add0e refactor: вынести namegen в internal-пакет, расширить пулы имён
- Перенос client/namegen.go в client/internal/namegen с экспортируемым
  Generate()
- Вынос данных имён в data/*.txt, загрузка через //go:embed
- Расширение пулов: мужские 729→760, женские 31→99, фамилии 60→286
  (вкл. мем-имена)
- Переписан feminizeSurname через []rune (убрана хрупкая байтовая
  арифметика на len-4)
- Переход с math/rand на math/rand/v2
- Юнит-тесты: parseLines, feminizeSurname, целостность пулов, форма и
  покрытие по полу у Generate
2026-05-18 17:51:27 +03:00
samosvalishe ead97d0089 refactor: удалить поддержку Yandex Telemost и мёртвый код
Удаляет флаг -yandex-link, getYandexCreds и ветку Telemost из основного
потока клиента. Убрана зависимость gorilla/websocket.

Вычищен мёртвый код, всплывший после удаления:
- browserprofile.ApplyHTTP / Random / profileList
- dnsdial DohResolver.LookupIPAddr / queryIPs / parseAnswer / dohCache
  и их тесты (единственный production-вызыватель — путь forwarder)
- устаревшая строка -captcha-solver в README

Публичные DoH-эндпоинты Yandex оставлены (RU-дружественный fallback, не
связан с Telemost).
2026-05-18 17:24:11 +03:00
samosvalishe ac3a6031d0 refactor: вынести солвер captcha в internal/captcha
Вытаскивает auto-captcha пайплайн из client/main и даёт ему узкий публичный
интерфейс, чтобы main.go больше не держал ~1.2k строк обработки VK-челленджей.

Новые пакеты под client/internal/:

- browserprofile: типы Profile / Saved плюс Load / Save / Random и инжекторы
  заголовков ApplyHTTP / ApplyFhttp (перенесены из profiles.go + main.go).
  manual_captcha.go тоже переключён на него.
- captcha: package-level entrypoint Solve(ctx, *Error, ...), плюс
  Error / ParseError / IsCaptcha (переименованы из VkCaptchaError /
  ParseVkCaptchaError / IsCaptchaError). Сессия, scoring слайдера, синтез
  курсора и PoW теперь неэкспортируемая деталь реализации.

solveVkCaptcha в main.go сжимается до обёртки над captcha.Solve с загрузкой
SavedProfile.
2026-05-18 16:15:59 +03:00
samosvalishe 130d5e9298 refactor: убрать суффикс V2 из солвера captcha
После удаления POC-пути суффикс V2 рудиментарен — нет v1, от которого надо
отличать. Механическое переименование в captcha.go и captcha_slider.go
(бывшие captcha_v2{,_slider}.go):

- captchaV2* → captcha* (имена структур/переменных/констант/regex/ошибок)
- *V2 → * (slider-хелперы, sample/score-функции, abs-хелперы)
- solveVkCaptchaV2 → solveCaptchaAuto (вызов обновлён)
- log-префиксы "v2 captcha" / "v2 slider" убраны
2026-05-18 16:07:04 +03:00
samosvalishe 5137ddd80b refactor: удалить slider POC путь captcha
Удаляет slider_captcha.go / slider_captcha_test.go и fallback
captchaSolveModeSliderPOC. POC дублировал v2-солвер с захардкоженным
debug_info, scoring только по RGB и единственной попыткой — строго хуже
v2-пути, который уже делает ретраи внутри.

- Удалён глобал autoCaptchaSliderPOC, параметр useSliderPOC у solveVkCaptcha,
  captchaSolveModeSliderPOC и его ветки в dispatch-цикле.
- Последовательность ретраев сведена к Auto → Manual.
- Общие image-хелперы (sliderTileRect, pixelDiff, absDiff) перенесены в
  captcha_v2_slider.go.
- Удалены теперь неиспользуемые generateBrowserFp, fetchCaptchaBootstrap,
  solvePoW.
2026-05-18 16:02:29 +03:00
samosvalishe 1c6b7a89ca refactor: удалить v1-солвер captcha и осовременить стиль
- Удалён legacy v1 auto-captcha путь: callCaptchaNotRobot, глобал
  captchaSolverVersion, флаг -captcha-solver. v2-солвер — единственный
  auto-путь; slider POC и ручной fallback остаются.
- Удалены закомментированные блоки generateFakeCursor/generateCheckboxCursor
  и generateSliderCursor/buildSliderCursor.
- Убраны неиспользуемые параметры candidateIndex/candidateCount у
  requestSliderCheck.
- interface{} заменён на any во всех .go файлах.
- Паттерн sync.WaitGroup Add+Done+go func заменён на wg.Go (Go 1.25).
- Несколько циклов for i := 0; i < N; i++ переведены на for range N.
2026-05-18 15:48:58 +03:00
samosvalishe b3694ad557 chore: добавить .idea в gitignore 2026-05-18 15:48:05 +03:00
samosvalishe 7433305511 feat: вырезать идентифицирующие proxy-заголовки, расширить пул имён
- rewriteProxyRequest теперь вырезает X-Requested-With, X-Android-Package,
  X-Android-Cert, X-Client-Data, X-Discord-Locale, X-Discord-Timezone,
  Save-Data, Purpose, Sec-Purpose перед форвардом captcha-запросов
- maleFirstNames расширен с 39 до 735 записей из исторического корпуса имён
2026-05-12 01:15:34 +03:00
samosvalishe e134893df3 fix: форматирование 2026-05-12 00:11:17 +03:00
samosvalishe 4e5690cd04 feat: перенести DoH-резолвер, добавить флаг -dns
Заменяет bschaatsbergen/dnsdialer (только UDP) на внутренний пакет dnsdial.
Добавляет поддержку DNS-over-HTTPS и режим auto (проба UDP/53 → залипающий
fallback на DoH при сбое).

Новый флаг: -dns udp|doh|auto (по умолчанию: auto)
2026-05-11 23:46:27 +03:00
samosvalishe 7a0f98f730 perf: убрать аллокации на горячем пути, TCP DPI-split и KCP FEC
- Атомарный счётчик nonce вместо per-packet rand.Read (syscall getrandom);
  wire-формат не изменён, сервер декодирует без правок
- wrapInto: TX-путь без аллокаций с заранее выделенным буфером;
  wrapPacket оставлен для тестов и control-путей
- Кеш указателя при приёме WG исключает аллокацию addr.String() на пакет
  (быстрый путь — сравнение указателей, медленный — строк)
- Атомики статистики throughput спрятаны за isDebug — снижает трафик
  cache-line по N стримам в production-сборках
- splitFirstWriteConn разбивает первую TCP-запись на байте 6 + задержка
  20ms, ломая STUN magic cookie между сегментами против поверхностного DPI
- VK_TURN_KCP_FEC=data:parity включает Reed-Solomon FEC поверх KCP;
  обе стороны должны совпадать; по умолчанию 0:0 (выключено)
- Исправлен WaitGroup: wg.Add(1) → wg.Add(2) для двух горутин в
  oneDtlsConnection; раньше wg.Wait() возвращался слишком рано
2026-05-11 23:46:27 +03:00
samosvalishe 334a17f1af feat: добавить флаг для своих DNS-серверов 2026-05-11 23:46:26 +03:00
samosvalishe 942d0fff43 feat: initial commit 2025-11-25 11:38:20 +00:00