重构代码, 支持 use as library.

现在根目录作为一个可用的库,而可执行文件的代码放在 cmd/verysimple 文件夹中。

只是粗略地使其能够运行,有待进一步重构完善。

同时更新了 Makefile 和 .github/workflows
This commit is contained in:
e1732a364fed
2022-04-25 20:17:51 +08:00
parent a0ef5ca575
commit ba1135d0d5
21 changed files with 614 additions and 539 deletions

View File

@@ -24,18 +24,18 @@ jobs:
- name: Build
run: |
make -f Makefile_release PACK=1 BUILD_VERSION=${{ steps.get_version.outputs.VERSION }}
cd cmd/verysimple/ && make -f Makefile_release main PACK=1 BUILD_VERSION=${{ steps.get_version.outputs.VERSION }}
- name: touch xz archive
shell: bash
run: |
touch -mt $(date +%Y01010000) *.tar.xz
cd cmd/verysimple/ && touch -mt $(date +%Y01010000) *.tar.xz
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
if: github.event_name == 'release'
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./*.tar.xz
file: cmd/verysimple/*.tar.xz
tag: ${{ github.ref }}
file_glob: true

View File

@@ -0,0 +1,37 @@
name: Build For Release
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18
- name: Get version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
- name: Build
run: |
make -f Makefile_release extra PACK=1 BUILD_VERSION=${{ steps.get_version.outputs.VERSION }}
- name: touch xz archive
shell: bash
run: |
touch -mt $(date +%Y01010000) *.tar.xz
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./*.tar.xz
tag: ${{ github.ref }}
file_glob: true

2
.gitignore vendored
View File

@@ -4,7 +4,7 @@ client.toml
server.toml
v2ray_simple
v2ray_simple_*
verysimple
cmd/verysimple/verysimple
verysimple_*
*.exe
*.DS_Store

109
Makefile
View File

@@ -1,107 +1,2 @@
# 该Makefile 只支持linux中使用. 不过幸亏golang厉害交叉编译相当简单
#
# for building with filename "verysimple" and pack into verysimple_xxx.tgz:
# make PACK=1
#
# 简单起见该makefile只支持64位
#
# for embedding geoip file:
# make tags="embed_geoip" macm1
#
# 目前发布版直接使用go1.18编译你如果想编译出相同文件也要使用go1.18才行
# 现在该Makefile文件不用来编译发布包所以这里版本可以随便自己填了,我们也不用每更新一个官方版本就改动一次文件.
# 很棒吧.
# 现在这个Makefile文件是你自己的了随便改.
# 不过 现在 BUILD_VERSION 默认会获取当前git 的 commit id, 你可以自行改成任何值, 比如注释掉第二行, 用第一行
# BUILD_VERSION :=myversion
BUILD_VERSION := $(shell git rev-parse --short HEAD)
prefix :=verysimple
linuxAmd :=_linux_amd64
linuxArm :=_linux_arm64
androidArm64 :=_android_arm64
macosAmd :=_macos
macosArm :=_macm1
windows :=_win10
#这些Fn变量是用于发布包压缩包的名称不是可执行文件名称可执行文件统一叫 verysimple
linuxAmdFn:=${prefix}${linuxAmd}
linuxArmFn:=${prefix}${linuxArm}
macFn :=${prefix}${macosAmd}
macM1Fn :=${prefix}${macosArm}
winFn :=${prefix}${windows}
androidArm64Fn :=${prefix}${androidArm64}
cmd:=go build -tags $(tags) -trimpath -ldflags "-X 'main.Version=${BUILD_VERSION}' -s -w -buildid=" -o
ifdef PACK
define compile
CGO_ENABLED=0 GOOS=$(2) GOARCH=$(3) $(cmd) $(1)
mv $(1) verysimple$(4)
tar -cJf $(1).tar.xz verysimple$(4) examples/
rm verysimple$(4)
endef
else
define compile
CGO_ENABLED=0 GOOS=$(2) GOARCH=$(3) $(cmd) $(1)$(4)
endef
endif
all: linux_amd64 linux_arm64 android_arm64 macos macm1 win10
getver:
@echo $(BUILD_VERSION)
#注意调用参数时,逗号前后不能留空格
linux_amd64:
$(call compile, $(linuxAmdFn),linux,amd64)
linux_arm64:
$(call compile, $(linuxArmFn),linux,arm64)
android_arm64:
$(call compile, $(androidArm64Fn),android,arm64)
macos:
$(call compile, $(macFn),darwin,amd64)
#提供macos 的apple silicon版本.
macm1:
$(call compile, $(macM1Fn),darwin,arm64)
win10:
$(call compile, $(winFn),windows,amd64,.exe)
clean:
rm -f verysimple
rm -f verysimple.exe
rm -f $(linuxAmdFn)
rm -f $(linuxArmFn)
rm -f ${winFn}.exe
rm -f $(macFn)
rm -f $(macM1Fn)
rm -f $(androidArm64Fn)
rm -f $(linuxAmdFn).tar.xz
rm -f $(linuxArmFn).tar.xz
rm -f ${winFn}.tar.xz
rm -f $(macFn).tar.xz
rm -f $(macM1Fn).tar.xz
rm -f $(androidArm64Fn).tar.xz
rmlog:
rm -f vs_log
rm -f vs_log_client
rm -f vs_log_server
all:
cd cmd/verysimple/ && make verysimple_cmd

View File

@@ -1,69 +1,2 @@
#BUILD_VERSION := vx.x.x-beta.x 这个将在github action里自动通过tag配置, 参见 .github/workflows/build_release.yml
prefix :=verysimple
cmd:=go build -tags $(tags) -trimpath -ldflags "-X 'main.Version=${BUILD_VERSION}' -s -w -buildid=" -o
ifdef PACK
define compile
CGO_ENABLED=0 GOOS=$(2) GOARCH=$(3) GOARM=$(5) $(cmd) $(1)
mv $(1) verysimple$(4)
tar -cJf $(1).tar.xz verysimple$(4) examples/
rm verysimple$(4)
endef
else
define compile
CGO_ENABLED=0 GOOS=$(2) GOARCH=$(3) $(cmd) $(1)$(4)
endef
endif
all: linux_amd64 linux_arm64 android_arm64 macos macm1 win10 win10_arm
extra: linux_arm32_v7 linux_mips64 linux_mips win32
# 注意调用参数时,逗号前后不能留空格
# 关于arm版本号 https://github.com/goreleaser/goreleaser/issues/36
linux_amd64:
$(call compile, ${prefix}_linux_amd64,linux,amd64)
linux_arm64:
$(call compile, ${prefix}_linux_arm64,linux,arm64)
linux_arm32_v7:
$(call compile, ${prefix}_linux_arm32_v7a,linux,arm,,7)
linux_mips64:
$(call compile, ${prefix}_linux_mips64,linux,mips64)
linux_mips:
$(call compile, ${prefix}_linux_mips,linux,mips)
android_arm64:
$(call compile, ${prefix}_android_arm64,android,arm64)
macos:
$(call compile, ${prefix}_macOS_intel,darwin,amd64)
macm1:
$(call compile, ${prefix}_macOS_apple,darwin,arm64)
win32:
$(call compile, ${prefix}_win32,windows,386,.exe)
win10:
$(call compile, ${prefix}_win10,windows,amd64,.exe)
win10_arm:
$(call compile, ${prefix}_win10_arm64,windows,arm64,.exe)
clean:
rm -f ${prefix}
rm -f ${prefix}.exe
rm -f ${prefix}_*
rm -f *.tar.xz
all:
cd cmd/verysimple/ && make -f Makefile_release main

View File

@@ -483,6 +483,17 @@ https://github.com/e1732a364fed/v2ray_simple/discussions/3
对于功能的golang test请使用 `go test ./... -count=1` 命令。如果要详细的打印出test的过程可以添加 -v 参数
内网测试命令示例:
在 cmd/verysimple 文件夹中, 打开两个终端,
```
./verysimple -c ../../examples/quic.client.toml -ll 0
```
```
./verysimple -c ../../examples/quic.server.toml -ll 0
```
## 测速
测试环境ubuntu虚拟机, 使用开源测试工具

108
cmd/verysimple/Makefile Normal file
View File

@@ -0,0 +1,108 @@
# 该Makefile 只支持linux中使用. 不过幸亏golang厉害交叉编译相当简单
#
# for building with filename "verysimple" and pack into verysimple_xxx.tgz:
# make PACK=1
#
# 简单起见该makefile只支持64位
#
# for embedding geoip file:
# make tags="embed_geoip" macm1
#
# 目前发布版直接使用go1.18编译你如果想编译出相同文件也要使用go1.18才行
# 现在该Makefile文件不用来编译发布包所以这里版本可以随便自己填了,我们也不用每更新一个官方版本就改动一次文件.
# 很棒吧.
# 现在这个Makefile文件是你自己的了随便改.
# 不过 现在 BUILD_VERSION 默认会获取当前git 的 commit id, 你可以自行改成任何值, 比如注释掉第二行, 用第一行
# BUILD_VERSION :=myversion
BUILD_VERSION := $(shell git rev-parse --short HEAD)
prefix :=verysimple
linuxAmd :=_linux_amd64
linuxArm :=_linux_arm64
androidArm64 :=_android_arm64
macosAmd :=_macos
macosArm :=_macm1
windows :=_win10
#这些Fn变量是用于发布包压缩包的名称不是可执行文件名称可执行文件统一叫 verysimple
linuxAmdFn:=${prefix}${linuxAmd}
linuxArmFn:=${prefix}${linuxArm}
macFn :=${prefix}${macosAmd}
macM1Fn :=${prefix}${macosArm}
winFn :=${prefix}${windows}
androidArm64Fn :=${prefix}${androidArm64}
cmd:=go build -tags $(tags) -trimpath -ldflags "-X 'main.Version=${BUILD_VERSION}' -s -w -buildid=" -o
ifdef PACK
define compile
CGO_ENABLED=0 GOOS=$(2) GOARCH=$(3) $(cmd) $(1)
mv $(1) verysimple$(4)
tar -cJf $(1).tar.xz verysimple$(4) -C ../../ examples/
rm verysimple$(4)
endef
else
define compile
CGO_ENABLED=0 GOOS=$(2) GOARCH=$(3) $(cmd) $(1)$(4)
endef
endif
verysimple_cmd: linux_amd64 linux_arm64 android_arm64 macos macm1 win10
@echo "make verysimple cmd"
getver:
@echo $(BUILD_VERSION)
#注意调用参数时,逗号前后不能留空格
linux_amd64:
$(call compile, $(linuxAmdFn),linux,amd64)
linux_arm64:
$(call compile, $(linuxArmFn),linux,arm64)
android_arm64:
$(call compile, $(androidArm64Fn),android,arm64)
macos:
$(call compile, $(macFn),darwin,amd64)
#提供macos 的apple silicon版本.
macm1:
$(call compile, $(macM1Fn),darwin,arm64)
win10:
$(call compile, $(winFn),windows,amd64,.exe)
clean:
rm -f verysimple
rm -f verysimple.exe
rm -f $(linuxAmdFn)
rm -f $(linuxArmFn)
rm -f ${winFn}.exe
rm -f $(macFn)
rm -f $(macM1Fn)
rm -f $(androidArm64Fn)
rm -f $(linuxAmdFn).tar.xz
rm -f $(linuxArmFn).tar.xz
rm -f ${winFn}.tar.xz
rm -f $(macFn).tar.xz
rm -f $(macM1Fn).tar.xz
rm -f $(androidArm64Fn).tar.xz
rmlog:
rm -f vs_log
rm -f vs_log_client
rm -f vs_log_server

View File

@@ -0,0 +1,69 @@
#BUILD_VERSION := vx.x.x-beta.x 这个将在github action里自动通过tag配置, 参见 .github/workflows/build_release.yml
prefix :=verysimple
cmd:=go build -tags $(tags) -trimpath -ldflags "-X 'main.Version=${BUILD_VERSION}' -s -w -buildid=" -o
ifdef PACK
define compile
CGO_ENABLED=0 GOOS=$(2) GOARCH=$(3) GOARM=$(5) $(cmd) $(1)
mv $(1) verysimple$(4)
tar -cJf $(1).tar.xz verysimple$(4) -C ../../ examples/
rm verysimple$(4)
endef
else
define compile
CGO_ENABLED=0 GOOS=$(2) GOARCH=$(3) $(cmd) $(1)$(4)
endef
endif
main: linux_amd64 linux_arm64 android_arm64 macos macm1 win10 win10_arm
extra: linux_arm32_v7 linux_mips64 linux_mips win32
# 注意调用参数时,逗号前后不能留空格
# 关于arm版本号 https://github.com/goreleaser/goreleaser/issues/36
linux_amd64:
$(call compile, ${prefix}_linux_amd64,linux,amd64)
linux_arm64:
$(call compile, ${prefix}_linux_arm64,linux,arm64)
linux_arm32_v7:
$(call compile, ${prefix}_linux_arm32_v7a,linux,arm,,7)
linux_mips64:
$(call compile, ${prefix}_linux_mips64,linux,mips64)
linux_mips:
$(call compile, ${prefix}_linux_mips,linux,mips)
android_arm64:
$(call compile, ${prefix}_android_arm64,android,arm64)
macos:
$(call compile, ${prefix}_macOS_intel,darwin,amd64)
macm1:
$(call compile, ${prefix}_macOS_apple,darwin,arm64)
win32:
$(call compile, ${prefix}_win32,windows,386,.exe)
win10:
$(call compile, ${prefix}_win10,windows,amd64,.exe)
win10_arm:
$(call compile, ${prefix}_win10_arm64,windows,arm64,.exe)
clean:
rm -f ${prefix}
rm -f ${prefix}.exe
rm -f ${prefix}_*
rm -f *.tar.xz

View File

@@ -8,6 +8,8 @@ import (
"strconv"
"strings"
vs "github.com/e1732a364fed/v2ray_simple"
"github.com/asaskevich/govalidator"
"github.com/e1732a364fed/v2ray_simple/advLayer/quic"
"github.com/e1732a364fed/v2ray_simple/netLayer"
@@ -193,8 +195,8 @@ func generateConfigFileInteractively() {
"将此次生成的配置投入运行(热加载)",
}
confClient := StandardConf{}
confServer := StandardConf{}
confClient := vs.StandardConf{}
confServer := vs.StandardConf{}
var clientStr, serverStr string
@@ -220,7 +222,7 @@ func generateConfigFileInteractively() {
Domains: []string{"geosite:cn"},
}}
confClient.App = &AppConf{MyCountryISO_3166: "CN"}
confClient.App = &vs.AppConf{MyCountryISO_3166: "CN"}
clientStr, err = utils.GetPurgedTomlStr(confClient)
if err != nil {
@@ -247,8 +249,8 @@ func generateConfigFileInteractively() {
fmt.Printf("\n")
case 2: //clear
confClient = StandardConf{}
confServer = StandardConf{}
confClient = vs.StandardConf{}
confServer = vs.StandardConf{}
clientStr = ""
serverStr = ""
case 3: //output
@@ -632,10 +634,10 @@ func interactively_hotRemoveServerOrClient() {
printAllState(os.Stdout)
var items []string
if len(allServers) > 0 {
if len(vs.AllServers) > 0 {
items = append(items, "listen")
}
if len(allClients) > 0 {
if len(vs.AllClients) > 0 {
items = append(items, "dial")
}
@@ -665,7 +667,7 @@ func interactively_hotRemoveServerOrClient() {
var theInt int64
if (will_delete_dial && len(allClients) > 1) || (will_delete_listen && len(allServers) > 1) {
if (will_delete_dial && len(vs.AllClients) > 1) || (will_delete_listen && len(vs.AllServers) > 1) {
validateFunc := func(input string) error {
theInt, err = strconv.ParseInt(input, 10, 64)
@@ -673,11 +675,11 @@ func interactively_hotRemoveServerOrClient() {
return errors.New("Invalid number")
}
if will_delete_dial && int(theInt) >= len(allClients) {
if will_delete_dial && int(theInt) >= len(vs.AllClients) {
return errors.New("must with in len of dial array")
}
if will_delete_listen && int(theInt) >= len(allServers) {
if will_delete_listen && int(theInt) >= len(vs.AllServers) {
return errors.New("must with in len of listen array")
}
@@ -705,15 +707,15 @@ func interactively_hotRemoveServerOrClient() {
will_delete_index = int(theInt)
if will_delete_dial {
allClients[will_delete_index].Stop()
allClients = utils.TrimSlice(allClients, will_delete_index)
vs.AllClients[will_delete_index].Stop()
vs.AllClients = utils.TrimSlice(vs.AllClients, will_delete_index)
}
if will_delete_listen {
listenerArray[will_delete_index].Close()
allServers[will_delete_index].Stop()
vs.ListenerArray[will_delete_index].Close()
vs.AllServers[will_delete_index].Stop()
allServers = utils.TrimSlice(allServers, will_delete_index)
listenerArray = utils.TrimSlice(listenerArray, will_delete_index)
vs.AllServers = utils.TrimSlice(vs.AllServers, will_delete_index)
vs.ListenerArray = utils.TrimSlice(vs.ListenerArray, will_delete_index)
}
@@ -755,7 +757,7 @@ func interactively_hotLoadConfigFile() {
fmt.Printf("你输入了 %s\n", fpath)
standardConf, err = LoadTomlConfFile(fpath)
standardConf, err = vs.LoadTomlConfFile(fpath)
if err != nil {
log.Printf("can not load standard config file: %s\n", err)

View File

@@ -9,6 +9,8 @@ import (
"net/http"
"os"
vs "github.com/e1732a364fed/v2ray_simple"
"github.com/e1732a364fed/v2ray_simple/advLayer"
"github.com/e1732a364fed/v2ray_simple/netLayer"
"github.com/e1732a364fed/v2ray_simple/proxy"
@@ -128,16 +130,16 @@ func tryDownloadMMDB() {
}
func printAllState(w io.Writer) {
fmt.Fprintln(w, "activeConnectionCount", activeConnectionCount)
fmt.Fprintln(w, "allDownloadBytesSinceStart", allDownloadBytesSinceStart)
fmt.Fprintln(w, "allUploadBytesSinceStart", allUploadBytesSinceStart)
fmt.Fprintln(w, "activeConnectionCount", vs.ActiveConnectionCount)
fmt.Fprintln(w, "allDownloadBytesSinceStart", vs.AllDownloadBytesSinceStart)
fmt.Fprintln(w, "allUploadBytesSinceStart", vs.AllUploadBytesSinceStart)
for i, s := range allServers {
for i, s := range vs.AllServers {
fmt.Fprintln(w, "inServer", i, proxy.GetFullName(s), s.AddrStr())
}
for i, c := range allClients {
for i, c := range vs.AllClients {
fmt.Fprintln(w, "outClient", i, proxy.GetFullName(c), c.AddrStr())
}
}
@@ -148,8 +150,8 @@ func tryDownloadGeositeSourceFromConfiguredProxy() {
var outClient proxy.Client
if defaultOutClient != nil {
outClient = defaultOutClient
if vs.DefaultOutClient != nil {
outClient = vs.DefaultOutClient
fmt.Println("trying to download geosite through your proxy dial")
} else {
fmt.Println("trying to download geosite directly")
@@ -165,7 +167,7 @@ func tryDownloadGeositeSourceFromConfiguredProxy() {
protocol = "http"
`
clientConf, err := LoadTomlConfStr(tempClientConfStr)
clientConf, err := vs.LoadTomlConfStr(tempClientConfStr)
if err != nil {
fmt.Println("can not create LoadTomlConfStr: ", err)
@@ -180,7 +182,7 @@ protocol = "http"
listenAddrStr := netLayer.GetRandLocalPrivateAddr(true, false)
clientEndInServer.SetAddrStr(listenAddrStr)
listener = listenSer(clientEndInServer, outClient, false)
listener = vs.ListenSer(clientEndInServer, outClient, false)
proxyurl = "http://" + listenAddrStr
@@ -200,10 +202,10 @@ func hotLoadDialConfForRuntime(conf []*proxy.DialConf) {
log.Println("can not create outClient: ", err)
return
}
if defaultOutClient == nil {
defaultOutClient = outClient
if vs.DefaultOutClient == nil {
vs.DefaultOutClient = outClient
}
allClients = append(allClients, outClient)
vs.AllClients = append(vs.AllClients, outClient)
}
}
@@ -215,8 +217,8 @@ func hotLoadListenConfForRuntime(conf []*proxy.ListenConf) {
log.Println("can not create inServer: ", err)
return
}
listenSer(inServer, defaultOutClient, true)
allServers = append(allServers, inServer)
vs.ListenSer(inServer, vs.DefaultOutClient, true)
vs.AllServers = append(vs.AllServers, inServer)
}

269
cmd/verysimple/main.go Normal file
View File

@@ -0,0 +1,269 @@
package main
import (
"flag"
"fmt"
"log"
"os"
"os/signal"
"runtime/pprof"
"strings"
"syscall"
vs "github.com/e1732a364fed/v2ray_simple"
"github.com/e1732a364fed/v2ray_simple/netLayer"
"github.com/e1732a364fed/v2ray_simple/proxy"
"github.com/e1732a364fed/v2ray_simple/utils"
"github.com/pkg/profile"
"go.uber.org/zap"
)
var (
configFileName string
standardConf vs.StandardConf
startPProf bool
startMProf bool
)
func init() {
flag.StringVar(&configFileName, "c", "client.toml", "config file name")
flag.BoolVar(&startPProf, "pp", false, "pprof")
flag.BoolVar(&startMProf, "mp", false, "memory pprof")
}
func main() {
os.Exit(mainFunc())
}
func mainFunc() (result int) {
defer func() {
if r := recover(); r != nil {
if ce := utils.CanLogFatal("Captured panic!"); ce != nil {
ce.Write(zap.Any("err:", r))
} else {
log.Fatalln("panic captured!", r)
}
result = -3
}
}()
flag.Parse()
if cmdPrintVer {
printVersion_simple()
//根据 cmdPrintVer 的定义, 我们直接退出
return
} else {
printVersion()
}
if !utils.IsFlagGiven("lf") {
if strings.Contains(configFileName, "server") {
utils.LogOutFileName += "_server"
} else if strings.Contains(configFileName, "client") {
utils.LogOutFileName += "_client"
}
}
utils.ShouldLogToFile = true
utils.InitLog()
if startPProf {
f, _ := os.OpenFile("cpu.pprof", os.O_CREATE|os.O_RDWR, 0644)
defer f.Close()
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
if startMProf {
//若不使用 NoShutdownHook, 我们ctrl+c退出时不会产生 pprof文件
p := profile.Start(profile.MemProfile, profile.MemProfileRate(1), profile.NoShutdownHook)
defer p.Stop()
}
utils.Info("Program started")
defer utils.Info("Program exited")
var err error
if standardConf, err = vs.LoadConfig(configFileName); err != nil && !isFlexible() {
log.Printf("no config exist, and no api server or interactive cli enabled, exiting...")
return -1
}
netLayer.Prepare()
fmt.Printf("Log Level:%d\n", utils.LogLevel)
fmt.Printf("UseReadv:%t\n", netLayer.UseReadv)
fmt.Printf("tls_lazy_encrypt:%t\n", vs.Tls_lazy_encrypt)
runPreCommands()
var defaultInServer proxy.Server
//load inServers and vs.RoutePolicy
switch vs.ConfMode {
case vs.SimpleMode:
var hase bool
var eie utils.ErrInErr
defaultInServer, hase, eie = proxy.ServerFromURL(vs.SimpleConf.Server_ThatListenPort_Url)
if hase {
if ce := utils.CanLogErr("can not create local server"); ce != nil {
ce.Write(zap.Error(eie))
}
return -1
}
if !defaultInServer.CantRoute() && vs.SimpleConf.Route != nil {
netLayer.LoadMaxmindGeoipFile("")
//极简模式只支持通过 mycountry进行 geoip分流 这一种情况
vs.RoutePolicy = netLayer.NewRoutePolicy()
if vs.SimpleConf.MyCountryISO_3166 != "" {
vs.RoutePolicy.AddRouteSet(netLayer.NewRouteSetForMyCountry(vs.SimpleConf.MyCountryISO_3166))
}
}
case vs.StandardMode:
vs.LoadCommonComponentsFromStandardConf(&standardConf)
//虽然标准模式支持多个Server目前先只考虑一个
//多个Server存在的话则必须要用 tag指定路由; 然后我们需在预先阶段就判断好tag指定的路由
if len(standardConf.Listen) < 1 {
utils.Warn("no listen in config settings")
break
}
for _, serverConf := range standardConf.Listen {
thisConf := serverConf
if thisConf.Protocol == "tproxy" {
vs.ListenTproxy(thisConf.GetAddrStrForListenOrDial())
continue
}
if thisConf.Uuid == "" && vs.Default_uuid != "" {
thisConf.Uuid = vs.Default_uuid
}
thisServer, err := proxy.NewServer(thisConf)
if err != nil {
if ce := utils.CanLogErr("can not create local server:"); ce != nil {
ce.Write(zap.Error(err))
}
continue
}
vs.AllServers = append(vs.AllServers, thisServer)
if tag := thisServer.GetTag(); tag != "" {
vs.ServersTagMap[tag] = thisServer
}
}
}
// load outClients
switch vs.ConfMode {
case vs.SimpleMode:
var hase bool
var eie utils.ErrInErr
vs.DefaultOutClient, hase, eie = proxy.ClientFromURL(vs.SimpleConf.Client_ThatDialRemote_Url)
if hase {
if ce := utils.CanLogErr("can not create remote client"); ce != nil {
ce.Write(zap.Error(eie))
}
return -1
}
case vs.StandardMode:
if len(standardConf.Dial) < 1 {
utils.Warn("no dial in config settings")
break
}
for _, thisConf := range standardConf.Dial {
if thisConf.Uuid == "" && vs.Default_uuid != "" {
thisConf.Uuid = vs.Default_uuid
}
thisClient, err := proxy.NewClient(thisConf)
if err != nil {
if ce := utils.CanLogErr("can not create remote client: "); ce != nil {
ce.Write(zap.Error(err))
}
continue
}
vs.AllClients = append(vs.AllClients, thisClient)
if tag := thisClient.GetTag(); tag != "" {
vs.ClientsTagMap[tag] = thisClient
}
}
if len(vs.AllClients) > 0 {
vs.DefaultOutClient = vs.AllClients[0]
} else {
vs.DefaultOutClient = vs.DirectClient
}
}
configFileQualifiedToRun := false
if (defaultInServer != nil || len(vs.AllServers) > 0 || len(vs.TproxyList) > 0) && (vs.DefaultOutClient != nil) {
configFileQualifiedToRun = true
if vs.ConfMode == vs.SimpleMode {
vs.ListenSer(defaultInServer, vs.DefaultOutClient, true)
} else {
for _, inServer := range vs.AllServers {
vs.ListenSer(inServer, vs.DefaultOutClient, true)
}
}
}
//没配置可用的listen或者dial而且还无法动态更改配置
if !configFileQualifiedToRun && !isFlexible() {
utils.Error("No valid proxy settings available, exit now.")
return -1
}
if enableApiServer {
go checkConfigAndTryRunApiServer()
}
if interactive_mode {
runCli()
}
{
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)
<-osSignals
utils.Info("Program got close signal.")
//在程序ctrl+C关闭时, 会主动Close所有的监听端口. 主要是被报告windows有时退出程序之后, 端口还是处于占用状态.
// 用下面代码以试图解决端口占用问题.
for _, listener := range vs.ListenerArray {
if listener != nil {
listener.Close()
}
}
for _, tm := range vs.TproxyList {
tm.Stop()
}
}
return
}

View File

@@ -1,4 +1,4 @@
package main
package v2ray_simple
import (
"testing"

View File

@@ -1,4 +1,4 @@
package main
package v2ray_simple
import (
"errors"
@@ -70,7 +70,7 @@ func LoadTomlConfFile(fileNamePath string) (StandardConf, error) {
}
//mainfallback, dnsMachine, routePolicy
func loadCommonComponentsFromStandardConf() {
func LoadCommonComponentsFromStandardConf(standardConf *StandardConf) {
if len(standardConf.Fallbacks) != 0 {
mainFallback = httpLayer.NewClassicFallbackFromConfList(standardConf.Fallbacks)
@@ -98,18 +98,18 @@ func loadCommonComponentsFromStandardConf() {
netLayer.LoadMaxmindGeoipFile("")
routePolicy = netLayer.NewRoutePolicy()
RoutePolicy = netLayer.NewRoutePolicy()
if hasAppLevelMyCountry {
routePolicy.AddRouteSet(netLayer.NewRouteSetForMyCountry(standardConf.App.MyCountryISO_3166))
RoutePolicy.AddRouteSet(netLayer.NewRouteSetForMyCountry(standardConf.App.MyCountryISO_3166))
}
netLayer.LoadRulesForRoutePolicy(standardConf.Route, routePolicy)
netLayer.LoadRulesForRoutePolicy(standardConf.Route, RoutePolicy)
}
}
// 先检查configFileName是否存在存在就尝试加载文件到 standardConf 或者 simpleConf否则尝试 -L参数
func loadConfig() (err error) {
func LoadConfig(configFileName string) (standardConf StandardConf, err error) {
fpath := utils.GetFilePath(configFileName)
if fpath != "" {
@@ -123,11 +123,11 @@ func loadConfig() (err error) {
return
}
confMode = 1
ConfMode = 1
//loglevel 和 noreadv这种会被 命令行覆盖的配置,需要直接在 loadConfig函数中先处理一遍
if appConf := standardConf.App; appConf != nil {
default_uuid = appConf.DefaultUUID
Default_uuid = appConf.DefaultUUID
if appConf.LogLevel != nil && !utils.IsFlagGiven("ll") {
utils.LogLevel = *appConf.LogLevel
@@ -146,19 +146,19 @@ func loadConfig() (err error) {
// 默认所有json格式的文件都为 极简模式
var hasE bool
simpleConf, hasE, err = proxy.LoadSimpleConfigFile(fpath)
SimpleConf, hasE, err = proxy.LoadSimpleConfigFile(fpath)
if hasE {
log.Printf("can not load simple config file: %s\n", err)
return
}
if simpleConf.Fallbacks != nil {
mainFallback = httpLayer.NewClassicFallbackFromConfList(simpleConf.Fallbacks)
if SimpleConf.Fallbacks != nil {
mainFallback = httpLayer.NewClassicFallbackFromConfList(SimpleConf.Fallbacks)
}
confMode = 0
ConfMode = 0
if simpleConf.Client_ThatDialRemote_Url == "" {
simpleConf.Client_ThatDialRemote_Url = "direct://"
if SimpleConf.Client_ThatDialRemote_Url == "" {
SimpleConf.Client_ThatDialRemote_Url = "direct://"
}
return
}
@@ -172,7 +172,7 @@ func loadConfig() (err error) {
return
}
simpleConf = proxy.SimpleConf{
SimpleConf = proxy.SimpleConf{
Server_ThatListenPort_Url: listenURL,
}
@@ -184,7 +184,7 @@ func loadConfig() (err error) {
return
}
simpleConf.Client_ThatDialRemote_Url = dialURL
SimpleConf.Client_ThatDialRemote_Url = dialURL
}
} else {

335
main.go
View File

@@ -1,22 +1,17 @@
package main
package v2ray_simple
import (
"bytes"
"errors"
"flag"
"fmt"
"io"
"log"
"net"
"os"
"os/signal"
"runtime/pprof"
"strings"
"sync/atomic"
"syscall"
"time"
"github.com/pkg/profile"
"go.uber.org/zap"
"github.com/e1732a364fed/v2ray_simple/advLayer/grpc"
@@ -38,62 +33,51 @@ import (
)
const (
simpleMode = iota
standardMode
v2rayCompatibleMode
SimpleMode = iota
StandardMode
V2rayCompatibleMode
)
//统计数据
var (
activeConnectionCount int32
allDownloadBytesSinceStart uint64
allUploadBytesSinceStart uint64
ActiveConnectionCount int32
AllDownloadBytesSinceStart uint64
AllUploadBytesSinceStart uint64
)
var (
configFileName string
uniqueTestDomain string //有时需要测试到单一网站的流量,此时为了避免其它干扰,需要在这里声明 一下 该域名,然后程序里会进行过滤
confMode int = -1 //0: simple json, 1: standard toml, 2: v2ray compatible json
simpleConf proxy.SimpleConf
standardConf StandardConf
directClient, _, _ = proxy.ClientFromURL("direct://")
defaultOutClient proxy.Client
default_uuid string
ConfMode int = -1 //0: simple json, 1: standard toml, 2: v2ray compatible json
SimpleConf proxy.SimpleConf
DirectClient, _, _ = proxy.ClientFromURL("direct://")
DefaultOutClient proxy.Client
Default_uuid string
allServers = make([]proxy.Server, 0, 8)
allClients = make([]proxy.Client, 0, 8)
listenerArray []net.Listener
AllServers = make([]proxy.Server, 0, 8)
AllClients = make([]proxy.Client, 0, 8)
ListenerArray []net.Listener
serversTagMap = make(map[string]proxy.Server)
clientsTagMap = make(map[string]proxy.Client)
ServersTagMap = make(map[string]proxy.Server)
ClientsTagMap = make(map[string]proxy.Client)
listenURL string //用于命令行模式
dialURL string //用于命令行模式
tls_lazy_encrypt bool
tls_lazy_secure bool
Tls_lazy_encrypt bool
Tls_lazy_secure bool
routePolicy *netLayer.RoutePolicy
RoutePolicy *netLayer.RoutePolicy
mainFallback *httpLayer.ClassicFallback
dnsMachine *netLayer.DNSMachine
startPProf bool
startMProf bool
tproxyList []tproxy.Machine
TproxyList []tproxy.Machine
)
func init() {
flag.BoolVar(&startPProf, "pp", false, "pprof")
flag.BoolVar(&startMProf, "mp", false, "memory pprof")
flag.BoolVar(&tls_lazy_encrypt, "lazy", false, "tls lazy encrypt (splice)")
flag.BoolVar(&tls_lazy_secure, "ls", false, "tls lazy secure, use special techs to ensure the tls lazy encrypt data can't be detected. Only valid at client end.")
flag.StringVar(&configFileName, "c", "client.toml", "config file name")
flag.BoolVar(&Tls_lazy_encrypt, "lazy", false, "tls lazy encrypt (splice)")
flag.BoolVar(&Tls_lazy_secure, "ls", false, "tls lazy secure, use special techs to ensure the tls lazy encrypt data can't be detected. Only valid at client end.")
flag.StringVar(&listenURL, "L", "", "listen URL (i.e. the listen part in config file), only enbled when config file is not provided.")
flag.StringVar(&dialURL, "D", "", "dial URL (i.e. the dial part in config file), only enbled when config file is not provided.")
@@ -102,244 +86,9 @@ func init() {
}
func main() {
os.Exit(mainFunc())
}
func mainFunc() (result int) {
defer func() {
if r := recover(); r != nil {
if ce := utils.CanLogFatal("Captured panic!"); ce != nil {
ce.Write(zap.Any("err:", r))
} else {
log.Fatalln("panic captured!", r)
}
result = -3
}
}()
flag.Parse()
if cmdPrintVer {
printVersion_simple()
//根据 cmdPrintVer 的定义, 我们直接退出
return
} else {
printVersion()
}
if !utils.IsFlagGiven("lf") {
if strings.Contains(configFileName, "server") {
utils.LogOutFileName += "_server"
} else if strings.Contains(configFileName, "client") {
utils.LogOutFileName += "_client"
}
}
utils.ShouldLogToFile = true
utils.InitLog()
if startPProf {
f, _ := os.OpenFile("cpu.pprof", os.O_CREATE|os.O_RDWR, 0644)
defer f.Close()
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
if startMProf {
//若不使用 NoShutdownHook, 我们ctrl+c退出时不会产生 pprof文件
p := profile.Start(profile.MemProfile, profile.MemProfileRate(1), profile.NoShutdownHook)
defer p.Stop()
}
utils.Info("Program started")
defer utils.Info("Program exited")
if err := loadConfig(); err != nil && !isFlexible() {
log.Printf("no config exist, and no api server or interactive cli enabled, exiting...")
return -1
}
netLayer.Prepare()
fmt.Printf("Log Level:%d\n", utils.LogLevel)
fmt.Printf("UseReadv:%t\n", netLayer.UseReadv)
fmt.Printf("tls_lazy_encrypt:%t\n", tls_lazy_encrypt)
runPreCommands()
var defaultInServer proxy.Server
//load inServers and routePolicy
switch confMode {
case simpleMode:
var hase bool
var eie utils.ErrInErr
defaultInServer, hase, eie = proxy.ServerFromURL(simpleConf.Server_ThatListenPort_Url)
if hase {
if ce := utils.CanLogErr("can not create local server"); ce != nil {
ce.Write(zap.Error(eie))
}
return -1
}
if !defaultInServer.CantRoute() && simpleConf.Route != nil {
netLayer.LoadMaxmindGeoipFile("")
//极简模式只支持通过 mycountry进行 geoip分流 这一种情况
routePolicy = netLayer.NewRoutePolicy()
if simpleConf.MyCountryISO_3166 != "" {
routePolicy.AddRouteSet(netLayer.NewRouteSetForMyCountry(simpleConf.MyCountryISO_3166))
}
}
case standardMode:
loadCommonComponentsFromStandardConf()
//虽然标准模式支持多个Server目前先只考虑一个
//多个Server存在的话则必须要用 tag指定路由; 然后我们需在预先阶段就判断好tag指定的路由
if len(standardConf.Listen) < 1 {
utils.Warn("no listen in config settings")
break
}
for _, serverConf := range standardConf.Listen {
thisConf := serverConf
if thisConf.Protocol == "tproxy" {
listenTproxy(thisConf.GetAddrStrForListenOrDial())
continue
}
if thisConf.Uuid == "" && default_uuid != "" {
thisConf.Uuid = default_uuid
}
thisServer, err := proxy.NewServer(thisConf)
if err != nil {
if ce := utils.CanLogErr("can not create local server:"); ce != nil {
ce.Write(zap.Error(err))
}
continue
}
allServers = append(allServers, thisServer)
if tag := thisServer.GetTag(); tag != "" {
serversTagMap[tag] = thisServer
}
}
}
// load outClients
switch confMode {
case simpleMode:
var hase bool
var eie utils.ErrInErr
defaultOutClient, hase, eie = proxy.ClientFromURL(simpleConf.Client_ThatDialRemote_Url)
if hase {
if ce := utils.CanLogErr("can not create remote client"); ce != nil {
ce.Write(zap.Error(eie))
}
return -1
}
case standardMode:
if len(standardConf.Dial) < 1 {
utils.Warn("no dial in config settings")
break
}
for _, thisConf := range standardConf.Dial {
if thisConf.Uuid == "" && default_uuid != "" {
thisConf.Uuid = default_uuid
}
thisClient, err := proxy.NewClient(thisConf)
if err != nil {
if ce := utils.CanLogErr("can not create remote client: "); ce != nil {
ce.Write(zap.Error(err))
}
continue
}
allClients = append(allClients, thisClient)
if tag := thisClient.GetTag(); tag != "" {
clientsTagMap[tag] = thisClient
}
}
if len(allClients) > 0 {
defaultOutClient = allClients[0]
} else {
defaultOutClient = directClient
}
}
configFileQualifiedToRun := false
if (defaultInServer != nil || len(allServers) > 0 || len(tproxyList) > 0) && (defaultOutClient != nil) {
configFileQualifiedToRun = true
if confMode == simpleMode {
listenSer(defaultInServer, defaultOutClient, true)
} else {
for _, inServer := range allServers {
listenSer(inServer, defaultOutClient, true)
}
}
}
//没配置可用的listen或者dial而且还无法动态更改配置
if !configFileQualifiedToRun && !isFlexible() {
utils.Error("No valid proxy settings available, exit now.")
return -1
}
if enableApiServer {
go checkConfigAndTryRunApiServer()
}
if interactive_mode {
runCli()
}
{
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)
<-osSignals
utils.Info("Program got close signal.")
//在程序ctrl+C关闭时, 会主动Close所有的监听端口. 主要是被报告windows有时退出程序之后, 端口还是处于占用状态.
// 用下面代码以试图解决端口占用问题.
for _, listener := range listenerArray {
if listener != nil {
listener.Close()
}
}
for _, tm := range tproxyList {
tm.Stop()
}
}
return
}
//非阻塞. 在main函数中被调用。也可以在 test代码中直接使用 listenSer 函数 来手动开启新的转发流程。
//非阻塞. 在main函数中被调用。也可以在 test代码中直接使用 ListenSer 函数 来手动开启新的转发流程。
// 若 not_temporary 为true, 则生成的listener将会被添加到 listenerArray 中
func listenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, not_temporary bool) (thisListener net.Listener) {
func ListenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, not_temporary bool) (thisListener net.Listener) {
var err error
@@ -411,7 +160,7 @@ func listenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, not_
}
if not_temporary {
listenerArray = append(listenerArray, thisListener)
ListenerArray = append(ListenerArray, thisListener)
}
@@ -470,7 +219,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy
forbidDNS_orRoute: forbidDNS_orRoute,
}
iics.isTlsLazyServerEnd = tls_lazy_encrypt && canLazyEncryptServer(inServer)
iics.isTlsLazyServerEnd = Tls_lazy_encrypt && canLazyEncryptServer(inServer)
wrappedConn := thisLocalConnectionInstance
@@ -980,7 +729,7 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
inServer := iics.inServer
//尝试分流, 获取到真正要发向 的 outClient
if !iics.forbidDNS_orRoute && routePolicy != nil && !(inServer != nil && inServer.CantRoute()) {
if !iics.forbidDNS_orRoute && RoutePolicy != nil && !(inServer != nil && inServer.CantRoute()) {
desc := &netLayer.TargetDescription{
Addr: targetAddr,
@@ -993,10 +742,10 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
ce.Write(zap.Any("source", desc))
}
outtag := routePolicy.GetOutTag(desc)
outtag := RoutePolicy.GetOutTag(desc)
if outtag == "direct" {
client = directClient
client = DirectClient
iics.routedToDirect = true
routed = true
@@ -1007,7 +756,7 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
}
} else {
if tagC, ok := clientsTagMap[outtag]; ok {
if tagC, ok := ClientsTagMap[outtag]; ok {
client = tagC
routed = true
if ce := utils.CanLogInfo("Route"); ce != nil {
@@ -1047,7 +796,7 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
iics.inServerTlsRawReadRecorder.StopRecord()
}
} else {
isTlsLazy_clientEnd = tls_lazy_encrypt && canLazyEncryptClient(client)
isTlsLazy_clientEnd = Tls_lazy_encrypt && canLazyEncryptClient(client)
}
@@ -1062,7 +811,7 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
log.Printf("loading TLS SniffConn %t %t\n", isTlsLazy_clientEnd, iics.isTlsLazyServerEnd)
}
wlc = tlsLayer.NewSniffConn(iics.baseLocalConn, wlc, isTlsLazy_clientEnd, tls_lazy_secure)
wlc = tlsLayer.NewSniffConn(iics.baseLocalConn, wlc, isTlsLazy_clientEnd, Tls_lazy_secure)
}
@@ -1266,7 +1015,7 @@ func dialClient(targetAddr netLayer.Addr,
if isTlsLazy_clientEnd {
if tls_lazy_secure && wlc != nil {
if Tls_lazy_secure && wlc != nil {
// 如果使用secure办法则我们每次不能先拨号而是要detect用户的首包后再拨号
// 这种情况只需要客户端操作, 此时我们wrc直接传入原始的 刚拨号好的 tcp连接即 clientConn
@@ -1660,7 +1409,7 @@ func dialClient_andRelay(iics incomingInserverConnState, targetAddr netLayer.Add
if !targetAddr.IsUDP() {
if tls_lazy_encrypt && !iics.routedToDirect {
if Tls_lazy_encrypt && !iics.routedToDirect {
// 我们加了回落之后,就无法确定 “未使用tls的outClient 一定是在服务端” 了
if isTlsLazy_clientEnd {
@@ -1693,11 +1442,11 @@ func dialClient_andRelay(iics incomingInserverConnState, targetAddr netLayer.Add
utils.PutBytes(iics.theFallbackFirstBuffer.Bytes()) //这个Buf不是从utils.GetBuf创建的而是从一个 GetBytes的[]byte 包装 的所以我们要PutBytes而不是PutBuf
}
atomic.AddInt32(&activeConnectionCount, 1)
atomic.AddInt32(&ActiveConnectionCount, 1)
netLayer.Relay(&realTargetAddr, wrc, wlc, &allDownloadBytesSinceStart, &allUploadBytesSinceStart)
netLayer.Relay(&realTargetAddr, wrc, wlc, &AllDownloadBytesSinceStart, &AllUploadBytesSinceStart)
atomic.AddInt32(&activeConnectionCount, -1)
atomic.AddInt32(&ActiveConnectionCount, -1)
return
@@ -1710,12 +1459,12 @@ func dialClient_andRelay(iics incomingInserverConnState, targetAddr netLayer.Add
}
atomic.AddInt32(&activeConnectionCount, 1)
atomic.AddInt32(&ActiveConnectionCount, 1)
if client.IsUDP_MultiChannel() {
utils.Debug("Relaying UDP with MultiChannel")
netLayer.RelayUDP_separate(udp_wrc, udp_wlc, &targetAddr, &allDownloadBytesSinceStart, &allUploadBytesSinceStart, func(raddr netLayer.Addr) netLayer.MsgConn {
netLayer.RelayUDP_separate(udp_wrc, udp_wlc, &targetAddr, &AllDownloadBytesSinceStart, &AllUploadBytesSinceStart, func(raddr netLayer.Addr) netLayer.MsgConn {
utils.Debug("Relaying UDP with MultiChannel,dialfunc called")
_, udp_wrc, _, _, result := dialClient(raddr, client, iics.baseLocalConn, nil, "", false)
@@ -1732,11 +1481,11 @@ func dialClient_andRelay(iics incomingInserverConnState, targetAddr netLayer.Add
})
} else {
netLayer.RelayUDP(udp_wrc, udp_wlc, &allDownloadBytesSinceStart, &allUploadBytesSinceStart)
netLayer.RelayUDP(udp_wrc, udp_wlc, &AllDownloadBytesSinceStart, &AllUploadBytesSinceStart)
}
atomic.AddInt32(&activeConnectionCount, -1)
atomic.AddInt32(&ActiveConnectionCount, -1)
return
}

View File

@@ -1,4 +1,4 @@
package main
package v2ray_simple
import (
"crypto/tls"
@@ -115,8 +115,8 @@ protocol = "direct"
t.FailNow()
}
listenSer(clientEndInServer, clientEndOutClient, false)
listenSer(serverEndInServer, serverEndOutClient, false)
ListenSer(clientEndInServer, clientEndOutClient, false)
ListenSer(serverEndInServer, serverEndOutClient, false)
proxyurl := "http://127.0.0.1:" + clientListenPort

View File

@@ -1,4 +1,4 @@
package main
package v2ray_simple
import (
"io"
@@ -85,7 +85,7 @@ func tryTlsLazyRawCopy(useSecureMethod bool, proxy_client proxy.UserClient, prox
wrcVless := wrc.(*vless.UserTCPConn)
tlsConn := wrcVless.Conn.(*tlsLayer.Conn)
rawWRC = tlsConn.GetRaw(tls_lazy_encrypt)
rawWRC = tlsConn.GetRaw(Tls_lazy_encrypt)
} else {
rawWRC = wrc.(*net.TCPConn) //因为是direct
@@ -97,7 +97,7 @@ func tryTlsLazyRawCopy(useSecureMethod bool, proxy_client proxy.UserClient, prox
}
if tls_lazy_encrypt {
if Tls_lazy_encrypt {
theRecorder.StopRecord()
theRecorder.ReleaseBuffers()
}

View File

@@ -1,4 +1,4 @@
package main
package v2ray_simple
import (
"go.uber.org/zap"
@@ -9,7 +9,7 @@ import (
"github.com/e1732a364fed/v2ray_simple/utils"
)
func listenTproxy(addr string) {
func ListenTproxy(addr string) {
utils.Info("Start running Tproxy")
ad, err := netLayer.NewAddr(addr)
@@ -26,7 +26,7 @@ func listenTproxy(addr string) {
}
udpConn := startLoopUDP(ad)
tproxyList = append(tproxyList, tproxy.Machine{Addr: ad, Listener: lis, UDPConn: udpConn})
TproxyList = append(TproxyList, tproxy.Machine{Addr: ad, Listener: lis, UDPConn: udpConn})
}
@@ -42,7 +42,7 @@ func startLoopTCP(ad netLayer.Addr) (net.Listener, error) {
passToOutClient(incomingInserverConnState{
wrappedConn: tcpconn,
defaultClient: defaultOutClient,
defaultClient: DefaultOutClient,
}, false, tcpconn, nil, targetAddr)
})
@@ -75,7 +75,7 @@ func startLoopUDP(ad netLayer.Addr) *net.UDPConn {
}
go passToOutClient(incomingInserverConnState{
defaultClient: defaultOutClient,
defaultClient: DefaultOutClient,
}, false, nil, msgConn, raddr)
}

View File

@@ -1,12 +1,12 @@
//go:build !linux
// +build !linux
package main
package v2ray_simple
import (
"github.com/e1732a364fed/v2ray_simple/utils"
)
func listenTproxy(addr string) {
func ListenTproxy(addr string) {
utils.Warn("Tproxy not possible on non-linux device")
}

View File

@@ -1,4 +1,4 @@
package main
package v2ray_simple
import (
"fmt"
@@ -190,10 +190,10 @@ protocol = "direct"
t.FailNow()
}
listenSer(clientEndInServer, clientEndOutClient, false)
listenSer(clientEndInServer2, clientEndOutClient, false)
listenSer(clientEndInServer3, clientEndOutClient, false)
listenSer(serverEndInServer, serverEndOutClient, false)
ListenSer(clientEndInServer, clientEndOutClient, false)
ListenSer(clientEndInServer2, clientEndOutClient, false)
ListenSer(clientEndInServer3, clientEndOutClient, false)
ListenSer(serverEndInServer, serverEndOutClient, false)
m := new(dns.Msg)
m.SetQuestion(dns.Fqdn("www.qq.com"), dns.TypeA)