# DragonTCP Hybrid Transport This branch keeps the lightweight DragonTCP Android architecture that was working well: ```text Android apps -> Android VpnService userspace TCP adapter -> local HTTP/HTTPS CONNECT proxy on 127.0.0.1:8080 -> DragonTCP transport over TCP/53 -> DragonTCP server -> destination website ``` The heavy raw-IP DragonTCP VPN server is **not** used. The Linux server is again only a relay/proxy server; it does not create a TUN interface and does not need NAT/iptables. ## What changed on the wire The old DragonTCP transport used a fixed text/frame pattern: ```text UP + request id + length + XOR(0xAD, ASCII CPUSH/CPULL/...) OK + request id + length + XOR(0xAD, response) ``` The Hybrid transport replaces that network layer with compact binary records: ```text Request header (29 bytes) 1 byte mode 16 bytes random session ID 8 bytes sequence / stream offset 4 bytes payload length Response header (5 bytes) 1 byte status 4 bytes body length ``` There are no constant `UP`, `OK`, `CPUSH`, `CPULL`, or `DATA` strings on the wire. Payload bytes are masked with a sequence-dependent SHA-256 counter keystream. The operation is still XOR-based, but the XOR bytes change with session, mode, sequence, direction, and block number instead of using the same 0xAD byte for every position. This is traffic shaping/obfuscation, not authenticated encryption. ## Path probing Before the first proxied connection, the client probes the phone-to-server path once and caches the result for 30 minutes. Upload and download are tested independently against a ladder from small records through 1 MiB. A binary search is used, so it does not need to fail at every size between the maximum and minimum. Example log: ```text path probe: upload=32768 download=1400 persistent=true ``` If the server is capped at 1400 bytes, the client can discover: ```text path probe: upload=1400 download=1400 persistent=true ``` instead of beginning at 1 MiB and repeatedly halving during real traffic. ## Separate upload/download sizing Upload and download maintain independent record sizes. Runtime adaptation is still present as a safety net if network conditions change after the initial probe. Useful log events remain concise: ```text adaptive upload chunk: 32768 -> 16384 after transport failure adaptive download pipeline: 64 -> 32 after transport failure adaptive download chunk: 1400 -> 700 after transport failure ``` ## Batched downloads One download request can receive many ordered DATA responses. The client uses one download worker but pipelines up to 256 response records per request, subject to an approximately 1 MiB useful-data cap per batch. This is especially important on restricted paths. If the safe record size is 32 bytes, one TCP/53 request can still bring back many 32-byte records instead of requiring a new request for every 32 useful bytes. ## Reconnect behavior The transport supports persistent TCP connections and forced connection rotation. Core/CLI semantics: ```text --chunk-reconnect-every 0 persistent --chunk-reconnect-every 1 automatic compatibility mode --chunk-reconnect-every N rotate after N logical requests, N >= 2 ``` Automatic mode probes persistent request reuse. If it works, DragonTCP keeps the connection. If it does not, DragonTCP falls back to one logical request per TCP connection. The supplied APK is based on the current Logs Page UI, whose Reconnect field still requires a value of at least 1. In this APK, leave it at `1` for Auto. The full Android source in this package also contains the newer explicit `0 = persistent` UI behavior for rebuilding with the Android SDK. ## Optional token The token remains optional. Server without token: ```bash sudo ./dragontcp-hybrid-server-linux-amd64 --chunk-max 1048576 ``` Server with token: ```bash sudo ./dragontcp-hybrid-server-linux-amd64 \ --token 'YOUR_SECRET' \ --chunk-max 1048576 ``` ## Server Default server port is TCP/53: ```bash sudo ./dragontcp-hybrid-server-linux-amd64 \ --port 53 \ --chunk-max 1048576 ``` Useful debug mode: ```bash sudo ./dragontcp-hybrid-server-linux-amd64 \ --port 53 \ --chunk-max 1048576 \ --debug \ --debug-stats-interval 10s ``` The server is a lightweight TCP relay. It does not create Linux TUN devices. ## Android Install `DragonTCP-Hybrid-Android-arm64.apk`, configure the server IP/port, and connect as before. Recommended initial settings: ```text Server: YOUR_SERVER_IP Port: 53 Token: optional Max chunk: 1048576 Min chunk: 32 Reconnect: 1 (Auto in supplied APK) Timeout: 2 ``` The Android TUN frontend continues to point applications at the local DragonTCP HTTP proxy. DNS continues to use the existing lightweight adapter's DNS-over-proxy path. ## Source layout ```text core/ cmd/dragontcp-client/ cmd/dragontcp-server/ internal/protocol/ # TCP tuning + legacy helpers internal/wire/ # new compact binary framing + changing mask android/ src/com/dragontcp/client/ src/tech/xvanturing/freeproxy/ lib/arm64-v8a/libdragontcp_client.so ``` ## Building the Go core ```bash cd core go test ./... go build -trimpath -ldflags='-s -w' \ -o ../bin/dragontcp-hybrid-server-linux-amd64 \ ./cmd/dragontcp-server GOOS=android GOARCH=arm64 CGO_ENABLED=0 \ go build -trimpath -ldflags='-s -w' \ -o ../android/lib/arm64-v8a/libdragontcp_client.so \ ./cmd/dragontcp-client ``` `android/build_apk.sh` contains the source build procedure for the Android application when an Android SDK and Kotlin compiler are installed. ## Validation performed The new Go transport was tested with: - Go unit tests for client/server/wire code. - changing-mask round-trip test. - 8 MiB HTTP download through the DragonTCP proxy with SHA-256 equality. - HTTPS CONNECT download through DragonTCP with byte-for-byte equality. - persistent connection mode. - forced reconnect-every-1 mode. - a server restricted to 1400-byte records, where path probing selected 1400 bytes automatically and the download still completed correctly. The supplied APK embeds the exact Android ARM64 Go core built from this source. ## SafeSpeed v3 This release is built directly from the confirmed-working Hybrid v1. The wire protocol is unchanged: same compact binary request/response headers, same 16-byte session IDs, same SHA-256-derived XOR keystream, same probe packets, same upload transaction behavior, and same server framing. The only transport scheduling change is that the download pipeline starts at 256 records (the same maximum already supported by v1) instead of starting at 32 and slowly growing one record per successful request. This is especially important when the probed record size is small. The broken Hybrid v2 changes are intentionally absent: no multi-request upload pipeline and no 65,535-record mega-batches.