V7
This commit is contained in:
@@ -1,209 +1,136 @@
|
||||
# DragonTCP VPN v3
|
||||
# DragonTCP Lite VPN
|
||||
|
||||
DragonTCP v3 is a real Android layer-3 VPN over DragonTCP's adaptive XOR-framed
|
||||
TCP transport. It captures IPv4 and IPv6 through Android `VpnService`, passes
|
||||
the TUN file descriptor to the Go core, and transfers raw IP packets to a Linux
|
||||
DragonTCP server listening on TCP/53.
|
||||
|
||||
This release fixes two important problems from the previous packet-VPN build:
|
||||
|
||||
1. Android can emit IPv6 link-local/control packets such as `fe80::...` on the
|
||||
VPN TUN. Those packets no longer terminate the DragonTCP session. The client
|
||||
drops packets whose source is not the assigned DragonTCP VPN address, and the
|
||||
server independently treats source-mismatch/control packets as non-fatal
|
||||
drops.
|
||||
2. The DragonTCP transport chunk ceiling is restored to **1 MiB (1,048,576
|
||||
bytes)**. Raw IP packets remain limited to 65,535 bytes, but multiple TUN
|
||||
packets are batched into transfer objects up to 1 MiB so chunk sizes above
|
||||
the VPN MTU are actually useful.
|
||||
This version deliberately returns to the lightweight DragonTCP architecture.
|
||||
DragonTCP itself is an HTTP/HTTPS CONNECT proxy tunnel; Android's `VpnService`
|
||||
is only the local adapter that feeds normal app TCP traffic into that proxy.
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
Android apps
|
||||
|
|
||||
| IPv4 + IPv6 default routes
|
||||
v
|
||||
Android VpnService TUN (MTU 1280)
|
||||
|
|
||||
| raw IPv4/IPv6 packets
|
||||
v
|
||||
DragonTCP Android Go core
|
||||
|
|
||||
| packet batching (up to 1 MiB transfer objects)
|
||||
| adaptive fragmentation 32 B .. 1 MiB
|
||||
| XOR 0xAD framing
|
||||
v
|
||||
TCP/53
|
||||
|
|
||||
v
|
||||
DragonTCP Linux server
|
||||
|
|
||||
v
|
||||
Linux TUN dragontcp0
|
||||
|
|
||||
| forwarding / NAT
|
||||
v
|
||||
Internet
|
||||
|
|
||||
| IPv4 TCP / DNS packets
|
||||
v
|
||||
Android VpnService TUN
|
||||
|
|
||||
| lightweight userspace TCP adapter
|
||||
v
|
||||
127.0.0.1:8080 HTTP CONNECT
|
||||
|
|
||||
v
|
||||
DragonTCP Go client
|
||||
|
|
||||
| adaptive records + mandatory XOR 0xAD
|
||||
| TCP/53
|
||||
v
|
||||
DragonTCP Lite server
|
||||
|
|
||||
v
|
||||
Internet destination
|
||||
```
|
||||
|
||||
Because the tunnel carries raw IP packets, it can carry TCP, UDP, DNS, ICMP,
|
||||
IPv4 and IPv6. It does not depend on applications supporting an HTTP proxy.
|
||||
There is **no Linux TUN**, no server NAT, no raw-IP DragonTCP protocol, and no
|
||||
packet batching on the DragonTCP server. The remote side is the same style of
|
||||
lightweight stream proxy that worked in the earlier Termux tests.
|
||||
|
||||
## Included files
|
||||
## Defaults
|
||||
|
||||
Android:
|
||||
|
||||
```text
|
||||
bin/dragontcp-vpn-server-linux-amd64
|
||||
bin/dragontcp-vpn-server-linux-arm64
|
||||
bin/dragontcp-vpn-client-linux-amd64 # test/debug client
|
||||
android/build/DragonTCP-VPN.apk
|
||||
android/lib/arm64-v8a/libdragontcp_vpn.so
|
||||
core/ # complete Go source
|
||||
android/src/ # complete Android Java source
|
||||
build_core.sh
|
||||
build_all.sh
|
||||
android/build_apk.sh
|
||||
Server port: 53/TCP
|
||||
Token: optional / empty allowed
|
||||
Local proxy: 127.0.0.1:8080
|
||||
Pollers: 1 (fixed)
|
||||
Reconnect Every: 1
|
||||
Chunk Start: Max Chunk
|
||||
Chunk Min: 32
|
||||
Chunk Max: 1,048,576 bytes
|
||||
Chunk Grow After: 16 successes
|
||||
Chunk timeout: 2 seconds
|
||||
XOR: 0xAD, mandatory
|
||||
DNS: 1.1.1.1 through DNS-over-TCP through DragonTCP
|
||||
```
|
||||
|
||||
## Server
|
||||
The Android log is intentionally quiet. It shows service state, actual errors,
|
||||
and DragonTCP adaptive changes such as:
|
||||
|
||||
The server needs root or equivalent CAP_NET_ADMIN permissions because it
|
||||
creates a Linux TUN and configures forwarding/NAT.
|
||||
```text
|
||||
adaptive upload chunk: 65536 -> 32768 after transport failure
|
||||
adaptive download chunk: 32 -> 64 after stable success
|
||||
```
|
||||
|
||||
Install networking tools on Debian/Ubuntu if needed:
|
||||
It does not redraw the screen or print periodic traffic statistics.
|
||||
|
||||
## Android traffic behavior
|
||||
|
||||
- IPv4 TCP: forwarded through DragonTCP.
|
||||
- DNS UDP/53: converted to DNS-over-TCP and sent to `1.1.1.1` through the local
|
||||
DragonTCP HTTP CONNECT proxy.
|
||||
- IPv6: captured by the VPN and dropped so it cannot bypass DragonTCP.
|
||||
- Other UDP: not forwarded in this HTTP CONNECT build.
|
||||
- ICMP/ping: not forwarded.
|
||||
|
||||
This trade-off keeps DragonTCP itself lightweight and stream-oriented.
|
||||
|
||||
## Start the server
|
||||
|
||||
Port 53 is privileged on Linux, so run as root:
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y iproute2 iptables
|
||||
sudo ./dragontcp-lite-server-linux-amd64 --chunk-max 1048576
|
||||
```
|
||||
|
||||
Start:
|
||||
No token is required by default. To require one:
|
||||
|
||||
```bash
|
||||
sudo ./dragontcp-vpn-server-linux-amd64 \
|
||||
--token 'YOUR_SECRET' \
|
||||
--debug
|
||||
sudo ./dragontcp-lite-server-linux-amd64 --token 'SECRET' --chunk-max 1048576
|
||||
```
|
||||
|
||||
Defaults:
|
||||
The Android Token field must contain the same value.
|
||||
|
||||
```text
|
||||
listen TCP port 53
|
||||
server chunk max 1048576 bytes (1 MiB)
|
||||
transfer batch max 1048576 bytes (1 MiB)
|
||||
batch delay 1ms
|
||||
TUN MTU 1280
|
||||
server IPv4 10.123.0.1/16
|
||||
server IPv6 fd7a:4472:6167:6f6e::1/64
|
||||
poll wait 100ms
|
||||
queued packet limit 2048/client
|
||||
queued byte limit 8 MiB/client
|
||||
auto NAT enabled
|
||||
```
|
||||
|
||||
Useful explicit command:
|
||||
If you do not want to run the binary as root:
|
||||
|
||||
```bash
|
||||
sudo ./dragontcp-vpn-server-linux-amd64 \
|
||||
--token 'YOUR_SECRET' \
|
||||
--chunk-max 1048576 \
|
||||
--vpn-buffer-bytes 8388608 \
|
||||
--batch-delay 1ms \
|
||||
--debug \
|
||||
--debug-stats-interval 5s
|
||||
sudo setcap cap_net_bind_service=+ep ./dragontcp-lite-server-linux-amd64
|
||||
./dragontcp-lite-server-linux-amd64
|
||||
```
|
||||
|
||||
Per-packet/batch diagnostics are very verbose:
|
||||
If TCP/53 is already occupied by a DNS resolver, free that port first.
|
||||
|
||||
```bash
|
||||
--debug-packets
|
||||
```
|
||||
## Android usage
|
||||
|
||||
## Android app
|
||||
1. Install `DragonTCP-LiteVPN-arm64.apk`.
|
||||
2. Enter the server address.
|
||||
3. Leave Port at `53`.
|
||||
4. Leave Token empty if the server was started without `--token`.
|
||||
5. Keep `Reconnect every = 1` for restrictive networks.
|
||||
6. Press **CONNECT** and approve Android's VPN dialog.
|
||||
7. Press **STOP** to terminate both the TUN adapter and DragonTCP core.
|
||||
|
||||
Install `android/build/DragonTCP-VPN.apk`.
|
||||
The app excludes its own UID from the VPN, so the DragonTCP TCP/53 transport
|
||||
uses the physical/mobile network and does not loop into its own TUN interface.
|
||||
|
||||
The UI asks for:
|
||||
|
||||
```text
|
||||
Server
|
||||
TCP port
|
||||
Token
|
||||
Maximum transport fragment
|
||||
Minimum transport fragment
|
||||
Timeout
|
||||
```
|
||||
|
||||
Defaults:
|
||||
|
||||
```text
|
||||
Port 53
|
||||
Max 1048576
|
||||
Min 32
|
||||
Timeout 2s
|
||||
Pollers 1 (fixed)
|
||||
VPN MTU 1280
|
||||
```
|
||||
|
||||
The adaptive record starts at Max and shrinks after transport failures. The
|
||||
1 MiB value is a DragonTCP transport ceiling, not the IP MTU.
|
||||
|
||||
### Why 1 MiB can now help even though the VPN MTU is 1280
|
||||
|
||||
The old packet-VPN sent one TUN packet per DragonTCP transfer object, so a
|
||||
record size larger than the IP packet had no benefit. v3 batches adjacent TUN
|
||||
packets for a short window:
|
||||
|
||||
```text
|
||||
1280-byte packet --+
|
||||
1280-byte packet ---+
|
||||
1280-byte packet ----+--> one DragonTCP transfer object --> adaptive fragments
|
||||
... |
|
||||
1280-byte packet ----+
|
||||
```
|
||||
|
||||
A busy flow can therefore produce transfer objects much larger than 65,535
|
||||
bytes. If the network accepts large DragonTCP records, fewer transactions are
|
||||
needed. If it does not, the same transfer object is automatically fragmented
|
||||
into smaller records and retried.
|
||||
|
||||
## Android link-local source fix
|
||||
|
||||
A log such as this from the previous build:
|
||||
|
||||
```text
|
||||
VPN stopped: source fe80::... does not match session address
|
||||
```
|
||||
|
||||
is no longer fatal.
|
||||
|
||||
The Android core now logs an occasional line such as:
|
||||
|
||||
```text
|
||||
VPN DROP local packet (source fe80::... is not assigned VPN address) dropped=1
|
||||
```
|
||||
|
||||
and continues running. The server also performs a non-fatal drop as a second
|
||||
line of defense.
|
||||
|
||||
## Build from source
|
||||
## Build everything from source
|
||||
|
||||
Requirements:
|
||||
|
||||
- Go 1.22+
|
||||
- JDK 17+
|
||||
- Android SDK platform/build-tools
|
||||
- zip
|
||||
- Android SDK platform + build-tools (35 works)
|
||||
- Android 10 / API 29 or newer on the phone
|
||||
- Kotlin compiler 1.9.x distribution containing
|
||||
`kotlinx-coroutines-core-jvm.jar`
|
||||
- `zip`
|
||||
|
||||
No Android NDK is required for this build.
|
||||
|
||||
Set the SDK directory:
|
||||
Example environment:
|
||||
|
||||
```bash
|
||||
export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
|
||||
export KOTLIN_HOME="$HOME/.sdkman/candidates/kotlin/current"
|
||||
```
|
||||
|
||||
Build native components and APK:
|
||||
Then:
|
||||
|
||||
```bash
|
||||
./build_all.sh
|
||||
@@ -212,37 +139,62 @@ Build native components and APK:
|
||||
Outputs:
|
||||
|
||||
```text
|
||||
bin/dragontcp-vpn-server-linux-amd64
|
||||
bin/dragontcp-vpn-server-linux-arm64
|
||||
android/lib/arm64-v8a/libdragontcp_vpn.so
|
||||
android/build/DragonTCP-VPN.apk
|
||||
bin/dragontcp-lite-server-linux-amd64
|
||||
bin/dragontcp-lite-server-linux-arm64
|
||||
android/lib/arm64-v8a/libdragontcp_client.so
|
||||
android/build/DragonTCP-LiteVPN-arm64.apk
|
||||
```
|
||||
|
||||
Build only the Go/native components:
|
||||
`libdragontcp_client.so` is intentionally the Android ARM64 Go executable stored
|
||||
in the APK native-library directory. `DragonService` launches it with
|
||||
`ProcessBuilder`; it is not JNI.
|
||||
|
||||
## Build only the Go core/server
|
||||
|
||||
```bash
|
||||
./build_core.sh
|
||||
```
|
||||
|
||||
Build only the APK after the native core exists:
|
||||
## Build only the APK
|
||||
|
||||
After the core has been built:
|
||||
|
||||
```bash
|
||||
cd android
|
||||
./build_apk.sh
|
||||
```
|
||||
|
||||
## Testing performed
|
||||
The script creates a local debug signing key if one does not already exist.
|
||||
For production distribution, supply your own keystore/signing process.
|
||||
|
||||
The Go packages compile with `go test ./...`.
|
||||
## Source layout
|
||||
|
||||
A local mock-TUN test verified:
|
||||
```text
|
||||
core/ DragonTCP Go client/server
|
||||
android/src/com/dragontcp/client/ Android UI + VpnService
|
||||
android/src/tech/xvanturing/... Lightweight TUN-to-proxy stack
|
||||
android/lib/arm64-v8a/ Embedded DragonTCP Android core
|
||||
licenses/ Third-party licenses
|
||||
```
|
||||
|
||||
- an IPv6 `fe80::` source packet is dropped without terminating the client;
|
||||
- a valid packet immediately afterward still passes;
|
||||
- 120 IPv4 packets were combined into a **120,241-byte transfer object**,
|
||||
proving that transfer objects larger than 65,535 bytes work;
|
||||
- the echoed packets were returned byte-for-byte and in order;
|
||||
- the same path also works with a fixed **32-byte DragonTCP fragment size**.
|
||||
## Third-party stack
|
||||
|
||||
A physical Android phone is still required to validate device/vendor-specific
|
||||
`VpnService` behavior and the real mobile-network TCP/53 path.
|
||||
The userspace Android TUN/TCP adapter is adapted from the Apache-2.0-licensed
|
||||
FreeProxy project. See `THIRD_PARTY_NOTICES.md` and
|
||||
`licenses/FreeProxy-APACHE-2.0.txt`.
|
||||
|
||||
## Validation performed for this package
|
||||
|
||||
- Go unit/build checks: PASS.
|
||||
- Empty-token client/server protocol: PASS.
|
||||
- Fixed 1 poller + reconnect every 1: PASS.
|
||||
- 8 MiB HTTP transfer through local DragonTCP proxy: SHA-256 exact.
|
||||
- Kotlin TUN adapter compilation: PASS.
|
||||
- Android Java service/UI compilation: PASS.
|
||||
- ARM64 Android DragonTCP core build: PASS.
|
||||
- APK resource/DEX/native packaging: PASS.
|
||||
- APK signature verification (v3): PASS.
|
||||
- Supplied APK uses the same signing certificate as the previous v7 APK (versionCode 8), so it can be installed as an in-place update over v7.
|
||||
|
||||
A physical Android device is still required to validate the final VpnService
|
||||
path against a real mobile network.
|
||||
|
||||
Reference in New Issue
Block a user