Commit Graph

45 Commits

Author SHA1 Message Date
samosvalishe 9d7d754740 refactor(logging): унифицировать stdlib log.* в logx по client/cmd
internal/client/captcha, captcha/manual, dnsdial: добавить package-level Log +
SetLogger; убрать прямой обход -debug через stdlib log.Printf. cmd/{client,
server}/main.go: сначала строить logger, весь вывод через logger.{Info,Warn,
Error}f; оставлен один log.Fatalf только для сбоя разбора конфига до логгера.
dnsdial: log.Panicf → panic(fmt.Sprintf).

Исправлены уровни:
- vkauth/token.go: пути [FATAL] теперь Errorf; Auto/Manual captcha failed →
  Warnf; ignored-cleanup-error → Debugf.
- vkauth/client.go: HandleAuthError/cache invalidated → Warnf; throttle wait →
  Debugf; Failed-with-client_id → Warnf.
- udprelay: "Backing off 60s" + SetDeadline failed → Warnf.
- captcha: PoW/show_type/check status/debug_info → Debugf; endSession/close-body/
  script-drift → Warnf.

Префиксы нормализованы к [STREAM %d] [Pkg] msg / [Pkg] msg.
2026-05-20 11:26:21 +03:00
samosvalishe 52e7cb83e6 fix: утечки, уровни logx, обход логгера
- logx: добавить префиксы [DEBUG]/[INFO]/[WARN]/[ERROR]; уровни были
  неразличимы в выводе (всё шло через голый log.Printf).
- logx: добавить хелпер OrNop для nil-проверок на стороне конструктора.
- vkauth/{client,token}.go: заменить прямой log.Printf на c.log.Infof
  (97 мест обходили унифицированный логгер после прошлого рефакторинга).
- udprelay.oneTURN: буферизовать error chan (cap 1) + select на ctx.Done в
  TURNLoop — небуферизованный send блокировался навсегда, когда TURNLoop
  выходил по ctx до чтения, утекали горутина + TURN-стрим.

- udprelay: перенести write-цикл conn2->relay в wg.Go (был голый go func, мог
  пережить wg.Wait и читать из закрытого conn).
- udprelay.TURNLoop: заменить time.Sleep(2s) на select+ctx, чтобы shutdown не
  блокировался per-stream.
- udprelay.Run / tcpfwd.Run: возвращать error вместо log.Panicf при сбое listen;
  cmd/* теперь log.Fatalf на всплывшей ошибке.
- cmd/*: log.Panicf → log.Fatalf для CLI-ошибок (без stack trace на плохой флаг).
- kcptun.NewKCPOverDTLS: закрывать серверный kcp.Listener на error-путях после
  SetDeadline/AcceptKCP (утекал при любом сбое).
- doc пакета udprelay: переписать устаревшее утверждение "avoid importing
  vkauth" (файл импортирует vkauth ради sentinel-ошибок).
- udprelay: lifecycle-сообщения ("Established/Closed DTLS connection")
  Errorf → Infof; строка "relayed-address" под DebugEnabled использует Debugf.
- tcpfwd: lifecycle-сообщения ("connected/disconnected/waiting/listening")
  Errorf → Infof, "failed to wrap listener" → Warnf.
- tcpfwd.maintainSession doc: "fixed 2-3s backoff" было неверно (3s при сбое
  setup, 2s после disconnect).
- pool.go doc: "bond client (in main)" → internal/proxy/bondclient.
- srtpmimicry.Unwrap: doc предупреждает, что AEAD открывает in-place внутри
  wire, поэтому вызыватели должны считать wire потреблённым.
- комментарии-алиасы GetCredsFunc udprelay/tcpfwd: убрать фикцию "cmd/main
  wiring stability" (всё в internal/).

Build чисто, go vet чисто, все тесты проходят.
2026-05-19 22:24:21 +03:00
samosvalishe aff95e87d3 refactor: унифицировать логирование в internal/proxy/* через logx.Logger
Заменяет прямой log.Printf на logger.Errorf/Debugf в каждом proxy-пакете
(udprelay, tcpfwd, bondclient, bondserver, udpserver, tcpfwdserver). Вывод
остаётся совместимым (под капотом stdlib log), но теперь может быть глобально
перенаправлен сменой реализации Logger.

Тесты + lint проходят.
2026-05-19 21:57:33 +03:00
samosvalishe 51bda46446 refactor: симметрия, вынос серверных хендлеров
- internal/proxy/udpserver: handleUDPConnection вынесен из server-main
- internal/proxy/tcpfwdserver: handleVLESSConnection + prefixedConn + pipeConn
  вынесены из server-main
- cmd/vk-turn-server/main.go: 396 → 134 строк, глобалы убраны
- internal/proxy/udprelay: добавлен entrypoint Run() симметрично tcpfwd.Run;
  Pool → packetPool (unexported); listener+fan-in вынесены из client-main
- cmd/vk-turn-client/main.go: 262 → 130 строк, package-глобалы убраны
- dtlsdial.Dialer: кеш self-signed сертификата на Dialer (sync.Once) вместо
  регенерации на каждый handshake
- captcha.solveCaptchaPoW: переиспользование буфера (вместо 10M конкатенаций
  строк), ctx-проверка каждые 1024 итерации (было 4096)

Тесты + lint проходят.
2026-05-19 21:53:13 +03:00
samosvalishe ed6825976a fix: исправить баги, sentinel-ошибки, устаревшие доки
Баги:
- udprelay: errors.Is(DeadlineExceeded) вместо сравнения строк; короткий
  backoff в ветке lockout; обернуть DTLS-ошибку через %w
- bondserver.copyBondToBackend: лимит pending-map в 1024 (паритет с bondclient)
- srtpmimicry.RelayPacketConn: bufPool для горячего UDP-пути (паритет с listen.go)
- vkauth.token.go: ручной солвер под ctx.WithTimeout(ctx, ...) вместо Background
  — нет утечки горутины при shutdown

Гигиена:
- sentinel-ошибки vkauth как var = errors.New(...); вызыватели используют errors.Is
- убраны устаревшие комментарии этапов рефакторинга (Pion SPDX, "Package bond",
  internal/bond, удалённый файл заметок)
- .gitignore: *.exe, *.so

Тесты + lint проходят.
2026-05-19 21:47:48 +03:00
samosvalishe 7e3369f478 docs: заметка DTLS-как-обфускация + breaking changes в README
- internal/transport/dtlsdial/doc.go: объяснить, что DTLS используется как слой
  обфускации под content-фильтр VK TURN, а не как граница безопасности;
  задокументировать, почему -no-dtls был убран и почему решения вроде
  self-signed сертификатов / send-only CID намеренны.
- README: добавить врезку breaking-changes под "Защита от блокировок"; убрать
  строки -no-dtls и server -vless-bond из таблиц флагов; отметить, что bond
  автоопределяется по magic-префиксу на сервере.

Завершает рефакторинг. Все этапы зелёные: go build / go vet / go test / gofmt.
CLI и wire-форматы бит-в-бит кроме двух удалений (-no-dtls на клиенте,
-vless-bond на сервере).
2026-05-19 21:18:58 +03:00
samosvalishe 6c9bfbae82 refactor(config): сгруппировать опции по доменам
Заменяет плоские структуры config.Client / config.Server на
доменно-сгруппированные под-структуры, чтобы форма повторяла концептуальные
слои прокси:

  type Client struct {
      TURN  TURNOpts   // Host, Port, UDP, N
      Obf   ObfOpts    // WrapMode, WrapKey, GenWrapKey
      Proxy ProxyOpts  // Mode, Listen, Peer
      VK    VKOpts     // Link, StreamsPerCred, ManualCaptcha
      DNS   DNSOpts    // Mode, Servers
      Log   LogOpts    // Debug
  }
  type Server struct { Obf; Proxy{Mode, Listen, Connect}; Log }

Enum ProxyMode (udp | tcpfwd | tcpfwd-bond) заменяет два параллельных bool
VLESSMode / VLESSBond в коде вызывающих. Поверхность CLI (-vless, -vless-bond)
не изменена; clientProxyMode / serverProxyMode в Parse* мапят bool в enum.

cmd/vk-turn-{client,server}/main.go: каждый cfg.X теперь cfg.Group.X. Тесты
обновлены; новый TestParseClient_ProxyMode покрывает все четыре комбинации
флагов (включая -vless-bond без -vless, который молча игнорируется как и раньше).

Без изменений флагов CLI, дефолтов, поведения и wire-формата. go build /
go vet / go test / gofmt чисто.
2026-05-19 20:59:23 +03:00
samosvalishe e212465f83 refactor(proxy): вынести общие хелперы (минимальный объём)
Исходный план просил proxy.Engine + интерфейс Handler, объединяющий udprelay и
tcpfwd. После разбора кода заявленные ~70% пересечения оказались ближе к ~30
строкам: udprelay (WG → DTLS-terminate → wrap → TURN) и tcpfwd (TCP → smux →
KCP → DTLS → wrap → TURN) наслаивают wrap/DTLS по-разному и имеют разные
жизненные циклы. Engine с двумя if-ветками просто загнал бы дублирование внутрь,
а не убрал.

Объём минимальный: новый пакет internal/proxy/common с тем, что реально
идентично:

  - тип GetCredsFunc (дублировался в обоих пакетах).
  - DialTURN(ctx, host, port, udp, peer, link, streamID, getCreds) — берёт creds
    и открывает turndial-стрим. Политика retry на auth-ошибке остаётся в udprelay.
  - NewClientWrap(key) — возвращает (nil, nil) при пустом/коротком ключе, иначе
    srtpmimicry.NewConn(key, false).

udprelay и tcpfwd теперь импортируют common.DialTURN / common.NewClientWrap.
Их локальные объявления GetCredsFunc становятся type alias на
common.GetCredsFunc, чтобы связка cmd/vk-turn-client компилировалась без churn.

bond-as-tcpfwd-option отменён вместе с интерфейсом Handler; bondclient остаётся
отдельным пакетом, подключённым через Deps.BondHandler.

Без изменений wire-формата, флагов CLI и поведения. go build / go vet /
go test / gofmt чисто.
2026-05-19 20:52:02 +03:00
samosvalishe 1fb869b3e1 refactor(layout): переименовать пакеты (split wire/transport/proxy)
internal/wrap → internal/wire/srtpmimicry; правки doc ("обфускация, не security").
internal/bond/{frame,client,server} → internal/wire/bondframe,
internal/proxy/bondclient, internal/proxy/bondserver.
internal/netadapt → internal/netconn.
internal/turnpipe → internal/transport/turndial; internal/dtlsdial →
internal/transport/dtlsdial.
tcputil → internal/transport/kcptun; selectedKCPProfile и selectedFEC теперь
кешируются через sync.Once (env читается один раз вместо per-connection).
internal/proxy/udp → internal/proxy/udprelay; internal/proxy/vless →
internal/proxy/tcpfwd. Флаг CLI -vless сохранён.
internal/ish → internal/client/ish; doc пакета расширен (iSH = Linux user-mode
эмулятор на iOS, только linux/386).

Чисто механическое переименование + обновление import-путей/идентификаторов.
Wire-формат, флаги CLI и поведение не изменены. go build + go test зелёные.
2026-05-19 20:42:46 +03:00
samosvalishe 7fd2d9594d refactor(logx): заменить Deps{Debug,Debugf} на интерфейс logx.Logger
Добавляет internal/logx с Debugf/Infof/Warnf/Errorf + DebugEnabled().
Протягивает logx.Logger через bondclient, bondserver, proxy/udp, proxy/vless,
vkauth. Убирает глобалы isDebug/debugf из обоих бинарей. Переносит
globalBondRegistry из package init в main (инициализация после
config.ParseServer), закрывая давний footgun "Debug=false на init".
2026-05-19 17:54:19 +03:00
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