修订文档,代码;添加-dt, -geosite命令行参数, 以及相关的toml配置中的app配置

-dt可调节拨号超时秒数,app配置:dial_timeout
-geosite:app配置:geosite_folder
-geoip: app配置:geoip_file
This commit is contained in:
e1732a364fed
2000-01-01 00:00:00 +00:00
parent c92219d18d
commit 95e0ce32e9
9 changed files with 55 additions and 29 deletions

View File

@@ -14,9 +14,6 @@
本项目不考虑应用 i18n. 这是本项目的强制约定。
以后可以考虑 "zh i18n", 以中文作为基础 然后翻译到别的语言。
# 所发的PR是有优先级的
随着项目不断扩大,一些对不同成分的优化会有不同的优先级
@@ -26,8 +23,8 @@
1. 代理问题如果直接就导致无法代理或闪退这是重大bug必须立即在下一个beta版本修复
2. 协议是否有bug、程序是否有安全问题、内存泄漏问题等这个也很重要。必须在下一个正式版本修复
3. 原作功能补充
4. 新功能添加
5. 代码优化、代码结构性问题。这个因为结构性问题比较复杂,需要慢慢实现,慢慢改
4. 新功能添加, 如果是添加新代理协议,一般要在正式版中加入。
5. 代码优化、代码结构性问题。这个因为结构性问题比较复杂,需要慢慢实现,慢慢改。如果是大范围结构性的改动,在下一个重要版本中加入。
6. 编译优化,这个是低优先级,而且也是很好处理的。
7. 安装教程、一键脚本、安卓客户端等。这个有时间再说,最低优先级。安装教程我也有一份 install.md ,不定时更新。

View File

@@ -21,13 +21,13 @@ var (
simpleConf proxy.SimpleConf
)
//VS 标准toml文件格式 由 proxy.StandardConf 和 AppConf两部分组成
// VS 标准toml文件格式 由 proxy.StandardConf 和 AppConf两部分组成
type VSConf struct {
AppConf *AppConf `toml:"app"`
proxy.StandardConf
}
//AppConf 配置App级别的配置
// AppConf 配置App级别的配置
type AppConf struct {
LogLevel *int `toml:"loglevel"` //需要为指针, 否则无法判断0到底是未给出的默认值还是 显式声明的0
LogFile *string `toml:"logfile"`
@@ -39,6 +39,11 @@ type AppConf struct {
AdminPass string `toml:"admin_pass"` //用于apiServer等情况
UDP_timeout *int `toml:"udp_timeout"`
DialTimeoutSeconds *int `toml:"dial_timeout"`
GeoipFile *string `toml:"geoip_file"`
GeositeFolder *string `toml:"geosite_folder"`
}
func setupByAppConf(ac *AppConf) {
@@ -63,6 +68,19 @@ func setupByAppConf(ac *AppConf) {
netLayer.UDP_timeout = time.Minute * time.Duration(minutes)
}
}
if ac.DialTimeoutSeconds != nil {
if s := *ac.DialTimeoutSeconds; s > 0 {
netLayer.DialTimeout = time.Duration(s) * time.Second
}
}
if ac.GeoipFile != nil {
netLayer.GeoipFileName = *ac.GeoipFile
}
if ac.GeositeFolder != nil {
netLayer.GeositeFolder = *ac.GeositeFolder
}
}
}

View File

@@ -11,6 +11,7 @@ import (
"runtime/pprof"
"strings"
"syscall"
"time"
"github.com/pkg/profile"
"go.uber.org/zap"
@@ -31,6 +32,7 @@ var (
listenURL string //用于命令行模式
dialURL string //用于命令行模式
//jsonMode int
dialTimeoutSecond int
allServers = make([]proxy.Server, 0, 8)
allClients = make([]proxy.Client, 0, 8)
@@ -55,6 +57,9 @@ func init() {
flag.IntVar(&utils.LogLevel, "ll", utils.DefaultLL, "log level,0=debug, 1=info, 2=warning, 3=error, 4=dpanic, 5=panic, 6=fatal")
//有时发现在某些情况下dns查询或者tcp链接的建立很慢甚至超过8秒, 所以开放自定义超时时间,便于在不同环境下测试
flag.IntVar(&dialTimeoutSecond, "dt", int(netLayer.DialTimeout/time.Second), "dial timeout, in second")
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)")
@@ -72,7 +77,8 @@ func init() {
flag.StringVar(&utils.LogOutFileName, "lf", defaultLogFile, "output file for log; If empty, no log file will be used.")
flag.StringVar(&netLayer.GeoipFileName, "geoip", defaultGeoipFn, "geoip maxmind file name")
flag.StringVar(&netLayer.GeoipFileName, "geoip", defaultGeoipFn, "geoip maxmind file name (relative or absolute path)")
flag.StringVar(&netLayer.GeositeFolder, "geosite", netLayer.DefaultGeositeFolder, "geosite folder name (set it to the relative or absolute path of your geosite/data folder)")
flag.StringVar(&utils.ExtraSearchPath, "path", "", "search path for mmdb, geosite and other required files")
}
@@ -134,7 +140,7 @@ func mainFunc() (result int) {
}
// config by bool params
// config params step
{
if disableSplice {
netLayer.SystemCanSplice = false
@@ -167,6 +173,8 @@ func mainFunc() (result int) {
if useNativeUrlFormat {
proxy.UrlFormat = proxy.UrlNativeFormat
}
netLayer.DialTimeout = time.Duration(dialTimeoutSecond) * time.Second
}
var configMode int

View File

@@ -12,6 +12,8 @@ import (
var (
//你可以通过向这个map插入 自定义函数的方式 来拓展 vs的 拨号功能, 可以拨号 其它 net包无法拨号的 network
CustomDialerMap = make(map[string]func(address string, timeout time.Duration) (net.Conn, error))
DialTimeout time.Duration = defaultDialTimeout
)
const (
@@ -101,7 +103,7 @@ defaultPart:
//若tls到达了这里则说明a的ip没有给出而只给出了域名所以上面tcp部分没有直接拨号
if sockopt == nil && localAddr == nil {
resultConn, err = net.DialTimeout("tcp", a.String(), defaultDialTimeout)
resultConn, err = net.DialTimeout("tcp", a.String(), DialTimeout)
} else {
newA := *a
@@ -112,7 +114,7 @@ defaultPart:
} else {
//一般情况下unix domain socket 会到达这里,其他情况则都被前面代码捕获到了
if sockopt == nil {
resultConn, err = net.DialTimeout(a.Network, a.String(), defaultDialTimeout)
resultConn, err = net.DialTimeout(a.Network, a.String(), DialTimeout)
} else {
resultConn, err = a.DialWithOpt(sockopt, localAddr)
}
@@ -143,7 +145,7 @@ dialedPart:
func (a Addr) DialWithOpt(sockopt *Sockopt, localAddr net.Addr) (net.Conn, error) {
dialer := &net.Dialer{
Timeout: defaultDialTimeout,
Timeout: DialTimeout,
}
if localAddr != nil {
dialer.LocalAddr = localAddr

View File

@@ -26,7 +26,7 @@ geosite是v2fly社区维护的非常有用本作以及任何其它项目
geosite数据格式可参考
https://github.com/v2fly/v2ray-core/blob/master/app/router/routercommon/common.proto
or xray app/router/config.proto
or xray's app/router/config.proto
然而我们不引用任何v2ray和xray的代码, 也不使用protobuf
我们只能自行读取该项目原始文件,然后生成自己的数据结构
@@ -76,14 +76,16 @@ wget https://github.com/v2fly/domain-list-community/archive/refs/tags/$tag.tar.x
*/
const DefaultGeositeFolder = "geosite/data"
var (
GeositeListMap = make(map[string]*GeositeList)
geositeFolder = "geosite/data"
GeositeFolder = DefaultGeositeFolder
)
func HasGeositeFolder() bool {
geositeFolder = utils.GetFilePath(geositeFolder)
return utils.DirExist(geositeFolder)
GeositeFolder = utils.GetFilePath(GeositeFolder)
return utils.DirExist(GeositeFolder)
}
// v2fly经典匹配配置
@@ -95,7 +97,7 @@ func HasGeositeFolder() bool {
func IsDomainInsideGeosite(geositeName string, domain string) bool {
geositeName = strings.ToUpper(geositeName)
glist := GeositeListMap[geositeName]
//log.Println("IsDomainInsideGeosite called", geositeName, len(glist))
if glist == nil {
return false
}
@@ -148,9 +150,11 @@ func (mdh MapGeositeDomainHaser) HasDomain(d string) bool {
return found
}
// 从 geosite/data 文件夹中读取所有文件并加载到 GeositeListMap 中.
// 从 GeositeFolder (geosite/data) 文件夹中读取所有文件并加载到 GeositeListMap 中.
//
// 该 geosite/data 就是 github.com/v2fly/domain-list-community 项目的 data文件夹.
//
// todo: 直接加载tar, 而不是分别加载碎片文件. 实现加载tar后就可以把geosite内嵌到vs中。
func LoadGeositeFiles() (err error) {
if !HasGeositeFolder() {
@@ -158,7 +162,7 @@ func LoadGeositeFiles() (err error) {
}
ref := make(map[string]*GeositeRawList)
err = filepath.WalkDir(geositeFolder, func(path string, info fs.DirEntry, err error) error {
err = filepath.WalkDir(GeositeFolder, func(path string, info fs.DirEntry, err error) error {
if err != nil {
return err
}
@@ -190,13 +194,14 @@ func LoadGeositeFiles() (err error) {
}
// DownloadCommunity_DomainListFiles 从 v2fly/domain-list-community 下载数据文件, 并放到 geosite文件夹中。
// 如果已存在geosite文件夹return immediately.
// 如果已存在geosite文件夹,立即return.
//
// 该函数适用于系统中没有git的情况, 如果有git我们直接 git clone就行了,而且还能不断pull进行滚动更新
func DownloadCommunity_DomainListFiles(proxyurl string) {
if HasGeositeFolder() {
utils.PrintStr("geosite/data folder already exists.\n")
utils.PrintStr(GeositeFolder)
utils.PrintStr(" folder already exists.\n")
return
}

View File

@@ -55,9 +55,6 @@ func init() {
type ServerCreator struct{ proxy.CreatorCommonStruct }
func (ServerCreator) URLToListenConf(url *url.URL, lc *proxy.ListenConf, format int) (*proxy.ListenConf, error) {
if format != proxy.StandardMode {
return lc, utils.ErrUnImplemented
}
if lc == nil {
return nil, utils.ErrNilParameter
}

View File

@@ -1,4 +1,4 @@
//Package simplesocks implements SimpleSocks protocol for proxy.Server and proxy.Client.
// Package simplesocks implements SimpleSocks (defined by trojan-go) protocol for proxy.Server and proxy.Client.
//
// See https://p4gefau1t.github.io/trojan-go/developer/simplesocks/
package simplesocks
@@ -28,7 +28,7 @@ var (
crlf = []byte{0x0d, 0x0a}
)
//依照trojan协议的格式读取 地址的域名、ip、port信息
// 依照trojan协议的格式读取 地址的域名、ip、port信息
func GetAddrFrom(buf utils.ByteReader) (addr netLayer.Addr, err error) {
var b1 byte

View File

@@ -22,9 +22,6 @@ func init() {
type ServerCreator struct{ proxy.CreatorCommonStruct }
func (ServerCreator) URLToListenConf(url *url.URL, lc *proxy.ListenConf, format int) (*proxy.ListenConf, error) {
if format != proxy.StandardMode {
return lc, utils.ErrUnImplemented
}
if lc == nil {
return nil, utils.ErrNilParameter
}

View File

@@ -95,6 +95,8 @@ func (s *Server) Handshake(underlay net.Conn) (result net.Conn, msgConn netLayer
returnErr = utils.ErrInErr{ErrDesc: "read underlay failed", ErrDetail: err, Data: wholeReadLen}
return
}
//todo: 根据 https://www.ihcblog.com/a-better-tls-obfs-proxy/
//trojan的 CRLF 是为了模拟http服务器的行为, 所以此时不要一次性Read而是要Read到CRLF为止
if wholeReadLen < 17 {
//根据下面回答HTTP的最小长度恰好是16字节但是是0.9版本。1.0是18字节1.1还要更长。总之我们可以直接不返回fallback地址