mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-10-26 18:21:07 +08:00
修订文档; 将大部分Fatal的代码改为Error.
This commit is contained in:
@@ -61,7 +61,7 @@ win10_arm:
|
||||
|
||||
|
||||
clean:
|
||||
rm -f verysimple
|
||||
rm -f verysimple.exe
|
||||
rm -f ${prefix}
|
||||
rm -f ${prefix}.exe
|
||||
rm -f ${prefix}_*
|
||||
rm -f *.tar.xz
|
||||
|
||||
18
README.md
18
README.md
@@ -171,10 +171,28 @@ tls lazy encrypt 特性 运行时可以用 -lazy 参数打开(服务端客户
|
||||
|
||||
电脑客户端的话直接自己到release下载就行。
|
||||
|
||||
#### 客户端的 geoip和 geosite
|
||||
|
||||
注意如果要geoip分流,而且要自己的mmdb文件的话(高玩情况),还要下载mmdb;
|
||||
|
||||
|
||||
默认第一次运行是会自动下载mmdb文件的,所以不用太担心。
|
||||
|
||||
不过geosite的话,也是需要下载的,可以通过交互模式进行下载,或者通过如下命令下载
|
||||
|
||||
```sh
|
||||
#在verysimple可执行文件所在目录
|
||||
git clone github.com/v2fly/domain-list-community
|
||||
mv domain-list-community geosite
|
||||
```
|
||||
|
||||
通过git下载的好处是, 自己想要更新时,直接 `git pull` 即可;
|
||||
|
||||
通过 交互模式进行下载的好处是, 如果你配置了配置文件, 并且有一个可用的节点, 则交互模式优先通过你的节点来下载geosite.
|
||||
|
||||
这样可以避免github被墙的情况。
|
||||
|
||||
|
||||
### 编译安装
|
||||
|
||||
```sh
|
||||
|
||||
13
commands.go
13
commands.go
@@ -59,8 +59,17 @@ func init() {
|
||||
|
||||
cliCmdList = append(cliCmdList, CliCmd{
|
||||
"生成随机ssl证书", func() {
|
||||
tlsLayer.GenerateRandomCertKeyFiles("yourcert.pem", "yourcert.key")
|
||||
fmt.Printf("生成成功!请查看目录中的 yourcert.pem 和 yourcert.key")
|
||||
err := tlsLayer.GenerateRandomCertKeyFiles("yourcert.pem", "yourcert.key")
|
||||
if err == nil {
|
||||
fmt.Printf("生成成功!请查看目录中的 yourcert.pem 和 yourcert.key")
|
||||
|
||||
} else {
|
||||
|
||||
log.Printf("生成失败,")
|
||||
log.Printf(err.Error())
|
||||
log.Printf("\n")
|
||||
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ func loadConfig() (err error) {
|
||||
|
||||
if appConf.LogLevel != nil && !utils.IsFlagPassed("ll") {
|
||||
utils.LogLevel = *appConf.LogLevel
|
||||
utils.InitLog()
|
||||
|
||||
}
|
||||
if appConf.NoReadV && !utils.IsFlagPassed("readv") {
|
||||
|
||||
@@ -19,29 +19,25 @@
|
||||
api在不复杂时,可以使用纯空格、换行符 分隔的字符串形式,或者toml的形式.
|
||||
|
||||
### 功能列表
|
||||
1. 生成toml配置文件功能
|
||||
2. 动态调节当前运行时 所用的 LogLevel
|
||||
3. 查看本次程序开始运行起所使用的流量(双向)
|
||||
1. 生成toml配置文件功能【已实现】
|
||||
2. 动态调节当前运行时 所用的 LogLevel 【已实现】
|
||||
3. 查看本次程序开始运行起所使用的流量(双向)【已实现下载流量查询】
|
||||
4. 查看自某一天开始所用掉的总流量
|
||||
5. 动态插入一个 新 inServer / outClient;
|
||||
5. 动态插入一个 新 inServer / outClient;【已实现】
|
||||
6. 动态修改 某个 inServer/outClient 的 uuid
|
||||
7. 动态调节 hy手动挡阻控模式 的发送速率
|
||||
8. 动态删除一个 inServer /outClient
|
||||
7. 动态调节 hy手动挡阻控模式 的发送速率【已实现】
|
||||
8. 动态删除一个 inServer /outClient【已实现】
|
||||
9. 动态控制每一个 inServer / outClient 的网速上限 (不太好实现)
|
||||
|
||||
其它小功能
|
||||
1. 生成uuid
|
||||
2. 生成随机证书 以及对应私钥
|
||||
1. 生成uuid【已实现】
|
||||
2. 生成随机证书 以及对应私钥【已实现】
|
||||
|
||||
# 原始函数、命令行 与 API的关系
|
||||
|
||||
每一个API都要有对应的原始golang函数, 然后命令行命令与 api都会调用该原始函数。
|
||||
每一个API都尽量有对应的原始golang函数, 然后命令行命令与 api都会调用该原始函数。
|
||||
|
||||
我们每一个API,在API功能允许的情况下,都要有对应的命令行参数,可在程序刚运行时就返回一个字符串结果
|
||||
|
||||
|
||||
但是交互模式下,动态生成配置文件的机制,要更复杂;
|
||||
它要一项一项去提示输入,然后生成配置文件,这个是个重点,也不是简单的api能做到的。
|
||||
我们每一个API,在API功能允许的情况下,都应该要有对应的命令行参数,可在程序刚运行时就返回一个字符串结果
|
||||
|
||||
本作规定,原始函数、命令行 与 API 这三个功能 的go文件 全部放在 项目根目录。
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package httpLayer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
|
||||
"github.com/hahahrfool/v2ray_simple/netLayer"
|
||||
"github.com/hahahrfool/v2ray_simple/utils"
|
||||
@@ -304,11 +303,12 @@ func NewClassicFallbackFromConfList(fcl []*FallbackConf) *ClassicFallback {
|
||||
for _, fc := range fcl {
|
||||
addr, err := netLayer.NewAddrFromAny(fc.Dest)
|
||||
if err != nil {
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal("NewClassicFallbackFromConfList, netLayer.NewAddrFromAny err", zap.Error(err))
|
||||
} else {
|
||||
log.Fatalln("NewClassicFallbackFromConfList, netLayer.NewAddrFromAny err", err)
|
||||
if ce := utils.CanLogErr("NewClassicFallbackFromConfList failed"); ce != nil {
|
||||
ce.Write(zap.String("netLayer.NewAddrFromAny err", err.Error()))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
var aMask byte
|
||||
if len(fc.Alpn) > 2 {
|
||||
|
||||
27
main.go
27
main.go
@@ -100,6 +100,7 @@ func main() {
|
||||
printVersion()
|
||||
|
||||
}
|
||||
utils.InitLog()
|
||||
|
||||
if startPProf {
|
||||
f, _ := os.OpenFile("cpu.pprof", os.O_CREATE|os.O_RDWR, 0644)
|
||||
@@ -126,8 +127,6 @@ func main() {
|
||||
fmt.Printf("Log Level:%d\n", utils.LogLevel)
|
||||
fmt.Printf("UseReadv:%t\n", netLayer.UseReadv)
|
||||
|
||||
utils.InitLog()
|
||||
|
||||
runPreCommands()
|
||||
|
||||
var defaultInServer proxy.Server
|
||||
@@ -174,7 +173,10 @@ func main() {
|
||||
|
||||
thisServer, err := proxy.NewServer(thisConf)
|
||||
if err != nil {
|
||||
log.Fatalln("can not create local server: ", err)
|
||||
if ce := utils.CanLogErr("can not create local server:"); ce != nil {
|
||||
ce.Write(zap.Error(err))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
allServers = append(allServers, thisServer)
|
||||
@@ -208,7 +210,10 @@ func main() {
|
||||
|
||||
thisClient, err := proxy.NewClient(thisConf)
|
||||
if err != nil {
|
||||
log.Fatalln("can not create remote client: ", err)
|
||||
if ce := utils.CanLogErr("can not create remote client: "); ce != nil {
|
||||
ce.Write(zap.Error(err))
|
||||
}
|
||||
continue
|
||||
}
|
||||
allClients = append(allClients, thisClient)
|
||||
|
||||
@@ -217,7 +222,13 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
defaultOutClient = allClients[0]
|
||||
if len(allClients) > 0 {
|
||||
defaultOutClient = allClients[0]
|
||||
|
||||
} else {
|
||||
defaultOutClient = directClient
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 后台运行主代码,而main函数只监听中断信号
|
||||
@@ -282,7 +293,7 @@ func listenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, not_
|
||||
|
||||
handleFunc := inServer.HandleInitialLayersFunc()
|
||||
if handleFunc == nil {
|
||||
utils.Fatal("inServer.IsHandleInitialLayers but inServer.HandleInitialLayersFunc() returns nil")
|
||||
panic("inServer.IsHandleInitialLayers but inServer.HandleInitialLayersFunc() returns nil")
|
||||
}
|
||||
|
||||
//baseConn可以为nil,quic就是如此
|
||||
@@ -349,7 +360,7 @@ func listenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client, not_
|
||||
|
||||
} else {
|
||||
if err != nil {
|
||||
utils.ZapLogger.Fatal(
|
||||
utils.ZapLogger.Error(
|
||||
"can not listen inServer on %s %s\n", zap.String("addr", inServer.AddrStr()), zap.Error(err))
|
||||
|
||||
}
|
||||
@@ -647,7 +658,7 @@ func handshakeInserver_and_passToOutClient(iics incomingInserverConnState) {
|
||||
if iics.theFallbackFirstBuffer == nil {
|
||||
//不应该,至少能读到1字节的。
|
||||
|
||||
utils.Fatal("No FirstBuffer")
|
||||
panic("No FirstBuffer")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package netLayer
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
@@ -20,21 +19,35 @@ type SpecialDnsServerConf struct {
|
||||
Domains []string `toml:"domain"` //指定哪些域名需要通过 该dns服务器进行查询
|
||||
}
|
||||
|
||||
func loadSpecialDnsServerConf_fromTomlUnmarshaledMap(m map[string]any) *SpecialDnsServerConf {
|
||||
func loadSpecialDnsServerConf_fromTomlUnmarshalledMap(m map[string]any) *SpecialDnsServerConf {
|
||||
addr := m["addr"]
|
||||
if addr == nil {
|
||||
|
||||
if ce := utils.CanLogErr("LoadDnsMachine, addr required"); ce != nil {
|
||||
ce.Write()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
addrStr, ok := addr.(string)
|
||||
if !ok {
|
||||
if ce := utils.CanLogErr("LoadDnsMachine, addr not a string"); ce != nil {
|
||||
ce.Write()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
domains := m["domain"]
|
||||
if domains == nil {
|
||||
if ce := utils.CanLogErr("LoadDnsMachine, domain required"); ce != nil {
|
||||
ce.Write()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
domainsAnySlice, ok := domains.([]any)
|
||||
if !ok {
|
||||
if ce := utils.CanLogErr("LoadDnsMachine, domain not a list"); ce != nil {
|
||||
ce.Write()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
domainsSlice := []string{}
|
||||
@@ -42,6 +55,9 @@ func loadSpecialDnsServerConf_fromTomlUnmarshaledMap(m map[string]any) *SpecialD
|
||||
for _, anyD := range domainsAnySlice {
|
||||
dstr, ok := anyD.(string)
|
||||
if !ok {
|
||||
if ce := utils.CanLogErr("LoadDnsMachine, domain list contains non-string item"); ce != nil {
|
||||
ce.Write()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
domainsSlice = append(domainsSlice, dstr)
|
||||
@@ -59,7 +75,6 @@ func LoadDnsMachine(conf *DnsConf) *DNSMachine {
|
||||
var ok = false
|
||||
|
||||
if len(conf.Servers) > 0 {
|
||||
//log.Println("conf.Servers", conf.Servers)
|
||||
ok = true
|
||||
servers := conf.Servers
|
||||
|
||||
@@ -70,6 +85,10 @@ func LoadDnsMachine(conf *DnsConf) *DNSMachine {
|
||||
case string:
|
||||
ad, e := NewAddrByURL(server)
|
||||
if e != nil {
|
||||
if ce := utils.CanLogErr("LoadDnsMachine parse server url failed"); ce != nil {
|
||||
ce.Write(zap.Error(e))
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -77,21 +96,35 @@ func LoadDnsMachine(conf *DnsConf) *DNSMachine {
|
||||
|
||||
case map[string]any:
|
||||
|
||||
realServer := loadSpecialDnsServerConf_fromTomlUnmarshaledMap(server)
|
||||
realServer := loadSpecialDnsServerConf_fromTomlUnmarshalledMap(server)
|
||||
if realServer == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(realServer.Domains) <= 0 { //既然是特殊dns服务器, 那么就必须指定哪些域名要使用该dns服务器进行查询
|
||||
if ce := utils.CanLogErr("LoadDnsMachine, special domain list required"); ce != nil {
|
||||
ce.Write()
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
addr, e := NewAddrByURL(realServer.AddrUrlStr)
|
||||
if e != nil {
|
||||
|
||||
if ce := utils.CanLogErr("LoadDnsMachine, server url invalid"); ce != nil {
|
||||
ce.Write(zap.Error(e))
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if err := dm.AddNewServer(realServer.AddrUrlStr, &addr); err != nil {
|
||||
|
||||
if ce := utils.CanLogErr("LoadDnsMachine, AddNewServer failed"); ce != nil {
|
||||
ce.Write(zap.Error(err))
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -121,12 +154,12 @@ func LoadDnsMachine(conf *DnsConf) *DNSMachine {
|
||||
for _, str := range value {
|
||||
ad, err := NewAddrFromAny(str)
|
||||
if err != nil {
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal("LoadDnsMachine loading host err", zap.Error(err))
|
||||
} else {
|
||||
log.Fatalf("LoadDnsMachine loading host err %s\n", err)
|
||||
|
||||
if ce := utils.CanLogErr("LoadDnsMachine loading SpecialIP from list failed"); ce != nil {
|
||||
ce.Write(zap.Error(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
dm.SpecialIPPollicy[thishost] = append(dm.SpecialIPPollicy[thishost], ad.GetHashable().Addr())
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -151,7 +152,8 @@ func LoadGeositeFiles() (err error) {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
ref := make(map[string]*GeositeRawList)
|
||||
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
|
||||
err = filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package netLayer
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
@@ -22,7 +21,8 @@ func BenchmarkCheckMMDB_country(b *testing.B) {
|
||||
LoadMaxmindGeoipFile(utils.GetFilePath("../" + GeoipFileName))
|
||||
|
||||
if the_geoipdb == nil {
|
||||
log.Fatalln("err load")
|
||||
b.Log("err load")
|
||||
b.FailNow()
|
||||
}
|
||||
|
||||
theIP := net.ParseIP("1.22.233.44")
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -97,14 +96,16 @@ func BenchmarkReadVCopy(b *testing.B) {
|
||||
listenAddr := GetRandLocalAddr()
|
||||
listener, err := net.Listen("tcp", listenAddr)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
b.Log(err)
|
||||
b.FailNow()
|
||||
}
|
||||
|
||||
bigBytes := make([]byte, 10240) //10k
|
||||
|
||||
n, err := rand.Reader.Read(bigBytes)
|
||||
if err != nil || n != 10240 {
|
||||
log.Fatalln(n, err)
|
||||
b.Log(n, err)
|
||||
b.FailNow()
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -134,13 +135,15 @@ func BenchmarkReadVCopy(b *testing.B) {
|
||||
|
||||
tcpConn, err := net.Dial("tcp", listenAddr)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
b.Log(err)
|
||||
b.FailNow()
|
||||
}
|
||||
|
||||
for i := 0; i < transmitCount; i++ {
|
||||
_, e := tcpConn.Write(bigBytes)
|
||||
if e != nil {
|
||||
log.Fatalln(err)
|
||||
b.Log(err)
|
||||
b.FailNow()
|
||||
}
|
||||
}
|
||||
tcpConn.Close()
|
||||
@@ -156,7 +159,8 @@ func BenchmarkClassicCopy(b *testing.B) {
|
||||
listenAddr := GetRandLocalAddr()
|
||||
listener, err := net.Listen("tcp", listenAddr)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
b.Log(err)
|
||||
b.FailNow()
|
||||
}
|
||||
|
||||
const bigBytesLen = 10240
|
||||
@@ -165,7 +169,8 @@ func BenchmarkClassicCopy(b *testing.B) {
|
||||
|
||||
n, err := rand.Reader.Read(bigBytes)
|
||||
if err != nil || n != bigBytesLen {
|
||||
log.Fatalln(n, err)
|
||||
b.Log(n, err)
|
||||
b.FailNow()
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -207,14 +212,16 @@ func BenchmarkClassicCopy(b *testing.B) {
|
||||
|
||||
tcpConn, err := net.Dial("tcp", listenAddr)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
b.Log(err)
|
||||
b.FailNow()
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < transmitCount; i++ {
|
||||
_, e := tcpConn.Write(bigBytes)
|
||||
if e != nil {
|
||||
log.Fatalln(err)
|
||||
b.Log(err)
|
||||
b.FailNow()
|
||||
}
|
||||
}
|
||||
tcpConn.Close()
|
||||
@@ -294,7 +301,6 @@ func BenchmarkClassicCopy_SimulateRealWorld(b *testing.B) {
|
||||
for cursor := 0; cursor < bigBytesLen; cursor += unit {
|
||||
_, e := tcpConn.Write(bigBytes[cursor : cursor+unit])
|
||||
if e != nil {
|
||||
//log.Fatalln(err)
|
||||
b.Log(err)
|
||||
b.FailNow()
|
||||
}
|
||||
@@ -368,7 +374,6 @@ func BenchmarkClassicCopy_SimulateRealWorld_ReadV(b *testing.B) {
|
||||
for cursor := 0; cursor < bigBytesLen; cursor += unit {
|
||||
_, e := tcpConn.Write(bigBytes[cursor : cursor+unit])
|
||||
if e != nil {
|
||||
//log.Fatalln(err)
|
||||
b.Log(err)
|
||||
b.FailNow()
|
||||
}
|
||||
|
||||
@@ -33,8 +33,9 @@ func LoadRuleForRouteSet(rule *RuleConf) (rs *RouteSet) {
|
||||
if len(GeositeListMap) == 0 {
|
||||
err := LoadGeositeFiles()
|
||||
if err != nil {
|
||||
if ce := utils.CanLogWarn("LoadGeositeFiles err"); ce != nil {
|
||||
ce.Write(zap.Error(err))
|
||||
if ce := utils.CanLogErr("LoadGeositeFiles failed"); ce != nil {
|
||||
ce.Write(zap.Error(err), zap.String("Note", "You can use interactive-mode to download geosite files."))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,6 +72,14 @@ func LoadRuleForRouteSet(rule *RuleConf) (rs *RouteSet) {
|
||||
reg, err := regexp.Compile(d[colonIdx+1:])
|
||||
if err == nil {
|
||||
rs.Regex = append(rs.Regex, reg)
|
||||
} else {
|
||||
if ce := utils.CanLogErr("LoadRuleForRouteSet, regex illegal"); ce != nil {
|
||||
ce.Write(zap.Error(err))
|
||||
}
|
||||
}
|
||||
default:
|
||||
if ce := utils.CanLogErr("LoadRuleForRouteSet, not supported"); ce != nil {
|
||||
ce.Write(zap.String("item", d))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +106,10 @@ func LoadRuleForRouteSet(rule *RuleConf) (rs *RouteSet) {
|
||||
na, e := netip.ParseAddr(ipStr)
|
||||
if e == nil {
|
||||
rs.IPs[na] = true
|
||||
} else {
|
||||
if ce := utils.CanLogErr("LoadRuleForRouteSet, parse ip failed"); ce != nil {
|
||||
ce.Write(zap.String("ipStr", ipStr), zap.Error(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,10 @@ func NewClient(dc *DialConf) (Client, error) {
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
configCommonForClient(c, dc)
|
||||
e = configCommonForClient(c, dc)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
if dc.TLS {
|
||||
c.SetUseTLS()
|
||||
e = prepareTLS_forClient(c, dc)
|
||||
@@ -61,8 +64,10 @@ func NewClient(dc *DialConf) (Client, error) {
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
configCommonForClient(c, dc)
|
||||
|
||||
err = configCommonForClient(c, dc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.SetUseTLS()
|
||||
err = prepareTLS_forClient(c, dc)
|
||||
return c, err
|
||||
@@ -125,18 +130,17 @@ func NewServer(lc *ListenConf) (Server, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configCommonForServer(ser, lc)
|
||||
err = configCommonForServer(ser, lc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if lc.TLS {
|
||||
ser.SetUseTLS()
|
||||
err = prepareTLS_forServer(ser, lc)
|
||||
if err != nil {
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal("prepareTLS failed", zap.Error(err))
|
||||
} else {
|
||||
log.Fatalf("prepareTLS error %s\n", err)
|
||||
return nil, utils.ErrInErr{ErrDesc: "prepareTLS failed", ErrDetail: err}
|
||||
|
||||
}
|
||||
}
|
||||
return ser, nil
|
||||
}
|
||||
@@ -150,18 +154,15 @@ func NewServer(lc *ListenConf) (Server, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configCommonForServer(ser, lc)
|
||||
err = configCommonForServer(ser, lc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ser.SetUseTLS()
|
||||
err = prepareTLS_forServer(ser, lc)
|
||||
if err != nil {
|
||||
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal("prepareTLS failed", zap.Error(err))
|
||||
} else {
|
||||
log.Fatalf("prepareTLS error %s\n", err)
|
||||
|
||||
}
|
||||
return nil, utils.ErrInErr{ErrDesc: "prepareTLS failed", ErrDetail: err}
|
||||
|
||||
}
|
||||
return ser, nil
|
||||
@@ -286,7 +287,7 @@ func configCommon(ser ProxyCommon, cc *CommonConf) {
|
||||
}
|
||||
|
||||
//SetAddrStr, setNetwork, setIsDial(true),setDialConf(dc), call configCommon(setAdvancedLayer)
|
||||
func configCommonForClient(cli ProxyCommon, dc *DialConf) {
|
||||
func configCommonForClient(cli ProxyCommon, dc *DialConf) error {
|
||||
cli.setNetwork(dc.Network)
|
||||
cli.setIsDial(true)
|
||||
cli.setDialConf(dc)
|
||||
@@ -299,12 +300,13 @@ func configCommonForClient(cli ProxyCommon, dc *DialConf) {
|
||||
configCommon(cli, &dc.CommonConf)
|
||||
|
||||
if dc.AdvancedLayer == "ws" {
|
||||
cli.initWS_client()
|
||||
return cli.initWS_client()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//SetAddrStr,setNetwork, setTag, setCantRoute,setListenConf(lc),setFallback, call configCommon
|
||||
func configCommonForServer(ser ProxyCommon, lc *ListenConf) {
|
||||
func configCommonForServer(ser ProxyCommon, lc *ListenConf) error {
|
||||
ser.SetAddrStr(lc.GetAddrStrForListenOrDial())
|
||||
ser.setNetwork(lc.Network)
|
||||
ser.setListenConf(lc)
|
||||
@@ -314,10 +316,17 @@ func configCommonForServer(ser ProxyCommon, lc *ListenConf) {
|
||||
|
||||
switch lc.AdvancedLayer {
|
||||
case "ws":
|
||||
ser.initWS_server()
|
||||
err := ser.initWS_server()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case "grpc":
|
||||
ser.initGRPC_server()
|
||||
err := ser.initGRPC_server()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//case "quic":
|
||||
|
||||
//因为quic接管了tls层, 而我们的configCommonForServer是在tls配置之前被调用的
|
||||
@@ -331,15 +340,12 @@ func configCommonForServer(ser ProxyCommon, lc *ListenConf) {
|
||||
fa, err := netLayer.NewAddrFromAny(fallbackThing)
|
||||
|
||||
if err != nil {
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal("configCommonURLQueryForServer failed", zap.Any("invalid fallback", fallbackThing))
|
||||
} else {
|
||||
log.Fatalln("invalid fallback", fallbackThing)
|
||||
return utils.ErrInErr{ErrDesc: "configCommonURLQueryForServer failed", Data: fallbackThing}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ser.setFallback(fa)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package proxy
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -134,12 +135,12 @@ type ProxyCommon interface {
|
||||
GetWS_Client() *ws.Client //for outClient
|
||||
GetWS_Server() *ws.Server //for inServer
|
||||
|
||||
initWS_client() //for outClient
|
||||
initWS_server() //for inServer
|
||||
initWS_client() error //for outClient
|
||||
initWS_server() error //for inServer
|
||||
|
||||
GetGRPC_Server() *grpc.Server
|
||||
|
||||
initGRPC_server()
|
||||
initGRPC_server() error
|
||||
|
||||
IsMux() bool //如果用了grpc则此方法返回true
|
||||
|
||||
@@ -207,7 +208,10 @@ func prepareTLS_forClient(com ProxyCommon, dc *DialConf) error {
|
||||
|
||||
na, e := netLayer.NewAddr(com.AddrStr())
|
||||
if e != nil {
|
||||
log.Fatalln("prepareTLS_forClient,quic,netLayer.NewAddr err: ", e)
|
||||
if ce := utils.CanLogErr("prepareTLS_forClient,quic,netLayer.NewAddr failed"); ce != nil {
|
||||
ce.Write(zap.Error(e))
|
||||
}
|
||||
return e
|
||||
}
|
||||
return quic.DialCommonInitialLayer(&na, tls.Config{
|
||||
InsecureSkipVerify: dc.Insecure,
|
||||
@@ -297,7 +301,12 @@ func prepareTLS_forServer(com ProxyCommon, lc *ListenConf) error {
|
||||
certArray, err := tlsLayer.GetCertArrayFromFile(lc.TLSCert, lc.TLSKey)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("can't create tls cert from file: %s, %s, %s\n", lc.TLSCert, lc.TLSKey, err)
|
||||
|
||||
if ce := utils.CanLogErr("can't create tls cert"); ce != nil {
|
||||
ce.Write(zap.String("cert", lc.TLSCert), zap.String("key", lc.TLSKey), zap.Error(err))
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return quic.ListenInitialLayers(com.AddrStr(), tls.Config{
|
||||
@@ -575,15 +584,9 @@ func (s *ProxyCommonStruct) GetGRPC_Server() *grpc.Server {
|
||||
}
|
||||
|
||||
//for outClient
|
||||
func (s *ProxyCommonStruct) initWS_client() {
|
||||
func (s *ProxyCommonStruct) initWS_client() error {
|
||||
if s.dialConf == nil {
|
||||
const eStr = "initWS_client failed when no dialConf assigned"
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal(eStr)
|
||||
} else {
|
||||
log.Fatal(eStr)
|
||||
|
||||
}
|
||||
return errors.New("initWS_client failed when no dialConf assigned")
|
||||
}
|
||||
path := s.dialConf.Path
|
||||
if path == "" { // 至少Path需要为 "/"
|
||||
@@ -602,29 +605,19 @@ func (s *ProxyCommonStruct) initWS_client() {
|
||||
c, e := ws.NewClient(s.dialConf.GetAddrStr(), path)
|
||||
if e != nil {
|
||||
|
||||
const eStr2 = "initWS_client failed"
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal(eStr2, zap.Error(e))
|
||||
} else {
|
||||
log.Fatal(eStr2, e)
|
||||
|
||||
}
|
||||
return utils.ErrInErr{ErrDesc: "initWS_client failed", ErrDetail: e}
|
||||
|
||||
}
|
||||
c.UseEarlyData = useEarlyData
|
||||
s.ws_c = c
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ProxyCommonStruct) initWS_server() {
|
||||
func (s *ProxyCommonStruct) initWS_server() error {
|
||||
if s.listenConf == nil {
|
||||
|
||||
const eStr3 = "initWS_server failed when no listenConf assigned"
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal(eStr3)
|
||||
} else {
|
||||
log.Fatal(eStr3)
|
||||
}
|
||||
return errors.New("initWS_server failed when no listenConf assigned")
|
||||
|
||||
}
|
||||
path := s.listenConf.Path
|
||||
@@ -644,30 +637,24 @@ func (s *ProxyCommonStruct) initWS_server() {
|
||||
wss.UseEarlyData = useEarlyData
|
||||
|
||||
s.ws_s = wss
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ProxyCommonStruct) initGRPC_server() {
|
||||
func (s *ProxyCommonStruct) initGRPC_server() error {
|
||||
if s.listenConf == nil {
|
||||
|
||||
const eStr1 = "initGRPC_server failed when no listenConf assigned"
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal(eStr1)
|
||||
} else {
|
||||
log.Fatal(eStr1)
|
||||
}
|
||||
return errors.New("initGRPC_server failed when no listenConf assigned")
|
||||
|
||||
}
|
||||
|
||||
serviceName := s.listenConf.Path
|
||||
if serviceName == "" { //不能为空
|
||||
|
||||
const eStr2 = "initGRPC_server failed, path must be specified"
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal(eStr2)
|
||||
} else {
|
||||
log.Fatal(eStr2)
|
||||
}
|
||||
return errors.New("initGRPC_server failed, path must be specified")
|
||||
|
||||
}
|
||||
|
||||
s.grpc_s = grpc.NewServer(serviceName)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -280,7 +280,11 @@ func (u *UDPConn) StartReadRequest(udpPutter netLayer.UDP_Putter, dialFunc func(
|
||||
u.UDPConn.Close()
|
||||
udpPutter.CloseUDPRequestWriter() //只要读udp发生致命错误,我们就关闭RequestWriter,这样 StartPushResponse 方法中调用的 udpPutter.GetNewUDPResponse 就应该同步退出了
|
||||
|
||||
utils.ZapLogger.Fatal("socks5 failed UDPConn read", zap.Error(err))
|
||||
if ce := utils.CanLogWarn("socks5 failed UDPConn read"); ce != nil {
|
||||
|
||||
ce.Write(zap.Error(err))
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
26
test_test.go
26
test_test.go
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
@@ -32,11 +31,13 @@ func TestDNSLookup_CN(t *testing.T) {
|
||||
|
||||
r, _, err := c.Exchange(m, "114.114.114.114:53")
|
||||
if r == nil {
|
||||
log.Fatalln("*** error: ", err.Error())
|
||||
t.Log("*** error: ", err.Error())
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
log.Fatalln("*** err2 ", r.Rcode, r)
|
||||
t.Log("*** err2 ", r.Rcode, r)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
for _, a := range r.Answer {
|
||||
@@ -98,23 +99,28 @@ key = "cert.key"
|
||||
//domodemo in
|
||||
clientEndInServer, err := proxy.NewServer(clientConf.Listen[0])
|
||||
if err != nil {
|
||||
log.Fatalln("can not create clientEndInServer: ", err)
|
||||
t.Log("can not create clientEndInServer: ", err)
|
||||
t.FailNow()
|
||||
|
||||
}
|
||||
// vless out
|
||||
clientEndOutClient, err := proxy.NewClient(clientConf.Dial[0])
|
||||
if err != nil {
|
||||
log.Fatalln("can not create clientEndOutClient: ", err)
|
||||
t.Log("can not create clientEndOutClient: ", err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
//vless in
|
||||
serverEndInServer, err := proxy.NewServer(serverConf.Listen[0])
|
||||
if err != nil {
|
||||
log.Fatalln("can not create serverEndInServer: ", err)
|
||||
t.Log("can not create serverEndInServer: ", err)
|
||||
t.FailNow()
|
||||
}
|
||||
// direct out
|
||||
serverEndOutClient, err := proxy.NewClient(serverConf.Dial[0])
|
||||
if err != nil {
|
||||
log.Fatalln("can not create serverEndOutClient: ", err)
|
||||
t.Log("can not create serverEndOutClient: ", err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
listenSer(clientEndInServer, clientEndOutClient, false)
|
||||
@@ -126,11 +132,13 @@ key = "cert.key"
|
||||
|
||||
r, _, err := c.Exchange(m, "127.0.0.1:1080")
|
||||
if r == nil {
|
||||
log.Fatalln("error: ", err.Error())
|
||||
t.Log("error: ", err.Error())
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
log.Fatalln("err2 ", r.Rcode, r)
|
||||
t.Log("err2 ", r.Rcode, r)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
for _, a := range r.Answer {
|
||||
|
||||
@@ -11,14 +11,12 @@ import (
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/hahahrfool/v2ray_simple/utils"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func GenerateRandomeCert_Key() ([]byte, []byte) {
|
||||
@@ -81,29 +79,22 @@ func GenerateRandomTLSCert() []tls.Certificate {
|
||||
|
||||
}
|
||||
|
||||
func GenerateRandomCertKeyFiles(cfn, kfn string) {
|
||||
func GenerateRandomCertKeyFiles(cfn, kfn string) error {
|
||||
|
||||
cb, kb := GenerateRandomeCert_Key()
|
||||
|
||||
certOut, err := os.Create(cfn)
|
||||
if err != nil {
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal("failed to open file", zap.Error(err))
|
||||
} else {
|
||||
log.Fatalf("failed to open file %s", err)
|
||||
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
certOut.Write(cb)
|
||||
|
||||
kOut, err := os.Create(kfn)
|
||||
if err != nil {
|
||||
if utils.ZapLogger != nil {
|
||||
utils.ZapLogger.Fatal("failed to open file", zap.Error(err))
|
||||
} else {
|
||||
log.Fatalf("failed to open file %s", err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
kOut.Write(kb)
|
||||
@@ -111,6 +102,7 @@ func GenerateRandomCertKeyFiles(cfn, kfn string) {
|
||||
certOut.Close()
|
||||
kOut.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//如 certFile, keyFile 有一项没给出,则会自动生成随机证书
|
||||
|
||||
10
utils/log.go
10
utils/log.go
@@ -101,7 +101,7 @@ func CanLogLevel(l int, msg string) *zapcore.CheckedEntry {
|
||||
}
|
||||
|
||||
func CanLogErr(msg string) *zapcore.CheckedEntry {
|
||||
if LogLevel > Log_error {
|
||||
if LogLevel > Log_error || ZapLogger == nil {
|
||||
return nil
|
||||
}
|
||||
return ZapLogger.Check(zap.ErrorLevel, msg)
|
||||
@@ -109,28 +109,28 @@ func CanLogErr(msg string) *zapcore.CheckedEntry {
|
||||
}
|
||||
|
||||
func CanLogInfo(msg string) *zapcore.CheckedEntry {
|
||||
if LogLevel > Log_info {
|
||||
if LogLevel > Log_info || ZapLogger == nil {
|
||||
return nil
|
||||
}
|
||||
return ZapLogger.Check(zap.InfoLevel, msg)
|
||||
|
||||
}
|
||||
func CanLogWarn(msg string) *zapcore.CheckedEntry {
|
||||
if LogLevel > Log_warning {
|
||||
if LogLevel > Log_warning || ZapLogger == nil {
|
||||
return nil
|
||||
}
|
||||
return ZapLogger.Check(zap.WarnLevel, msg)
|
||||
|
||||
}
|
||||
func CanLogDebug(msg string) *zapcore.CheckedEntry {
|
||||
if LogLevel > Log_debug {
|
||||
if LogLevel > Log_debug || ZapLogger == nil {
|
||||
return nil
|
||||
}
|
||||
return ZapLogger.Check(zap.DebugLevel, msg)
|
||||
|
||||
}
|
||||
func CanLogFatal(msg string) *zapcore.CheckedEntry {
|
||||
if LogLevel > Log_fatal {
|
||||
if LogLevel > Log_fatal || ZapLogger == nil {
|
||||
return nil
|
||||
}
|
||||
return ZapLogger.Check(zap.FatalLevel, msg)
|
||||
|
||||
Reference in New Issue
Block a user