mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2024-12-30 02:37:01 +00:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3ae66ec62 | ||
|
|
38272319ee | ||
|
|
36b02f7d92 | ||
|
|
39495de718 | ||
|
|
88c5cac669 |
@@ -0,0 +1,48 @@
|
||||
name: Publish Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
- 'assets/**'
|
||||
- '.gitignore'
|
||||
- 'README.md'
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Get Version
|
||||
id: version
|
||||
uses: oprypin/find-latest-tag@v1
|
||||
with:
|
||||
repository: xjasonlyu/tun2socks
|
||||
|
||||
- name: Build and Push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
xjasonlyu/tun2socks:latest
|
||||
xjasonlyu/tun2socks:${{ steps.version.outputs.tag }}
|
||||
@@ -6,6 +6,11 @@ on:
|
||||
- master
|
||||
tags:
|
||||
- '*'
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
- 'assets/**'
|
||||
- '.gitignore'
|
||||
- 'README.md'
|
||||
|
||||
jobs:
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ NAME = "tun2socks"
|
||||
TAGS = ""
|
||||
BUILD_FLAGS = "-v"
|
||||
|
||||
VERSION = $(shell git describe --tags)
|
||||
VERSION = $(shell git describe --tags --abbrev=0)
|
||||
BUILD_TIME = $(shell date -u '+%FT%TZ')
|
||||
|
||||
LDFLAGS += -w -s -buildid=
|
||||
@@ -17,7 +17,7 @@ PLATFORM_LIST = \
|
||||
linux-amd64 \
|
||||
linux-arm64 \
|
||||
|
||||
.PHONY: $(PLATFORM_LIST)
|
||||
.PHONY: all docker $(PLATFORM_LIST)
|
||||
|
||||
all: $(PLATFORM_LIST)
|
||||
|
||||
|
||||
@@ -1,56 +1,60 @@
|
||||
# tun2socks
|
||||
<h1 align="center">tun2socks</h1>
|
||||
<h3 align="center">A tun2socks powered by gVisor TCP/IP stack.</h3>
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
A tun2socks implementation written in Go.
|
||||
<p align="center">
|
||||
<a href="https://github.com/xjasonlyu/tun2socks/actions">
|
||||
<img src="https://img.shields.io/github/workflow/status/xjasonlyu/tun2socks/Go/master?style=flat-square" alt="GitHub Workflow">
|
||||
</a>
|
||||
<a href="https://hub.docker.com/r/xjasonlyu/tun2socks">
|
||||
<img src="https://img.shields.io/docker/pulls/xjasonlyu/tun2socks?style=flat-square" alt="Docker Pulls">
|
||||
</a>
|
||||
<a href="https://img.shields.io/github/go-mod/go-version/xjasonlyu/tun2socks">
|
||||
<img src="https://img.shields.io/github/go-mod/go-version/xjasonlyu/tun2socks?style=flat-square" alt="Go Version">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/badge/github.com/xjasonlyu/tun2socks">
|
||||
<img src="https://goreportcard.com/badge/github.com/xjasonlyu/tun2socks?style=flat-square" alt="Go Report">
|
||||
</a>
|
||||
<a href="https://github.com/xjasonlyu/tun2socks/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/xjasonlyu/tun2socks?style=flat-square" alt="GitHub License">
|
||||
</a>
|
||||
<a href="https://img.shields.io/tokei/lines/github/xjasonlyu/tun2socks">
|
||||
<img src="https://img.shields.io/tokei/lines/github/xjasonlyu/tun2socks?style=flat-square" alt="Total Lines">
|
||||
</a>
|
||||
<a href="https://github.com/xjasonlyu/tun2socks/releases">
|
||||
<img src="https://img.shields.io/github/v/release/xjasonlyu/tun2socks?include_prereleases&style=flat-square" alt="Release">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Features
|
||||
|
||||
- External RESTful API support
|
||||
- Fake DNS with manual hosts support
|
||||
- IPv4/IPv6 support
|
||||
- ICMP echoing
|
||||
- IPv6 support
|
||||
- Optimized UDP transmission for game acceleration
|
||||
- Pure Go implementation, no CGO required
|
||||
- Pure Go implementation, no more CGO required
|
||||
- Router mode, routing all the traffic in LAN
|
||||
- Socks5, Shadowsocks protocol support for remote connections
|
||||
- TCP/IP stack powered by [gVisor](https://github.com/google/gvisor)
|
||||
- Up to 2.5Gbps throughput (10x faster than [v1](https://github.com/xjasonlyu/tun2socks/tree/v1))
|
||||
|
||||
### Requirements
|
||||
## Requirements
|
||||
|
||||
| Target | Minimum | Recommended |
|
||||
| --- | --- | --- |
|
||||
| :----- | :-----: | :---------: |
|
||||
| System | linux darwin | linux |
|
||||
| Memory | >20MB | +∞ |
|
||||
| CPU | ANY | amd64 arm64 |
|
||||
| Memory | >20MB | >128MB |
|
||||
| CPU | amd64 arm64 | amd64 |
|
||||
|
||||
## QuickStart
|
||||
## Performance
|
||||
|
||||
Download from precompiled [Releases](https://github.com/xjasonlyu/tun2socks/releases).
|
||||
> iPerf3 tested on Debian 10 with i5-10500, 8G RAM
|
||||
|
||||
create tun
|
||||

|
||||
|
||||
```shell script
|
||||
ip tuntap add mode tun dev tun0
|
||||
ip addr add 198.18.0.1/15 dev tun0
|
||||
ip link set dev tun0 up
|
||||
```
|
||||
## How to Build
|
||||
|
||||
run
|
||||
### build from source code
|
||||
|
||||
```shell script
|
||||
./tun2socks --loglevel WARN --device tun://tun0 --proxy socks5://server:port --interface eth0
|
||||
```
|
||||
|
||||
or just
|
||||
|
||||
```shell script
|
||||
PROXY=socks5://server:port LOGLEVEL=WARN sh ./scripts/entrypoint.sh
|
||||
```
|
||||
|
||||
## Build from source
|
||||
Go compiler version >= 1.15 is required
|
||||
|
||||
```text
|
||||
$ git clone https://github.com/xjasonlyu/tun2socks.git
|
||||
@@ -58,17 +62,207 @@ $ cd tun2socks
|
||||
$ make
|
||||
```
|
||||
|
||||
## Issues
|
||||
### build docker image
|
||||
|
||||
Due to the implementation of pure Go, the memory usage is higher than the previous version.
|
||||
If you are memory sensitive, please go back to [v1](https://github.com/xjasonlyu/tun2socks/tree/v1).
|
||||
```text
|
||||
$ docker build -t tun2socks .
|
||||
```
|
||||
|
||||
## TODO
|
||||
or
|
||||
|
||||
- [ ] Windows support
|
||||
```text
|
||||
$ docker build -t tun2socks -f ./docker/Dockerfile.aarch64 .
|
||||
```
|
||||
|
||||
## QuickStart
|
||||
|
||||
Download from precompiled [Releases](https://github.com/xjasonlyu/tun2socks/releases).
|
||||
|
||||
<details>
|
||||
<summary><b>With Docker</b></summary>
|
||||
|
||||
> Since Go 1.12, the runtime now uses MADV_FREE to release unused memory on **linux**. This is more efficient but may result in higher reported RSS. The kernel will reclaim the unused data when it is needed. To revert to the Go 1.11 behavior (MADV_DONTNEED), set the environment variable GODEBUG=madvdontneed=1.
|
||||
|
||||
### create docker network (macvlan mode)
|
||||
|
||||
```shell script
|
||||
docker network create -d macvlan \
|
||||
--subnet=172.20.1.0/25 \
|
||||
--gateway=172.20.1.1 \
|
||||
-o parent=eth0 \
|
||||
switch
|
||||
```
|
||||
|
||||
### pull `tun2socks` docker image
|
||||
|
||||
```shell script
|
||||
docker pull xjasonlyu/tun2socks:latest
|
||||
```
|
||||
|
||||
### run as gateway
|
||||
|
||||
> DNS configuration is required.
|
||||
|
||||
```shell script
|
||||
docker run -d \
|
||||
--network switch \
|
||||
--name tun2socks \
|
||||
--ip 172.20.1.2 \
|
||||
--privileged \
|
||||
--restart always \
|
||||
--sysctl net.ipv4.ip_forward=1 \
|
||||
-e PROXY=socks5://server:port \
|
||||
-e KEY=VALUE... \
|
||||
xjasonlyu/tun2socks:latest
|
||||
```
|
||||
|
||||
### use docker-compose (recommended)
|
||||
|
||||
```yaml
|
||||
version: '2.4'
|
||||
|
||||
services:
|
||||
tun2socks:
|
||||
image: xjasonlyu/tun2socks:latest
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- '/dev/net/tun:/dev/net/tun'
|
||||
environment:
|
||||
# - GODEBUG=madvdontneed=1
|
||||
- PROXY=socks5://server:port
|
||||
- LOGLEVEL=INFO
|
||||
- API=api://:8080
|
||||
- DNS=dns://:53
|
||||
- HOSTS=localhost=127.0.0.1,router.local=172.20.1.1
|
||||
- EXCLUDED=1.1.1.1,1.0.0.1
|
||||
- EXTRACMD=
|
||||
networks:
|
||||
switch:
|
||||
ipv4_address: 172.20.1.2
|
||||
restart: always
|
||||
container_name: tun2socks
|
||||
|
||||
networks:
|
||||
switch:
|
||||
name: switch
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: '172.20.1.0/25'
|
||||
gateway: 172.20.1.1
|
||||
driver: macvlan
|
||||
driver_opts:
|
||||
parent: eth0
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>With Linux</b></summary>
|
||||
|
||||
### create tun
|
||||
|
||||
```shell script
|
||||
ip tuntap add mode tun dev tun0
|
||||
ip addr add 198.18.0.1/15 dev tun0
|
||||
ip link set dev tun0 up
|
||||
```
|
||||
|
||||
### config policy routing
|
||||
|
||||
```shell script
|
||||
echo "100 tun2socks" >> /etc/iproute2/rt_tables
|
||||
|
||||
ip route add default via 198.18.0.1 dev tun0 table tun2socks
|
||||
ip route add 172.17.0.0/16 dev eth0 src 172.17.0.3 table tun2socks
|
||||
ip route add 198.18.0.0/15 dev tun0 src 198.18.0.1 table tun2socks
|
||||
|
||||
ip rule add from 172.20.0.3 to 198.18.0.0/15 priority 1000 prohibit
|
||||
ip rule add from 172.20.0.3 priority 2000 table main
|
||||
ip rule add from all priority 3000 table tun2socks
|
||||
```
|
||||
|
||||
### run
|
||||
|
||||
> bind to a specific interface to prevent traffic looping.
|
||||
|
||||
```shell script
|
||||
./tun2socks --loglevel info --device tun://tun0 --proxy socks5://server:port --interface eth0
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>With Script</b></summary>
|
||||
|
||||
> entrypoint.sh would take care of tun & routes.
|
||||
|
||||
```shell script
|
||||
PROXY=socks5://server:port LOGLEVEL=INFO sh ./scripts/entrypoint.sh
|
||||
```
|
||||
</details>
|
||||
|
||||
## Details
|
||||
|
||||
<details>
|
||||
<summary><b>API Reference</b></summary>
|
||||
|
||||
| Path | Methods | Parameters | Description |
|
||||
| :--- | :------ | :--------: | :---------- |
|
||||
| `/logs` | GET | `level` | Get real-time logs |
|
||||
| `/traffic` | GET | / | Get real-time traffic data |
|
||||
| `/version` | GET | / | Get current version |
|
||||
| `/connections` | GET | `interval` | Get all connections |
|
||||
| `/connections` | DELETE | / | Close all connections |
|
||||
| `/connections/{id}` | DELETE | / | Close connection by `id` |
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Help Text</b></summary>
|
||||
|
||||
```text
|
||||
NAME:
|
||||
tun2socks - A tun2socks powered by gVisor TCP/IP stack.
|
||||
|
||||
USAGE:
|
||||
tun2socks [global options] [arguments...]
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
--api value URL of external API to listen
|
||||
--device value, -d value URL of device to open
|
||||
--dns value URL of fake DNS to listen
|
||||
--hosts value Extra hosts mapping
|
||||
--interface value, -i value Bind interface to dial
|
||||
--loglevel value, -l value Set logging level (default: "INFO")
|
||||
--proxy value, -p value URL of proxy to dial
|
||||
--version, -v Print current version (default: false)
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Proxy URL</b></summary>
|
||||
|
||||
| Protocol | Scheme | Examples |
|
||||
| :------- | :----- | :------- |
|
||||
| direct | `direct` | `direct://` |
|
||||
| socks5 | `socks5` | `socks5://username:password@server:port` |
|
||||
| shadowsocks | `ss`, `shadowsocks` | `ss://method:password@server:port` |
|
||||
|
||||
</details>
|
||||
|
||||
## Credits
|
||||
|
||||
- [Dreamacro/clash](https://github.com/Dreamacro/clash)
|
||||
- [google/gvisor](https://github.com/google/gvisor)
|
||||
- [majek/slirpnetstack](https://github.com/majek/slirpnetstack)
|
||||
|
||||
## Known Issues
|
||||
|
||||
Due to the implementation of pure Go, the memory usage is higher than the previous version.
|
||||
If you are sensitive to memory, please go back to [v1](https://github.com/xjasonlyu/tun2socks/tree/v1).
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] Windows support
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
@@ -2,7 +2,7 @@ version: '2.4'
|
||||
|
||||
services:
|
||||
tun2socks:
|
||||
image: xjasonlyu/tun2socks:arm64-dev
|
||||
image: xjasonlyu/tun2socks:latest
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
@@ -10,15 +10,15 @@ services:
|
||||
environment:
|
||||
- GODEBUG=madvdontneed=1
|
||||
- PROXY=
|
||||
- LOGLEVEL=warning
|
||||
- API=:8080
|
||||
- LOGLEVEL=
|
||||
- API=
|
||||
- DNS=
|
||||
- HOSTS=
|
||||
- EXCLUDED=
|
||||
- EXTRACMD=
|
||||
networks:
|
||||
switch:
|
||||
ipv4_address: 172.20.1.20
|
||||
ipv4_address: 172.20.1.2
|
||||
restart: always
|
||||
container_name: tun2socks
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@ require (
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
||||
github.com/urfave/cli/v2 v2.2.0
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
github.com/xjasonlyu/clash v0.15.1-0.20201105074459-aa45c8b56cf6
|
||||
go.uber.org/atomic v1.7.0
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 // indirect
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 // indirect
|
||||
golang.org/x/sys v0.0.0-20201106081118-db71ae66460a // indirect
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20201105065002-ab9a79fe812a
|
||||
gvisor.dev/gvisor v0.0.0-20201107070040-22fc22ad6ef7
|
||||
)
|
||||
|
||||
@@ -227,8 +227,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
|
||||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/xjasonlyu/clash v0.15.1-0.20201105074459-aa45c8b56cf6 h1:iQsLkjayjJs29VOeXaeznpy1jddiuRjstj6MfFbKVoM=
|
||||
@@ -336,8 +336,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 h1:HlFl4V6pEMziuLXyRkm5BIYq1y1GAbb02pRlWvI54OM=
|
||||
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201106081118-db71ae66460a h1:ALUFBKlIyeY7y5ZgPJmblk/vKz+zBQSnNiPkt41sgeg=
|
||||
golang.org/x/sys v0.0.0-20201106081118-db71ae66460a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -423,6 +423,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -431,8 +432,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gvisor.dev/gvisor v0.0.0-20201105065002-ab9a79fe812a h1:io3nR9e7V26iORClxbTxnrNBhxAvdvgMKU8E+at6idc=
|
||||
gvisor.dev/gvisor v0.0.0-20201105065002-ab9a79fe812a/go.mod h1:t4GUXJhnQEPtYSvrvRNW5CNdBQ2oWZBy7P+FbCVKBFY=
|
||||
gvisor.dev/gvisor v0.0.0-20201107070040-22fc22ad6ef7 h1:JKZNg4wnh94dWyhXSNOQ4jkliNbcRJt1Vs5NPyMOo48=
|
||||
gvisor.dev/gvisor v0.0.0-20201107070040-22fc22ad6ef7/go.mod h1:t4GUXJhnQEPtYSvrvRNW5CNdBQ2oWZBy7P+FbCVKBFY=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@@ -77,6 +77,17 @@ func NewDefaultStack(linkEp stack.LinkEndpoint, th tcpHandleFunc, uh udpHandleFu
|
||||
// Ref: https://github.com/majek/slirpnetstack/blob/master/stack.go
|
||||
WithPromiscuousMode(defaultNICID, nicPromiscuousModeEnabled),
|
||||
|
||||
// Enable spoofing if a stack may send packets from unowned addresses.
|
||||
// This change required changes to some netgophers since previously,
|
||||
// promiscuous mode was enough to let the netstack respond to all
|
||||
// incoming packets regardless of the packet's destination address. Now
|
||||
// that a stack.Route is not held for each incoming packet, finding a route
|
||||
// may fail with local addresses we don't own but accepted packets for
|
||||
// while in promiscuous mode. Since we also want to be able to send from
|
||||
// any address (in response the received promiscuous mode packets), we need
|
||||
// to enable spoofing.
|
||||
//
|
||||
// Ref: https://github.com/google/gvisor/commit/8c0701462a84ff77e602f1626aec49479c308127
|
||||
WithSpoofing(defaultNICID, nicSpoofingEnabled),
|
||||
)
|
||||
}
|
||||
|
||||
+19
-11
@@ -11,6 +11,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
|
||||
|
||||
"github.com/xjasonlyu/tun2socks/internal/adapter"
|
||||
"github.com/xjasonlyu/tun2socks/pkg/log"
|
||||
)
|
||||
|
||||
const udpNoChecksum = true
|
||||
@@ -19,16 +20,16 @@ type udpHandleFunc func(adapter.UDPPacket)
|
||||
|
||||
func WithUDPHandler(handle udpHandleFunc) Option {
|
||||
return func(s *stack.Stack) error {
|
||||
udpHandlePacket := func(r *stack.Route, id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
|
||||
udpHandlePacket := func(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
|
||||
// Ref: gVisor pkg/tcpip/transport/udp/endpoint.go HandlePacket
|
||||
hdr := header.UDP(pkt.TransportHeader().View())
|
||||
if int(hdr.Length()) > pkt.Data.Size()+header.UDPMinimumSize {
|
||||
udpHdr := header.UDP(pkt.TransportHeader().View())
|
||||
if int(udpHdr.Length()) > pkt.Data.Size()+header.UDPMinimumSize {
|
||||
// Malformed packet.
|
||||
s.Stats().UDP.MalformedPacketsReceived.Increment()
|
||||
return true
|
||||
}
|
||||
|
||||
if !verifyChecksum(r, hdr, pkt) {
|
||||
if !verifyChecksum(udpHdr, pkt) {
|
||||
// Checksum error.
|
||||
s.Stats().UDP.ChecksumErrors.Increment()
|
||||
return true
|
||||
@@ -36,8 +37,14 @@ func WithUDPHandler(handle udpHandleFunc) Option {
|
||||
|
||||
s.Stats().UDP.PacketsReceived.Increment()
|
||||
|
||||
// make a clone here.
|
||||
route := r.Clone()
|
||||
netHdr := pkt.Network()
|
||||
route, err := s.FindRoute(pkt.NICID, netHdr.DestinationAddress(), netHdr.SourceAddress(), pkt.NetworkProtocolNumber, false /* multicastLoop */)
|
||||
if err != nil {
|
||||
log.Warnf("[STACK] find route error: %v", err)
|
||||
return true
|
||||
}
|
||||
route.ResolveWith(pkt.SourceLinkAddress())
|
||||
|
||||
packet := &udpPacket{
|
||||
id: id,
|
||||
r: &route,
|
||||
@@ -138,7 +145,7 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u
|
||||
// On IPv4, UDP checksum is optional, and a zero value indicates the
|
||||
// transmitter skipped the checksum generation (RFC768).
|
||||
// On IPv6, UDP checksum is not optional (RFC2460 Section 8.1).
|
||||
if r.Capabilities()&stack.CapabilityTXChecksumOffload == 0 &&
|
||||
if r.RequiresTXTransportChecksum() &&
|
||||
(!noChecksum || r.NetProto == header.IPv6ProtocolNumber) {
|
||||
xsum := r.PseudoHeaderChecksum(udp.ProtocolNumber, length)
|
||||
for _, v := range data.Views() {
|
||||
@@ -166,10 +173,11 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u
|
||||
// On IPv4, UDP checksum is optional, and a zero value means the transmitter
|
||||
// omitted the checksum generation (RFC768).
|
||||
// On IPv6, UDP checksum is not optional (RFC2460 Section 8.1).
|
||||
func verifyChecksum(r *stack.Route, hdr header.UDP, pkt *stack.PacketBuffer) bool {
|
||||
if r.Capabilities()&stack.CapabilityRXChecksumOffload == 0 &&
|
||||
(hdr.Checksum() != 0 || r.NetProto == header.IPv6ProtocolNumber) {
|
||||
xsum := r.PseudoHeaderChecksum(udp.ProtocolNumber, hdr.Length())
|
||||
func verifyChecksum(hdr header.UDP, pkt *stack.PacketBuffer) bool {
|
||||
if !pkt.RXTransportChecksumValidated &&
|
||||
(hdr.Checksum() != 0 || pkt.NetworkProtocolNumber == header.IPv6ProtocolNumber) {
|
||||
netHdr := pkt.Network()
|
||||
xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, netHdr.DestinationAddress(), netHdr.SourceAddress(), hdr.Length())
|
||||
for _, v := range pkt.Data.Views() {
|
||||
xsum = header.Checksum(v, xsum)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/xjasonlyu/tun2socks/pkg/log"
|
||||
)
|
||||
|
||||
const Usage = "A tun2socks implementation written in Go."
|
||||
const About = "A tun2socks powered by gVisor TCP/IP stack."
|
||||
|
||||
var (
|
||||
Version string
|
||||
@@ -19,7 +19,7 @@ var (
|
||||
|
||||
func main() {
|
||||
app := &cli.App{
|
||||
Usage: Usage,
|
||||
Usage: About,
|
||||
Version: Version,
|
||||
Action: cmd.Main,
|
||||
Flags: []cli.Flag{
|
||||
|
||||
Reference in New Issue
Block a user