mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2024-12-30 02:37:01 +00:00
Compare commits
14
Commits
v2.0.0-rc.2
...
v2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcf9d280b8 | ||
|
|
f18362714d | ||
|
|
95dc93cb41 | ||
|
|
d42cf2ceb5 | ||
|
|
25749c7596 | ||
|
|
2835cfae75 | ||
|
|
0e2d98b951 | ||
|
|
b435fbc51a | ||
|
|
b858c8758a | ||
|
|
08674e64af | ||
|
|
3b641119db | ||
|
|
8c7075050c | ||
|
|
ca7d161f58 | ||
|
|
f559f9bd3c |
@@ -0,0 +1,9 @@
|
||||
.github/
|
||||
.github/**
|
||||
assets/
|
||||
assets/**
|
||||
.dockerignore
|
||||
*.yml
|
||||
*.md
|
||||
.gitignore
|
||||
Dockerfile*
|
||||
@@ -4,6 +4,8 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- '*'
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
- 'assets/**'
|
||||
@@ -19,12 +21,18 @@ jobs:
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
platforms: all
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
@@ -32,17 +40,28 @@ jobs:
|
||||
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
|
||||
- name: Build and Push (dev)
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
xjasonlyu/tun2socks:dev
|
||||
|
||||
- name: Get Version
|
||||
id: shell
|
||||
run: |
|
||||
echo ::set-output name=version::$(git describe --tags --abbrev=0)
|
||||
|
||||
- name: Build and Push (latest)
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
xjasonlyu/tun2socks:latest
|
||||
xjasonlyu/tun2socks:${{ steps.version.outputs.tag }}
|
||||
xjasonlyu/tun2socks:${{ steps.shell.outputs.version }}
|
||||
|
||||
@@ -25,6 +25,8 @@ jobs:
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Cache go module
|
||||
uses: actions/cache@v2
|
||||
@@ -43,9 +45,6 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
DIR: bin
|
||||
NAME: tun2socks
|
||||
run: make -j releases
|
||||
|
||||
- name: Upload Release
|
||||
|
||||
+4
-4
@@ -1,17 +1,17 @@
|
||||
FROM golang:alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
WORKDIR /tun2socks-src
|
||||
COPY . /tun2socks-src
|
||||
|
||||
RUN apk add --no-cache make git \
|
||||
&& go mod download \
|
||||
&& make docker \
|
||||
&& /app/bin/tun2socks-docker -v
|
||||
&& mv ./bin/tun2socks-docker /tun2socks
|
||||
|
||||
FROM alpine:latest
|
||||
|
||||
COPY ./scripts/entrypoint.sh /entrypoint.sh
|
||||
COPY --from=builder /app/bin/tun2socks-docker /usr/bin/tun2socks
|
||||
COPY --from=builder /tun2socks /usr/bin/tun2socks
|
||||
|
||||
RUN apk add --update --no-cache iptables iproute2 \
|
||||
&& chmod +x /entrypoint.sh
|
||||
|
||||
@@ -4,7 +4,7 @@ NAME = "tun2socks"
|
||||
TAGS = ""
|
||||
BUILD_FLAGS = "-v"
|
||||
|
||||
VERSION = $(shell git describe --tags --abbrev=0)
|
||||
VERSION = $(shell git describe --tags || echo "unknown version")
|
||||
BUILD_TIME = $(shell date -u '+%FT%TZ')
|
||||
|
||||
LDFLAGS += -w -s -buildid=
|
||||
@@ -14,12 +14,14 @@ GO_BUILD = CGO_ENABLED=0 go build $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(
|
||||
|
||||
PLATFORM_LIST = \
|
||||
darwin-amd64 \
|
||||
freebsd-amd64 \
|
||||
freebsd-arm64 \
|
||||
linux-amd64 \
|
||||
linux-arm64 \
|
||||
openbsd-amd64 \
|
||||
openbsd-arm64 \
|
||||
|
||||
.PHONY: all docker $(PLATFORM_LIST)
|
||||
|
||||
all: $(PLATFORM_LIST)
|
||||
all: linux-amd64 darwin-amd64
|
||||
|
||||
docker:
|
||||
$(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
@@ -27,17 +29,31 @@ docker:
|
||||
darwin-amd64:
|
||||
GOARCH=amd64 GOOS=darwin $(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
|
||||
freebsd-amd64:
|
||||
GOARCH=amd64 GOOS=freebsd $(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
|
||||
freebsd-arm64:
|
||||
GOARCH=arm64 GOOS=freebsd $(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
|
||||
linux-amd64:
|
||||
GOARCH=amd64 GOOS=linux $(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
|
||||
linux-arm64:
|
||||
GOARCH=arm64 GOOS=linux $(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
|
||||
openbsd-amd64:
|
||||
GOARCH=amd64 GOOS=openbsd $(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
|
||||
openbsd-arm64:
|
||||
GOARCH=arm64 GOOS=openbsd $(GO_BUILD) -o $(DIR)/$(NAME)-$@
|
||||
|
||||
zip_releases=$(addsuffix .zip, $(PLATFORM_LIST))
|
||||
|
||||
$(zip_releases): %.zip : %
|
||||
zip -m -j $(DIR)/$(NAME)-$(basename $@).zip $(DIR)/$(NAME)-$(basename $@)
|
||||
|
||||
all-arch: $(PLATFORM_LIST)
|
||||
|
||||
releases: $(zip_releases)
|
||||
|
||||
clean:
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
| Target | Minimum | Recommended |
|
||||
| :----- | :-----: | :---------: |
|
||||
| System | linux darwin | linux |
|
||||
| System | linux darwin freebsd openbsd | linux |
|
||||
| Memory | >20MB | >128MB |
|
||||
| CPU | amd64 arm64 | amd64 |
|
||||
|
||||
@@ -71,7 +71,7 @@ $ docker build -t tun2socks .
|
||||
or
|
||||
|
||||
```text
|
||||
$ docker build -t tun2socks -f ./docker/Dockerfile.aarch64 .
|
||||
$ docker build -t tun2socks -f .Dockerfile.aarch64 .
|
||||
```
|
||||
|
||||
## QuickStart
|
||||
@@ -191,6 +191,35 @@ ip rule add from all priority 3000 table tun2socks
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>With MacOS</b></summary>
|
||||
|
||||
### start tun2socks
|
||||
```shell script
|
||||
./tun2socks --loglevel info --device tun://utun123 --proxy socks5://server:port --interface eth0
|
||||
```
|
||||
|
||||
### config interface
|
||||
|
||||
```shell script
|
||||
sudo ifconfig utun123 198.18.0.1 netmask 255.255.255.255 198.18.0.1 up
|
||||
```
|
||||
|
||||
### config route
|
||||
|
||||
```shell script
|
||||
sudo route del default
|
||||
sudo route add default 198.18.0.1
|
||||
sudo route add ${proxy_server_ip} ${your_gateway}
|
||||
```
|
||||
|
||||
### check route table
|
||||
|
||||
```shell script
|
||||
netstat -nr
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>With Script</b></summary>
|
||||
|
||||
@@ -257,6 +286,7 @@ GLOBAL OPTIONS:
|
||||
- [Dreamacro/clash](https://github.com/Dreamacro/clash)
|
||||
- [google/gvisor](https://github.com/google/gvisor)
|
||||
- [majek/slirpnetstack](https://github.com/majek/slirpnetstack)
|
||||
- [WireGuard/wireguard-go](https://github.com/WireGuard/wireguard-go)
|
||||
|
||||
## Known Issues
|
||||
|
||||
@@ -266,3 +296,5 @@ If you are sensitive to memory, please go back to [v1](https://github.com/xjason
|
||||
## TODO
|
||||
|
||||
- [ ] Windows support
|
||||
- [x] FreeBSD support
|
||||
- [x] OpenBSD support
|
||||
|
||||
@@ -9,14 +9,16 @@ require (
|
||||
github.com/go-chi/render v1.0.1
|
||||
github.com/gofrs/uuid v3.3.0+incompatible
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
||||
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-20201106081118-db71ae66460a // indirect
|
||||
golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
|
||||
golang.zx2c4.com/wireguard v0.0.20200320
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20201107070040-22fc22ad6ef7
|
||||
gvisor.dev/gvisor v0.0.0-20201107072535-9e848922ed33
|
||||
)
|
||||
|
||||
@@ -201,6 +201,8 @@ github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7z
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
@@ -245,6 +247,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@@ -284,6 +287,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
@@ -332,12 +336,13 @@ golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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-20201106081118-db71ae66460a h1:ALUFBKlIyeY7y5ZgPJmblk/vKz+zBQSnNiPkt41sgeg=
|
||||
golang.org/x/sys v0.0.0-20201106081118-db71ae66460a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf h1:kt3wY1Lu5MJAnKTfoMR52Cu4gwvna4VTzNOiT8tY73s=
|
||||
golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf/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=
|
||||
@@ -380,6 +385,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wireguard v0.0.20200320 h1:1vE6zVeO7fix9cJX1Z9ZQ+ikPIIx7vIyU0o0tLDD88g=
|
||||
golang.zx2c4.com/wireguard v0.0.20200320/go.mod h1:lDian4Sw4poJ04SgHh35nzMVwGSYlPumkdnHcucAQoY=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
@@ -432,8 +439,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-20201107070040-22fc22ad6ef7 h1:JKZNg4wnh94dWyhXSNOQ4jkliNbcRJt1Vs5NPyMOo48=
|
||||
gvisor.dev/gvisor v0.0.0-20201107070040-22fc22ad6ef7/go.mod h1:t4GUXJhnQEPtYSvrvRNW5CNdBQ2oWZBy7P+FbCVKBFY=
|
||||
gvisor.dev/gvisor v0.0.0-20201107072535-9e848922ed33 h1:Iy80PPGcHGhOacbFJk/Cn8lV0k8dcg8UJBo8e5qV9Ac=
|
||||
gvisor.dev/gvisor v0.0.0-20201107072535-9e848922ed33/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=
|
||||
|
||||
+5
-10
@@ -13,11 +13,11 @@ import (
|
||||
"github.com/xjasonlyu/clash/component/dialer"
|
||||
"github.com/xjasonlyu/tun2socks/internal/api"
|
||||
"github.com/xjasonlyu/tun2socks/internal/core"
|
||||
"github.com/xjasonlyu/tun2socks/internal/dev"
|
||||
"github.com/xjasonlyu/tun2socks/internal/dns"
|
||||
"github.com/xjasonlyu/tun2socks/internal/proxy"
|
||||
"github.com/xjasonlyu/tun2socks/internal/tunnel"
|
||||
"github.com/xjasonlyu/tun2socks/pkg/log"
|
||||
"github.com/xjasonlyu/tun2socks/pkg/tun"
|
||||
)
|
||||
|
||||
func bindToInterface(name string) {
|
||||
@@ -51,7 +51,7 @@ func Main(c *cli.Context) error {
|
||||
if c.IsSet("interface") {
|
||||
name := c.String("interface")
|
||||
bindToInterface(name)
|
||||
log.Infof("[IFCE] bind to interface: %s", name)
|
||||
log.Infof("[DIALER] bind to interface: %s", name)
|
||||
}
|
||||
|
||||
if c.IsSet("api") { /* initiate API */
|
||||
@@ -71,16 +71,11 @@ func Main(c *cli.Context) error {
|
||||
}
|
||||
|
||||
deviceURL := c.String("device")
|
||||
device, err := dev.Open(deviceURL)
|
||||
device, err := tun.Open(deviceURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open device %s: %w", deviceURL, err)
|
||||
}
|
||||
defer func() {
|
||||
err := device.Close()
|
||||
if err != nil {
|
||||
log.Errorf("close device %s error: %v", deviceURL, err)
|
||||
}
|
||||
}()
|
||||
defer device.Close()
|
||||
|
||||
proxyURL := c.String("proxy")
|
||||
if err := proxy.Register(proxyURL); err != nil {
|
||||
@@ -90,7 +85,7 @@ func Main(c *cli.Context) error {
|
||||
if _, err := core.NewDefaultStack(device, tunnel.Add, tunnel.AddPacket); err != nil {
|
||||
return fmt.Errorf("initiate stack: %w", err)
|
||||
}
|
||||
log.Infof("[STACK] %s --> %s", device.String(), proxy.String())
|
||||
log.Infof("[STACK] %s --> %s", deviceURL, proxyURL)
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
+18
-59
@@ -3,6 +3,7 @@ package core
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
_ "unsafe"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
@@ -103,7 +104,7 @@ func (p *udpPacket) WriteBack(b []byte, addr net.Addr) (int, error) {
|
||||
data := v.ToVectorisedView()
|
||||
// if addr is not provided, write back use original dst Addr as src Addr.
|
||||
if addr == nil {
|
||||
return sendUDP(p.r, data, p.id.LocalPort, p.id.RemotePort, udpNoChecksum)
|
||||
return _sendUDP(p.r, data, p.id.LocalPort, p.id.RemotePort, udpNoChecksum)
|
||||
}
|
||||
|
||||
udpAddr, ok := addr.(*net.UDPAddr)
|
||||
@@ -113,75 +114,33 @@ func (p *udpPacket) WriteBack(b []byte, addr net.Addr) (int, error) {
|
||||
|
||||
r := p.r.Clone()
|
||||
defer r.Release()
|
||||
|
||||
if ipv4 := udpAddr.IP.To4(); ipv4 != nil {
|
||||
r.LocalAddress = tcpip.Address(ipv4)
|
||||
} else {
|
||||
r.LocalAddress = tcpip.Address(udpAddr.IP)
|
||||
}
|
||||
return sendUDP(&r, data, uint16(udpAddr.Port), p.id.RemotePort, udpNoChecksum)
|
||||
return _sendUDP(&r, data, uint16(udpAddr.Port), p.id.RemotePort, udpNoChecksum)
|
||||
}
|
||||
|
||||
// _sendUDP wraps sendUDP with some default parameters.
|
||||
func _sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, noChecksum bool) (int, error) {
|
||||
if err := sendUDP(r, data, localPort, remotePort, 0 /* ttl */, true /* useDefaultTTL */, 0 /* tos */, nil /* owner */, noChecksum); err != nil {
|
||||
return 0, fmt.Errorf("%s", err)
|
||||
}
|
||||
return data.Size(), nil
|
||||
}
|
||||
|
||||
// sendUDP sends a UDP segment via the provided network endpoint and under the
|
||||
// provided identity.
|
||||
func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, noChecksum bool) (int, error) {
|
||||
// Allocate a buffer for the UDP header.
|
||||
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||
ReserveHeaderBytes: header.UDPMinimumSize + int(r.MaxHeaderLength()),
|
||||
Data: data,
|
||||
})
|
||||
|
||||
// Initialize the UDP header.
|
||||
udpHdr := header.UDP(pkt.TransportHeader().Push(header.UDPMinimumSize))
|
||||
pkt.TransportProtocolNumber = udp.ProtocolNumber
|
||||
|
||||
length := uint16(pkt.Size())
|
||||
udpHdr.Encode(&header.UDPFields{
|
||||
SrcPort: localPort,
|
||||
DstPort: remotePort,
|
||||
Length: length,
|
||||
})
|
||||
|
||||
// Set the checksum field unless TX checksum offload is enabled.
|
||||
// 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.RequiresTXTransportChecksum() &&
|
||||
(!noChecksum || r.NetProto == header.IPv6ProtocolNumber) {
|
||||
xsum := r.PseudoHeaderChecksum(udp.ProtocolNumber, length)
|
||||
for _, v := range data.Views() {
|
||||
xsum = header.Checksum(v, xsum)
|
||||
}
|
||||
udpHdr.SetChecksum(^udpHdr.CalculateChecksum(xsum))
|
||||
}
|
||||
|
||||
ttl := r.DefaultTTL()
|
||||
if err := r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{
|
||||
Protocol: udp.ProtocolNumber,
|
||||
TTL: ttl,
|
||||
TOS: 0, /* default */
|
||||
}, pkt); err != nil {
|
||||
r.Stats().UDP.PacketSendErrors.Increment()
|
||||
return 0, fmt.Errorf("%s", err)
|
||||
}
|
||||
|
||||
// Track count of packets sent.
|
||||
r.Stats().UDP.PacketsSent.Increment()
|
||||
return data.Size(), nil
|
||||
}
|
||||
//
|
||||
//go:linkname sendUDP gvisor.dev/gvisor/pkg/tcpip/transport/udp.sendUDP
|
||||
func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, ttl uint8, useDefaultTTL bool, tos uint8, owner tcpip.PacketOwner, noChecksum bool) *tcpip.Error
|
||||
|
||||
// verifyChecksum verifies the checksum unless RX checksum offload is enabled.
|
||||
// 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(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)
|
||||
}
|
||||
return hdr.CalculateChecksum(xsum) == 0xffff
|
||||
}
|
||||
return true
|
||||
}
|
||||
//
|
||||
//go:linkname verifyChecksum gvisor.dev/gvisor/pkg/tcpip/transport/udp.verifyChecksum
|
||||
func verifyChecksum(hdr header.UDP, pkt *stack.PacketBuffer) bool
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
package dev
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
|
||||
"github.com/xjasonlyu/tun2socks/internal/dev/tun"
|
||||
)
|
||||
|
||||
const defaultScheme = "tun"
|
||||
|
||||
type Device struct {
|
||||
url *url.URL
|
||||
io.Closer
|
||||
stack.LinkEndpoint
|
||||
}
|
||||
|
||||
func Open(deviceURL string) (device *Device, err error) {
|
||||
if !strings.Contains(deviceURL, "://") {
|
||||
deviceURL = defaultScheme + "://" + deviceURL
|
||||
}
|
||||
|
||||
var u *url.URL
|
||||
if u, err = url.Parse(deviceURL); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
ep stack.LinkEndpoint
|
||||
c io.Closer
|
||||
)
|
||||
switch strings.ToLower(u.Scheme) {
|
||||
case "tun":
|
||||
name := u.Host
|
||||
ep, c, err = tun.Open(name)
|
||||
default:
|
||||
err = errors.New("unsupported device type")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
device = &Device{
|
||||
url: u,
|
||||
Closer: c,
|
||||
LinkEndpoint: ep,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Close closes device.
|
||||
func (d *Device) Close() error {
|
||||
return d.Closer.Close()
|
||||
}
|
||||
|
||||
// Name returns name of device.
|
||||
func (d *Device) Name() string {
|
||||
return d.url.Host
|
||||
}
|
||||
|
||||
// Type returns type of device.
|
||||
func (d *Device) Type() string {
|
||||
return strings.ToLower(d.url.Scheme)
|
||||
}
|
||||
|
||||
// String returns full URL string.
|
||||
func (d *Device) String() string {
|
||||
return d.url.String()
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// +build !darwin,!linux
|
||||
|
||||
package tun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
func Open(_ string) (stack.LinkEndpoint, io.Closer, error) {
|
||||
return nil, nil, fmt.Errorf("operation was not supported on %s", runtime.GOOS)
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/songgao/water"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
|
||||
"github.com/xjasonlyu/tun2socks/pkg/link/rwc"
|
||||
)
|
||||
|
||||
func Open(name string) (ep stack.LinkEndpoint, c io.Closer, err error) {
|
||||
config := water.Config{
|
||||
DeviceType: water.TUN,
|
||||
}
|
||||
config.Name = name
|
||||
|
||||
var ifce *water.Interface
|
||||
ifce, err = water.New(config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var mtu uint32
|
||||
mtu, err = getMTU(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ep, err = rwc.New(ifce, mtu)
|
||||
c = ifce
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getMTU(name string) (uint32, error) {
|
||||
// open datagram socket
|
||||
fd, err := syscall.Socket(
|
||||
syscall.AF_INET,
|
||||
syscall.SOCK_DGRAM,
|
||||
0,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
defer syscall.Close(fd)
|
||||
|
||||
// do ioctl call
|
||||
var ifr struct {
|
||||
name [16]byte
|
||||
mtu uint32
|
||||
}
|
||||
copy(ifr.name[:], name)
|
||||
|
||||
_, _, errno := syscall.Syscall(
|
||||
syscall.SYS_IOCTL,
|
||||
uintptr(fd),
|
||||
uintptr(syscall.SIOCGIFMTU),
|
||||
uintptr(unsafe.Pointer(&ifr)),
|
||||
)
|
||||
if errno != 0 {
|
||||
return 0, fmt.Errorf("get MTU on %s: %s", name, errno.Error())
|
||||
}
|
||||
|
||||
return ifr.mtu, nil
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"io"
|
||||
"syscall"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/fdbased"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/rawfile"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/tun"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
type closeFunc func() error
|
||||
|
||||
func (f closeFunc) Close() error {
|
||||
return f()
|
||||
}
|
||||
|
||||
func Open(name string) (ep stack.LinkEndpoint, c io.Closer, err error) {
|
||||
var fd int
|
||||
fd, err = tun.Open(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var mtu uint32
|
||||
mtu, err = rawfile.GetMTU(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ep, err = fdbased.New(&fdbased.Options{
|
||||
FDs: []int{fd},
|
||||
MTU: mtu,
|
||||
EthernetHeader: false,
|
||||
})
|
||||
|
||||
c = closeFunc(func() error {
|
||||
return syscall.Close(fd)
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
@@ -4,9 +4,15 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/xjasonlyu/clash/component/dialer"
|
||||
"github.com/xjasonlyu/clash/component/resolver"
|
||||
)
|
||||
|
||||
func init() { /* use bound dialer to resolve DNS */
|
||||
func init() {
|
||||
|
||||
// enable ipv6
|
||||
resolver.DisableIPv6 = false
|
||||
|
||||
// use bound dialer to resolve DNS
|
||||
net.DefaultResolver.PreferGo = true
|
||||
net.DefaultResolver.Dial = dialer.DialContext
|
||||
}
|
||||
|
||||
@@ -31,7 +31,10 @@ func Start(dnsURL string, rawHosts []string) error {
|
||||
return errors.New("unsupported scheme")
|
||||
}
|
||||
|
||||
var serverAddr = u.Host
|
||||
serverAddr := u.Host
|
||||
if serverAddr == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
fakeIPRange := u.Query().Get("fake-ip-range")
|
||||
if fakeIPRange == "" {
|
||||
|
||||
@@ -92,7 +92,7 @@ func (ss *Socks5) DialUDP(_ *adapter.Metadata) (_ net.PacketConn, err error) {
|
||||
// zeros. RFC1928
|
||||
var targetAddr socks5.Addr = []byte{socks5.AtypIPv4, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
bindAddr, err := socks5.ClientHandshake(c, targetAddr, socks5.CmdUDPAssociate, user)
|
||||
addr, err := socks5.ClientHandshake(c, targetAddr, socks5.CmdUDPAssociate, user)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("client hanshake: %w", err)
|
||||
}
|
||||
@@ -110,7 +110,17 @@ func (ss *Socks5) DialUDP(_ *adapter.Metadata) (_ net.PacketConn, err error) {
|
||||
pc.Close()
|
||||
}()
|
||||
|
||||
return &socksPacketConn{PacketConn: pc, rAddr: bindAddr.UDPAddr(), tcpConn: c}, nil
|
||||
bindAddr := addr.UDPAddr()
|
||||
if bindAddr.IP.IsUnspecified() {
|
||||
udpAddr, err := resolveUDPAddr("udp", ss.Addr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bindAddr.IP = udpAddr.IP
|
||||
}
|
||||
|
||||
return &socksPacketConn{PacketConn: pc, rAddr: bindAddr, tcpConn: c}, nil
|
||||
}
|
||||
|
||||
type socksPacketConn struct {
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
|
||||
const (
|
||||
udpTimeout = 30 * time.Second
|
||||
udpBufferSize = 64 << 10 // KiB
|
||||
udpBufferSize = (1 << 16) - 1 // largest possible UDP datagram
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -162,8 +162,7 @@ func (e *Endpoint) Wait() {
|
||||
e.wg.Wait()
|
||||
}
|
||||
|
||||
// Close closes io.ReadWriteCloser and set closed to true.
|
||||
// Close closes io.ReadWriteCloser.
|
||||
func (e *Endpoint) Close() error {
|
||||
e.rwc.Close()
|
||||
return nil
|
||||
return e.rwc.Close()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
const defaultScheme = "tun"
|
||||
|
||||
type Device interface {
|
||||
stack.LinkEndpoint
|
||||
|
||||
Name() string // returns the current name
|
||||
Close() error // stops and closes the tun
|
||||
}
|
||||
|
||||
// Open opens TUN Device with given URL.
|
||||
func Open(rawURL string) (Device, error) {
|
||||
if !strings.Contains(rawURL, "://") {
|
||||
rawURL = defaultScheme + "://" + rawURL
|
||||
}
|
||||
|
||||
var u *url.URL
|
||||
u, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if strings.ToLower(u.Scheme) != defaultScheme {
|
||||
return nil, errors.New("unsupported TUN scheme")
|
||||
}
|
||||
|
||||
var n uint64
|
||||
if mtu := u.Query().Get("mtu"); mtu != "" {
|
||||
n, _ = strconv.ParseUint(mtu, 10, 32)
|
||||
}
|
||||
|
||||
name := u.Host
|
||||
return CreateTUN(name, uint32(n))
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// +build !darwin,!freebsd,!linux,!openbsd
|
||||
|
||||
package tun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func CreateTUN(_ string, _ uint32) (Device, error) {
|
||||
return nil, fmt.Errorf("operation was not supported on %s", runtime.GOOS)
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/fdbased"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/rawfile"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/tun"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
type linuxTun struct {
|
||||
stack.LinkEndpoint
|
||||
|
||||
tunName string
|
||||
tunFile *os.File
|
||||
}
|
||||
|
||||
func CreateTUN(name string, n uint32) (Device, error) {
|
||||
fd, err := tun.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if n > 0 {
|
||||
if err := setMTU(name, n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var mtu uint32
|
||||
if mtu, err = rawfile.GetMTU(name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ep stack.LinkEndpoint
|
||||
if ep, err = fdbased.New(&fdbased.Options{
|
||||
FDs: []int{fd},
|
||||
MTU: mtu,
|
||||
// TUN only
|
||||
EthernetHeader: false,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &linuxTun{
|
||||
LinkEndpoint: ep,
|
||||
tunName: name,
|
||||
tunFile: os.NewFile(uintptr(fd), "tun"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *linuxTun) Name() string {
|
||||
return t.tunName
|
||||
}
|
||||
|
||||
func (t *linuxTun) Close() error {
|
||||
return t.tunFile.Close()
|
||||
}
|
||||
|
||||
func setMTU(name string, n uint32) error {
|
||||
// open datagram socket
|
||||
fd, err := unix.Socket(
|
||||
unix.AF_INET,
|
||||
unix.SOCK_DGRAM,
|
||||
0,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer unix.Close(fd)
|
||||
|
||||
const ifReqSize = unix.IFNAMSIZ + 64
|
||||
|
||||
// do ioctl call
|
||||
var ifr [ifReqSize]byte
|
||||
copy(ifr[:], name)
|
||||
*(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = n
|
||||
_, _, errno := unix.Syscall(
|
||||
unix.SYS_IOCTL,
|
||||
uintptr(fd),
|
||||
uintptr(unix.SIOCSIFMTU),
|
||||
uintptr(unsafe.Pointer(&ifr[0])),
|
||||
)
|
||||
|
||||
if errno != 0 {
|
||||
return errors.New("failed to set MTU of TUN device")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// +build darwin freebsd openbsd
|
||||
|
||||
package tun
|
||||
|
||||
import (
|
||||
"golang.zx2c4.com/wireguard/tun"
|
||||
|
||||
"github.com/xjasonlyu/clash/common/pool"
|
||||
"github.com/xjasonlyu/tun2socks/pkg/link/rwc"
|
||||
)
|
||||
|
||||
const offset = 4
|
||||
|
||||
type unixTun struct {
|
||||
*rwc.Endpoint
|
||||
|
||||
device tun.Device
|
||||
}
|
||||
|
||||
func CreateTUN(name string, n uint32) (Device, error) {
|
||||
device, err := tun.CreateTUN(name, int(n))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mtu, err := device.MTU()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ut := &unixTun{
|
||||
device: device,
|
||||
}
|
||||
|
||||
if ut.Endpoint, err = rwc.New(ut, uint32(mtu)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ut, nil
|
||||
}
|
||||
|
||||
func (t *unixTun) Read(packet []byte) (n int, err error) {
|
||||
buf := pool.Get(offset + len(packet))
|
||||
defer pool.Put(buf)
|
||||
|
||||
if n, err = t.device.Read(buf, offset); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
copy(packet, buf[offset:offset+n])
|
||||
return
|
||||
}
|
||||
|
||||
func (t *unixTun) Write(packet []byte) (int, error) {
|
||||
buf := pool.Get(offset + len(packet))
|
||||
defer pool.Put(buf)
|
||||
|
||||
copy(buf[offset:], packet)
|
||||
return t.device.Write(buf[:offset+len(packet)], offset)
|
||||
}
|
||||
|
||||
func (t *unixTun) Name() string {
|
||||
name, _ := t.device.Name()
|
||||
return name
|
||||
}
|
||||
|
||||
func (t *unixTun) Close() error {
|
||||
return t.device.Close()
|
||||
}
|
||||
@@ -30,7 +30,7 @@ config_route() {
|
||||
# clone main route
|
||||
ip route show table main |
|
||||
while read -r route; do
|
||||
ip route add $route table "$TABLE"
|
||||
ip route add ${route%linkdown*} table "$TABLE"
|
||||
done
|
||||
|
||||
# config default route
|
||||
|
||||
Reference in New Issue
Block a user