v3
This commit is contained in:
@@ -1,13 +1,21 @@
|
||||
# DragonTCP Full Android VPN v1
|
||||
# DragonTCP VPN v3
|
||||
|
||||
This build replaces the old HTTP-proxy-only Android design with a real layer-3
|
||||
VPN packet tunnel.
|
||||
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.
|
||||
|
||||
It does **not** use the uploaded `jni.zip` and does not depend on HEV or any
|
||||
other tun2socks binary. The Android `VpnService` TUN file descriptor is passed
|
||||
directly to the DragonTCP Go core with Unix `SCM_RIGHTS`, and the Go core moves
|
||||
raw IPv4/IPv6 packets through DragonTCP's adaptive, XOR-framed TCP/53
|
||||
transport.
|
||||
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
|
||||
|
||||
@@ -18,59 +26,58 @@ Android apps
|
||||
v
|
||||
Android VpnService TUN (MTU 1280)
|
||||
|
|
||||
| raw IPv4/IPv6 packets
|
||||
v
|
||||
DragonTCP Go VPN core
|
||||
DragonTCP Android Go core
|
||||
|
|
||||
| adaptive small records, XOR 0xAD, TCP/53
|
||||
| packet batching (up to 1 MiB transfer objects)
|
||||
| adaptive fragmentation 32 B .. 1 MiB
|
||||
| XOR 0xAD framing
|
||||
v
|
||||
DragonTCP VPN server
|
||||
TCP/53
|
||||
|
|
||||
v
|
||||
DragonTCP Linux server
|
||||
|
|
||||
v
|
||||
Linux TUN dragontcp0
|
||||
|
|
||||
| IP forwarding + NAT
|
||||
| forwarding / NAT
|
||||
v
|
||||
Internet
|
||||
```
|
||||
|
||||
Because complete IP packets are tunneled, this carries TCP, UDP, DNS, ICMP,
|
||||
IPv4 and IPv6. Applications do not need HTTP or SOCKS proxy support.
|
||||
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
|
||||
core/ # complete Go source
|
||||
android/src/ # complete Android Java source
|
||||
build_core.sh
|
||||
build_all.sh
|
||||
android/build_apk.sh
|
||||
```
|
||||
|
||||
## Server requirements
|
||||
## Server
|
||||
|
||||
The full VPN server needs root/CAP_NET_ADMIN because it creates a Linux TUN
|
||||
interface and enables packet forwarding/NAT.
|
||||
The server needs root or equivalent CAP_NET_ADMIN permissions because it
|
||||
creates a Linux TUN and configures forwarding/NAT.
|
||||
|
||||
Install the normal Linux networking tools if they are not already present:
|
||||
Install networking tools on Debian/Ubuntu if needed:
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y iproute2 iptables
|
||||
```
|
||||
|
||||
TCP port 53 must be free.
|
||||
|
||||
Check:
|
||||
|
||||
```bash
|
||||
sudo ss -lntp | grep ':53'
|
||||
```
|
||||
|
||||
## Start the server
|
||||
Start:
|
||||
|
||||
```bash
|
||||
sudo ./dragontcp-vpn-server-linux-amd64 \
|
||||
@@ -78,130 +85,125 @@ sudo ./dragontcp-vpn-server-linux-amd64 \
|
||||
--debug
|
||||
```
|
||||
|
||||
The defaults are:
|
||||
Defaults:
|
||||
|
||||
```text
|
||||
listen 0.0.0.0:53/TCP
|
||||
TUN dragontcp0
|
||||
TUN MTU 1280
|
||||
server IPv4 10.123.0.1/16
|
||||
server IPv6 fd7a:4472:6167:6f6e::1/64
|
||||
maximum fragment 65535 bytes
|
||||
poll wait 100ms
|
||||
auto NAT enabled
|
||||
private targets blocked
|
||||
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
|
||||
```
|
||||
|
||||
The server automatically enables IPv4/IPv6 forwarding and installs
|
||||
MASQUERADE/forward rules with `iptables`/`ip6tables` when available.
|
||||
|
||||
If you manage routing/NAT yourself:
|
||||
|
||||
```bash
|
||||
sudo ./dragontcp-vpn-server-linux-amd64 \
|
||||
--token 'YOUR_SECRET' \
|
||||
--auto-nat=false
|
||||
```
|
||||
|
||||
To allow clients to reach private/LAN destination addresses too:
|
||||
|
||||
```bash
|
||||
--allow-private
|
||||
```
|
||||
|
||||
## Debug server
|
||||
|
||||
Normal diagnostics:
|
||||
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
|
||||
```
|
||||
|
||||
Very verbose per-IP-packet diagnostics:
|
||||
Per-packet/batch diagnostics are very verbose:
|
||||
|
||||
```bash
|
||||
--debug-packets
|
||||
```
|
||||
|
||||
Do not leave `--debug-packets` enabled for high-throughput use.
|
||||
|
||||
## Android app
|
||||
|
||||
Install:
|
||||
Install `android/build/DragonTCP-VPN.apk`.
|
||||
|
||||
```text
|
||||
DragonTCP-VPN.apk
|
||||
```
|
||||
|
||||
The UI is intentionally small:
|
||||
The UI asks for:
|
||||
|
||||
```text
|
||||
Server
|
||||
TCP Port
|
||||
TCP port
|
||||
Token
|
||||
Maximum fragment
|
||||
Minimum fragment
|
||||
Maximum transport fragment
|
||||
Minimum transport fragment
|
||||
Timeout
|
||||
|
||||
CONNECT
|
||||
STOP
|
||||
|
||||
Live log
|
||||
```
|
||||
|
||||
Defaults:
|
||||
|
||||
```text
|
||||
Port 53
|
||||
Max 1280
|
||||
Max 1048576
|
||||
Min 32
|
||||
Timeout 2s
|
||||
Pollers 1 (fixed)
|
||||
MTU 1280 (fixed)
|
||||
VPN MTU 1280
|
||||
```
|
||||
|
||||
The starting DragonTCP record size is always the configured maximum. On a
|
||||
transport failure the client automatically reduces it. With Max=1280 and
|
||||
Min=32 the reduction path can converge approximately as:
|
||||
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 -> 640 -> 320 -> 160 -> 80 -> 40 -> 32
|
||||
1280-byte packet --+
|
||||
1280-byte packet ---+
|
||||
1280-byte packet ----+--> one DragonTCP transfer object --> adaptive fragments
|
||||
... |
|
||||
1280-byte packet ----+
|
||||
```
|
||||
|
||||
After sustained successful full-size records it cautiously grows again.
|
||||
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.
|
||||
|
||||
The app assigns itself a stable private DragonTCP VPN IPv4/IPv6 pair on first
|
||||
run. The DragonTCP app UID itself is excluded from the VPN so the TCP/53
|
||||
transport cannot recursively enter its own TUN interface.
|
||||
## Android link-local source fix
|
||||
|
||||
## Why Max defaults to 1280
|
||||
A log such as this from the previous build:
|
||||
|
||||
This version transports IP packets, not an HTTP byte stream. The Android VPN
|
||||
MTU is 1280, so an individual IP packet normally cannot exceed 1280 bytes.
|
||||
The UI still accepts larger DragonTCP record ceilings up to 65535, but there
|
||||
is usually no throughput benefit unless the VPN MTU is raised too.
|
||||
```text
|
||||
VPN stopped: source fe80::... does not match session address
|
||||
```
|
||||
|
||||
## Building everything from source
|
||||
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 and build-tools
|
||||
- `zip`
|
||||
- Android SDK platform/build-tools
|
||||
- zip
|
||||
|
||||
No Android NDK is required in this build.
|
||||
No Android NDK is required for this build.
|
||||
|
||||
Set the SDK path:
|
||||
Set the SDK directory:
|
||||
|
||||
```bash
|
||||
export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
|
||||
```
|
||||
|
||||
Build server, Android native core, and APK:
|
||||
Build native components and APK:
|
||||
|
||||
```bash
|
||||
./build_all.sh
|
||||
@@ -216,76 +218,31 @@ android/lib/arm64-v8a/libdragontcp_vpn.so
|
||||
android/build/DragonTCP-VPN.apk
|
||||
```
|
||||
|
||||
Build only Go/native components:
|
||||
Build only the Go/native components:
|
||||
|
||||
```bash
|
||||
./build_core.sh
|
||||
```
|
||||
|
||||
Build only APK after the core is present:
|
||||
Build only the APK after the native core exists:
|
||||
|
||||
```bash
|
||||
./android/build_apk.sh
|
||||
cd android
|
||||
./build_apk.sh
|
||||
```
|
||||
|
||||
## Android TUN fd handoff
|
||||
## Testing performed
|
||||
|
||||
The Android service creates the VPN using `VpnService.Builder.establish()`.
|
||||
It then sends that TUN file descriptor to the Go child over a private Unix
|
||||
socket using Android `LocalSocket.setFileDescriptorsForSend()`. The Go side
|
||||
receives the descriptor with `SCM_RIGHTS` and directly reads/writes IP
|
||||
packets.
|
||||
The Go packages compile with `go test ./...`.
|
||||
|
||||
This avoids JNI and avoids passing an inherited descriptor through
|
||||
`ProcessBuilder`.
|
||||
A local mock-TUN test verified:
|
||||
|
||||
## Protocol packet mode
|
||||
- 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**.
|
||||
|
||||
Packet mode still uses the DragonTCP request/response envelope:
|
||||
|
||||
```text
|
||||
request : UP + request-id + length + XOR(payload)
|
||||
response : OK + request-id + length + XOR(payload)
|
||||
```
|
||||
|
||||
The VPN payload protocol is binary rather than text to reduce overhead on very
|
||||
small records.
|
||||
|
||||
Commands include:
|
||||
|
||||
```text
|
||||
VOPEN
|
||||
VPUSH fragment
|
||||
VPULL fragment
|
||||
VCLOSE
|
||||
```
|
||||
|
||||
A random 128-bit session ID is used after authenticated session creation.
|
||||
Packets and fragments have sequence/offset fields so retries do not duplicate
|
||||
bytes.
|
||||
|
||||
## Test mode
|
||||
|
||||
For protocol testing without root/TUN/NAT, the server has:
|
||||
|
||||
```bash
|
||||
./dragontcp-vpn-server-linux-amd64 \
|
||||
--host 127.0.0.1 \
|
||||
--port 19053 \
|
||||
--token test \
|
||||
--mock-echo
|
||||
```
|
||||
|
||||
This echoes complete IP packets back to the client instead of forwarding them
|
||||
to the Internet.
|
||||
|
||||
During development the packet path was tested with IPv4 and IPv6 1280-byte
|
||||
packets while the server forced a 32-byte maximum DragonTCP fragment. Both
|
||||
were reassembled byte-for-byte correctly.
|
||||
|
||||
## Security
|
||||
|
||||
XOR 0xAD remains protocol obfuscation, not cryptographic encryption. HTTPS
|
||||
and other TLS-based application protocols retain their own end-to-end
|
||||
security, but the DragonTCP transport itself should not be considered
|
||||
cryptographically confidential.
|
||||
A physical Android phone is still required to validate device/vendor-specific
|
||||
`VpnService` behavior and the real mobile-network TCP/53 path.
|
||||
|
||||
Reference in New Issue
Block a user