Compare commits

...
69 Commits
Author SHA1 Message Date
xjasonlyu b95e2794b3 Chore: comment text 2021-05-13 14:06:07 +08:00
xjasonlyu 70afaf3d55 Fix(stack): update udp transport 2021-05-13 13:29:26 +08:00
xjasonlyu b51ad6feb1 Fix(rwbased): endpoint interface 2021-05-13 13:13:22 +08:00
xjasonlyu 9618b7a7b8 Chore: update go modules
use original gvisor tcpip stack.
2021-05-13 13:10:32 +08:00
xjasonlyu 60021cc0ef Chore: update discussions 2021-05-05 13:40:41 +08:00
xjasonlyu 293fab7635 Chore: update README_ZH 2021-05-05 13:20:33 +08:00
Jason LyuandGitHub 1c4e782314 Update issue templates 2021-05-05 13:01:17 +08:00
xjasonlyu 66710aa203 Fix: panics with invalid ss url (https://github.com/xjasonlyu/tun2socks/issues/49) 2021-05-05 11:59:47 +08:00
xjasonlyu 3f7fdc1d83 Fix: atomic operation panic
This reverts commit 094199656b.
2021-03-22 13:04:49 +08:00
xjasonlyu 1bd8029562 Optimize: use gvisor tun for linux 2021-03-21 21:13:07 +08:00
xjasonlyu a1847d7153 Fix: udp for gvisor stack 2021-03-21 20:57:18 +08:00
xjasonlyu 36144e7484 Chore: update dependencies 2021-03-21 20:44:57 +08:00
xjasonlyu 094199656b Chore: make set operation atomic 2021-03-13 11:50:14 +08:00
xjasonlyu f41b844e43 Chore: minor changes in actions 2021-03-03 12:56:02 +08:00
xjasonlyu 688d74a407 Chore: add more info to socks5 2021-03-03 12:46:31 +08:00
xjasonlyu 1b2dddff31 Chore: update dependencies 2021-03-02 23:25:52 +08:00
xjasonlyu 82ac59b0f2 Fix: invalid argument when set MTU (https://github.com/xjasonlyu/tun2socks/issues/33) 2021-03-01 21:37:46 +08:00
xjasonlyu 6887c1180e Chore: add udp-timeout option to docker image 2021-02-28 14:16:23 +08:00
xjasonlyu 9502706ed9 Feature: add an option to set udp timeout 2021-02-26 14:22:16 +08:00
xjasonlyu ec4d98c4bf Fix: reset udp timeout after sending 2021-02-26 09:50:34 +08:00
xjasonlyu ee932ff16c Chore: update static check command 2021-02-22 14:16:39 +08:00
xjasonlyu a8fdfe537d Chore: update dependencies 2021-02-22 12:39:47 +08:00
xjasonlyu ac07d3d6fd Feature: add 32bit support 2021-02-17 17:42:06 +08:00
xjasonlyu d5d4b17256 Fix: dirty commit string 2021-02-17 17:02:15 +08:00
xjasonlyu 4531a74a20 Feature: add darwin-arm64 support (https://github.com/xjasonlyu/tun2socks/issues/29) 2021-02-17 16:12:01 +08:00
xjasonlyu b15f93225b Chore: bump to go1.16 2021-02-17 16:10:11 +08:00
xjasonlyu edf76afd11 Chore: tidy Dockerfile 2021-02-17 13:32:39 +08:00
xjasonlyu bb702f57d8 Feature: add linux-s390x 2021-02-15 20:18:33 +08:00
xjasonlyu b5980dd79d Chore: update README 2021-02-14 20:46:08 +08:00
xjasonlyu 2fee5a6d55 Chore: update dependencies 2021-02-14 20:41:50 +08:00
xjasonlyu b2b7e8bc46 Chore(tun): minor changes 2021-02-14 20:38:26 +08:00
xjasonlyu 0e1e04acc7 Fix: avoid extra copy on windows 2021-02-14 20:25:04 +08:00
xjasonlyu 361a8133c9 Chore: spaces to tab 2021-02-14 17:33:12 +08:00
xjasonlyu 3f73becd66 Fix: ignore static check 2021-02-14 15:50:44 +08:00
xjasonlyu 14b905c125 Feature: full 64bit support 2021-02-14 15:45:42 +08:00
xjasonlyu 4294f56125 Chore: use gVisor 20210213011838-e7ae604b523e 2021-02-14 11:44:54 +08:00
xjasonlyu d98e2234d9 Chore: always use zip to release 2021-02-14 11:21:36 +08:00
xjasonlyu 43b8dd885d Chore: udp timeout => 60s 2021-02-13 13:18:30 +08:00
xjasonlyu 3e3990ef8d Chore: update README 2021-02-12 14:41:33 +08:00
xjasonlyu 88e9402793 Chore: go workflow ignore docker 2021-02-11 22:26:59 +08:00
xjasonlyu f0129eb7ca Chore: optimize docker/entrypoint.sh 2021-02-11 18:51:05 +08:00
xjasonlyu fe9be45844 Chore: tidy go.sum 2021-02-11 16:56:20 +08:00
xjasonlyu b54d9936f9 Chore: unexported globals with _
Use uber’s go style.
2021-02-11 16:10:40 +08:00
xjasonlyu 7e6a9b6a09 Chore: add a comment to dialer 2021-02-11 16:04:20 +08:00
xjasonlyu 454ea0a49b Fix(log): default level may race
Rename global variables in uber’s style.
2021-02-11 15:56:45 +08:00
xjasonlyu 04d0e1e9a7 Chore: move to wiki 2021-02-11 14:19:37 +08:00
xjasonlyu e849c9a451 Fix(stack/udp): shadow variables 2021-02-11 14:01:36 +08:00
xjasonlyu c28690bfc9 Fix: deprecate metadata.Valid method 2021-02-11 13:55:53 +08:00
xjasonlyu 7955052b01 Chore: adjust version output format 2021-02-11 13:40:01 +08:00
xjasonlyu 7e55b71b30 Fix: replace pflag with flag
pflag was deprecated due to poor maintenance
2021-02-11 13:06:12 +08:00
xjasonlyu c96c5946c8 Fix: /proc/sys permission in docker 2021-02-10 20:21:22 +08:00
xjasonlyu 708b7b234d Chore: update README 2021-02-10 16:55:31 +08:00
xjasonlyu 96e0c8c390 Chore: adapt fwmark option 2021-02-10 16:40:36 +08:00
xjasonlyu 7f7f2913a8 Feature: add fwmark support 2021-02-10 15:46:55 +08:00
xjasonlyu ea62deb0b6 Refactor: rewrite engine 2021-02-10 13:11:11 +08:00
xjasonlyu 34fb632f38 Chore: trim spaces 2021-02-09 14:16:55 +08:00
xjasonlyu 08f236a01c Fix: lost stack log info 2021-02-08 20:23:02 +08:00
xjasonlyu ae77a8a009 Refactor: autonomize core package 2021-02-08 20:04:51 +08:00
xjasonlyu 203e545241 Chore: update README 2021-02-08 18:55:58 +08:00
xjasonlyu 136c90d310 Chore: ignore all .md files 2021-02-08 18:32:05 +08:00
xjasonlyu 06a7cf6718 Chore: use gVisor 20210207054208-21036aed5e58 2021-02-08 16:03:16 +08:00
xjasonlyu ab59724d87 Chore: rewrite README 2021-02-08 14:55:09 +08:00
xjasonlyu 50bed22076 Chore: Makefile rename docker -> tun2socks 2021-02-08 14:35:58 +08:00
xjasonlyu 849f47baf7 Chore: decrease maxUDPQueueSize 2021-02-07 20:43:55 +08:00
xjasonlyu ace24826d2 Chore: move stack & device to core 2021-02-07 18:49:55 +08:00
xjasonlyu 669a601f1a Chore: move stack & device to component 2021-02-07 18:45:52 +08:00
xjasonlyu 103009cb1d Chore: add stack field to Engine 2021-02-07 18:38:19 +08:00
xjasonlyu ea1832adaa Chore: cleanup Makefile 2021-02-07 18:24:01 +08:00
xjasonlyu cf4ac9b207 Refactor(proxy): use proto sub package 2021-02-07 18:22:00 +08:00
69 changed files with 938 additions and 931 deletions
+1 -1
View File
@@ -2,5 +2,5 @@
.gitignore
# Other
bin/*
build/*
docs/*
+33
View File
@@ -0,0 +1,33 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Environment**
- OS: [e.g. `Ubuntu-20.04`]
- Version: [e.g. `v2.1.0`]
- Network: [e.g. route tables, iptables rules]
**Log**
Paste the tun2socks log below with the log level set to `DEBUG`.
```
```
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. [First Step]
2. [Second Step]
3. ……
**Expected behavior**
A clear and concise description of what you expected to happen.
**Additional context**
Add any other context about the problem here.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem?**
A clear and concise description of what the problem is.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+3 -3
View File
@@ -8,7 +8,7 @@ on:
- '*'
paths-ignore:
- 'docs/**'
- 'README.md'
- '**.md'
jobs:
@@ -51,7 +51,7 @@ jobs:
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm/v7,linux/arm64
tags: |
xjasonlyu/tun2socks:dev
ghcr.io/xjasonlyu/tun2socks:dev
@@ -67,7 +67,7 @@ jobs:
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm/v7,linux/arm64
tags: |
xjasonlyu/tun2socks:latest
xjasonlyu/tun2socks:${{ steps.shell.outputs.version }}
+6 -5
View File
@@ -9,7 +9,8 @@ on:
- '*'
paths-ignore:
- 'docs/**'
- 'README.md'
- 'docker/**'
- '**.md'
jobs:
build:
@@ -19,7 +20,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.15.x
go-version: 1.16.x
- name: Check out code into the Go module directory
uses: actions/checkout@v2
@@ -38,7 +39,7 @@ jobs:
run: |
go test ./...
go vet ./...
go get -u honnef.co/go/tools/cmd/staticcheck
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck -- $(go list ./...)
- name: Build
@@ -51,6 +52,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: bin/*
files: build/*
draft: true
prerelease: true
prerelease: false
+1 -1
View File
@@ -4,7 +4,7 @@
*.dll
*.so
*.dylib
bin/
build/
# IDE
.idea/
+5 -7
View File
@@ -4,9 +4,8 @@ WORKDIR /tun2socks-src
COPY . /tun2socks-src
RUN apk add --no-cache make git \
&& go mod download \
&& make docker \
&& mv ./bin/tun2socks-docker /tun2socks
&& make tun2socks \
&& mv ./build/tun2socks /tun2socks
FROM alpine:latest
LABEL org.opencontainers.image.source="https://github.com/xjasonlyu/tun2socks"
@@ -18,14 +17,13 @@ RUN apk add --update --no-cache iptables iproute2 \
&& chmod +x /entrypoint.sh
ENV TUN=tun0
ENV ETH=eth0
ENV TUN_ADDR=198.18.0.1
ENV TUN_MASK=255.254.0.0
ENV LOGLEVEL=INFO
ENV ADDR=198.18.0.1/15
ENV LOGLEVEL=info
ENV PROXY=direct://
ENV MTU=9000
ENV STATS=
ENV TOKEN=
ENV UDP_TIMEOUT=
ENV EXTRA_COMMANDS=
ENV TUN_INCLUDED_ROUTES=
ENV TUN_EXCLUDED_ROUTES=
+107 -32
View File
@@ -1,72 +1,147 @@
BINDIR = "bin"
NAME = "tun2socks"
BINARY := tun2socks
MODULE := github.com/xjasonlyu/tun2socks
TAGS = ""
BUILD_FLAGS = "-v"
BUILD_DIR := build
BUILD_TAGS :=
BUILD_FLAGS := -v
BUILD_COMMIT := $(shell git rev-parse --short HEAD)
BUILD_VERSION := $(shell git describe --abbrev=0 --tags HEAD)
VERSION = $(shell git describe --tags || echo "unknown version")
BUILD_TIME = $(shell date -u '+%FT%TZ')
CGO_ENABLED := 0
GO111MODULE := on
LDFLAGS += -w -s -buildid=
LDFLAGS += -X "github.com/xjasonlyu/tun2socks/constant.Version=$(VERSION)"
LDFLAGS += -X "github.com/xjasonlyu/tun2socks/constant.BuildTime=$(BUILD_TIME)" # RFC3339
GO_BUILD = GO111MODULE=on CGO_ENABLED=0 go build $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' -trimpath
LDFLAGS += -X "$(MODULE)/constant.Version=$(BUILD_VERSION)"
LDFLAGS += -X "$(MODULE)/constant.GitCommit=$(BUILD_COMMIT)"
PLATFORM_LIST = \
GO_BUILD = GO111MODULE=$(GO111MODULE) CGO_ENABLED=$(CGO_ENABLED) \
go build $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' -trimpath
UNIX_ARCH_LIST = \
darwin-amd64 \
darwin-arm64 \
freebsd-386 \
freebsd-amd64 \
freebsd-arm64 \
linux-386 \
linux-amd64 \
linux-arm64 \
linux-armv5 \
linux-armv6 \
linux-armv7 \
linux-mips-softfloat \
linux-mips-hardfloat \
linux-mipsle-softfloat \
linux-mipsle-hardfloat \
linux-mips64 \
linux-mips64le \
linux-ppc64 \
linux-ppc64le \
linux-s390x \
openbsd-386 \
openbsd-amd64 \
openbsd-arm64 \
openbsd-arm64
WINDOWS_ARCH_LIST = \
windows-386 \
windows-amd64 \
windows-arm32v7
all: linux-amd64 darwin-amd64 windows-amd64
.PHONY: docker
docker:
$(GO_BUILD) -o $(BINDIR)/$(NAME)-$@
tun2socks:
$(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)
darwin-amd64:
GOARCH=amd64 GOOS=darwin $(GO_BUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=amd64 GOOS=darwin $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
darwin-arm64:
GOARCH=arm64 GOOS=darwin $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
freebsd-386:
GOARCH=386 GOOS=freebsd $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
freebsd-amd64:
GOARCH=amd64 GOOS=freebsd $(GO_BUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=amd64 GOOS=freebsd $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
freebsd-arm64:
GOARCH=arm64 GOOS=freebsd $(GO_BUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=arm64 GOOS=freebsd $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-386:
GOARCH=386 GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-amd64:
GOARCH=amd64 GOOS=linux $(GO_BUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=amd64 GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-arm64:
GOARCH=arm64 GOOS=linux $(GO_BUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=arm64 GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-armv5:
GOARCH=arm GOARM=5 GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-armv6:
GOARCH=arm GOARM=6 GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-armv7:
GOARCH=arm GOARM=7 GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-mips-softfloat:
GOARCH=mips GOMIPS=softfloat GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-mips-hardfloat:
GOARCH=mips GOMIPS=hardfloat GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-mipsle-softfloat:
GOARCH=mipsle GOMIPS=softfloat GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-mipsle-hardfloat:
GOARCH=mipsle GOMIPS=hardfloat GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-mips64:
GOARCH=mips64 GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-mips64le:
GOARCH=mips64le GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-ppc64:
GOARCH=ppc64 GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-ppc64le:
GOARCH=ppc64le GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
linux-s390x:
GOARCH=s390x GOOS=linux $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
openbsd-386:
GOARCH=386 GOOS=openbsd $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
openbsd-amd64:
GOARCH=amd64 GOOS=openbsd $(GO_BUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=amd64 GOOS=openbsd $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
openbsd-arm64:
GOARCH=arm64 GOOS=openbsd $(GO_BUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=arm64 GOOS=openbsd $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@
windows-386:
GOARCH=386 GOOS=windows $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@.exe
windows-amd64:
GOARCH=amd64 GOOS=windows $(GO_BUILD) -o $(BINDIR)/$(NAME)-$@.exe
GOARCH=amd64 GOOS=windows $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@.exe
gz_releases=$(addsuffix .gz, $(PLATFORM_LIST))
zip_releases=$(addsuffix .zip, $(WINDOWS_ARCH_LIST))
windows-arm32v7:
GOARCH=arm GOARM=7 GOOS=windows $(GO_BUILD) -o $(BUILD_DIR)/$(BINARY)-$@.exe
$(gz_releases): %.gz : %
chmod +x $(BINDIR)/$(NAME)-$(basename $@)
gzip -f -S .gz $(BINDIR)/$(NAME)-$(basename $@)
unix_releases := $(addsuffix .zip, $(UNIX_ARCH_LIST))
windows_releases := $(addsuffix .zip, $(WINDOWS_ARCH_LIST))
$(zip_releases): %.zip : %
zip -m -j $(BINDIR)/$(NAME)-$(basename $@).zip $(BINDIR)/$(NAME)-$(basename $@).exe
$(unix_releases): %.zip: %
@zip -qmj $(BUILD_DIR)/$(BINARY)-$(basename $@).zip $(BUILD_DIR)/$(BINARY)-$(basename $@)
all-arch: $(PLATFORM_LIST) $(WINDOWS_ARCH_LIST)
$(windows_releases): %.zip: %
@zip -qmj $(BUILD_DIR)/$(BINARY)-$(basename $@).zip $(BUILD_DIR)/$(BINARY)-$(basename $@).exe
releases: $(gz_releases) $(zip_releases)
all-arch: $(UNIX_ARCH_LIST) $(WINDOWS_ARCH_LIST)
releases: $(unix_releases) $(windows_releases)
clean:
rm $(BINDIR)/*
rm -rf $(BUILD_DIR)
+33 -271
View File
@@ -1,291 +1,53 @@
<h1 align="center">tun2socks</h1>
<h3 align="center">A tun2socks powered by gVisor TCP/IP stack.</h3>
![tun2socks](docs/logo.png)
<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>
[![GitHub Workflow][1]](https://github.com/xjasonlyu/tun2socks/actions)
[![Go Version][2]](https://github.com/xjasonlyu/tun2socks/blob/main/go.mod)
[![Go Report][3]](https://goreportcard.com/badge/github.com/xjasonlyu/tun2socks)
[![GitHub License][4]](https://github.com/xjasonlyu/tun2socks/blob/main/LICENSE)
[![Releases][5]](https://github.com/xjasonlyu/tun2socks/releases)
[1]: https://img.shields.io/github/workflow/status/xjasonlyu/tun2socks/Go?style=flat-square
[2]: https://img.shields.io/github/go-mod/go-version/xjasonlyu/tun2socks/main?style=flat-square
[3]: https://goreportcard.com/badge/github.com/xjasonlyu/tun2socks?style=flat-square
[4]: https://img.shields.io/github/license/xjasonlyu/tun2socks?style=flat-square
[5]: https://img.shields.io/github/v/release/xjasonlyu/tun2socks?include_prereleases&style=flat-square
English | [简体中文](README_ZH.md)
## Features
- ICMP echoing
- IPv6 support
- Optimized UDP transmission for game acceleration
- 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))
- **Fully support:** IPv4/IPv6/ICMP/TCP/UDP
- **Proxy protocol:** Socks5/Shadowsocks
- **Game ready:** optimized UDP transmission
- **Pure Go:** no CGO required, stability improved
- **Router mode:** forwarding packets in LAN
- **TCP/IP stack:** powered by **[gVisor](https://github.com/google/gvisor)**
- **High performance:** >2.5Gbps throughput
## Requirements
| Target | Minimum | Recommended |
| :----- | :-----: | :---------: |
| System | linux darwin freebsd openbsd | linux |
| System | Linux MacOS Freebsd OpenBSD Windows | Linux or MacOS |
| Memory | >20MB | >128MB |
| CPU | amd64 arm64 | amd64 |
| CPU | ANY | AMD64 or ARM64 |
## Performance
## Documentation
> iPerf3 tested on Debian 10 with i5-10500, 8G RAM
Documentations and quick start guides can be found at [Github Wiki](https://github.com/xjasonlyu/tun2socks/wiki).
## How to Build
## Community
### build from source code
Go compiler version >= 1.15 is required
```text
$ git clone https://github.com/xjasonlyu/tun2socks.git
$ cd tun2socks
$ make
```
### build docker image
```text
$ docker build -t tun2socks .
```
or
```text
$ docker build -t tun2socks -f .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 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>
> 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
Usage of tun2socks:
-d, --device string Use this device [driver://]name
-i, --interface string Use network INTERFACE (Darwin/Linux only)
-l, --loglevel string Log level [debug|info|warn|error|silent] (default "info")
-m, --mtu int Maximum transmission unit
-p, --proxy string Use this proxy [protocol://]host[:port]
--stats string HTTP statistic server listen address
--token string HTTP statistic server auth token
-v, --version Show version information and quit
```
</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>
Welcome and feel free to ask any questions at [Github Discussions](https://github.com/xjasonlyu/tun2socks/discussions).
## Credits
- [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)
- [Dreamacro/clash](https://github.com/Dreamacro/clash) - A rule-based tunnel in Go
- [google/gvisor](https://github.com/google/gvisor) - Application Kernel for Containers
- [wireguard-go](https://git.zx2c4.com/wireguard-go) - Go Implementation of WireGuard
## Known Issues
## License
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).
[GPL-3.0](https://github.com/xjasonlyu/tun2socks/blob/main/LICENSE)
## TODO
- [x] Windows support
- [x] FreeBSD support
- [x] OpenBSD support
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fxjasonlyu%2Ftun2socks.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fxjasonlyu%2Ftun2socks?ref=badge_large)
+68
View File
@@ -0,0 +1,68 @@
![tun2socks](docs/logo.png)
[![GitHub Workflow][1]](https://github.com/xjasonlyu/tun2socks/actions)
[![Go Version][2]](https://github.com/xjasonlyu/tun2socks/blob/main/go.mod)
[![Go Report][3]](https://goreportcard.com/badge/github.com/xjasonlyu/tun2socks)
[![GitHub License][4]](https://github.com/xjasonlyu/tun2socks/blob/main/LICENSE)
[![Releases][5]](https://github.com/xjasonlyu/tun2socks/releases)
[1]: https://img.shields.io/github/workflow/status/xjasonlyu/tun2socks/Go?style=flat-square
[2]: https://img.shields.io/github/go-mod/go-version/xjasonlyu/tun2socks/main?style=flat-square
[3]: https://goreportcard.com/badge/github.com/xjasonlyu/tun2socks?style=flat-square
[4]: https://img.shields.io/github/license/xjasonlyu/tun2socks?style=flat-square
[5]: https://img.shields.io/github/v/release/xjasonlyu/tun2socks?include_prereleases&style=flat-square
[English](README.md) | 简体中文
## 为什么使用 tun2socks
通过在主机上运行`tun2socks`,可以轻松地接管所有的`TCP/UDP`流量,同时提供诸多专业的功能特性,这包括:
- 强制使不支持代理的程序走代理
- 配合Clash、V2Ray等工具实现全局代理上网
- 配合Burp、Charles等工具进行应用层数据的调试
- 配合DHCP、CoreDNS等工具部署路由模式代理局域网流量
## 特性介绍
- **全面支持:** IPv4/IPv6/ICMP/TCP/UDP
- **代理协议:** Socks5/Shadowsocks
- **游戏加速:** 针对UDP传输的优化
- **纯Go实现:** 无需CGO,稳定性提升
- **路由模式:** 转发代理局域网内所有流量
- **TCP/IP栈:** 由 **[gVisor](https://github.com/google/gvisor)** 强力驱动
- **高性能:** >2.5Gbps 的带宽吞吐量
## 硬件需求
| 目标 | 最小 | 建议 |
| :--- | :---: | :---: |
| 系统 | Linux MacOS Freebsd OpenBSD Windows | Linux or MacOS |
| 内存 | >20MB | >128MB |
| 架构 | ANY | AMD64 or ARM64 |
## 使用文档
文档以及使用方式,请看 [Github Wiki](https://github.com/xjasonlyu/tun2socks/wiki)。
## 交流讨论
欢迎来讨论区交流提问,[Github Discussions](https://github.com/xjasonlyu/tun2socks/discussions)。
## 注意事项
1. 由于采用了纯Go实现,所以这一版本的`tun2socks`在有大量连接时内存消耗通常较多。如果您的需求对内存消耗极为敏感,请继续使用 [v1](https://github.com/xjasonlyu/tun2socks/tree/v1) 版本。
2. `tun2socks`只应该专注于将网络层的TCP/UDP流量转发给SOCKS服务器,其他的如DNS(DoH)、DHCP等模块功能应该交由第三方应用实现,所以弃用了DNS模块。
3. 因为是通过用户空间的网络栈接管所有流量并处理转发,在高吞吐时CPU的使用量会剧增,所以CPU的性能直接与可以达到的最大带宽挂钩。
## 特别感谢
- [Dreamacro/clash](https://github.com/Dreamacro/clash) - A rule-based tunnel in Go
- [google/gvisor](https://github.com/google/gvisor) - Application Kernel for Containers
- [wireguard-go](https://git.zx2c4.com/wireguard-go) - Go Implementation of WireGuard
## License
[GPL-3.0](https://github.com/xjasonlyu/tun2socks/blob/main/LICENSE)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fxjasonlyu%2Ftun2socks.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fxjasonlyu%2Ftun2socks?ref=badge_large)
+9 -3
View File
@@ -1,8 +1,11 @@
package dialer
import "net"
import (
"net"
"sync"
)
var _boundInterface *net.Interface
var _bindOnce sync.Once
// BindToInterface binds dialer to specific interface.
func BindToInterface(name string) error {
@@ -10,6 +13,9 @@ func BindToInterface(name string) error {
if err != nil {
return err
}
_boundInterface = i
_bindOnce.Do(func() {
addControl(bindToInterface(i))
})
return nil
}
+15 -13
View File
@@ -7,18 +7,20 @@ import (
"golang.org/x/sys/unix"
)
func bindToInterface(network, address string, c syscall.RawConn) error {
ipStr, _, _ := net.SplitHostPort(address)
if ip := net.ParseIP(ipStr); ip != nil && !ip.IsGlobalUnicast() {
return nil
}
return c.Control(func(fd uintptr) {
switch network {
case "tcp4", "udp4":
unix.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, _boundInterface.Index)
case "tcp6", "udp6":
unix.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BOUND_IF, _boundInterface.Index)
func bindToInterface(i *net.Interface) controlFunc {
return func(network, address string, c syscall.RawConn) error {
ipStr, _, _ := net.SplitHostPort(address)
if ip := net.ParseIP(ipStr); ip != nil && !ip.IsGlobalUnicast() {
return nil
}
})
return c.Control(func(fd uintptr) {
switch network {
case "tcp4", "udp4":
unix.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, i.Index)
case "tcp6", "udp6":
unix.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BOUND_IF, i.Index)
}
})
}
}
+10 -8
View File
@@ -7,13 +7,15 @@ import (
"golang.org/x/sys/unix"
)
func bindToInterface(network, address string, c syscall.RawConn) error {
ipStr, _, _ := net.SplitHostPort(address)
if ip := net.ParseIP(ipStr); ip != nil && !ip.IsGlobalUnicast() {
return nil
}
func bindToInterface(i *net.Interface) controlFunc {
return func(network, address string, c syscall.RawConn) error {
ipStr, _, _ := net.SplitHostPort(address)
if ip := net.ParseIP(ipStr); ip != nil && !ip.IsGlobalUnicast() {
return nil
}
return c.Control(func(fd uintptr) {
unix.BindToDevice(int(fd), _boundInterface.Name)
})
return c.Control(func(fd uintptr) {
unix.BindToDevice(int(fd), i.Name)
})
}
}
+5 -2
View File
@@ -4,9 +4,12 @@ package dialer
import (
"errors"
"net"
"syscall"
)
func bindToInterface(network, address string, c syscall.RawConn) error {
return errors.New("unsupported platform")
func bindToInterface(_ *net.Interface) controlFunc {
return func(string, string, syscall.RawConn) error {
return errors.New("unsupported platform")
}
}
+37
View File
@@ -0,0 +1,37 @@
package dialer
import (
"errors"
"net"
"syscall"
)
type controlFunc func(string, string, syscall.RawConn) error
var (
_controlPool = make([]controlFunc, 0, 2)
)
func addControl(f controlFunc) {
_controlPool = append(_controlPool, f)
}
func setControl(i interface{}) {
control := func(address, network string, c syscall.RawConn) error {
for _, f := range _controlPool {
if err := f(address, network, c); err != nil {
return err
}
}
return nil
}
switch v := i.(type) {
case *net.Dialer:
v.Control = control
case *net.ListenConfig:
v.Control = control
default:
panic(errors.New("wrong type"))
}
}
+2 -10
View File
@@ -11,20 +11,12 @@ func Dial(network, address string) (net.Conn, error) {
func DialContext(ctx context.Context, network, address string) (net.Conn, error) {
d := &net.Dialer{}
if _boundInterface != nil {
d.Control = bindToInterface
}
setControl(d)
return d.DialContext(ctx, network, address)
}
func ListenPacket(network, address string) (net.PacketConn, error) {
lc := &net.ListenConfig{}
if _boundInterface != nil {
lc.Control = bindToInterface
}
setControl(lc)
return lc.ListenPacket(context.Background(), network, address)
}
+14
View File
@@ -0,0 +1,14 @@
package dialer
import (
"sync"
)
var _setOnce sync.Once
// SetMark sets the mark for each packet sent through this dialer(socket).
func SetMark(i int) {
_setOnce.Do(func() {
addControl(setMark(i))
})
}
+15
View File
@@ -0,0 +1,15 @@
package dialer
import (
"syscall"
"golang.org/x/sys/unix"
)
func setMark(i int) controlFunc {
return func(_, _ string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_MARK, i)
})
}
}
+14
View File
@@ -0,0 +1,14 @@
// +build !linux
package dialer
import (
"errors"
"syscall"
)
func setMark(_ int) controlFunc {
return func(string, string, syscall.RawConn) error {
return errors.New("fwmark: linux only")
}
}
+2
View File
@@ -3,6 +3,8 @@ package dialer
import "net"
func init() {
// We must use this DialContext to query DNS
// when using net default resolver.
net.DefaultResolver.PreferGo = true
net.DefaultResolver.Dial = DialContext
}
+30 -2
View File
@@ -35,6 +35,34 @@ const (
AtypIPv6 Atyp = 0x04
)
// Reply field as defined in RFC 1928 section 6.
type Reply uint8
func (r Reply) String() string {
switch r {
case 0x00:
return "succeeded"
case 0x01:
return "general SOCKS server failure"
case 0x02:
return "connection not allowed by ruleset"
case 0x03:
return "network unreachable"
case 0x04:
return "host unreachable"
case 0x05:
return "connection refused"
case 0x06:
return "TTL expired"
case 0x07:
return "command not supported"
case 0x08:
return "address type not supported"
default:
return "unassigned"
}
}
// MaxAddrLen is the maximum size of SOCKS address in bytes.
const MaxAddrLen = 1 + 1 + 255 + 2
@@ -184,8 +212,8 @@ func ClientHandshake(rw io.ReadWriter, addr Addr, command Command, user *User) (
return nil, err
}
if buf[1] != 0x00 /* SUCCEEDED */ {
return nil, fmt.Errorf("unsucceed reply: %X", buf[1])
if rep := Reply(buf[1]); rep != 0x00 /* SUCCEEDED */ {
return nil, fmt.Errorf("%#X: %s", rep, rep.String())
}
return ReadAddr(rw, buf)
-2
View File
@@ -1,2 +0,0 @@
// Package constant provides global constants/variables of this project.
package constant
@@ -1,4 +1,4 @@
package adapter
package constant
import (
"bytes"
@@ -87,7 +87,3 @@ func (m *Metadata) Network() string {
func (m *Metadata) String() string {
return m.DestinationAddress()
}
func (m *Metadata) Valid() bool {
return m.SrcIP != nil && m.DstIP != nil
}
+5 -3
View File
@@ -1,8 +1,10 @@
package constant
const Name = "tun2socks"
const (
Name = "tun2socks"
)
var (
Version = ""
BuildTime = ""
Version string
GitCommit string
)
+7 -5
View File
@@ -1,12 +1,14 @@
package adapter
package core
import (
"net"
"gvisor.dev/gvisor/pkg/tcpip/stack"
)
type TCPConn interface {
net.Conn
Metadata() *Metadata
ID() *stack.TransportEndpointID
}
type UDPPacket interface {
@@ -16,12 +18,12 @@ type UDPPacket interface {
// Drop call after packet is used, could release resources in this function.
Drop()
// ID returns the transport endpoint id of packet.
ID() *stack.TransportEndpointID
// LocalAddr returns the source IP/Port of packet.
LocalAddr() net.Addr
// Metadata returns the metadata of packet.
Metadata() *Metadata
// RemoteAddr returns the destination IP/Port of packet.
RemoteAddr() net.Addr
@@ -1,4 +1,4 @@
// Package channel provides the implementation of io.ReadWriter
// Package rwbased provides the implementation of io.ReadWriter
// based data-link layer endpoints.
package rwbased
@@ -90,12 +90,12 @@ func (e *Endpoint) writePacket(pkt *stack.PacketBuffer) tcpip.Error {
}
// WritePacket writes packet back into io.ReadWriter.
func (e *Endpoint) WritePacket(_ stack.RouteInfo, _ *stack.GSO, _ tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) tcpip.Error {
func (e *Endpoint) WritePacket(_ stack.RouteInfo, _ tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) tcpip.Error {
return e.writePacket(pkt)
}
// WritePackets writes packets back into io.ReadWriter.
func (e *Endpoint) WritePackets(_ stack.RouteInfo, _ *stack.GSO, pkts stack.PacketBufferList, _ tcpip.NetworkProtocolNumber) (int, tcpip.Error) {
func (e *Endpoint) WritePackets(_ stack.RouteInfo, pkts stack.PacketBufferList, _ tcpip.NetworkProtocolNumber) (int, tcpip.Error) {
n := 0
for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() {
if err := e.writePacket(pkt); err != nil {
+33
View File
@@ -0,0 +1,33 @@
// +build darwin freebsd openbsd
package tun
import (
"github.com/xjasonlyu/tun2socks/common/pool"
)
const (
offset = 4 /* 4 bytes TUN_PI */
defaultMTU = 1500
)
func (t *TUN) Read(packet []byte) (n int, err error) {
buf := pool.Get(offset + len(packet))
defer pool.Put(buf)
if n, err = t.nt.Read(buf, offset); err != nil {
return
}
copy(packet, buf[offset:offset+n])
return
}
func (t *TUN) Write(packet []byte) (int, error) {
buf := pool.Get(offset + len(packet))
defer pool.Put(buf)
copy(buf[offset:], packet)
return t.nt.Write(buf[:offset+len(packet)], offset)
}
+15
View File
@@ -0,0 +1,15 @@
package tun
const (
offset = 0
defaultMTU = 0 /* auto */
)
func (t *TUN) Read(packet []byte) (int, error) {
return t.nt.Read(packet, offset)
}
func (t *TUN) Write(packet []byte) (int, error) {
return t.nt.Write(packet, offset)
}
+1 -1
View File
@@ -2,7 +2,7 @@
package tun
import (
"github.com/xjasonlyu/tun2socks/device"
"github.com/xjasonlyu/tun2socks/core/device"
)
const Driver = "tun"
@@ -1,11 +1,12 @@
// +build linux
package tun
import (
"errors"
"fmt"
"unsafe"
"github.com/xjasonlyu/tun2socks/device"
"github.com/xjasonlyu/tun2socks/core/device"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/tcpip/link/fdbased"
@@ -30,7 +31,7 @@ func Open(opts ...Option) (device.Device, error) {
}
if len(t.name) >= unix.IFNAMSIZ {
return nil, errors.New("interface name too long")
return nil, fmt.Errorf("interface name too long: %s", t.name)
}
fd, err := tun.Open(t.name)
@@ -100,7 +101,7 @@ func setMTU(name string, n uint32) error {
)
if errno != 0 {
return errors.New("failed to set MTU")
return fmt.Errorf("failed to set MTU: %w", errno)
}
return nil
@@ -5,9 +5,8 @@ package tun
import (
"fmt"
"github.com/xjasonlyu/tun2socks/common/pool"
"github.com/xjasonlyu/tun2socks/device"
"github.com/xjasonlyu/tun2socks/device/rwbased"
"github.com/xjasonlyu/tun2socks/core/device"
"github.com/xjasonlyu/tun2socks/core/device/rwbased"
"golang.zx2c4.com/wireguard/tun"
)
@@ -27,7 +26,12 @@ func Open(opts ...Option) (device.Device, error) {
opt(t)
}
nt, err := tun.CreateTUN(t.name, int(t.mtu))
forcedMTU := defaultMTU
if t.mtu > 0 {
forcedMTU = int(t.mtu)
}
nt, err := tun.CreateTUN(t.name, forcedMTU)
if err != nil {
return nil, fmt.Errorf("create tun: %w", err)
}
@@ -39,7 +43,7 @@ func Open(opts ...Option) (device.Device, error) {
}
t.mtu = uint32(mtu)
ep, err := rwbased.New(t, uint32(mtu))
ep, err := rwbased.New(t, t.mtu)
if err != nil {
return nil, fmt.Errorf("create endpoint: %w", err)
}
@@ -48,26 +52,6 @@ func Open(opts ...Option) (device.Device, error) {
return t, nil
}
func (t *TUN) Read(packet []byte) (n int, err error) {
buf := pool.Get(offset + len(packet))
defer pool.Put(buf)
if n, err = t.nt.Read(buf, offset); err != nil {
return
}
copy(packet, buf[offset:offset+n])
return
}
func (t *TUN) Write(packet []byte) (int, error) {
buf := pool.Get(offset + len(packet))
defer pool.Put(buf)
copy(buf[offset:], packet)
return t.nt.Write(buf[:offset+len(packet)], offset)
}
func (t *TUN) Name() string {
name, _ := t.nt.Name()
return name
+6
View File
@@ -0,0 +1,6 @@
package core
type Handler interface {
Add(TCPConn)
AddPacket(UDPPacket)
}
View File
+4 -2
View File
@@ -2,6 +2,8 @@
package stack
import (
"github.com/xjasonlyu/tun2socks/core"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
@@ -14,12 +16,12 @@ import (
type Stack struct {
*stack.Stack
handler Handler
handler core.Handler
nicID tcpip.NICID
}
// New allocates a new *Stack with given options.
func New(ep stack.LinkEndpoint, handler Handler, opts ...Option) (*Stack, error) {
func New(ep stack.LinkEndpoint, handler core.Handler, opts ...Option) (*Stack, error) {
s := &Stack{
Stack: stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{
+5 -13
View File
@@ -5,10 +5,9 @@ import (
"net"
"time"
"github.com/xjasonlyu/tun2socks/common/adapter"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -50,15 +49,8 @@ func withTCPHandler() Option {
conn := &tcpConn{
Conn: gonet.NewTCPConn(&wq, ep),
metadata: &adapter.Metadata{
Net: adapter.TCP,
SrcIP: net.IP(id.RemoteAddress),
SrcPort: id.RemotePort,
DstIP: net.IP(id.LocalAddress),
DstPort: id.LocalPort,
},
id: &id,
}
s.handler.Add(conn)
})
s.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
@@ -83,9 +75,9 @@ func setKeepalive(ep tcpip.Endpoint) error {
type tcpConn struct {
net.Conn
metadata *adapter.Metadata
id *stack.TransportEndpointID
}
func (c *tcpConn) Metadata() *adapter.Metadata {
return c.metadata
func (c *tcpConn) ID() *stack.TransportEndpointID {
return c.id
}
+31 -46
View File
@@ -4,8 +4,6 @@ import (
"fmt"
"net"
"github.com/xjasonlyu/tun2socks/common/adapter"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/buffer"
"gvisor.dev/gvisor/pkg/tcpip/header"
@@ -23,7 +21,7 @@ func withUDPHandler() Option {
udpHandlePacket := func(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
// Ref: gVisor pkg/tcpip/transport/udp/endpoint.go HandlePacket
udpHdr := header.UDP(pkt.TransportHeader().View())
if int(udpHdr.Length()) > pkt.Data.Size()+header.UDPMinimumSize {
if int(udpHdr.Length()) > pkt.Data().Size()+header.UDPMinimumSize {
// Malformed packet.
s.Stats().UDP.MalformedPacketsReceived.Increment()
return true
@@ -39,18 +37,11 @@ func withUDPHandler() Option {
packet := &udpPacket{
s: s,
id: id,
id: &id,
data: pkt.Data().ExtractVV(),
nicID: pkt.NICID,
netHdr: pkt.Network(),
netProto: pkt.NetworkProtocolNumber,
payload: pkt.Data.ToView(),
metadata: &adapter.Metadata{
Net: adapter.UDP,
SrcIP: net.IP(id.RemoteAddress),
SrcPort: id.RemotePort,
DstIP: net.IP(id.LocalAddress),
DstPort: id.LocalPort,
},
}
s.handler.AddPacket(packet)
@@ -63,30 +54,27 @@ func withUDPHandler() Option {
type udpPacket struct {
s *Stack
id stack.TransportEndpointID
id *stack.TransportEndpointID
data buffer.VectorisedView
nicID tcpip.NICID
netHdr header.Network
netProto tcpip.NetworkProtocolNumber
payload []byte
metadata *adapter.Metadata
}
func (p *udpPacket) Data() []byte {
return p.payload
return p.data.ToView()
}
func (p *udpPacket) Drop() {
/* Release */
func (p *udpPacket) Drop() {}
func (p *udpPacket) ID() *stack.TransportEndpointID {
return p.id
}
func (p *udpPacket) LocalAddr() net.Addr {
return &net.UDPAddr{IP: net.IP(p.id.LocalAddress), Port: int(p.id.LocalPort)}
}
func (p *udpPacket) Metadata() *adapter.Metadata {
return p.metadata
}
func (p *udpPacket) RemoteAddr() net.Addr {
return &net.UDPAddr{IP: net.IP(p.id.RemoteAddress), Port: int(p.id.RemotePort)}
}
@@ -98,33 +86,30 @@ func (p *udpPacket) WriteBack(b []byte, addr net.Addr) (int, error) {
return 0, fmt.Errorf("%s", &tcpip.ErrMessageTooLong{})
}
route, err := p.s.FindRoute(p.nicID, p.netHdr.DestinationAddress(), p.netHdr.SourceAddress(), p.netProto, false /* multicastLoop */)
var (
localAddress tcpip.Address
localPort uint16
)
if udpAddr, ok := addr.(*net.UDPAddr); !ok {
localAddress = p.netHdr.DestinationAddress()
localPort = p.id.LocalPort
} else if ipv4 := udpAddr.IP.To4(); ipv4 != nil {
localAddress = tcpip.Address(ipv4)
localPort = uint16(udpAddr.Port)
} else {
localAddress = tcpip.Address(udpAddr.IP)
localPort = uint16(udpAddr.Port)
}
route, err := p.s.FindRoute(p.nicID, localAddress, p.netHdr.SourceAddress(), p.netProto, false /* multicastLoop */)
if err != nil {
return 0, fmt.Errorf("%#v find route: %s", p.id, err)
}
defer route.Release()
data := v.ToVectorisedView()
// if addr is not provided, write back use original dst Addr as src Addr.
if addr == nil {
if err := sendUDP(route, data, p.id.LocalPort, p.id.RemotePort, udpNoChecksum); err != nil {
return 0, fmt.Errorf("%v", err)
}
return data.Size(), nil
}
udpAddr, ok := addr.(*net.UDPAddr)
if !ok {
return 0, fmt.Errorf("type %T is not a valid udp address", addr)
}
if ipv4 := udpAddr.IP.To4(); ipv4 != nil {
route.LocalAddress = tcpip.Address(ipv4)
} else {
route.LocalAddress = tcpip.Address(udpAddr.IP)
}
if err := sendUDP(route, data, uint16(udpAddr.Port), p.id.RemotePort, udpNoChecksum); err != nil {
if err = sendUDP(route, data, localPort, p.id.RemotePort, udpNoChecksum); err != nil {
return 0, fmt.Errorf("%v", err)
}
return data.Size(), nil
@@ -154,7 +139,7 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u
// 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) {
(!noChecksum || r.NetProto() == header.IPv6ProtocolNumber) {
xsum := r.PseudoHeaderChecksum(udp.ProtocolNumber, length)
for _, v := range data.Views() {
xsum = header.Checksum(v, xsum)
@@ -164,7 +149,7 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u
ttl := r.DefaultTTL()
if err := r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{
if err := r.WritePacket(stack.NetworkHeaderParams{
Protocol: udp.ProtocolNumber,
TTL: ttl,
TOS: 0, /* default */
@@ -187,7 +172,7 @@ func verifyChecksum(hdr header.UDP, pkt *stack.PacketBuffer) bool {
(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() {
for _, v := range pkt.Data().Views() {
xsum = header.Checksum(v, xsum)
}
return hdr.CalculateChecksum(xsum) == 0xffff
-5
View File
@@ -1,5 +0,0 @@
// +build darwin freebsd openbsd
package tun
const offset = 4 /* 4 bytes TUN_PI */
-3
View File
@@ -1,3 +0,0 @@
package tun
const offset = 0
-43
View File
@@ -1,43 +0,0 @@
version: '2.4'
services:
tun2socks:
image: ghcr.io/xjasonlyu/tun2socks:latest
cap_add:
- NET_ADMIN
devices:
- '/dev/net/tun:/dev/net/tun'
environment:
- GODEBUG=madvdontneed=1
- LOGLEVEL=
- TUN=
- ETH=
- TUN_ADDR=
- TUN_MASK=
- PROXY=
- STATS=
- TOKEN=
- MTU=
- EXTRA_COMMANDS=
- TUN_INCLUDED_ROUTES=
- TUN_EXCLUDED_ROUTES=
networks:
switch:
ipv4_address: 172.20.1.2
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.rp_filter=0
restart: unless-stopped
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
+42 -44
View File
@@ -1,47 +1,40 @@
#!/bin/sh
TUN="${TUN:-tun0}"
ETH="${ETH:-eth0}"
TUN_ADDR="${TUN_ADDR:-198.18.0.1}"
TUN_MASK="${TUN_MASK:-255.254.0.0}"
LOGLEVEL="${LOGLEVEL:-INFO}"
ADDR="${ADDR:-198.18.0.1/15}"
LOGLEVEL="${LOGLEVEL:-info}"
mk_tun() {
# params
NAME="$1"
ADDR="$2"
MASK="$3"
# default values
TABLE="${TABLE:-0x22b}"
FWMARK="${FWMARK:-0x22b}"
CLONE_MAIN="${CLONE_MAIN:-1}"
create_tun() {
# create tun device
ip tuntap add mode tun dev "$NAME"
ip addr add "$ADDR/$MASK" dev "$NAME"
ip link set dev "$NAME" up
ip tuntap add mode tun dev "$TUN"
ip addr add "$ADDR" dev "$TUN"
ip link set dev "$TUN" up
}
create_table() {
if [ "$CLONE_MAIN" -ne 0 ]; then
# clone main route table
ip route show table main |
while read -r route; do
ip route add ${route%linkdown*} table "$TABLE"
done
# replace default route
ip route replace default dev "$TUN" table "$TABLE"
else
# just add default route
ip route add default dev "$TUN" table "$TABLE"
fi
}
config_route() {
# params
TABLE="$1"
TUN_IF="$2"
ETH_IF="$3"
# add custom table
printf "%s\t%s\n" 100 "$TABLE" >>/etc/iproute2/rt_tables
# clone main route
ip route show table main |
while read -r route; do
ip route add ${route%linkdown*} table "$TABLE"
done
# config default route
ip route del default table "$TABLE"
ip route add default dev "$TUN_IF" table "$TABLE"
# policy routing
tun=$(ip -4 addr show "$TUN_IF" | awk 'NR==2 {print $2}')
eth=$(ip -4 addr show "$ETH_IF" | awk 'NR==2 {split($2,a,"/");print a[1]}')
ip rule add from "$eth" to "$tun" priority 9998 prohibit
ip rule add from "$eth" priority 9999 table main
ip rule add from all priority 10000 table "$TABLE"
ip rule add not fwmark "$FWMARK" table "$TABLE"
ip rule add fwmark "$FWMARK" to "$ADDR" prohibit
# add tun included routes
for addr in $(echo "$TUN_INCLUDED_ROUTES" | tr ',' '\n'); do
@@ -55,8 +48,9 @@ config_route() {
}
main() {
mk_tun "$TUN" "$TUN_ADDR" "$TUN_MASK"
config_route "tun2socks" "$TUN" "$ETH"
create_tun
create_table
config_route
# execute extra commands
if [ -n "$EXTRA_COMMANDS" ]; then
@@ -64,22 +58,26 @@ main() {
fi
if [ -n "$MTU" ]; then
ARGS="--mtu $MTU"
ARGS="-mtu $MTU"
fi
if [ -n "$STATS" ]; then
ARGS="$ARGS --stats $STATS"
ARGS="$ARGS -stats $STATS"
fi
if [ -n "$TOKEN" ]; then
ARGS="$ARGS --token $TOKEN"
ARGS="$ARGS -token $TOKEN"
fi
if [ -n "$UDP_TIMEOUT" ]; then
ARGS="$ARGS -udp-timeout $UDP_TIMEOUT"
fi
exec tun2socks \
--loglevel "$LOGLEVEL" \
--interface "$ETH" \
--device "$TUN" \
--proxy "$PROXY" \
-loglevel "$LOGLEVEL" \
-fwmark "$FWMARK" \
-device "$TUN" \
-proxy "$PROXY" \
$ARGS
}
-15
View File
@@ -1,15 +0,0 @@
#!/bin/sh
# Create the necessary file structure for /dev/net/tun
if [ ! -c /dev/net/tun ]; then
if [ ! -d /dev/net ]; then
mkdir -m 755 /dev/net
fi
mknod /dev/net/tun c 10 200
chmod 0755 /dev/net/tun
fi
# Load the tun module if not already loaded
if ( ! (lsmod | grep -q "^tun\s")); then
insmod /lib/modules/tun.ko
fi
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

+103 -62
View File
@@ -2,63 +2,95 @@ package engine
import (
"errors"
"os"
"github.com/xjasonlyu/tun2socks/component/dialer"
"github.com/xjasonlyu/tun2socks/device"
"github.com/xjasonlyu/tun2socks/core/device"
"github.com/xjasonlyu/tun2socks/core/stack"
"github.com/xjasonlyu/tun2socks/log"
"github.com/xjasonlyu/tun2socks/proxy"
"github.com/xjasonlyu/tun2socks/stack"
"github.com/xjasonlyu/tun2socks/stats"
"github.com/xjasonlyu/tun2socks/tunnel"
)
type Engine struct {
mtu uint32
iface string
stats string
token string
logLevel string
rawProxy string
rawDevice string
var _engine = &engine{}
// Start starts the default engine up.
func Start() error {
return _engine.start()
}
// Stop shuts the default engine down.
func Stop() error {
return _engine.stop()
}
// Insert loads *Key to the default engine.
func Insert(k *Key) {
_engine.insert(k)
}
type Key struct {
MTU int
Mark int
UDPTimeout int
Proxy string
Stats string
Token string
Device string
LogLevel string
Interface string
Version bool
}
type engine struct {
*Key
stack *stack.Stack
proxy proxy.Proxy
device device.Device
}
func New(opts ...Option) *Engine {
e := &Engine{}
for _, opt := range opts {
opt(e)
func (e *engine) start() error {
if e.Key == nil {
return errors.New("empty key")
}
return e
}
func (e *Engine) Start() error {
for _, set := range []func() error{
if e.Version {
showVersion()
os.Exit(0)
}
for _, f := range []func() error{
e.setLogLevel,
e.setMark,
e.setInterface,
e.setStats,
e.setUDPTimeout,
e.setProxy,
e.setDevice,
e.setStack,
} {
if err := set(); err != nil {
if err := f(); err != nil {
return err
}
}
return nil
}
func (e *Engine) Stop() {
func (e *engine) stop() error {
if e.device != nil {
if err := e.device.Close(); err != nil {
log.Fatalf("%v", err)
}
return e.device.Close()
}
return nil
}
func (e *Engine) setLogLevel() error {
level, err := log.ParseLevel(e.logLevel)
func (e *engine) insert(k *Key) {
e.Key = k
}
func (e *engine) setLogLevel() error {
level, err := log.ParseLevel(e.LogLevel)
if err != nil {
return err
}
@@ -66,62 +98,71 @@ func (e *Engine) setLogLevel() error {
return nil
}
func (e *Engine) setInterface() error {
if e.iface != "" {
if err := dialer.BindToInterface(e.iface); err != nil {
func (e *engine) setMark() error {
if e.Mark != 0 {
dialer.SetMark(e.Mark)
log.Infof("[DIALER] set fwmark: %#x", e.Mark)
}
return nil
}
func (e *engine) setInterface() error {
if e.Interface != "" {
if err := dialer.BindToInterface(e.Interface); err != nil {
return err
}
log.Infof("[BOUND] bind to interface: %s", e.iface)
log.Infof("[DIALER] use interface: %s", e.Interface)
}
return nil
}
func (e *Engine) setStats() error {
if e.stats != "" {
func (e *engine) setStats() error {
if e.Stats != "" {
go func() {
_ = stats.Start(e.stats, e.token)
_ = stats.Start(e.Stats, e.Token)
}()
log.Infof("[STATS] listen and serve at: http://%s", e.stats)
log.Infof("[STATS] serve at: http://%s", e.Stats)
}
return nil
}
func (e *Engine) setProxy() error {
if e.rawProxy == "" {
func (e *engine) setUDPTimeout() error {
if e.UDPTimeout > 0 {
tunnel.SetUDPTimeout(e.UDPTimeout)
}
return nil
}
func (e *engine) setProxy() (err error) {
if e.Proxy == "" {
return errors.New("empty proxy")
}
p, err := parseProxy(e.rawProxy)
if err != nil {
return err
}
e.proxy = p
proxy.SetDialer(p)
return nil
e.proxy, err = parseProxy(e.Proxy)
proxy.SetDialer(e.proxy)
return
}
func (e *Engine) setDevice() error {
if e.rawDevice == "" {
func (e *engine) setDevice() (err error) {
if e.Device == "" {
return errors.New("empty device")
}
d, err := parseDevice(e.rawDevice, e.mtu)
if err != nil {
return err
}
e.device = d
return nil
e.device, err = parseDevice(e.Device, uint32(e.MTU))
return
}
func (e *Engine) setStack() error {
handler := &fakeTunnel{}
if _, err := stack.New(e.device, handler, stack.WithDefault()); err != nil {
return err
}
log.Infof(
"[STACK] %s://%s <-> %s://%s",
e.device.Type(), e.device.Name(),
e.proxy.Proto(), e.proxy.Addr(),
)
return nil
func (e *engine) setStack() (err error) {
defer func() {
if err == nil {
log.Infof(
"[STACK] %s://%s <-> %s://%s",
e.device.Type(), e.device.Name(),
e.proxy.Proto(), e.proxy.Addr(),
)
}
}()
e.stack, err = stack.New(e.device, &fakeTunnel{}, stack.WithDefault())
return
}
-40
View File
@@ -1,40 +0,0 @@
package engine
type Option func(*Engine)
func WithDevice(device string) Option {
return func(e *Engine) {
e.rawDevice = device
}
}
func WithInterface(iface string) Option {
return func(e *Engine) {
e.iface = iface
}
}
func WithLogLevel(level string) Option {
return func(e *Engine) {
e.logLevel = level
}
}
func WithMTU(mtu int) Option {
return func(e *Engine) {
e.mtu = uint32(mtu)
}
}
func WithProxy(proxy string) Option {
return func(e *Engine) {
e.rawProxy = proxy
}
}
func WithStats(stats, token string) Option {
return func(e *Engine) {
e.stats = stats
e.token = token
}
}
+14 -11
View File
@@ -6,9 +6,10 @@ import (
"net/url"
"strings"
"github.com/xjasonlyu/tun2socks/device"
"github.com/xjasonlyu/tun2socks/device/tun"
"github.com/xjasonlyu/tun2socks/core/device"
"github.com/xjasonlyu/tun2socks/core/device/tun"
"github.com/xjasonlyu/tun2socks/proxy"
"github.com/xjasonlyu/tun2socks/proxy/proto"
)
func parseDevice(s string, mtu uint32) (device.Device, error) {
@@ -34,7 +35,7 @@ func parseDevice(s string, mtu uint32) (device.Device, error) {
func parseProxy(s string) (proxy.Proxy, error) {
if !strings.Contains(s, "://") {
s = proxy.Socks5Proto.String() + "://" + s /* default protocol */
s = proto.Socks5.String() + "://" + s /* default protocol */
}
u, err := url.Parse(s)
@@ -42,17 +43,17 @@ func parseProxy(s string) (proxy.Proxy, error) {
return nil, err
}
proto := strings.ToLower(u.Scheme)
protocol := strings.ToLower(u.Scheme)
switch proto {
case proxy.DirectProto.String():
switch protocol {
case proto.Direct.String():
return proxy.NewDirect(), nil
case proxy.Socks5Proto.String():
case proto.Socks5.String():
return proxy.NewSocks5(parseSocks(u))
case proxy.ShadowsocksProto.String():
case proto.Shadowsocks.String():
return proxy.NewShadowsocks(parseShadowsocks(u))
default:
return nil, fmt.Errorf("unsupported protocol: %s", proto)
return nil, fmt.Errorf("unsupported protocol: %s", protocol)
}
}
@@ -72,8 +73,10 @@ func parseShadowsocks(u *url.URL) (address, method, password, obfsMode, obfsHost
} else {
data, _ := base64.RawURLEncoding.DecodeString(u.User.String())
userInfo := strings.SplitN(string(data), ":", 2)
method = userInfo[0]
password = userInfo[1]
if len(userInfo) == 2 {
method = userInfo[0]
password = userInfo[1]
}
}
rawQuery, _ := url.QueryUnescape(u.RawQuery)
+4 -5
View File
@@ -1,19 +1,18 @@
package engine
import (
"github.com/xjasonlyu/tun2socks/common/adapter"
"github.com/xjasonlyu/tun2socks/stack"
"github.com/xjasonlyu/tun2socks/core"
"github.com/xjasonlyu/tun2socks/tunnel"
)
var _ stack.Handler = (*fakeTunnel)(nil)
var _ core.Handler = (*fakeTunnel)(nil)
type fakeTunnel struct{}
func (*fakeTunnel) Add(conn adapter.TCPConn) {
func (*fakeTunnel) Add(conn core.TCPConn) {
tunnel.Add(conn)
}
func (*fakeTunnel) AddPacket(packet adapter.UDPPacket) {
func (*fakeTunnel) AddPacket(packet core.UDPPacket) {
tunnel.AddPacket(packet)
}
+22
View File
@@ -0,0 +1,22 @@
package engine
import (
"fmt"
"runtime"
"strings"
V "github.com/xjasonlyu/tun2socks/constant"
)
func showVersion() {
fmt.Print(versionString())
fmt.Print(releaseString())
}
func versionString() string {
return fmt.Sprintf("%s-%s\n", V.Name, strings.TrimPrefix(V.Version, "v"))
}
func releaseString() string {
return fmt.Sprintf("%s/%s, %s, %s\n", runtime.GOOS, runtime.GOARCH, runtime.Version(), V.GitCommit)
}
+12 -12
View File
@@ -1,22 +1,22 @@
module github.com/xjasonlyu/tun2socks
go 1.15
go 1.16
require (
github.com/Dreamacro/go-shadowsocks2 v0.1.6
github.com/Dreamacro/go-shadowsocks2 v0.1.7
github.com/go-chi/chi v4.1.2+incompatible
github.com/go-chi/cors v1.1.1
github.com/go-chi/cors v1.2.0
github.com/go-chi/render v1.0.1
github.com/gofrs/uuid v4.0.0+incompatible
github.com/google/btree v1.0.1 // indirect
github.com/gorilla/websocket v1.4.2
github.com/sirupsen/logrus v1.7.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.5.1
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
go.uber.org/atomic v1.7.0
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324
golang.zx2c4.com/wireguard v0.0.20201118
gvisor.dev/gvisor v0.0.0-20210207010352-2042ce9bee2d
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf // indirect
golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
golang.zx2c4.com/wireguard v0.0.0-20210511144717-5846b622837e
gvisor.dev/gvisor v0.0.0-20210513011327-a6cb1e3905c7
)
+33 -48
View File
@@ -43,8 +43,8 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Dreamacro/go-shadowsocks2 v0.1.6 h1:PysSf9sLT3Qn8jhlin5v7Rk68gOQG4K5BZFY1nxLGxI=
github.com/Dreamacro/go-shadowsocks2 v0.1.6/go.mod h1:LSXCjyHesPY3pLjhwff1mQX72ItcBT/N2xNC685cYeU=
github.com/Dreamacro/go-shadowsocks2 v0.1.7 h1:8CtbE1HoPPMfrQZGXmlluq6dO2lL31W6WRRE8fabc4Q=
github.com/Dreamacro/go-shadowsocks2 v0.1.7/go.mod h1:8p5G4cAj5ZlXwUR+Ww63gfSikr8kvw8uw3TDwLAJpUc=
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
@@ -70,7 +70,7 @@ github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4q
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
@@ -81,9 +81,7 @@ github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kw
github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -110,8 +108,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/cors v1.1.1 h1:eHuqxsIw89iXcWnWUN8R72JMibABJTN/4IOYI5WERvw=
github.com/go-chi/cors v1.1.1/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I=
github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8=
github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -123,7 +121,7 @@ github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.6.1-0.20180915234121-886344bea079/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
@@ -157,8 +155,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -214,7 +213,6 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -254,32 +252,28 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
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/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=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
@@ -298,20 +292,18 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
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-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=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf h1:B2n+Zi5QeYRDAEodEu72OS36gmTWjgpXr2+cWcBW90o=
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -372,15 +364,13 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -396,9 +386,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -418,7 +406,6 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -443,31 +430,28 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201117222635-ba5294a509c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q=
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -519,8 +503,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.20201118 h1:QL8y2C7uO8T6z1GY+UX/hSeWiYEBurQkXjOTRFtCvXU=
golang.zx2c4.com/wireguard v0.0.20201118/go.mod h1:Dz+cq5bnrai9EpgYj4GDof/+qaGzbRWbeaAOs1bUYa0=
golang.zx2c4.com/wireguard v0.0.0-20210511144717-5846b622837e h1:/AMGtSyF7svgx+Z2aoM/6G2WKthoJa5QZES9HZX3Ask=
golang.zx2c4.com/wireguard v0.0.0-20210511144717-5846b622837e/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
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=
@@ -596,7 +580,7 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.36.0-dev.0.20210122012134-2c42474aca0c/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0-dev.0.20210208035533-9280052d3665/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -617,11 +601,12 @@ 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.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gvisor.dev/gvisor v0.0.0-20210207010352-2042ce9bee2d h1:cuJjBXot1TB6japiM1zO6gGwyqyKUUvt1ZwA2tkR9tw=
gvisor.dev/gvisor v0.0.0-20210207010352-2042ce9bee2d/go.mod h1:bGHhdxWoqL+3AwdMfePr6TWTcvHO33egRmxDPAQFdJE=
gvisor.dev/gvisor v0.0.0-20210513011327-a6cb1e3905c7 h1:c0MQmDSfJ944PQU9zDoUSkin5AeVbKgAmVF7c6ci8xU=
gvisor.dev/gvisor v0.0.0-20210513011327-a6cb1e3905c7/go.mod h1:ucHEMlckp+S/YzKEpwwAyGBhAh807Wxq/8Erc6gFxCE=
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 -5
View File
@@ -8,8 +8,8 @@ import (
)
var (
logCh = make(chan interface{})
source = observable.NewObservable(logCh)
_logCh = make(chan interface{})
_source = observable.NewObservable(_logCh)
)
type Event struct {
@@ -24,16 +24,16 @@ func newEvent(level Level, format string, args ...interface{}) *Event {
Time: time.Now(),
Message: fmt.Sprintf(format, args...),
}
logCh <- event /* send all events to logCh */
_logCh <- event /* send all events to logCh */
return event
}
func Subscribe() observable.Subscription {
sub, _ := source.Subscribe()
sub, _ := _source.Subscribe()
return sub
}
func UnSubscribe(sub observable.Subscription) {
source.UnSubscribe(sub)
_source.UnSubscribe(sub)
}
+5 -5
View File
@@ -2,14 +2,14 @@ package log
import (
"os"
"sync/atomic"
"github.com/sirupsen/logrus"
"go.uber.org/atomic"
)
var (
// defaultLevel is package default logging level.
defaultLevel = InfoLevel
// _defaultLevel is package default logging level.
_defaultLevel = atomic.NewUint32(uint32(InfoLevel))
)
func init() {
@@ -18,7 +18,7 @@ func init() {
}
func SetLevel(level Level) {
atomic.StoreUint32((*uint32)(&defaultLevel), uint32(level))
_defaultLevel.Store(uint32(level))
}
func Debugf(format string, args ...interface{}) {
@@ -43,7 +43,7 @@ func Fatalf(format string, args ...interface{}) {
func logf(level Level, format string, args ...interface{}) {
event := newEvent(level, format, args...)
if event.Level > defaultLevel {
if uint32(event.Level) > _defaultLevel.Load() {
return
}
+20 -47
View File
@@ -1,69 +1,42 @@
package main
import (
"fmt"
"flag"
"os"
"os/signal"
"runtime"
"syscall"
"github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/engine"
"github.com/xjasonlyu/tun2socks/log"
flag "github.com/spf13/pflag"
)
var (
device string
iface string
level string
proxy string
stats string
token string
mtu int
version bool
)
var key = new(engine.Key)
func init() {
flag.StringVarP(&device, "device", "d", "", "Use this device [driver://]name")
flag.StringVarP(&iface, "interface", "i", "", "Use network INTERFACE (Linux and MacOS only)")
flag.StringVarP(&proxy, "proxy", "p", "", "Use this proxy [protocol://]host[:port]")
flag.StringVarP(&level, "loglevel", "l", "info", "Log level [debug|info|warn|error|silent]")
flag.StringVar(&stats, "stats", "", "HTTP statistic server listen address")
flag.StringVar(&token, "token", "", "HTTP statistic server auth token")
flag.IntVarP(&mtu, "mtu", "m", 0, "Set device maximum transmission unit (MTU)")
flag.BoolVarP(&version, "version", "v", false, "Show version information and quit")
flag.IntVar(&key.Mark, "fwmark", 0, "Set firewall MARK (Linux only)")
flag.IntVar(&key.MTU, "mtu", 0, "Set device maximum transmission unit (MTU)")
flag.IntVar(&key.UDPTimeout, "udp-timeout", 0, "Set timeout for each UDP session")
flag.BoolVar(&key.Version, "version", false, "Show version information and quit")
flag.StringVar(&key.Device, "device", "", "Use this device [driver://]name")
flag.StringVar(&key.Interface, "interface", "", "Use network INTERFACE (Linux/MacOS only)")
flag.StringVar(&key.LogLevel, "loglevel", "info", "Log level [debug|info|warn|error|silent]")
flag.StringVar(&key.Proxy, "proxy", "", "Use this proxy [protocol://]host[:port]")
flag.StringVar(&key.Stats, "stats", "", "HTTP statistic server listen address")
flag.StringVar(&key.Token, "token", "", "HTTP statistic server auth token")
flag.Parse()
}
func main() {
if version {
fmt.Printf("%s %s\n%s/%s, %s, %s\n",
constant.Name,
constant.Version,
runtime.GOOS,
runtime.GOARCH,
runtime.Version(),
constant.BuildTime,
)
os.Exit(0)
engine.Insert(key)
checkErr := func(msg string, f func() error) {
if err := f(); err != nil {
log.Fatalf("Failed to %s: %v", msg, err)
}
}
options := []engine.Option{
engine.WithDevice(device),
engine.WithInterface(iface),
engine.WithLogLevel(level),
engine.WithMTU(mtu),
engine.WithProxy(proxy),
engine.WithStats(stats, token),
}
eng := engine.New(options...)
if err := eng.Start(); err != nil {
log.Fatalf("Start engine error: %v", err)
}
defer eng.Stop()
checkErr("start engine", engine.Start)
defer checkErr("stop engine", engine.Stop)
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
+10 -8
View File
@@ -5,31 +5,33 @@ import (
"errors"
"net"
"github.com/xjasonlyu/tun2socks/common/adapter"
M "github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/proxy/proto"
)
var _ Proxy = (*Base)(nil)
type Base struct {
addr string
addr string
proto proto.Proto
}
func NewBase(addr string) *Base {
return &Base{addr: addr}
func NewBase(addr string, proto proto.Proto) *Base {
return &Base{addr: addr, proto: proto}
}
func (b *Base) Addr() string {
return b.addr
}
func (b *Base) Proto() string {
return ""
func (b *Base) Proto() proto.Proto {
return b.proto
}
func (b *Base) DialContext(context.Context, *adapter.Metadata) (net.Conn, error) {
func (b *Base) DialContext(context.Context, *M.Metadata) (net.Conn, error) {
return nil, errors.New("not supported")
}
func (b *Base) DialUDP(*adapter.Metadata) (net.PacketConn, error) {
func (b *Base) DialUDP(*M.Metadata) (net.PacketConn, error) {
return nil, errors.New("not supported")
}
+8 -9
View File
@@ -4,8 +4,9 @@ import (
"context"
"net"
"github.com/xjasonlyu/tun2socks/common/adapter"
"github.com/xjasonlyu/tun2socks/component/dialer"
M "github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/proxy/proto"
)
var _ Proxy = (*Direct)(nil)
@@ -16,15 +17,13 @@ type Direct struct {
func NewDirect() *Direct {
return &Direct{
Base: &Base{},
Base: &Base{
proto: proto.Direct,
},
}
}
func (d *Direct) Proto() string {
return DirectProto.String()
}
func (d *Direct) DialContext(ctx context.Context, metadata *adapter.Metadata) (net.Conn, error) {
func (d *Direct) DialContext(ctx context.Context, metadata *M.Metadata) (net.Conn, error) {
c, err := dialer.DialContext(ctx, "tcp", metadata.DestinationAddress())
if err != nil {
return nil, err
@@ -33,7 +32,7 @@ func (d *Direct) DialContext(ctx context.Context, metadata *adapter.Metadata) (n
return c, nil
}
func (d *Direct) DialUDP(_ *adapter.Metadata) (net.PacketConn, error) {
func (d *Direct) DialUDP(*M.Metadata) (net.PacketConn, error) {
pc, err := dialer.ListenPacket("udp", "")
if err != nil {
return nil, err
@@ -46,7 +45,7 @@ type directPacketConn struct {
}
func (pc *directPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
if m, ok := addr.(*adapter.Metadata); ok && m.DstIP != nil {
if m, ok := addr.(*M.Metadata); ok && m.DstIP != nil {
return pc.PacketConn.WriteTo(b, m.UDPAddr())
}
+7 -7
View File
@@ -1,22 +1,22 @@
package proxy
package proto
import "fmt"
const (
DirectProto Proto = iota
ShadowsocksProto
Socks5Proto
Direct Proto = iota
Shadowsocks
Socks5
)
type Proto uint8
func (proto Proto) String() string {
switch proto {
case DirectProto:
case Direct:
return "direct"
case ShadowsocksProto:
case Shadowsocks:
return "ss"
case Socks5Proto:
case Socks5:
return "socks5"
default:
return fmt.Sprintf("proto(%d)", proto)
+8 -7
View File
@@ -6,7 +6,8 @@ import (
"net"
"time"
"github.com/xjasonlyu/tun2socks/common/adapter"
M "github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/proxy/proto"
)
const (
@@ -18,14 +19,14 @@ var (
)
type Dialer interface {
DialContext(context.Context, *adapter.Metadata) (net.Conn, error)
DialUDP(*adapter.Metadata) (net.PacketConn, error)
DialContext(context.Context, *M.Metadata) (net.Conn, error)
DialUDP(*M.Metadata) (net.PacketConn, error)
}
type Proxy interface {
Dialer
Addr() string
Proto() string
Proto() proto.Proto
}
// SetDialer sets default Dialer.
@@ -34,18 +35,18 @@ func SetDialer(d Dialer) {
}
// Dial uses default Dialer to dial TCP.
func Dial(metadata *adapter.Metadata) (net.Conn, error) {
func Dial(metadata *M.Metadata) (net.Conn, error) {
ctx, cancel := context.WithTimeout(context.Background(), tcpConnectTimeout)
defer cancel()
return _defaultDialer.DialContext(ctx, metadata)
}
// DialContext uses default Dialer to dial TCP with context.
func DialContext(ctx context.Context, metadata *adapter.Metadata) (net.Conn, error) {
func DialContext(ctx context.Context, metadata *M.Metadata) (net.Conn, error) {
return _defaultDialer.DialContext(ctx, metadata)
}
// DialUDP uses default Dialer to dial UDP.
func DialUDP(metadata *adapter.Metadata) (net.PacketConn, error) {
func DialUDP(metadata *M.Metadata) (net.PacketConn, error) {
return _defaultDialer.DialUDP(metadata)
}
+9 -9
View File
@@ -6,10 +6,11 @@ import (
"fmt"
"net"
"github.com/xjasonlyu/tun2socks/common/adapter"
"github.com/xjasonlyu/tun2socks/component/dialer"
obfs "github.com/xjasonlyu/tun2socks/component/simple-obfs"
"github.com/xjasonlyu/tun2socks/component/socks5"
M "github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/proxy/proto"
"github.com/Dreamacro/go-shadowsocks2/core"
)
@@ -32,18 +33,17 @@ func NewShadowsocks(addr, method, password, obfsMode, obfsHost string) (*Shadows
}
return &Shadowsocks{
Base: NewBase(addr),
Base: &Base{
addr: addr,
proto: proto.Shadowsocks,
},
cipher: cipher,
obfsMode: obfsMode,
obfsHost: obfsHost,
}, nil
}
func (ss *Shadowsocks) Proto() string {
return ShadowsocksProto.String()
}
func (ss *Shadowsocks) DialContext(ctx context.Context, metadata *adapter.Metadata) (c net.Conn, err error) {
func (ss *Shadowsocks) DialContext(ctx context.Context, metadata *M.Metadata) (c net.Conn, err error) {
c, err = dialer.DialContext(ctx, "tcp", ss.Addr())
if err != nil {
return nil, fmt.Errorf("connect to %s: %w", ss.Addr(), err)
@@ -69,7 +69,7 @@ func (ss *Shadowsocks) DialContext(ctx context.Context, metadata *adapter.Metada
return
}
func (ss *Shadowsocks) DialUDP(_ *adapter.Metadata) (net.PacketConn, error) {
func (ss *Shadowsocks) DialUDP(*M.Metadata) (net.PacketConn, error) {
pc, err := dialer.ListenPacket("udp", "")
if err != nil {
return nil, fmt.Errorf("listen packet: %w", err)
@@ -92,7 +92,7 @@ type ssPacketConn struct {
func (pc *ssPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
var packet []byte
if m, ok := addr.(*adapter.Metadata); ok {
if m, ok := addr.(*M.Metadata); ok {
packet, err = socks5.EncodeUDPPacket(m.SerializesSocksAddr(), b)
} else {
packet, err = socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b)
+10 -11
View File
@@ -4,12 +4,12 @@ import (
"context"
"fmt"
"io"
"io/ioutil"
"net"
"github.com/xjasonlyu/tun2socks/common/adapter"
"github.com/xjasonlyu/tun2socks/component/dialer"
"github.com/xjasonlyu/tun2socks/component/socks5"
M "github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/proxy/proto"
)
var _ Proxy = (*Socks5)(nil)
@@ -23,17 +23,16 @@ type Socks5 struct {
func NewSocks5(addr, user, pass string) (*Socks5, error) {
return &Socks5{
Base: NewBase(addr),
Base: &Base{
addr: addr,
proto: proto.Socks5,
},
user: user,
pass: pass,
}, nil
}
func (ss *Socks5) Proto() string {
return Socks5Proto.String()
}
func (ss *Socks5) DialContext(ctx context.Context, metadata *adapter.Metadata) (c net.Conn, err error) {
func (ss *Socks5) DialContext(ctx context.Context, metadata *M.Metadata) (c net.Conn, err error) {
c, err = dialer.DialContext(ctx, "tcp", ss.Addr())
if err != nil {
return nil, fmt.Errorf("connect to %s: %w", ss.Addr(), err)
@@ -58,7 +57,7 @@ func (ss *Socks5) DialContext(ctx context.Context, metadata *adapter.Metadata) (
return
}
func (ss *Socks5) DialUDP(_ *adapter.Metadata) (_ net.PacketConn, err error) {
func (ss *Socks5) DialUDP(*M.Metadata) (_ net.PacketConn, err error) {
ctx, cancel := context.WithTimeout(context.Background(), tcpConnectTimeout)
defer cancel()
@@ -104,7 +103,7 @@ func (ss *Socks5) DialUDP(_ *adapter.Metadata) (_ net.PacketConn, err error) {
}
go func() {
io.Copy(ioutil.Discard, c)
io.Copy(io.Discard, c)
c.Close()
// A UDP association terminates when the TCP connection that the UDP
// ASSOCIATE request arrived on terminates. RFC1928
@@ -132,7 +131,7 @@ type socksPacketConn struct {
func (pc *socksPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
var packet []byte
if m, ok := addr.(*adapter.Metadata); ok {
if m, ok := addr.(*M.Metadata); ok {
packet, err = socks5.EncodeUDPPacket(m.SerializesSocksAddr(), b)
} else {
packet, err = socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b)
-10
View File
@@ -1,10 +0,0 @@
package stack
import (
"github.com/xjasonlyu/tun2socks/common/adapter"
)
type Handler interface {
Add(adapter.TCPConn)
AddPacket(adapter.UDPPacket)
}
+1 -1
View File
@@ -31,7 +31,7 @@ func getConnections(w http.ResponseWriter, r *http.Request) {
return
}
conn, err := upgrader.Upgrade(w, r, nil)
conn, err := _upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
+6 -6
View File
@@ -8,7 +8,7 @@ import (
"strings"
"time"
"github.com/xjasonlyu/tun2socks/constant"
V "github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/log"
"github.com/xjasonlyu/tun2socks/tunnel/statistic"
@@ -19,7 +19,7 @@ import (
)
var (
upgrader = websocket.Upgrader{
_upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
@@ -60,7 +60,7 @@ func Start(addr, token string) error {
}
func hello(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, render.M{"hello": constant.Name})
render.JSON(w, r, render.M{"hello": V.Name})
}
func authenticator(token string) func(http.Handler) http.Handler {
@@ -114,7 +114,7 @@ func getLogs(w http.ResponseWriter, r *http.Request) {
var wsConn *websocket.Conn
if websocket.IsWebSocketUpgrade(r) {
wsConn, err = upgrader.Upgrade(w, r, nil)
wsConn, err = _upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
@@ -163,7 +163,7 @@ func traffic(w http.ResponseWriter, r *http.Request) {
var wsConn *websocket.Conn
if websocket.IsWebSocketUpgrade(r) {
var err error
wsConn, err = upgrader.Upgrade(w, r, nil)
wsConn, err = _upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
@@ -203,5 +203,5 @@ func traffic(w http.ResponseWriter, r *http.Request) {
}
func version(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, render.M{"version": constant.Version})
render.JSON(w, r, render.M{"version": V.Version, "commit": V.GitCommit})
}
+8 -8
View File
@@ -4,7 +4,7 @@ import (
"net"
"time"
"github.com/xjasonlyu/tun2socks/common/adapter"
M "github.com/xjasonlyu/tun2socks/constant"
"github.com/gofrs/uuid"
"go.uber.org/atomic"
@@ -16,11 +16,11 @@ type tracker interface {
}
type trackerInfo struct {
Start time.Time `json:"start"`
UUID uuid.UUID `json:"id"`
Metadata *adapter.Metadata `json:"metadata"`
UploadTotal *atomic.Int64 `json:"upload"`
DownloadTotal *atomic.Int64 `json:"download"`
Start time.Time `json:"start"`
UUID uuid.UUID `json:"id"`
Metadata *M.Metadata `json:"metadata"`
UploadTotal *atomic.Int64 `json:"upload"`
DownloadTotal *atomic.Int64 `json:"download"`
}
type tcpTracker struct {
@@ -30,7 +30,7 @@ type tcpTracker struct {
manager *Manager
}
func NewTCPTracker(conn net.Conn, metadata *adapter.Metadata, manager *Manager) *tcpTracker {
func NewTCPTracker(conn net.Conn, metadata *M.Metadata, manager *Manager) *tcpTracker {
id, _ := uuid.NewV4()
tt := &tcpTracker{
@@ -81,7 +81,7 @@ type udpTracker struct {
manager *Manager
}
func NewUDPTracker(conn net.PacketConn, metadata *adapter.Metadata, manager *Manager) *udpTracker {
func NewUDPTracker(conn net.PacketConn, metadata *M.Metadata, manager *Manager) *udpTracker {
id, _ := uuid.NewV4()
ut := &udpTracker{
+11 -7
View File
@@ -7,8 +7,9 @@ import (
"sync"
"time"
"github.com/xjasonlyu/tun2socks/common/adapter"
"github.com/xjasonlyu/tun2socks/common/pool"
M "github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/core"
"github.com/xjasonlyu/tun2socks/log"
"github.com/xjasonlyu/tun2socks/proxy"
"github.com/xjasonlyu/tun2socks/tunnel/statistic"
@@ -18,17 +19,20 @@ const (
tcpWaitTimeout = 5 * time.Second
)
func newTCPTracker(conn net.Conn, metadata *adapter.Metadata) net.Conn {
func newTCPTracker(conn net.Conn, metadata *M.Metadata) net.Conn {
return statistic.NewTCPTracker(conn, metadata, statistic.DefaultManager)
}
func handleTCP(localConn adapter.TCPConn) {
func handleTCP(localConn core.TCPConn) {
defer localConn.Close()
metadata := localConn.Metadata()
if !metadata.Valid() {
log.Warnf("[Metadata] not valid: %#v", metadata)
return
id := localConn.ID()
metadata := &M.Metadata{
Net: M.TCP,
SrcIP: net.IP(id.RemoteAddress),
SrcPort: id.RemotePort,
DstIP: net.IP(id.LocalAddress),
DstPort: id.LocalPort,
}
targetConn, err := proxy.Dial(metadata)
+12 -12
View File
@@ -3,7 +3,7 @@ package tunnel
import (
"runtime"
"github.com/xjasonlyu/tun2socks/common/adapter"
"github.com/xjasonlyu/tun2socks/core"
"github.com/xjasonlyu/tun2socks/log"
)
@@ -11,13 +11,13 @@ const (
// maxUDPQueueSize is the max number of UDP packets
// could be buffered. if queue is full, upcoming packets
// would be dropped util queue is ready again.
maxUDPQueueSize = 2 << 10
maxUDPQueueSize = 1 << 9
)
var (
tcpQueue = make(chan adapter.TCPConn) /* unbuffered */
udpQueue = make(chan adapter.UDPPacket, maxUDPQueueSize)
numUDPWorkers = max(runtime.NumCPU(), 4 /* at least 4 workers */)
_tcpQueue = make(chan core.TCPConn) /* unbuffered */
_udpQueue = make(chan core.UDPPacket, maxUDPQueueSize)
_numUDPWorkers = max(runtime.NumCPU(), 4 /* at least 4 workers */)
)
func init() {
@@ -25,14 +25,14 @@ func init() {
}
// Add adds tcpConn to tcpQueue.
func Add(conn adapter.TCPConn) {
tcpQueue <- conn
func Add(conn core.TCPConn) {
_tcpQueue <- conn
}
// AddPacket adds udpPacket to udpQueue.
func AddPacket(packet adapter.UDPPacket) {
func AddPacket(packet core.UDPPacket) {
select {
case udpQueue <- packet:
case _udpQueue <- packet:
default:
log.Warnf("queue is currently full, packet will be dropped")
packet.Drop()
@@ -47,8 +47,8 @@ func max(a, b int) int {
}
func process() {
for i := 0; i < numUDPWorkers; i++ {
queue := udpQueue
for i := 0; i < _numUDPWorkers; i++ {
queue := _udpQueue
go func() {
for packet := range queue {
handleUDP(packet)
@@ -56,7 +56,7 @@ func process() {
}()
}
for conn := range tcpQueue {
for conn := range _tcpQueue {
go handleTCP(conn)
}
}
+33 -24
View File
@@ -7,42 +7,50 @@ import (
"strconv"
"time"
"github.com/xjasonlyu/tun2socks/common/adapter"
"github.com/xjasonlyu/tun2socks/common/pool"
"github.com/xjasonlyu/tun2socks/component/nat"
M "github.com/xjasonlyu/tun2socks/constant"
"github.com/xjasonlyu/tun2socks/core"
"github.com/xjasonlyu/tun2socks/log"
"github.com/xjasonlyu/tun2socks/proxy"
"github.com/xjasonlyu/tun2socks/tunnel/statistic"
)
const (
udpSessionTimeout = 30 * time.Second
)
var (
// natTable uses source udp packet information
// _natTable uses source udp packet information
// as key to store destination udp packetConn.
natTable = nat.NewTable()
_natTable = nat.NewTable()
// _udpSessionTimeout is the default timeout for
// each UDP session.
_udpSessionTimeout = 60 * time.Second
)
func newUDPTracker(conn net.PacketConn, metadata *adapter.Metadata) net.PacketConn {
func SetUDPTimeout(v int) {
_udpSessionTimeout = time.Duration(v) * time.Second
}
func newUDPTracker(conn net.PacketConn, metadata *M.Metadata) net.PacketConn {
return statistic.NewUDPTracker(conn, metadata, statistic.DefaultManager)
}
func handleUDP(packet adapter.UDPPacket) {
metadata := packet.Metadata()
if !metadata.Valid() {
log.Warnf("[Metadata] not valid: %#v", metadata)
return
func handleUDP(packet core.UDPPacket) {
id := packet.ID()
metadata := &M.Metadata{
Net: M.UDP,
SrcIP: net.IP(id.RemoteAddress),
SrcPort: id.RemotePort,
DstIP: net.IP(id.LocalAddress),
DstPort: id.LocalPort,
}
generateNATKey := func(m *adapter.Metadata) string {
return m.SourceAddress() /* Full Cone NAT Key */
generateNATKey := func(m *M.Metadata) string {
return m.SourceAddress() /* as Full Cone NAT Key */
}
key := generateNATKey(metadata)
handle := func(drop bool) bool {
pc := natTable.Get(key)
pc := _natTable.Get(key)
if pc != nil {
handleUDPToRemote(packet, pc, metadata /* as net.Addr */, drop)
return true
@@ -55,7 +63,7 @@ func handleUDP(packet adapter.UDPPacket) {
}
lockKey := key + "-lock"
cond, loaded := natTable.GetOrCreateLock(lockKey)
cond, loaded := _natTable.GetOrCreateLock(lockKey)
go func() {
if loaded {
cond.L.Lock()
@@ -66,7 +74,7 @@ func handleUDP(packet adapter.UDPPacket) {
}
defer func() {
natTable.Delete(lockKey)
_natTable.Delete(lockKey)
cond.Broadcast()
}()
@@ -91,17 +99,17 @@ func handleUDP(packet adapter.UDPPacket) {
go func() {
defer pc.Close()
defer packet.Drop()
defer natTable.Delete(key)
defer _natTable.Delete(key)
handleUDPToLocal(packet, pc, udpSessionTimeout)
handleUDPToLocal(packet, pc)
}()
natTable.Set(key, pc)
_natTable.Set(key, pc)
handle(false /* drop */)
}()
}
func handleUDPToRemote(packet adapter.UDPPacket, pc net.PacketConn, remote net.Addr, drop bool) {
func handleUDPToRemote(packet core.UDPPacket, pc net.PacketConn, remote net.Addr, drop bool) {
defer func() {
if drop {
packet.Drop()
@@ -111,16 +119,17 @@ func handleUDPToRemote(packet adapter.UDPPacket, pc net.PacketConn, remote net.A
if _, err := pc.WriteTo(packet.Data() /* data */, remote); err != nil {
log.Warnf("[UDP] write to %s error: %v", remote, err)
}
pc.SetReadDeadline(time.Now().Add(_udpSessionTimeout)) /* reset timeout */
log.Infof("[UDP] %s --> %s", packet.RemoteAddr(), remote)
}
func handleUDPToLocal(packet adapter.UDPPacket, pc net.PacketConn, timeout time.Duration) {
func handleUDPToLocal(packet core.UDPPacket, pc net.PacketConn) {
buf := pool.Get(pool.MaxSegmentSize)
defer pool.Put(buf)
for /* just loop */ {
pc.SetReadDeadline(time.Now().Add(timeout))
pc.SetReadDeadline(time.Now().Add(_udpSessionTimeout))
n, from, err := pc.ReadFrom(buf)
if err != nil {
if !errors.Is(err, os.ErrDeadlineExceeded) /* ignore i/o timeout */ {