feat:添加回落和分流功能.

创建新子包netLayer, 将 proxy.Addr改为 netLayer.Addr
修订文档

RoutePolicy等分流机制也放到 netLayer

引入github.com/oschwald/maxminddb-golang 依赖,支持使用 GeoLite2-Country.mmdb 来进行ip分流

另外注意它默认的版本对于 golang.org/x/sys 包的依赖太老了,会导致go1.18中编译不通过,我在
go.mod 文件中新增了下面代码,就能通过编译了

```
require (
	golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect
)
```

verysimple的可执行文件的相同目录下,必须有该mmdb文件才能够开启ip分流功能

新配置方式:配置文件新加一行 "route":{ "mycountry":"CN" }

mycountry指定的国家的ip会被直连发送,其他地址ip会被发送到代理.

新配置方式,回落,直接在 local 项的 url 的 query部分添加 fallback=:80, 或者 fallback=127.0.0.1:80
即可 回落到指定端口.

将tls_test重新挪动到tlsLayer包中

在main.go中添加了 logLevel变量,并且把关于配置文件的部分挪动到 config.go

出了上面的分流和回落以外,还新增支持了 #xxx 的尾缀,用于配置该url的tag. tag在未来会被用于精准分流

Makefile中新增了 PACK 参数用于编译出 打包版的发行包;可选 tag=embed_geoip 参数用于将mmdb.tgz文件内置到可执行程序里

同时,我开始直接使用go1.18编译本项目,期待性能提升,因为这是新发布的版本,看了介绍据说对 mac m1有20%的提升.
This commit is contained in:
hahahrfool
2022-03-16 19:28:26 +08:00
parent 405207bc56
commit e664b9740e
27 changed files with 664 additions and 170 deletions

78
main.go
View File

@@ -1,11 +1,9 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os"
@@ -25,22 +23,36 @@ import (
"github.com/hahahrfool/v2ray_simple/proxy"
)
const (
log_debug = iota
log_info
log_warning
log_error
)
var (
desc = "v2ray_simple, a very simple implementation of V2Ray, 并且在某些地方试图走在v2ray前面"
configFileName string
uniqueTestDomain string //有时需要测试到单一网站的流量,此时为了避免其它干扰,需要在这里声明 一下 该域名,然后程序里会进行过滤
logLevel int //值越小越唠叨, 废话越多值越大打印的越少见log_开头的常量
conf *Config
//directClient proxy.Client
//另外本作暂时不考虑引入外界log包。依赖越少越好。
conf *Config
directClient proxy.Client
tls_lazy_encrypt bool
tls_lazy_secure bool
routePolicy *netLayer.RoutePolicy
)
func init() {
//directClient, _ = proxy.ClientFromURL("direct://")
directClient, _ = proxy.ClientFromURL("direct://")
flag.IntVar(&logLevel, "ll", log_warning, "log level,0=debug, 1=info, 2=warning, 3=error")
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.")
@@ -59,28 +71,6 @@ func printDesc() {
fmt.Printf("=============== 所有协议均可套tls ================\n")
}
type Config struct {
Server_ThatListenPort_Url string `json:"local"`
//RouteMethod string `json:"route"`
Client_ThatDialRemote_Url string `json:"remote"`
}
func loadConfig(fileName string) (*Config, error) {
path := common.GetFilePath(fileName)
if len(path) > 0 {
if cf, err := os.Open(path); err == nil {
defer cf.Close()
bytes, _ := ioutil.ReadAll(cf)
config := &Config{}
if err = json.Unmarshal(bytes, config); err != nil {
return nil, fmt.Errorf("can not parse config file %v, %v", fileName, err)
}
return config, nil
}
}
return nil, fmt.Errorf("can not load config file %v", fileName)
}
func main() {
printDesc()
@@ -102,6 +92,18 @@ func main() {
}
defer localServer.Stop()
if !localServer.CantRoute() && conf.Route != nil {
netLayer.LoadMaxmindGeoipFile("")
//目前只支持通过 mycountry进行 geoip分流 这一种情况
routePolicy = netLayer.NewRoutePolicy()
if conf.Route.MyCountryISO_3166 != "" {
routePolicy.AddRouteSet(netLayer.NewRouteSetForMyCountry(conf.Route.MyCountryISO_3166))
}
}
remoteClient, err := proxy.ClientFromURL(conf.Client_ThatDialRemote_Url)
if err != nil {
log.Println("can not create remote client: ", err)
@@ -217,9 +219,27 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
afterLocalServerHandshake:
var client proxy.Client
var client proxy.Client = remoteClient
client = remoteClient //如果加了白名单等过滤方式则client可能会等于direct等再说
//如果可以route
if !localServer.CantRoute() && routePolicy != nil {
if logLevel <= log_info {
log.Println("enabling routing feature")
}
//目前只支持一个 localServer/remoteClient, 所以目前根据tag分流是没有意义的以后再说
// 现在就用addr分流就行
outtag := routePolicy.GetOutTag(&netLayer.TargetDescription{
Addr: targetAddr,
})
if outtag == "direct" {
client = directClient
if logLevel <= log_info {
log.Println("routed to direct", targetAddr.UrlString())
}
}
}
// 我们在客户端 lazy_encrypt 探测时读取socks5 传来的信息因为这个和要发送到tls的信息是一模一样的所以就不需要等包上vless、tls后再判断了, 直接解包 socks5进行判断
//