mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-10-24 09:13:21 +08:00
重构代码, 修订文档
This commit is contained in:
@@ -8,8 +8,6 @@ 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"
|
||||
@@ -195,8 +193,8 @@ func generateConfigFileInteractively() {
|
||||
"将此次生成的配置投入运行(热加载)",
|
||||
}
|
||||
|
||||
confClient := vs.StandardConf{}
|
||||
confServer := vs.StandardConf{}
|
||||
confClient := proxy.StandardConf{}
|
||||
confServer := proxy.StandardConf{}
|
||||
|
||||
var clientStr, serverStr string
|
||||
|
||||
@@ -222,7 +220,7 @@ func generateConfigFileInteractively() {
|
||||
Domains: []string{"geosite:cn"},
|
||||
}}
|
||||
|
||||
confClient.App = &vs.AppConf{MyCountryISO_3166: "CN"}
|
||||
confClient.App = &proxy.AppConf{MyCountryISO_3166: "CN"}
|
||||
|
||||
clientStr, err = utils.GetPurgedTomlStr(confClient)
|
||||
if err != nil {
|
||||
@@ -249,8 +247,8 @@ func generateConfigFileInteractively() {
|
||||
fmt.Printf("\n")
|
||||
|
||||
case 2: //clear
|
||||
confClient = vs.StandardConf{}
|
||||
confServer = vs.StandardConf{}
|
||||
confClient = proxy.StandardConf{}
|
||||
confServer = proxy.StandardConf{}
|
||||
clientStr = ""
|
||||
serverStr = ""
|
||||
case 3: //output
|
||||
@@ -634,10 +632,10 @@ func interactively_hotRemoveServerOrClient() {
|
||||
printAllState(os.Stdout)
|
||||
|
||||
var items []string
|
||||
if len(vs.AllServers) > 0 {
|
||||
if len(AllServers) > 0 {
|
||||
items = append(items, "listen")
|
||||
}
|
||||
if len(vs.AllClients) > 0 {
|
||||
if len(AllClients) > 0 {
|
||||
items = append(items, "dial")
|
||||
}
|
||||
|
||||
@@ -667,7 +665,7 @@ func interactively_hotRemoveServerOrClient() {
|
||||
|
||||
var theInt int64
|
||||
|
||||
if (will_delete_dial && len(vs.AllClients) > 1) || (will_delete_listen && len(vs.AllServers) > 1) {
|
||||
if (will_delete_dial && len(AllClients) > 1) || (will_delete_listen && len(AllServers) > 1) {
|
||||
|
||||
validateFunc := func(input string) error {
|
||||
theInt, err = strconv.ParseInt(input, 10, 64)
|
||||
@@ -675,11 +673,11 @@ func interactively_hotRemoveServerOrClient() {
|
||||
return errors.New("Invalid number")
|
||||
}
|
||||
|
||||
if will_delete_dial && int(theInt) >= len(vs.AllClients) {
|
||||
if will_delete_dial && int(theInt) >= len(AllClients) {
|
||||
return errors.New("must with in len of dial array")
|
||||
}
|
||||
|
||||
if will_delete_listen && int(theInt) >= len(vs.AllServers) {
|
||||
if will_delete_listen && int(theInt) >= len(AllServers) {
|
||||
return errors.New("must with in len of listen array")
|
||||
}
|
||||
|
||||
@@ -707,15 +705,15 @@ func interactively_hotRemoveServerOrClient() {
|
||||
will_delete_index = int(theInt)
|
||||
|
||||
if will_delete_dial {
|
||||
vs.AllClients[will_delete_index].Stop()
|
||||
vs.AllClients = utils.TrimSlice(vs.AllClients, will_delete_index)
|
||||
AllClients[will_delete_index].Stop()
|
||||
AllClients = utils.TrimSlice(AllClients, will_delete_index)
|
||||
}
|
||||
if will_delete_listen {
|
||||
vs.ListenerArray[will_delete_index].Close()
|
||||
vs.AllServers[will_delete_index].Stop()
|
||||
ListenerArray[will_delete_index].Close()
|
||||
AllServers[will_delete_index].Stop()
|
||||
|
||||
vs.AllServers = utils.TrimSlice(vs.AllServers, will_delete_index)
|
||||
vs.ListenerArray = utils.TrimSlice(vs.ListenerArray, will_delete_index)
|
||||
AllServers = utils.TrimSlice(AllServers, will_delete_index)
|
||||
ListenerArray = utils.TrimSlice(ListenerArray, will_delete_index)
|
||||
|
||||
}
|
||||
|
||||
@@ -757,7 +755,7 @@ func interactively_hotLoadConfigFile() {
|
||||
|
||||
fmt.Printf("你输入了 %s\n", fpath)
|
||||
|
||||
standardConf, err = vs.LoadTomlConfFile(fpath)
|
||||
standardConf, err = proxy.LoadTomlConfFile(fpath)
|
||||
if err != nil {
|
||||
|
||||
log.Printf("can not load standard config file: %s\n", err)
|
||||
|
||||
@@ -134,12 +134,12 @@ func printAllState(w io.Writer) {
|
||||
fmt.Fprintln(w, "allDownloadBytesSinceStart", vs.AllDownloadBytesSinceStart)
|
||||
fmt.Fprintln(w, "allUploadBytesSinceStart", vs.AllUploadBytesSinceStart)
|
||||
|
||||
for i, s := range vs.AllServers {
|
||||
for i, s := range AllServers {
|
||||
fmt.Fprintln(w, "inServer", i, proxy.GetFullName(s), s.AddrStr())
|
||||
|
||||
}
|
||||
|
||||
for i, c := range vs.AllClients {
|
||||
for i, c := range AllClients {
|
||||
fmt.Fprintln(w, "outClient", i, proxy.GetFullName(c), c.AddrStr())
|
||||
}
|
||||
}
|
||||
@@ -150,8 +150,8 @@ func tryDownloadGeositeSourceFromConfiguredProxy() {
|
||||
|
||||
var outClient proxy.Client
|
||||
|
||||
if vs.DefaultOutClient != nil {
|
||||
outClient = vs.DefaultOutClient
|
||||
if DefaultOutClient != nil {
|
||||
outClient = DefaultOutClient
|
||||
fmt.Println("trying to download geosite through your proxy dial")
|
||||
} else {
|
||||
fmt.Println("trying to download geosite directly")
|
||||
@@ -167,7 +167,7 @@ func tryDownloadGeositeSourceFromConfiguredProxy() {
|
||||
protocol = "http"
|
||||
`
|
||||
|
||||
clientConf, err := vs.LoadTomlConfStr(tempClientConfStr)
|
||||
clientConf, err := proxy.LoadTomlConfStr(tempClientConfStr)
|
||||
if err != nil {
|
||||
fmt.Println("can not create LoadTomlConfStr: ", err)
|
||||
|
||||
@@ -182,7 +182,7 @@ protocol = "http"
|
||||
listenAddrStr := netLayer.GetRandLocalPrivateAddr(true, false)
|
||||
clientEndInServer.SetAddrStr(listenAddrStr)
|
||||
|
||||
listener = vs.ListenSer(clientEndInServer, outClient, false)
|
||||
listener = vs.ListenSer(clientEndInServer, outClient, nil)
|
||||
|
||||
proxyurl = "http://" + listenAddrStr
|
||||
|
||||
@@ -202,23 +202,27 @@ func hotLoadDialConfForRuntime(conf []*proxy.DialConf) {
|
||||
log.Println("can not create outClient: ", err)
|
||||
return
|
||||
}
|
||||
if vs.DefaultOutClient == nil {
|
||||
vs.DefaultOutClient = outClient
|
||||
if DefaultOutClient == nil {
|
||||
DefaultOutClient = outClient
|
||||
}
|
||||
vs.AllClients = append(vs.AllClients, outClient)
|
||||
AllClients = append(AllClients, outClient)
|
||||
}
|
||||
|
||||
}
|
||||
func hotLoadListenConfForRuntime(conf []*proxy.ListenConf) {
|
||||
|
||||
for _, l := range conf {
|
||||
for i, l := range conf {
|
||||
inServer, err := proxy.NewServer(l)
|
||||
if err != nil {
|
||||
log.Println("can not create inServer: ", err)
|
||||
log.Println("can not create inServer: ", i, err)
|
||||
return
|
||||
}
|
||||
vs.ListenSer(inServer, vs.DefaultOutClient, true)
|
||||
vs.AllServers = append(vs.AllServers, inServer)
|
||||
lis := vs.ListenSer(inServer, DefaultOutClient, &RoutingEnv)
|
||||
if lis != nil {
|
||||
ListenerArray = append(ListenerArray, lis)
|
||||
AllServers = append(AllServers, inServer)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime/pprof"
|
||||
@@ -11,7 +12,9 @@ import (
|
||||
"syscall"
|
||||
|
||||
vs "github.com/e1732a364fed/v2ray_simple"
|
||||
"github.com/e1732a364fed/v2ray_simple/httpLayer"
|
||||
"github.com/e1732a364fed/v2ray_simple/netLayer"
|
||||
"github.com/e1732a364fed/v2ray_simple/netLayer/tproxy"
|
||||
"github.com/e1732a364fed/v2ray_simple/proxy"
|
||||
"github.com/e1732a364fed/v2ray_simple/utils"
|
||||
"github.com/pkg/profile"
|
||||
@@ -20,16 +23,35 @@ import (
|
||||
|
||||
var (
|
||||
configFileName string
|
||||
standardConf vs.StandardConf
|
||||
startPProf bool
|
||||
startMProf bool
|
||||
listenURL string //用于命令行模式
|
||||
dialURL string //用于命令行模式
|
||||
jsonMode int
|
||||
|
||||
startPProf bool
|
||||
startMProf bool
|
||||
standardConf proxy.StandardConf
|
||||
simpleConf proxy.SimpleConf
|
||||
|
||||
AllServers = make([]proxy.Server, 0, 8)
|
||||
AllClients = make([]proxy.Client, 0, 8)
|
||||
|
||||
DefaultOutClient proxy.Client
|
||||
|
||||
TproxyList []*tproxy.Machine
|
||||
|
||||
ListenerArray []net.Listener
|
||||
|
||||
RoutingEnv proxy.RoutingEnv
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&configFileName, "c", "client.toml", "config file name")
|
||||
flag.BoolVar(&startPProf, "pp", false, "pprof")
|
||||
flag.BoolVar(&startMProf, "mp", false, "memory pprof")
|
||||
flag.IntVar(&jsonMode, "jm", 0, "json mode, 0:verysimple mode; 1: v2ray mode(not implemented yet)")
|
||||
|
||||
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.")
|
||||
|
||||
}
|
||||
|
||||
@@ -89,8 +111,14 @@ func mainFunc() (result int) {
|
||||
|
||||
utils.Info("Program started")
|
||||
defer utils.Info("Program exited")
|
||||
|
||||
var err error
|
||||
if standardConf, err = vs.LoadConfig(configFileName); err != nil && !isFlexible() {
|
||||
var mode int
|
||||
var mainFallback *httpLayer.ClassicFallback
|
||||
|
||||
standardConf, simpleConf, mode, mainFallback, err = proxy.LoadConfig(configFileName, listenURL, dialURL)
|
||||
|
||||
if err != nil && !isFlexible() {
|
||||
log.Printf("no config exist, and no api server or interactive cli enabled, exiting...")
|
||||
return -1
|
||||
}
|
||||
@@ -104,13 +132,18 @@ func mainFunc() (result int) {
|
||||
runPreCommands()
|
||||
|
||||
var defaultInServer proxy.Server
|
||||
var Default_uuid string
|
||||
|
||||
if mainFallback != nil {
|
||||
RoutingEnv.MainFallback = mainFallback
|
||||
}
|
||||
|
||||
//load inServers and vs.RoutePolicy
|
||||
switch vs.ConfMode {
|
||||
case vs.SimpleMode:
|
||||
switch mode {
|
||||
case proxy.SimpleMode:
|
||||
var hase bool
|
||||
var eie utils.ErrInErr
|
||||
defaultInServer, hase, eie = proxy.ServerFromURL(vs.SimpleConf.Server_ThatListenPort_Url)
|
||||
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))
|
||||
@@ -118,20 +151,20 @@ func mainFunc() (result int) {
|
||||
return -1
|
||||
}
|
||||
|
||||
if !defaultInServer.CantRoute() && vs.SimpleConf.Route != nil {
|
||||
if !defaultInServer.CantRoute() && 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))
|
||||
RoutingEnv.RoutePolicy = netLayer.NewRoutePolicy()
|
||||
if simpleConf.MyCountryISO_3166 != "" {
|
||||
RoutingEnv.RoutePolicy.AddRouteSet(netLayer.NewRouteSetForMyCountry(simpleConf.MyCountryISO_3166))
|
||||
|
||||
}
|
||||
}
|
||||
case vs.StandardMode:
|
||||
case proxy.StandardMode:
|
||||
|
||||
vs.LoadCommonComponentsFromStandardConf(&standardConf)
|
||||
RoutingEnv, Default_uuid = proxy.LoadEnvFromStandardConf(&standardConf)
|
||||
|
||||
//虽然标准模式支持多个Server,目前先只考虑一个
|
||||
//多个Server存在的话,则必须要用 tag指定路由; 然后,我们需在预先阶段就判断好tag指定的路由
|
||||
@@ -144,12 +177,15 @@ func mainFunc() (result int) {
|
||||
for _, serverConf := range standardConf.Listen {
|
||||
thisConf := serverConf
|
||||
if thisConf.Protocol == "tproxy" {
|
||||
vs.ListenTproxy(thisConf.GetAddrStrForListenOrDial())
|
||||
tm := vs.ListenTproxy(thisConf.GetAddrStrForListenOrDial())
|
||||
if tm != nil {
|
||||
TproxyList = append(TproxyList, tm)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if thisConf.Uuid == "" && vs.Default_uuid != "" {
|
||||
thisConf.Uuid = vs.Default_uuid
|
||||
if thisConf.Uuid == "" && Default_uuid != "" {
|
||||
thisConf.Uuid = Default_uuid
|
||||
}
|
||||
|
||||
thisServer, err := proxy.NewServer(thisConf)
|
||||
@@ -160,7 +196,7 @@ func mainFunc() (result int) {
|
||||
continue
|
||||
}
|
||||
|
||||
vs.AllServers = append(vs.AllServers, thisServer)
|
||||
AllServers = append(AllServers, thisServer)
|
||||
if tag := thisServer.GetTag(); tag != "" {
|
||||
vs.ServersTagMap[tag] = thisServer
|
||||
}
|
||||
@@ -169,18 +205,18 @@ func mainFunc() (result int) {
|
||||
}
|
||||
|
||||
// load outClients
|
||||
switch vs.ConfMode {
|
||||
case vs.SimpleMode:
|
||||
switch mode {
|
||||
case proxy.SimpleMode:
|
||||
var hase bool
|
||||
var eie utils.ErrInErr
|
||||
vs.DefaultOutClient, hase, eie = proxy.ClientFromURL(vs.SimpleConf.Client_ThatDialRemote_Url)
|
||||
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 vs.StandardMode:
|
||||
case proxy.StandardMode:
|
||||
|
||||
if len(standardConf.Dial) < 1 {
|
||||
utils.Warn("no dial in config settings")
|
||||
@@ -188,8 +224,8 @@ func mainFunc() (result int) {
|
||||
}
|
||||
|
||||
for _, thisConf := range standardConf.Dial {
|
||||
if thisConf.Uuid == "" && vs.Default_uuid != "" {
|
||||
thisConf.Uuid = vs.Default_uuid
|
||||
if thisConf.Uuid == "" && Default_uuid != "" {
|
||||
thisConf.Uuid = Default_uuid
|
||||
}
|
||||
|
||||
thisClient, err := proxy.NewClient(thisConf)
|
||||
@@ -199,32 +235,39 @@ func mainFunc() (result int) {
|
||||
}
|
||||
continue
|
||||
}
|
||||
vs.AllClients = append(vs.AllClients, thisClient)
|
||||
AllClients = append(AllClients, thisClient)
|
||||
|
||||
if tag := thisClient.GetTag(); tag != "" {
|
||||
vs.ClientsTagMap[tag] = thisClient
|
||||
}
|
||||
}
|
||||
|
||||
if len(vs.AllClients) > 0 {
|
||||
vs.DefaultOutClient = vs.AllClients[0]
|
||||
if len(AllClients) > 0 {
|
||||
DefaultOutClient = AllClients[0]
|
||||
|
||||
} else {
|
||||
vs.DefaultOutClient = vs.DirectClient
|
||||
DefaultOutClient = vs.DirectClient
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
configFileQualifiedToRun := false
|
||||
|
||||
if (defaultInServer != nil || len(vs.AllServers) > 0 || len(vs.TproxyList) > 0) && (vs.DefaultOutClient != nil) {
|
||||
if (defaultInServer != nil || len(AllServers) > 0 || len(TproxyList) > 0) && (DefaultOutClient != nil) {
|
||||
configFileQualifiedToRun = true
|
||||
|
||||
if vs.ConfMode == vs.SimpleMode {
|
||||
vs.ListenSer(defaultInServer, vs.DefaultOutClient, true)
|
||||
if mode == proxy.SimpleMode {
|
||||
lis := vs.ListenSer(defaultInServer, DefaultOutClient, &RoutingEnv)
|
||||
if lis != nil {
|
||||
ListenerArray = append(ListenerArray, lis)
|
||||
}
|
||||
} else {
|
||||
for _, inServer := range vs.AllServers {
|
||||
vs.ListenSer(inServer, vs.DefaultOutClient, true)
|
||||
for _, inServer := range AllServers {
|
||||
lis := vs.ListenSer(inServer, DefaultOutClient, &RoutingEnv)
|
||||
|
||||
if lis != nil {
|
||||
ListenerArray = append(ListenerArray, lis)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,13 +297,13 @@ func mainFunc() (result int) {
|
||||
//在程序ctrl+C关闭时, 会主动Close所有的监听端口. 主要是被报告windows有时退出程序之后, 端口还是处于占用状态.
|
||||
// 用下面代码以试图解决端口占用问题.
|
||||
|
||||
for _, listener := range vs.ListenerArray {
|
||||
for _, listener := range ListenerArray {
|
||||
if listener != nil {
|
||||
listener.Close()
|
||||
}
|
||||
}
|
||||
|
||||
for _, tm := range vs.TproxyList {
|
||||
for _, tm := range TproxyList {
|
||||
tm.Stop()
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/e1732a364fed/v2ray_simple/proxy"
|
||||
)
|
||||
|
||||
func TestLoadTomlConf(t *testing.T) {
|
||||
|
||||
var conf StandardConf
|
||||
var conf proxy.StandardConf
|
||||
_, err := toml.Decode(testTomlConfStr, &conf)
|
||||
|
||||
if err != nil {
|
||||
|
||||
19
doc.go
19
doc.go
@@ -2,26 +2,9 @@
|
||||
Package v2ray_simple provides a way to set up a proxy.
|
||||
|
||||
|
||||
Config Format 配置格式
|
||||
|
||||
一共有三种配置格式,极简模式,标准模式,兼容模式。
|
||||
|
||||
“极简模式”(即 verysimple mode),入口和出口仅有一个,而且都是使用共享链接的url格式来配置.
|
||||
|
||||
标准模式使用toml格式。
|
||||
|
||||
兼容模式可以兼容v2ray现有json格式。(暂未实现)。
|
||||
|
||||
极简模式的理念是,配置文件的字符尽量少,尽量短小精悍;
|
||||
|
||||
还有个命令行模式,就是直接把极简模式的url 放到命令行参数中,比如:
|
||||
|
||||
verysimple -L socks5://sfdfsaf -D direct://
|
||||
|
||||
|
||||
Structure 本项目结构
|
||||
|
||||
utils -> netLayer-> tlsLayer -> httpLayer -> advLayer -> proxy -> v2ray_simple
|
||||
utils -> netLayer-> tlsLayer -> httpLayer -> advLayer -> proxy -> v2ray_simple -> cmd/verysimple
|
||||
|
||||
|
||||
Chain
|
||||
|
||||
70
main.go
70
main.go
@@ -19,7 +19,6 @@ import (
|
||||
"github.com/e1732a364fed/v2ray_simple/advLayer/ws"
|
||||
"github.com/e1732a364fed/v2ray_simple/httpLayer"
|
||||
"github.com/e1732a364fed/v2ray_simple/netLayer"
|
||||
"github.com/e1732a364fed/v2ray_simple/netLayer/tproxy"
|
||||
"github.com/e1732a364fed/v2ray_simple/proxy"
|
||||
"github.com/e1732a364fed/v2ray_simple/tlsLayer"
|
||||
"github.com/e1732a364fed/v2ray_simple/utils"
|
||||
@@ -32,12 +31,6 @@ import (
|
||||
_ "github.com/e1732a364fed/v2ray_simple/proxy/vless"
|
||||
)
|
||||
|
||||
const (
|
||||
SimpleMode = iota
|
||||
StandardMode
|
||||
V2rayCompatibleMode
|
||||
)
|
||||
|
||||
//统计数据
|
||||
var (
|
||||
ActiveConnectionCount int32
|
||||
@@ -46,32 +39,16 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
uniqueTestDomain 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
|
||||
|
||||
ServersTagMap = make(map[string]proxy.Server)
|
||||
ClientsTagMap = make(map[string]proxy.Client)
|
||||
|
||||
listenURL string //用于命令行模式
|
||||
dialURL string //用于命令行模式
|
||||
|
||||
Tls_lazy_encrypt bool
|
||||
Tls_lazy_secure bool
|
||||
|
||||
RoutePolicy *netLayer.RoutePolicy
|
||||
mainFallback *httpLayer.ClassicFallback
|
||||
dnsMachine *netLayer.DNSMachine
|
||||
|
||||
TproxyList []tproxy.Machine
|
||||
//有时需要测试到单一网站的流量,此时为了避免其它干扰,可声明 一下 该域名,然后程序里会进行过滤
|
||||
uniqueTestDomain string
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -79,16 +56,13 @@ func init() {
|
||||
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.")
|
||||
|
||||
flag.StringVar(&uniqueTestDomain, "td", "", "test a single domain, like www.domain.com. Only valid when loglevel=0")
|
||||
|
||||
}
|
||||
|
||||
//非阻塞. 可以 直接使用 ListenSer 函数 来手动开启新的转发流程。
|
||||
// 若 not_temporary 为true, 则生成的listener将会被添加到 listenerArray 中
|
||||
func ListenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, not_temporary bool) (thisListener net.Listener) {
|
||||
// 若 not_temporary 为 false, 则不会使用 RoutingEnv进行路由或回落
|
||||
func ListenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, env *proxy.RoutingEnv) (thisListener net.Listener) {
|
||||
|
||||
var err error
|
||||
|
||||
@@ -144,7 +118,7 @@ func ListenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, not_
|
||||
}
|
||||
|
||||
handleFunc := func(conn net.Conn) {
|
||||
handleNewIncomeConnection(inServer, defaultOutClientForThis, conn, !not_temporary)
|
||||
handleNewIncomeConnection(inServer, defaultOutClientForThis, conn, env)
|
||||
}
|
||||
|
||||
network := inServer.Network()
|
||||
@@ -159,11 +133,6 @@ func ListenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, not_
|
||||
)
|
||||
}
|
||||
|
||||
if not_temporary {
|
||||
ListenerArray = append(ListenerArray, thisListener)
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
if err != nil {
|
||||
utils.ZapLogger.Error(
|
||||
@@ -194,9 +163,6 @@ type incomingInserverConnState struct {
|
||||
inServerTlsConn *tlsLayer.Conn
|
||||
inServerTlsRawReadRecorder *tlsLayer.Recorder
|
||||
|
||||
//shouldFallback bool
|
||||
forbidDNS_orRoute bool
|
||||
|
||||
theFallbackFirstBuffer *bytes.Buffer
|
||||
|
||||
isTlsLazyServerEnd bool
|
||||
@@ -204,19 +170,21 @@ type incomingInserverConnState struct {
|
||||
shouldCloseInSerBaseConnWhenFinish bool
|
||||
|
||||
routedToDirect bool
|
||||
|
||||
RoutingEnv *proxy.RoutingEnv //used in passToOutClient
|
||||
}
|
||||
|
||||
// handleNewIncomeConnection 会处理 网络层至高级层的数据,
|
||||
// 然后将代理层的处理发往 handshakeInserver_and_passToOutClient 函数。
|
||||
//
|
||||
// 在 listenSer 中被调用。
|
||||
func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy.Client, thisLocalConnectionInstance net.Conn, forbidDNS_orRoute bool) {
|
||||
func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy.Client, thisLocalConnectionInstance net.Conn, env *proxy.RoutingEnv) {
|
||||
|
||||
iics := incomingInserverConnState{
|
||||
baseLocalConn: thisLocalConnectionInstance,
|
||||
inServer: inServer,
|
||||
defaultClient: defaultClientForThis,
|
||||
forbidDNS_orRoute: forbidDNS_orRoute,
|
||||
baseLocalConn: thisLocalConnectionInstance,
|
||||
inServer: inServer,
|
||||
defaultClient: defaultClientForThis,
|
||||
RoutingEnv: env,
|
||||
}
|
||||
|
||||
iics.isTlsLazyServerEnd = Tls_lazy_encrypt && canLazyEncryptServer(inServer)
|
||||
@@ -527,7 +495,7 @@ func handshakeInserver(iics *incomingInserverConnState) (wlc net.Conn, udp_wlc n
|
||||
return
|
||||
}
|
||||
|
||||
// 在调用 passToOutClient前遇到err时调用
|
||||
// 在调用 passToOutClient前遇到err时调用, 若找出了buf,设置iics,并返回true
|
||||
func findoutFirstBuf(err error, iics *incomingInserverConnState) bool {
|
||||
if ce := utils.CanLogWarn("failed in inServer proxy handshake"); ce != nil {
|
||||
ce.Write(
|
||||
@@ -594,7 +562,7 @@ func handshakeInserver_and_passToOutClient(iics incomingInserverConnState) {
|
||||
func checkfallback(iics incomingInserverConnState) (targetAddr netLayer.Addr, wlc net.Conn) {
|
||||
//先检查 mainFallback,如果mainFallback中各项都不满足 或者根本没有 mainFallback 再检查 defaultFallback
|
||||
|
||||
if mainFallback != nil {
|
||||
if mf := iics.RoutingEnv.MainFallback; mf != nil {
|
||||
|
||||
utils.Debug("Fallback check")
|
||||
|
||||
@@ -639,7 +607,7 @@ func checkfallback(iics incomingInserverConnState) (targetAddr netLayer.Addr, wl
|
||||
}
|
||||
|
||||
{
|
||||
fbAddr := mainFallback.GetFallback(thisFallbackType, fallback_params...)
|
||||
fbAddr := mf.GetFallback(thisFallbackType, fallback_params...)
|
||||
|
||||
if ce := utils.CanLogDebug("Fallback check"); ce != nil {
|
||||
if fbAddr != nil {
|
||||
@@ -704,13 +672,13 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
|
||||
// 因为在direct时,netLayer.Addr 拨号时,会优先选用ip拨号,而且我们下面的分流阶段 如果使用ip的话,
|
||||
// 可以利用geoip文件, 可以做到国别分流.
|
||||
|
||||
if !iics.forbidDNS_orRoute && dnsMachine != nil && (targetAddr.Name != "" && len(targetAddr.IP) == 0) && targetAddr.Network != "unix" {
|
||||
if iics.RoutingEnv != nil && iics.RoutingEnv.DnsMachine != nil && (targetAddr.Name != "" && len(targetAddr.IP) == 0) && targetAddr.Network != "unix" {
|
||||
|
||||
if ce := utils.CanLogDebug("Dns querying"); ce != nil {
|
||||
ce.Write(zap.String("domain", targetAddr.Name))
|
||||
}
|
||||
|
||||
ip := dnsMachine.Query(targetAddr.Name)
|
||||
ip := iics.RoutingEnv.DnsMachine.Query(targetAddr.Name)
|
||||
|
||||
if ip != nil {
|
||||
targetAddr.IP = ip
|
||||
@@ -729,7 +697,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.RoutingEnv != nil && iics.RoutingEnv.RoutePolicy != nil && !(inServer != nil && inServer.CantRoute()) {
|
||||
|
||||
desc := &netLayer.TargetDescription{
|
||||
Addr: targetAddr,
|
||||
@@ -742,7 +710,7 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
|
||||
ce.Write(zap.Any("source", desc))
|
||||
}
|
||||
|
||||
outtag := RoutePolicy.GetOutTag(desc)
|
||||
outtag := iics.RoutingEnv.RoutePolicy.GetOutTag(desc)
|
||||
|
||||
if outtag == "direct" {
|
||||
client = DirectClient
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package v2ray_simple
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/url"
|
||||
@@ -13,18 +12,9 @@ import (
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/e1732a364fed/v2ray_simple/httpLayer"
|
||||
"github.com/e1732a364fed/v2ray_simple/netLayer"
|
||||
"github.com/e1732a364fed/v2ray_simple/proxy"
|
||||
"github.com/e1732a364fed/v2ray_simple/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
jsonMode int
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.IntVar(&jsonMode, "jm", 0, "json mode, 0:verysimple mode; 1: v2ray mode(not implemented yet)")
|
||||
}
|
||||
|
||||
type AppConf struct {
|
||||
LogLevel *int `toml:"loglevel"` //需要为指针, 否则无法判断0到底是未给出的默认值还是 显式声明的0
|
||||
DefaultUUID string `toml:"default_uuid"`
|
||||
@@ -32,7 +22,7 @@ type AppConf struct {
|
||||
|
||||
NoReadV bool `toml:"noreadv"`
|
||||
|
||||
AdminPass string `toml:"admin_pass"`
|
||||
AdminPass string `toml:"admin_pass"` //用于apiServer等情况
|
||||
|
||||
UDP_timeout *int `toml:"udp_timeout"`
|
||||
}
|
||||
@@ -44,8 +34,8 @@ type StandardConf struct {
|
||||
App *AppConf `toml:"app"`
|
||||
DnsConf *netLayer.DnsConf `toml:"dns"`
|
||||
|
||||
Listen []*proxy.ListenConf `toml:"listen"`
|
||||
Dial []*proxy.DialConf `toml:"dial"`
|
||||
Listen []*ListenConf `toml:"listen"`
|
||||
Dial []*DialConf `toml:"dial"`
|
||||
|
||||
Route []*netLayer.RuleConf `toml:"route"`
|
||||
Fallbacks []*httpLayer.FallbackConf `toml:"fallback"`
|
||||
@@ -69,21 +59,130 @@ func LoadTomlConfFile(fileNamePath string) (StandardConf, error) {
|
||||
|
||||
}
|
||||
|
||||
//mainfallback, dnsMachine, routePolicy
|
||||
func LoadCommonComponentsFromStandardConf(standardConf *StandardConf) {
|
||||
// 先检查configFileName是否存在,存在就尝试加载文件到 standardConf 或者 simpleConf,否则尝试 -L参数
|
||||
func LoadConfig(configFileName, listenURL, dialURL string) (standardConf StandardConf, simpleConf SimpleConf, confMode int, mainFallback *httpLayer.ClassicFallback, err error) {
|
||||
|
||||
fpath := utils.GetFilePath(configFileName)
|
||||
if fpath != "" {
|
||||
|
||||
ext := filepath.Ext(fpath)
|
||||
if ext == ".toml" {
|
||||
standardConf, err = LoadTomlConfFile(fpath)
|
||||
if err != nil {
|
||||
|
||||
log.Printf("can not load standard config file: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
confMode = StandardMode
|
||||
|
||||
//loglevel 和 noreadv这种会被 命令行覆盖的配置,需要直接在 loadConfig函数中先处理一遍
|
||||
if appConf := standardConf.App; appConf != nil {
|
||||
|
||||
if appConf.LogLevel != nil && !utils.IsFlagGiven("ll") {
|
||||
utils.LogLevel = *appConf.LogLevel
|
||||
utils.InitLog()
|
||||
|
||||
}
|
||||
if appConf.NoReadV && !utils.IsFlagGiven("readv") {
|
||||
netLayer.UseReadv = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
} else {
|
||||
|
||||
confMode = SimpleMode
|
||||
simpleConf, mainFallback, err = loadSimpleConf_byFile(fpath)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if listenURL != "" {
|
||||
log.Printf("No Such Config File:%s,will try using -L,-D parameter \n", configFileName)
|
||||
|
||||
confMode = SimpleMode
|
||||
simpleConf, err = loadSimpleConf_byUrl(listenURL, dialURL)
|
||||
} else {
|
||||
log.Printf("no -L listen URL provided \n")
|
||||
err = errors.New("no -L listen URL provided")
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func loadSimpleConf_byFile(fpath string) (simpleConf SimpleConf, mainFallback *httpLayer.ClassicFallback, err error) {
|
||||
//默认认为所有其他后缀的都是json格式,因为有时会用 server.json.vless 这种写法
|
||||
// 默认所有json格式的文件都为 极简模式
|
||||
|
||||
var hasE bool
|
||||
simpleConf, hasE, err = 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)
|
||||
}
|
||||
//ConfMode = 0
|
||||
|
||||
if simpleConf.Client_ThatDialRemote_Url == "" {
|
||||
simpleConf.Client_ThatDialRemote_Url = "direct://"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func loadSimpleConf_byUrl(listenURL, dialURL string) (simpleConf SimpleConf, err error) {
|
||||
|
||||
_, err = url.Parse(listenURL)
|
||||
if err != nil {
|
||||
log.Printf("listenURL given but invalid %s %s\n", listenURL, err)
|
||||
return
|
||||
}
|
||||
|
||||
simpleConf = SimpleConf{
|
||||
Server_ThatListenPort_Url: listenURL,
|
||||
}
|
||||
|
||||
if dialURL != "" {
|
||||
|
||||
_, err = url.Parse(dialURL)
|
||||
if err != nil {
|
||||
log.Printf("dialURL given but invalid %s %s\n", dialURL, err)
|
||||
return
|
||||
}
|
||||
|
||||
simpleConf.Client_ThatDialRemote_Url = dialURL
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type RoutingEnv struct {
|
||||
RoutePolicy *netLayer.RoutePolicy //used in passToOutClient
|
||||
MainFallback *httpLayer.ClassicFallback //used in checkFallback in passToOutClient
|
||||
DnsMachine *netLayer.DNSMachine //used in passToOutClient
|
||||
}
|
||||
|
||||
func LoadEnvFromStandardConf(standardConf *StandardConf) (routingEnv RoutingEnv, Default_uuid string) {
|
||||
|
||||
if len(standardConf.Fallbacks) != 0 {
|
||||
mainFallback = httpLayer.NewClassicFallbackFromConfList(standardConf.Fallbacks)
|
||||
routingEnv.MainFallback = httpLayer.NewClassicFallbackFromConfList(standardConf.Fallbacks)
|
||||
}
|
||||
|
||||
if dnsConf := standardConf.DnsConf; dnsConf != nil {
|
||||
dnsMachine = netLayer.LoadDnsMachine(dnsConf)
|
||||
routingEnv.DnsMachine = netLayer.LoadDnsMachine(dnsConf)
|
||||
}
|
||||
|
||||
var hasAppLevelMyCountry bool
|
||||
|
||||
if appConf := standardConf.App; appConf != nil {
|
||||
|
||||
Default_uuid = appConf.DefaultUUID
|
||||
|
||||
hasAppLevelMyCountry = appConf.MyCountryISO_3166 != ""
|
||||
|
||||
if appConf.UDP_timeout != nil {
|
||||
@@ -98,100 +197,14 @@ func LoadCommonComponentsFromStandardConf(standardConf *StandardConf) {
|
||||
|
||||
netLayer.LoadMaxmindGeoipFile("")
|
||||
|
||||
RoutePolicy = netLayer.NewRoutePolicy()
|
||||
routingEnv.RoutePolicy = netLayer.NewRoutePolicy()
|
||||
if hasAppLevelMyCountry {
|
||||
RoutePolicy.AddRouteSet(netLayer.NewRouteSetForMyCountry(standardConf.App.MyCountryISO_3166))
|
||||
routingEnv.RoutePolicy.AddRouteSet(netLayer.NewRouteSetForMyCountry(standardConf.App.MyCountryISO_3166))
|
||||
|
||||
}
|
||||
|
||||
netLayer.LoadRulesForRoutePolicy(standardConf.Route, RoutePolicy)
|
||||
netLayer.LoadRulesForRoutePolicy(standardConf.Route, routingEnv.RoutePolicy)
|
||||
}
|
||||
}
|
||||
|
||||
// 先检查configFileName是否存在,存在就尝试加载文件到 standardConf 或者 simpleConf,否则尝试 -L参数
|
||||
func LoadConfig(configFileName string) (standardConf StandardConf, err error) {
|
||||
|
||||
fpath := utils.GetFilePath(configFileName)
|
||||
if fpath != "" {
|
||||
|
||||
ext := filepath.Ext(fpath)
|
||||
if ext == ".toml" {
|
||||
standardConf, err = LoadTomlConfFile(fpath)
|
||||
if err != nil {
|
||||
|
||||
log.Printf("can not load standard config file: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
ConfMode = 1
|
||||
|
||||
//loglevel 和 noreadv这种会被 命令行覆盖的配置,需要直接在 loadConfig函数中先处理一遍
|
||||
if appConf := standardConf.App; appConf != nil {
|
||||
Default_uuid = appConf.DefaultUUID
|
||||
|
||||
if appConf.LogLevel != nil && !utils.IsFlagGiven("ll") {
|
||||
utils.LogLevel = *appConf.LogLevel
|
||||
utils.InitLog()
|
||||
|
||||
}
|
||||
if appConf.NoReadV && !utils.IsFlagGiven("readv") {
|
||||
netLayer.UseReadv = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
} else {
|
||||
//默认认为所有其他后缀的都是json格式,因为有时会用 server.json.vless 这种写法
|
||||
// 默认所有json格式的文件都为 极简模式
|
||||
|
||||
var hasE bool
|
||||
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)
|
||||
}
|
||||
ConfMode = 0
|
||||
|
||||
if SimpleConf.Client_ThatDialRemote_Url == "" {
|
||||
SimpleConf.Client_ThatDialRemote_Url = "direct://"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Printf("No Such Config File:%s,will try using -L parameter \n", configFileName)
|
||||
if listenURL != "" {
|
||||
_, err = url.Parse(listenURL)
|
||||
if err != nil {
|
||||
log.Printf("listenURL given but invalid %s %s\n", listenURL, err)
|
||||
return
|
||||
}
|
||||
|
||||
SimpleConf = proxy.SimpleConf{
|
||||
Server_ThatListenPort_Url: listenURL,
|
||||
}
|
||||
|
||||
if dialURL != "" {
|
||||
|
||||
_, err = url.Parse(dialURL)
|
||||
if err != nil {
|
||||
log.Printf("dialURL given but invalid %s %s\n", dialURL, err)
|
||||
return
|
||||
}
|
||||
|
||||
SimpleConf.Client_ThatDialRemote_Url = dialURL
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Printf("no -L listen URL provided \n")
|
||||
err = errors.New("no -L listen URL provided")
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
25
proxy/doc.go
25
proxy/doc.go
@@ -1,5 +1,22 @@
|
||||
/*Package proxy defines necessary components for proxy.
|
||||
|
||||
Config Format 配置格式
|
||||
|
||||
一共有三种配置格式,极简模式,标准模式,兼容模式。
|
||||
|
||||
“极简模式”(即 verysimple mode),入口和出口仅有一个,而且都是使用共享链接的url格式来配置.
|
||||
|
||||
标准模式使用toml格式。
|
||||
|
||||
兼容模式可以兼容v2ray现有json格式。(暂未实现)。
|
||||
|
||||
极简模式的理念是,配置文件的字符尽量少,尽量短小精悍;
|
||||
|
||||
还有个命令行模式,就是直接把极简模式的url 放到命令行参数中,比如:
|
||||
|
||||
verysimple -L socks5://sfdfsaf -D direct://
|
||||
|
||||
|
||||
Layer Definition
|
||||
|
||||
目前认为,一个传输过程大概由四个部分组成,基础连接(udp/tcp),TLS(可选),中间层(ws、grpc、http等,可选),具体协议(socks5,vless,trojan等).
|
||||
@@ -36,7 +53,7 @@ New Model - VSI 新的VSI 模型
|
||||
|
||||
11| -------------- (client real tcp/udp data)
|
||||
--------------------------------------------------------------------------------
|
||||
10| -------------- (inner proxy layer)
|
||||
10| (simplesocks) | (inner proxy layer)
|
||||
--------------------------------------------------------------------------------
|
||||
9 | [client real tcp/udp data] or [inner mux Layer]
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -51,7 +68,7 @@ New Model - VSI 新的VSI 模型
|
||||
4 | tcp/udp/unix domain socket/kcp | transport layer
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
实际上quic属于一种超级协议,横跨传输层一直到高级层,不过为了分类方便,这里认为它也是一种 高级层。
|
||||
另外,实际上quic属于一种超级协议,横跨传输层一直到高级层,不过为了分类方便,这里认为它也是一种 高级层。
|
||||
也就是说,如果遇到横跨多个层的协议,我们认为它属于其中最高的层级。
|
||||
|
||||
|
||||
@@ -93,7 +110,7 @@ New Model - VSI 新的VSI 模型
|
||||
}
|
||||
|
||||
我们项目的文件夹,netLayer 第3,4层,tlsLayer文件夹代表第5层; httpLayer第六层,
|
||||
advLayer文件夹 代表第七层, proxy文件夹代表第8层.
|
||||
advLayer文件夹 代表第七层, proxy文件夹代表第8层或第10层, 同时连带 处理了 第九层.
|
||||
|
||||
|
||||
同级的ws和grpc是独占的,可以都放到一个layer里,然后比如第八层配置了一个vless一个trojan,那么排列组合就是4种,vless+ws, vless+ grpc, trojan+ws, trojan+grpc.
|
||||
@@ -125,7 +142,7 @@ Contents of proxy package - proxy包内容
|
||||
|
||||
使用 RegisterClient 和 RegisterServer 来注册新的实现.
|
||||
|
||||
还定义了关于udp 转发到机制,该部分直接参考 各个UDP开头的 部分即可.
|
||||
还定义了关于udp 转发 的机制,该部分直接参考 relay_udp.go 即可.
|
||||
|
||||
Server and Client
|
||||
|
||||
|
||||
@@ -18,13 +18,20 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
//配置文件格式
|
||||
const (
|
||||
SimpleMode = iota
|
||||
StandardMode
|
||||
V2rayCompatibleMode
|
||||
)
|
||||
|
||||
//规定,如果 proxy的server的handshake如果返回的是具有内层mux的连接,该连接要实现 MuxMarker 接口.
|
||||
type MuxMarker interface {
|
||||
io.ReadWriteCloser
|
||||
IsMux()
|
||||
}
|
||||
|
||||
//实现 MusMarker
|
||||
//实现 MuxMarker
|
||||
type MuxMarkerConn struct {
|
||||
netLayer.ReadWrapper
|
||||
}
|
||||
@@ -206,7 +213,6 @@ type ProxyCommon interface {
|
||||
// verysimple规定,在加载完配置文件后,一个listen和一个dial所使用的全部层级都是确定了的.
|
||||
// 因为所有使用的层级都是确定的,就可以进行针对性优化
|
||||
type ProxyCommonStruct struct {
|
||||
//isdial bool
|
||||
listenConf *ListenConf
|
||||
dialConf *DialConf
|
||||
|
||||
@@ -348,7 +354,7 @@ func (pcs *ProxyCommonStruct) GetClientInnerMuxSession(wrc io.ReadWriteCloser) *
|
||||
}
|
||||
}
|
||||
|
||||
//return false
|
||||
//return false. As a placeholder.
|
||||
func (pcs *ProxyCommonStruct) IsUDP_MultiChannel() bool {
|
||||
return false
|
||||
}
|
||||
@@ -397,7 +403,6 @@ func (s *ProxyCommonStruct) CanFallback() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//return false. As a placeholder.
|
||||
func (s *ProxyCommonStruct) IsHandleInitialLayers() bool {
|
||||
return s.AdvancedL == "quic"
|
||||
}
|
||||
@@ -438,7 +443,6 @@ func (s *ProxyCommonStruct) IsMux() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//return nil. As a placeholder.
|
||||
func (s *ProxyCommonStruct) HandleInitialLayersFunc() func() (newConnChan chan net.Conn, baseConn any) {
|
||||
return s.listenCommonConnFunc
|
||||
}
|
||||
@@ -447,9 +451,6 @@ func (s *ProxyCommonStruct) SetUseTLS() {
|
||||
s.TLS = true
|
||||
}
|
||||
|
||||
//func (s *ProxyCommonStruct) setIsDial(b bool) {
|
||||
// s.isdial = b
|
||||
//}
|
||||
func (s *ProxyCommonStruct) setListenConf(lc *ListenConf) {
|
||||
s.listenConf = lc
|
||||
}
|
||||
@@ -457,19 +458,6 @@ func (s *ProxyCommonStruct) setDialConf(dc *DialConf) {
|
||||
s.dialConf = dc
|
||||
}
|
||||
|
||||
/*
|
||||
//true则为 Dial 端,false 则为 Listen 端
|
||||
func (s *ProxyCommonStruct) IsDial() bool {
|
||||
return s.isdial
|
||||
}
|
||||
func (s *ProxyCommonStruct) GetListenConf() *ListenConf {
|
||||
return s.listenConf
|
||||
}
|
||||
func (s *ProxyCommonStruct) GetDialConf() *DialConf {
|
||||
return s.dialConf
|
||||
}
|
||||
*/
|
||||
|
||||
func (s *ProxyCommonStruct) GetQuic_Client() *quic.Client {
|
||||
return s.quic_c
|
||||
}
|
||||
@@ -478,7 +466,6 @@ func (s *ProxyCommonStruct) setQuic_Client(c *quic.Client) {
|
||||
s.quic_c = c
|
||||
}
|
||||
|
||||
//for outClient
|
||||
func (s *ProxyCommonStruct) GetWS_Client() *ws.Client {
|
||||
return s.ws_c
|
||||
}
|
||||
@@ -490,7 +477,6 @@ func (s *ProxyCommonStruct) GetGRPC_Server() *grpc.Server {
|
||||
return s.grpc_s
|
||||
}
|
||||
|
||||
//for outClient
|
||||
func (s *ProxyCommonStruct) initWS_client() error {
|
||||
if s.dialConf == nil {
|
||||
return errors.New("initWS_client failed when no dialConf assigned")
|
||||
|
||||
@@ -75,12 +75,12 @@ protocol = "direct"
|
||||
|
||||
testServerConfStr := fmt.Sprintf(testServerConfFormatStr, protocol, clientDialPort, version, network)
|
||||
|
||||
clientConf, err := LoadTomlConfStr(testClientConfStr)
|
||||
clientConf, err := proxy.LoadTomlConfStr(testClientConfStr)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
t.FailNow()
|
||||
}
|
||||
serverConf, err := LoadTomlConfStr(testServerConfStr)
|
||||
serverConf, err := proxy.LoadTomlConfStr(testServerConfStr)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
t.FailNow()
|
||||
@@ -115,8 +115,8 @@ protocol = "direct"
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
ListenSer(clientEndInServer, clientEndOutClient, false)
|
||||
ListenSer(serverEndInServer, serverEndOutClient, false)
|
||||
ListenSer(clientEndInServer, clientEndOutClient, nil)
|
||||
ListenSer(serverEndInServer, serverEndOutClient, nil)
|
||||
|
||||
proxyurl := "http://127.0.0.1:" + clientListenPort
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/e1732a364fed/v2ray_simple/utils"
|
||||
)
|
||||
|
||||
func ListenTproxy(addr string) {
|
||||
func ListenTproxy(addr string) (tm *tproxy.Machine) {
|
||||
utils.Info("Start running Tproxy")
|
||||
|
||||
ad, err := netLayer.NewAddr(addr)
|
||||
@@ -26,8 +26,9 @@ func ListenTproxy(addr string) {
|
||||
}
|
||||
udpConn := startLoopUDP(ad)
|
||||
|
||||
TproxyList = append(TproxyList, tproxy.Machine{Addr: ad, Listener: lis, UDPConn: udpConn})
|
||||
tm = &tproxy.Machine{Addr: ad, Listener: lis, UDPConn: udpConn})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//非阻塞
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
package v2ray_simple
|
||||
|
||||
import (
|
||||
"github.com/e1732a364fed/v2ray_simple/netLayer/tproxy"
|
||||
"github.com/e1732a364fed/v2ray_simple/utils"
|
||||
)
|
||||
|
||||
func ListenTproxy(addr string) {
|
||||
func ListenTproxy(addr string) (tm *tproxy.Machine) {
|
||||
utils.Warn("Tproxy not possible on non-linux device")
|
||||
return
|
||||
}
|
||||
|
||||
12
udp_test.go
12
udp_test.go
@@ -136,12 +136,12 @@ protocol = "direct"
|
||||
|
||||
testServerConfStr := fmt.Sprintf(testServerConfFormatStr, protocol, clientDialPort, version, network)
|
||||
|
||||
clientConf, err := LoadTomlConfStr(testClientConfStr)
|
||||
clientConf, err := proxy.LoadTomlConfStr(testClientConfStr)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
t.FailNow()
|
||||
}
|
||||
serverConf, err := LoadTomlConfStr(testServerConfStr)
|
||||
serverConf, err := proxy.LoadTomlConfStr(testServerConfStr)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
t.FailNow()
|
||||
@@ -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, nil)
|
||||
ListenSer(clientEndInServer2, clientEndOutClient, nil)
|
||||
ListenSer(clientEndInServer3, clientEndOutClient, nil)
|
||||
ListenSer(serverEndInServer, serverEndOutClient, nil)
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion(dns.Fqdn("www.qq.com"), dns.TypeA)
|
||||
|
||||
Reference in New Issue
Block a user