From a9d556c39d080320be7c53dd3294855d37d7dc61 Mon Sep 17 00:00:00 2001 From: Andrey Prokopyuk Date: Sun, 11 Oct 2026 20:27:47 +0300 Subject: [PATCH 1/3] Document API 35 release verification and GOST half-close limitation --- docs/en/masque.md | 5 + docs/en/release-testing.md | 2 +- docs/reviews/release-api35-2026-10-11.md | 197 +++++++++++++++++++++++ docs/ru/masque.md | 5 + docs/ru/release-testing.md | 2 +- 5 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 docs/reviews/release-api35-2026-10-11.md diff --git a/docs/en/masque.md b/docs/en/masque.md index d813db3..3554945 100644 --- a/docs/en/masque.md +++ b/docs/en/masque.md @@ -69,6 +69,11 @@ normal routing and are not rewritten to the selected DoH provider. Oversized outgoing packets are dropped whole, with one diagnostic per UDP flow; following smaller packets keep working. The advertised receive limit also bounds outgoing payloads to avoid GOST closing a flow on an echo-sized oversized reply. +- The 2026-10-11 API 35 verification found lost final TCP bytes on immediate write + half-close with GOST 3.3.0: its relay handles EOF before bytes returned by the same + read. The failure also reproduces with the native client without Android TUN. + This is a server limitation; delaying FIN is not a fix. See the + [verification report](../reviews/release-api35-2026-10-11.md). - GOST 3.3.0 rejects IPv6 literal CONNECT-UDP targets. TCP IPv6 and local UDP bypass follow the profile's IPv6/routing policy. IPv4-only is the default. - The stats card shows QUIC RTT and outgoing packets declared lost over five minutes. diff --git a/docs/en/release-testing.md b/docs/en/release-testing.md index 98dbcb0..b0a8803 100644 --- a/docs/en/release-testing.md +++ b/docs/en/release-testing.md @@ -92,7 +92,7 @@ visible in the matrix; an emulator result never silently substitutes for it. | ID | Steps → required observation | | --- | --- | -| T01 | Ordinary-app HTTP and HTTPS requests through HTTPS/GOST, SSH/OpenSSH, HTTPS Jump, SSH Jump, SOCKS5 and MASQUE α; exercise both selections of HTTPS HTTP/3 preference (H12–H15). Use unique tokens, binary upload/download comparisons and server-side evidence. Exercise multiple requests and simultaneous streams; confirm destination/jump roles and no double traffic counting. Use an origin that replies only after the client write half-close; the full response must survive FIN on every transport. | +| T01 | Ordinary-app HTTP and HTTPS requests through HTTPS/GOST, SSH/OpenSSH, HTTPS Jump, SSH Jump, SOCKS5 and MASQUE α; exercise both selections of HTTPS HTTP/3 preference (H12–H15). Use unique tokens, binary upload/download comparisons and server-side evidence. Exercise multiple requests and simultaneous streams; confirm destination/jump roles and no double traffic counting. Use an origin that replies only after the client write half-close; the full response must survive FIN on every transport. Send payload and FIN consecutively without an artificial delay; on failure also exercise the production dialer directly against the same server version. | | T02 | Correct → wrong → missing → restored credentials at each authenticated hop. Require working controls and no successful origin delivery for the negative token. A “Connected” label with rejected requests is not success. | | T03 | Proxy refused, timeout, reset, unreachable origin and truncated response; restore each. Application must report bounded errors and recover. No direct fallback unless the selected routing policy explicitly calls for it. | | T04 | All-app routing on an emulator; selected-app routing on every device with two ordinary UIDs (included/excluded). Toggle local-network bypass and probe controlled LAN/private and public targets. Confirm included/excluded decisions from observed route, not just checkboxes. | diff --git a/docs/reviews/release-api35-2026-10-11.md b/docs/reviews/release-api35-2026-10-11.md new file mode 100644 index 0000000..369e5f5 --- /dev/null +++ b/docs/reviews/release-api35-2026-10-11.md @@ -0,0 +1,197 @@ +# API 35 signed-candidate verification — 2026-10-11 + +This is a dated, shortened acceptance snapshot, not full release approval. The user +limited the remaining run to 30 minutes. Rare UI combinations, long soaks and +unexecuted critical cases remain **NOT TESTED**. Only the dedicated API35 emulator +was requested; phone results and API26 signed-APK acceptance are not inferred from CI. + +## Candidate and independent automated evidence + +- Application source: `b3a478826504fbec177dfeab0a45ba768d8d72df` (main, PR #85). + This report/documentation branch does not change the tested application. +- Fastlane: `bundle exec fastlane android release_artifacts`, JDK21. +- Candidate: version `1.1.0`, arm64-v8a, versionCode `19002`, minSDK26, targetSDK36. + SHA-256: `3ffd2d25179047b83ccf8b636539788e2ba908213370b3f9bc43b8fb06982e0a`. +- Signer SHA-256: `8a014a2a558a75b5f900ee0c33cd50f24b7432734912406699fc08866747f822`. +- Five signed variants inventoried: universal19000, armeabi-v7a19001, + arm64-v8a19002, x8619003, x86_6419004. +- [Full main CI](https://github.com/andre487/AndroidMegaProxy/actions/runs/38152917219) + passed all suites at the exact source commit. Downloaded JUnit reports contain + 675 tests, zero failures/skips: Go225, native GOST/OpenSSH integration45, + Android JVM289, Python61, API26 integration27, API35 integration28. + Debug/emulator CI supports the signed test; it does not replace it. +- Android15/API35 Google APIs arm64, accelerated cold boot, dedicated Pixel8 AVD, + patch2024-09-05, 1080×2400, density420, page size4096. + Static APK zip alignment and both arm64 ELF LOAD segment alignments passed16KiB; + **16KiB runtime is NOT TESTED**. +- Real signed migration from v1.0.3, SHA-256 + `6ceef46e06b0b194aef90ee85fa91c2487d227a703f4622aa0dbf271a9cc0dcb`, + with identical signer. Requests succeeded before and after installation. + +## Confirmed failure: GOST final bytes lost on write half-close + +**T01 fails against official GOST3.3.0.** An ordinary included app writes a unique +17-byte body and immediately calls `shutdownOutput`; the origin reads until EOF +and echoes the complete body. Several GOST transports deliver zero bytes instead. +HTTP/HTTPS request success does not cover this stream boundary. + +The same immediate-FIN failure reproduces with the production MASQUE dialer directly +on the host, without Android TUN. GOST3.3.0 embeds `github.com/go-gost/x v0.16.0`; +its `internal/net/pipe.go:pipeHalf` handles a read error before writing bytes returned +by that same read. `(n > 0, io.EOF)` therefore discards the final data. + +A diagnostic build of the same GOST sources, with only the write-before-error order +corrected, passes the immediate-FIN production-dialer check. A separate250ms delay +also avoids the symptom, but is **not a client fix**. These diagnostic passes do not +replace the official-server failure. Existing native +`TestMASQUEHalfCloseThroughProductionWrappers` already covers consecutive Write / +CloseWrite with a correctly implemented server. + +No client workaround or personal-server change was applied. Release acceptance +remains blocked by the official-server failure and the unexecuted gates below. + +## Completed subscription checks + +18/18 executed subchecks passed. HTTPS primary/backup feed delivery used the +application's real platform TLS and encrypted ConfigStore state. The background +refresh was delivered by JobScheduler without forcing the job. Subsequent SSH +fixture setup initially retained the feed's default local-network bypass; those +private-origin probes were invalid. The feed was amended to explicitly preserve +test routing, automatic updates paused and effective routing verified before the +separate SSH control run. Raw setup failures remain in private evidence. + +## Device scenario ledger + +PASS means the complete named preparation check passed. NOT TESTED includes partial +scenarios: their completed subcases are described explicitly, while remaining +criteria are deferred. FAIL is preserved even where other subcases pass. + +| ID | Verdict | API35 evidence / remaining scope | +| --- | --- | --- | +| A01 | PASS | Recorded clean build source, toolchain, variants and locks. | +| A02 | PASS | Exact-commit full CI: 225 Go + 45 integration + 289 JVM + 61 Python + 27 API26 + 28 API35 tests; zero failed/skipped. | +| A03 | PASS | Five signed APKs built; hashes, signer, manifest and ABIs retained. | +| A04 | NOT TESTED | Manifest/component/asset inventory inspected; exhaustive policy/license review deferred. | +| A05 | NOT TESTED | No F-Droid submission/reproducibility run in this task. | +| A06 | NOT TESTED | Dedicated API35 emulator inventoried; phones/API26 signed acceptance and 16KiB runtime outside this run. | +| A07 | PASS | Disposable AVD and fixtures; no personal configuration used. | +| A08 | NOT TESTED | Private TCP/DoH/H3/OpenSSH fixtures established; SOCKS UDP fixture lacks working direct baseline. | +| A09 | NOT TESTED | Main CI checked; no tag, release publication or VirusTotal upload authorized. | +| I01 | NOT TESTED | Signed clean install/launch performed; exhaustive screen traversal deferred. Installed APK hash checked at exit. | +| I02 | NOT TESTED | Real v1.0.3→candidate upgrade while connected; profile ciphertext, selected/Always-on references and global settings preserved; before/after traffic passed. Counter/updater-source criteria deferred. | +| I03 | NOT TESTED | VPN consent granted; rejection/revocation/notification-denial permutations deferred. | +| I04 | NOT TESTED | Repeated start/stop/profile changes with traffic; exhaustive rapid actions/rotation deferred. | +| I05 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| I06 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| P01 | NOT TESTED | Imported/selected real transport profiles; exhaustive CRUD and restart combinations deferred. | +| P02 | NOT TESTED | Canonical synthetic imports performed; full export/import/error matrix deferred. | +| P03 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| P04 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| P05 | NOT TESTED | Trusted HTTPS/MASQUE identity and repeated wrong-host rejection; explicit exception and return to verification tested. Untrusted CA/JA3 permutations deferred. | +| P06 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| P07 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| T01 | FAIL | HTTP/HTTPS binary echo passed on 11 GOST variants and SSH/SSH Jump; both SSH half-close controls passed. Immediate write half-close loses final bytes on official GOST3.3.0; reproduced without Android TUN. See finding below. | +| T02 | NOT TESTED | 50 GOST auth/hostname negative requests: no token reached controlled origin, with working before/after controls. Exhaustive independent-hop combinations deferred. | +| T03 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| T04 | NOT TESTED | Ordinary included UID exercised; complete selected/all-app and local-bypass matrix deferred. | +| T05 | NOT TESTED | MASQUE/both-H3 512/1200/1350-byte UDP echoes passed; 4096-byte drop followed by successful 512-byte echo. TCP fallback UDP rejected. SOCKS UDP and IPv6 uplink not established. | +| T06 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| T07 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| T08 | NOT TESTED | Metrics screens captured; independently induced loss/expiry and counter correlation deferred. | +| T09 | NOT TESTED | Negotiation diagnostics collected; fingerprint wire fidelity/full algorithm matrix deferred. | +| T10 | NOT TESTED | External provider diagnostic matrix deferred. | +| C01 | NOT TESTED | Paused manual refresh, backup, all-sources failure and primary recovery passed; restart/ownership-removal combinations deferred. | +| C02 | NOT TESTED | Invalid UTF-8, empty snapshot, canonical ID collision and 403 rejected; exact working profile bytes preserved. Redirect/gzip/concurrent replacement cases deferred. | +| C03 | NOT TESTED | Actual scheduled background update passed: old HTTP/1.1 tunnel retained traffic, PRIVATE notification48703 and in-app Reconnect appeared; startup-delay/name-only/denied-channel permutations deferred. | +| C04 | NOT TESTED | Explicit Reconnect selected updated endpoint and HTTP/2 (independent negotiation logs), request passed and pending token cleared. Stale/two-update/after-Stop action permutations deferred. | +| C05 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| S01 | NOT TESTED | Authenticated/anonymous TCP and auth negatives passed; byte-boundary/URI matrix deferred. | +| S02 | NOT TESTED | UDP fixture baseline failed; resulting timeouts are inconclusive, not app failures. Exact-commit native/device CI supports UDP implementation independently. | +| S03 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| S04 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| H01 | NOT TESTED | Standalone MASQUE profiles imported and connected; full editor/serialization matrix deferred. | +| H02 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| H03 | NOT TESTED | Correct and repeated wrong/missing credentials tested; complete fingerprint matrix deferred. | +| H04 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| H05 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| H06 | NOT TESTED | Controlled browser origin test blocked by Chrome NET::ERR_CERT_AUTHORITY_INVALID; zero origin requests. Outer MASQUE connection is not evidence of inner browser H3. | +| H07 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| H08 | NOT TESTED | Chrome-size datagram sequence passed/dropped/recovered as described in T05; full size/IPv6/browser matrix deferred. | +| H09 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| H10 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| H11 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| H12 | NOT TESTED | HTTPS preference: available H3 and TCP fallback tested with ordinary HTTP/HTTPS/DNS/UDP; complete fallback fault injection deferred. | +| H13 | NOT TESTED | Both-H3, jump-only-H3, exit-only-H3 and neither-H3 chain traffic tested. Mixed chains fall back to TCP and reject non-DNS UDP; MTU/loss/handshake-stop matrix deferred. | +| H14 | NOT TESTED | Authentication/certificate terminal rejection tested; full fallback status-code/fingerprint/protection matrix deferred. | +| H15 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| L01 | NOT TESTED | Home/background retained real traffic; lock/task removal/notification-navigation combinations deferred. | +| L02 | NOT TESTED | Two server suspensions caused bounded request failures; first restoration recovered traffic without manual restart, second restoration followed by explicit Stop stayed stopped. Stop while engine reconnect is pending not independently established. | +| L03 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| L04 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| L05 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| L06 | PASS | Connected real signed upgrade recovered traffic. Same-candidate package replacement after explicit Stop stayed disconnected; manual Connect afterward recovered traffic. This second replacement is not claimed as migration. | +| L07 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| L08 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| L09 | NOT TESTED | Stopped VPN cannot deliver new benchmark-origin tokens; stalled admission/rapid callback combinations deferred. | +| L10 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| L11 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| D01 | NOT TESTED | Fresh Java InetAddress, JNI getaddrinfo and Android DnsResolver A queries passed. CUSTOM DoH outage failed as expected and recovery passed; capture correlation recorded below. All fallback/provider permutations deferred. | +| D02 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| D03 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| D04 | NOT TESTED | Ordinary UID: SSH trust activity, VPN service, update job service and FileProvider access all refused (four SecurityExceptions). Exhaustive exported-intent/broadcast matrix deferred. | +| D05 | NOT TESTED | Explicit UDP/TCP DNS, fragmented framing, pipelined queries, write half-close and AAAA suppression passed across 11 GOST variants. Corrected private DoH also passed UDP/TCP queries through SSH and SSH Jump. Full failure/malformed/stop/capture matrix deferred. | +| U01 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| U02 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| U03 | NOT TESTED | Arm64 signed upgrade preserved variant/signature and recovered traffic; other variants/installer permission flows deferred. | +| U04 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | +| E01 | PASS | Scoped logs and exit history collected: no observed candidate crash/ANR, six package-update exits. Expected negative-request errors and fixture/tool failures distinguished below. | +| E02 | PASS | Capture stopped; dedicated AVD/INI and own fixture processes/containers removed and checked. Existing AVDs and unrelated Docker resources preserved. | +| E03 | PASS | Installed APK hash matched candidate; all79 rows have explicit verdicts; private evidence excluded and five-file documentation allowlist checked. | + +## Final observations and restoration + +- Final priority block: **21/21 executed subchecks passed**. It includes corrected + DoH UDP/TCP through both SSH routes, three OS resolver APIs, CUSTOM DoH failure / + recovery, four private-component refusals, background traffic, two server + suspensions, recovery/Stop, stopped package replacement and manual reconnection. +- The valid-route SSH run contains14 successful subchecks and four initial DoH + failures caused by the private fixture missing `application/dns-message`. + After correcting that response header, all four UDP/TCP DNS controls passed in + the final block. These are infrastructure corrections, not retries to hide + candidate failures. Four SSH password/pin negatives reached no origin token; + together with50 GOST negatives, **54/54 delivered no successful origin request**. + Jump-password rejection and exhaustive SSH key-mode/TOFU permutations are deferred. +- Root emulator capture:49,691 packets, SHA-256 + `6598edc45d67e084c1cfd920bfafffc481f119a30ba370947a94ae029074e8cc`. + The five fresh D01 names occur in plaintext DNS packets only on the TUN interface + used during those tests; no corresponding IPv4 UDP/TCP53 packets were found on + underlying eth0/wlan0. The four positive queries also appear in the private DoH + origin journal; the failed CUSTOM query does not. This narrow observation does + not establish lockdown, IPv6, strict Private DNS, other UIDs or all Android builds. + No router/physical-uplink capture or full direct-control matrix was performed. +- Installed APK readback SHA-256 exactly matches the candidate above. +- Diagnostic log192,247 bytes: no matches for generated credentials, key headers, + synthetic profile names or fixture-domain/feed markers. No candidate Java/native + crash or ANR was observed in collected crash/exit evidence; exit history records + six `PACKAGE UPDATED` events. System Bluetooth and UI-automation failures belong + to different processes and are retained in private logs. +- SSH trust rejection opens the expected changed-key review; the test cancelled + replacement. A helper that failed to dismiss that dialog stopped its scenario; + it is not an application crash. One ADB transport interruption is also retained + separately from application verdicts. +- Capture and own fixture processes/containers stopped. Dedicated API35 AVD and + its INI removed; no test CA/probe app/configuration remains on a shared device. + Pre-existing AVDs and unrelated Docker resources were not removed. +- Raw evidence stays in ignored `dist/review-20261011-api35/`, directories0700 / + files0600. It includes credentials, packet captures and APKs and must not be + published. Report/docs contain no fixture credentials or private keys. + +## Decision + +The shortened review confirms core traffic, authentication rejection, subscriptions +and bounded recovery on this signed API35 candidate. It does **not** approve a +release: T01 has a reproduced GOST-server failure, SOCKS5 UDP and controlled browser +HTTP/3 are inconclusive, and deferred rows remain open. No client workaround, +upstream server publication, personal proxy change, merge, tag or release upload was +performed. Both language versions of the procedure now require immediate FIN with +no artificial delay and direct production-dialer isolation on failure. diff --git a/docs/ru/masque.md b/docs/ru/masque.md index 48224d9..70ef9c6 100644 --- a/docs/ru/masque.md +++ b/docs/ru/masque.md @@ -69,6 +69,11 @@ JSON использует `proxy.type: "MASQUE"`; ProxyList — Слишком большие исходящие пакеты отбрасываются целиком, с одним событием на UDP-поток; последующие малые пакеты продолжают проходить. Исходящий размер также ограничен объявленным лимитом приёма, чтобы GOST не закрывал поток на слишком большом echo-ответе. +- Проверка API 35 от 2026-10-11 выявила потерю последних TCP-данных при немедленном + write half-close с GOST 3.3.0: его relay обрабатывает EOF раньше байтов, возвращённых + тем же чтением. Отказ воспроизводится также прямым native-клиентом без Android TUN. + Это ограничение сервера; задержка перед FIN не является исправлением. См. + [отчёт проверки](../reviews/release-api35-2026-10-11.md). - GOST 3.3.0 отклоняет IPv6 literal targets в CONNECT-UDP. TCP IPv6 и локальный UDP-bypass следуют настройкам IPv6/маршрутизации профиля. По умолчанию используется только IPv4. - Карточка показывает QUIC RTT и исходящие пакеты, объявленные потерянными за пять минут. diff --git a/docs/ru/release-testing.md b/docs/ru/release-testing.md index 7f548c4..c3848cf 100644 --- a/docs/ru/release-testing.md +++ b/docs/ru/release-testing.md @@ -95,7 +95,7 @@ I01–I06, P01–P07, T01–T10, C01–C05, L01–L11, D01–D05, U01–U04 и E | ID | Действия → требуемый результат | | --- | --- | -| T01 | HTTP/HTTPS из обычного приложения через GOST, OpenSSH, HTTPS Jump, SSH Jump, SOCKS5 и MASQUE α, включая оба результата выбора HTTP/3 в HTTPS (H12–H15): уникальные токены, сравнение upload/download, серверные доказательства, повторные запросы и одновременные потоки. Проверить роли узлов и отсутствие двойного подсчёта трафика. Origin отвечает только после write half-close клиента: полный ответ должен сохраниться после FIN для каждого транспорта. | +| T01 | HTTP/HTTPS из обычного приложения через GOST, OpenSSH, HTTPS Jump, SSH Jump, SOCKS5 и MASQUE α, включая оба результата выбора HTTP/3 в HTTPS (H12–H15): уникальные токены, сравнение upload/download, серверные доказательства, повторные запросы и одновременные потоки. Проверить роли узлов и отсутствие двойного подсчёта трафика. Origin отвечает только после write half-close клиента: полный ответ должен сохраниться после FIN для каждого транспорта. Отправлять данные и FIN подряд, без искусственной задержки; при отказе отдельно проверить прямой production-dialer с той же версией сервера. | | T02 | Правильные → неверные → отсутствующие → восстановленные реквизиты каждого узла. Работающие контроли обязательны; отрицательный токен не должен успешно доходить до origin. Надпись «Подключено» при отказах не является успехом. | | T03 | Refused/timeout/reset прокси, недоступный origin, обрезанный ответ; затем восстановление. Ограниченное ожидание, понятная ошибка, восстановление; нет direct fallback вне явно выбранной routing policy. | | T04 | All-app routing на эмуляторе; selected-app на всех устройствах с двумя обычными UID — включённым/исключённым. Переключить local bypass, проверить контролируемые LAN/private и public адреса. Доказывать маршрутом, а не checkbox. | From 5de3c84e2db5e505f2ef2884649276ce42f4e2c2 Mon Sep 17 00:00:00 2001 From: Andrey Prokopyuk Date: Sun, 11 Oct 2026 20:49:37 +0300 Subject: [PATCH 2/3] Record confirmed browser HTTP3 through Android VPN --- docs/reviews/release-api35-2026-10-11.md | 69 ++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/docs/reviews/release-api35-2026-10-11.md b/docs/reviews/release-api35-2026-10-11.md index 369e5f5..ee4f060 100644 --- a/docs/reviews/release-api35-2026-10-11.md +++ b/docs/reviews/release-api35-2026-10-11.md @@ -114,7 +114,7 @@ criteria are deferred. FAIL is preserved even where other subcases pass. | H03 | NOT TESTED | Correct and repeated wrong/missing credentials tested; complete fingerprint matrix deferred. | | H04 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | | H05 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | -| H06 | NOT TESTED | Controlled browser origin test blocked by Chrome NET::ERR_CERT_AUTHORITY_INVALID; zero origin requests. Outer MASQUE connection is not evidence of inner browser H3. | +| H06 | NOT TESTED | Initial browser test was blocked by certificate trust. Follow-up below confirms real Chrome HTTP/3 through MASQUE and HTTPS preference with origin/capture evidence and normal public sites. Full fingerprint/path-MTU/Firefox matrix remains open. | | H07 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | | H08 | NOT TESTED | Chrome-size datagram sequence passed/dropped/recovered as described in T05; full size/IPv6/browser matrix deferred. | | H09 | NOT TESTED | Deferred in the shortened run; automated CI does not close this signed-device scenario. | @@ -190,8 +190,71 @@ criteria are deferred. FAIL is preserved even where other subcases pass. The shortened review confirms core traffic, authentication rejection, subscriptions and bounded recovery on this signed API35 candidate. It does **not** approve a -release: T01 has a reproduced GOST-server failure, SOCKS5 UDP and controlled browser -HTTP/3 are inconclusive, and deferred rows remain open. No client workaround, +release: T01 has a reproduced GOST-server failure, SOCKS5 UDP remains inconclusive, browser HTTP/3 is confirmed by the follow-up +below, and deferred rows remain open. No client workaround, upstream server publication, personal proxy change, merge, tag or release upload was performed. Both language versions of the procedure now require immediate FIN with no artificial delay and direct production-dialer isolation on failure. + + +## Targeted browser HTTP/3 follow-up + +The same signed candidate was reinstalled and its installed APK readback again +matched the SHA-256 above. A new accelerated cold-boot API 35 AVD used +Chrome 124.0.6367.219, UID 10145, selected-app routing including only Chrome and +local-network bypass disabled. Official GOST 3.3.0 and the same private HTTP/3 +origin were used. Proxy certificate verification stayed enabled; native logs +confirm TLS 1.3, ALPN h3 for MASQUE/preference and ALPN h2 for TCP fallback. + +The controlled origin's private CA was the previous browser-test obstacle. +[Chromium's QUIC testing guide](https://chromium.googlesource.com/website/+/refs/heads/main/site/quic/playing-with-quic/index.md) +describes the leaf-SPKI exception required for a custom certificate. Chrome was +configured to trust only that leaf's SPKI and force QUIC **only** for the private +origin. Android's `am set-debug-app` enabled its command-line file; no global +ignore-certificate-errors flag was used. Ordinary Alt-Svc on this custom origin +selected h2, so forced and natural negotiation evidence are kept separate. + +| Browser subcase | Verified result | +| --- | --- | +| Direct controlled origin, no VPN |5/5 pages: DevTools response/navigation protocol h3, expected URL/body token and origin HTTP/3.0. | +| Controlled origin through MASQUE |5/5 pages with the same three-way evidence. Inner browser UDP in TUN; protected outer UDP to the MASQUE port; no direct UDP to the origin. | +| Controlled origin through HTTPS with HTTP/3 preference |5/5 pages with the same three-way evidence. Outer UDP uses the dual-protocol proxy port; no direct UDP to the origin. | +| HTTPS preference with TCP-only proxy, forced inner QUIC |Two attempted pages: no successful browser response or origin request; ERR_QUIC_PROTOCOL_ERROR. Capture shows inner UDP in TUN and no direct UDP escape. | +| Same TCP-fallback profile, ordinary HTTPS |2/2 pages received h2; origin HTTP/2.0 and outer proxy HTTP/2 confirmed. Ordinary TCP traffic remained usable in this case. | +| MASQUE, ordinary public Cloudflare trace |No SPKI exception or forced QUIC. First page h2, following four h3; final trace body independently reports `http=http/3`. | +| MASQUE, ordinary public BrowserLeaks QUIC test |No SPKI exception or forced QUIC. Main HTML used h2; five successful probe responses from `quic.browserleaks.com` used h3. Main-document h2 is not a failed QUIC test. | + +For the public tests Chrome's command line contained only `--enable-quic` and +`--no-first-run`: certificate validation and Alt-Svc negotiation were normal. +Browser DevTools and page content were captured through CDP; these were real +browser requests routed through Android TUN, not the application's native Test +button or shell-UID networking. The private origin's benchmark address was not +directly reachable from the emulator during VPN cases. + +Independent root capture contained 7,640 packets with zero kernel drops, SHA-256 +`0da5900debfc025c78ccc849a747c1e84f6ab159366cd09e33a62d3c4ff9015c`. Within the controlled browser windows: + +- MASQUE: 94 inner UDP packets to the origin, 268 outer UDP packets to its proxy port. +- HTTPS→HTTP/3: 100 inner UDP packets, 248 outer UDP packets to its proxy port. +- Forced-QUIC TCP fallback: 16 inner UDP packets, 40 outer TCP packets to the proxy. +- No direct origin UDP packet on either underlying interface in those VPN windows. + +The origin recorded 6/7 GETs for the 5 unique URLs in the two positive VPN cases; +all five complete browser pages and corresponding origin paths passed. The first +harness incorrectly required exactly five server entries and labelled the extra +GETs FAIL. Verification was corrected to correlate every unique URL, successful +h3 response, body token and origin protocol; original raw verdicts are retained. +No failed browser request was rerun to obtain a passing verdict. Duplicate GETs +were not investigated as a throughput/long-soak claim. + +Final diagnostic log 43,959 bytes contained no generated credential markers. +DevTools forwarding, capture, own fixture processes and the dedicated AVD/INI +were removed; existing AVDs were untouched. Raw captures, browser snapshots +(including external exit-IP data), credentials and APK readback remain private +in ignored `dist/browser-h3-20261011/` (directories0700/files0600). + +**Browser HTTP/3 through the VPN is confirmed for this Chrome/API 35 candidate.** +This closes the browser portion left inconclusive in the shortened run. Firefox, +all path-MTU/fingerprint permutations, API26 browser acceptance and long-duration +stability are not inferred from it. The GOST immediate-half-close failure remains +unchanged and release approval is still withheld. From 222d46a4fbdcddd4d38e21dc9bca41df01f1390c Mon Sep 17 00:00:00 2001 From: Andrey Prokopyuk Date: Sun, 11 Oct 2026 23:49:51 +0300 Subject: [PATCH 3/3] Record real-application API 35 acceptance results and limitations --- docs/reviews/live-apps-api35-2026-10-11.md | 134 +++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 docs/reviews/live-apps-api35-2026-10-11.md diff --git a/docs/reviews/live-apps-api35-2026-10-11.md b/docs/reviews/live-apps-api35-2026-10-11.md new file mode 100644 index 0000000..667bda6 --- /dev/null +++ b/docs/reviews/live-apps-api35-2026-10-11.md @@ -0,0 +1,134 @@ +# Real-application API 35 verification — 2026-10-11 + +This report records a separate real-application acceptance run using the same +signed candidate as the earlier API 35 verification. The requested acceptance +sequence did **not pass in full**. This is a dated observation, not release approval. + +## Privacy + +Server addresses, domains, account names, credentials, profile names, video +identifiers and raw network captures are excluded. Servers and profiles are +identified only by their role and transport. Private configuration and raw +evidence remain outside version control. + +## Candidate and setup + +- Android API 35, a dedicated clean ARM64 emulator. +- MegaProxy 1.1.0, version code 19002. +- APK SHA-256: `3ffd2d25179047b83ccf8b636539788e2ba908213370b3f9bc43b8fb06982e0a`. +- Installation and any required store/video sign-in are completed before network scenarios. +- A user-provided configuration is imported through the application's UI. +- Split tunneling includes YouTube and Chrome; Vivaldi is excluded. +- VK Video and Chrome are included for the final controlled SOCKS5 checks. + +## Preparation evidence + +The candidate APK hash matches the earlier verified artifact. The excluded +browser was downloaded from its publisher and its APK signature verified. +The clean emulator has booted; store sign-in is complete. All four requested +applications are installed. Both video applications opened a public video +without an additional sign-in. Browser startup prompts are handled before +network scenarios. + +Application versions: YouTube 21.40.161, Chrome 154.0.8037.126, +Vivaldi 8.2.4147.157, VK Video 1.166. + +The temporary SOCKS5 server passed a host-side authentication and UDP DNS +round-trip preflight. Its access rules are restricted to the test client and +automatic cleanup was scheduled. This preflight is **not Android VPN coverage**; +the Android results and verified final cleanup are recorded below. + +## Scenario ledger + +| ID | Scenario | Verdict | +| --- | --- | --- | +| L01 | HTTPS profile negotiates HTTP/3; muted YouTube playback continues during Chrome browsing and speed checks | FAIL: optional HTTP/3 negotiation timed out; HTTPS fallback worked | +| L02 | Switching to MASQUE preserves YouTube playback and browser connectivity | FAIL: QUIC handshake timed out | +| L03 | Switching to SSH preserves playback and browsing through the TCP transport | PARTIAL: SSH and browsing worked; the full uninterrupted sequence was not established | +| L04 | An authenticated SOCKS5 server with UDP forwards VK Video, browsing and UDP checks | PASS after routing setup was corrected and frozen | +| L05 | Vivaldi remains outside the VPN while Chrome is included | PASS in explicitly checked intervals | +| L06 | Temporary server resources are removed; existing services are preserved | PASS | + +Successful playback alone does not prove use of QUIC: buffered playback must be +distinguished from continued media downloads, and the application's actual +traffic protocol must be distinguished from the outer proxy transport. +Browser checks alone do not establish the video application's protocol. + +## Routing and subscription interference + +The system VPN UID ranges include Chrome and YouTube and exclude Vivaldi. +An actual request in Vivaldi reported a different exit from the same check in +Chrome while the VPN was connected. This confirms the excluded browser's route. + +The imported subscription had hourly automatic updates enabled. Its interface +recorded a successful refresh during this run, and routing settings changed +before the video application was replaced. Subsequently, the effective VPN +allowlist contained only VK Video. Chrome's unresolved-name result in that +state is **not evidence of a SOCKS5 forwarding defect**. + +Automatic subscription updates were disabled on the test device, Chrome was +selected again, and the app's reconnect action applied the changes. System UID +ranges then confirmed Chrome and VK Video were included and Vivaldi excluded. +The final SOCKS5 results use this controlled setup. The original imported file +was not edited. Freeze subscription updates before a transport acceptance run; +exercise subscription refresh separately when it is the subject of the test. + +## HTTPS, MASQUE and SSH + +The first HTTPS connection fell back to HTTPS after an optional HTTP/3 +negotiation timeout. Chrome used HTTP/2 during this control run. The emulator +host initially routed proxy traffic through a separate host VPN. Direct host +routes, disabling that VPN, and restarting the emulator did not resolve the +Android handshake failure. HTTPS fallback connected without a suspected-blocking +warning in the observed final interval. MASQUE failed to establish its QUIC +session; failed handshakes produced suspected-blocking diagnostic events. + +A short capture limited to this emulator showed outbound QUIC Initial packets +to the expected destination and no returning packets. A host-side control using +the production MASQUE dialer and browser fingerprint succeeded, including both +external HTTP/3 probes. This narrows the discrepancy but **does not establish +the root cause or a specific client fix**. SOCKS5 UDP success below shows that +UDP is not universally unavailable on the emulator. + +The same long native YouTube video remained in picture-in-picture and advanced +beyond 33 minutes before it was stopped for the VK Video phase. SSH authentication +and host-key verification succeeded; Chrome loaded a diagnostic page and a +content site over HTTP/2. However, a failed MASQUE connection cannot count as +continuous media delivery through that proxy. YouTube media QUIC/HTTP/3 and the +complete uninterrupted HTTPS-to-MASQUE-to-SSH sequence remain **unverified**. + +The requested speed-test service completed its mobile web download measurement +through the HTTPS fallback: 7.26 Mbps download and 52 ms ping. The completed page +offered another test; it did not display an upload measurement. This is a single +live-network observation over HTTP/2, not an HTTP/3 performance result or a +controlled throughput benchmark. + +## SOCKS5 and native VK Video + +The manually added profile authenticated against the disposable UDP-capable +server. With the corrected VPN allowlist, Chrome loaded diagnostic and content +pages successfully. The content page returned HTTP 200 with populated content. + +The independent browser QUIC probe recorded successful HTTP/3 responses. The +app's native Test action separately confirmed HTTP/3 through both external probe +providers. These results establish actual UDP forwarding through SOCKS5; an +ordinary diagnostic-page request using HTTP/2 does not invalidate them. + +VK Video showed decoded video frames, its native media session reported PLAYING, +and its playback position advanced. The disposable server also recorded substantial +data delivery. VK Video's own media ALPN was not established; this scenario does +not require the video service itself to select HTTP/3. + +## Cleanup and remaining work + +The disposable service and cleanup timer were stopped. Its listening port, +exact tagged firewall rules, generated credentials/configuration and temporary +directory were verified absent. No temporary capture units remain. Both existing +proxy services and the original SSH service remained active. Captures and raw +configuration are private local evidence and are not attached to this report. + +The installed APK hash was checked again after restarting the emulator and +matches the candidate above. No production source was changed. Before accepting +the feature, diagnose the Android direct-MASQUE handshake discrepancy, establish +YouTube media QUIC independently, and repeat the uninterrupted profile-switch +sequence with frozen routing settings. Upload throughput was not measured.