249 lines
5.7 KiB
Markdown
249 lines
5.7 KiB
Markdown
# DragonTCP VPN v3
|
|
|
|
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.
|
|
|
|
## 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
|
|
```
|
|
|
|
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.
|
|
|
|
## Included files
|
|
|
|
```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
|
|
|
|
The server needs root or equivalent CAP_NET_ADMIN permissions because it
|
|
creates a Linux TUN and configures forwarding/NAT.
|
|
|
|
Install networking tools on Debian/Ubuntu if needed:
|
|
|
|
```bash
|
|
sudo apt-get update
|
|
sudo apt-get install -y iproute2 iptables
|
|
```
|
|
|
|
Start:
|
|
|
|
```bash
|
|
sudo ./dragontcp-vpn-server-linux-amd64 \
|
|
--token 'YOUR_SECRET' \
|
|
--debug
|
|
```
|
|
|
|
Defaults:
|
|
|
|
```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:
|
|
|
|
```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
|
|
```
|
|
|
|
Per-packet/batch diagnostics are very verbose:
|
|
|
|
```bash
|
|
--debug-packets
|
|
```
|
|
|
|
## Android app
|
|
|
|
Install `android/build/DragonTCP-VPN.apk`.
|
|
|
|
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
|
|
|
|
Requirements:
|
|
|
|
- Go 1.22+
|
|
- JDK 17+
|
|
- Android SDK platform/build-tools
|
|
- zip
|
|
|
|
No Android NDK is required for this build.
|
|
|
|
Set the SDK directory:
|
|
|
|
```bash
|
|
export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
|
|
```
|
|
|
|
Build native components and APK:
|
|
|
|
```bash
|
|
./build_all.sh
|
|
```
|
|
|
|
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
|
|
```
|
|
|
|
Build only the Go/native components:
|
|
|
|
```bash
|
|
./build_core.sh
|
|
```
|
|
|
|
Build only the APK after the native core exists:
|
|
|
|
```bash
|
|
cd android
|
|
./build_apk.sh
|
|
```
|
|
|
|
## Testing performed
|
|
|
|
The Go packages compile with `go test ./...`.
|
|
|
|
A local mock-TUN test verified:
|
|
|
|
- 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**.
|
|
|
|
A physical Android phone is still required to validate device/vendor-specific
|
|
`VpnService` behavior and the real mobile-network TCP/53 path.
|