修订代码, 示例, 文档; 正式将lazy从命令行参数 改为配置文件的配置。

写明lazy的 [[dial]] 要放在所有 dial 中最前面的位置。
This commit is contained in:
e1732a364fed
2022-05-09 16:14:27 +08:00
parent 7539d4769e
commit 4ab2d0ff12
6 changed files with 21 additions and 17 deletions

View File

@@ -34,7 +34,7 @@ socks5(包括 udp associate 以及用户密码)/http(以及用户密码)/socks5h
ws(以及earlydata)/grpc(以及multiMode,uTls以及 支持回落的 grpcSimple)/quic(以及hy阻控、手动挡 和 0-rtt)/smux,
dns(udp/tls)/route(geoip/geosite,分流功能完全与v2ray等价)/fallback(path/sni/alpn/PROXY protocol v1/v2),
dns(udp/tls)/route(geoip/geosite,分流功能完全与v2ray等价)/fallback(path/sni/alpn/PROXY protocol v1/v2), sniffing(tls)
tcp/udp/unix domain socket, tls(包括客户端证书验证), uTls, lazy, http伪装头,PROXY protocol v1/v2 监听, cli(交互模式)/apiServer

View File

@@ -250,13 +250,11 @@ func mainFunc() (result int) {
ce.Write(
zap.String("Log Level", utils.LogLevelStr(utils.LogLevel)),
zap.Bool("UseReadv", netLayer.UseReadv),
zap.Bool("tls_lazy_encrypt", vs.Tls_lazy_encrypt),
)
} else {
fmt.Printf("UseReadv:%t\n", netLayer.UseReadv)
fmt.Printf("tls_lazy_encrypt:%t\n", vs.Tls_lazy_encrypt)
}

View File

@@ -40,7 +40,9 @@ protocol = "socks5" # 必填, 作为本地入口 也可写为 http或者 socks5h
host = "127.0.0.1" # 必填, 可填ip或域名如果 network是unix的话要填一个文件名(不需要已存在,可以是完整路径).
port = 10800 # 必填
#uuid = "user:xx\npass:yy" # 可选. 本行 示范了当 user为 xx 且 密码为 yy 时所需的配置. user的值的结尾的右侧 和 pass 的左侧 中间用 \n 分隔开。
#uuid = "user:xx\npass:yy" # 可选. 本行 示范了 protocol为 socks5 或者 http时, 当 user为 xx 且 密码为 yy 时所需的配置.
# user的值的结尾的右侧 和 pass 的左侧 中间用 \n 分隔开。 你也可以使用toml的 多行字符串的语法。但是本示例为了清晰起见还是明确把linefeed写出来了。 这个顺序不能改, 必须user在前 pass在后, 且都不能为空
sniffing.enabled = true #可选,是否嗅探出 tls中的sni可以帮助 geosite 分流. 该项只能在listen填写而且一般都是在客户端填写服务端不用管。因为一般只有客户端需要分流。
@@ -69,6 +71,9 @@ host = "127.0.0.1" # 同listen对应配置, 可填ip或域名如果 netwo
# 除了在 protocol 字段使用 s尾缀 之外还可以明示使用tls.
# 这两种方法不可重复使用.我们首选前者, 更简约, 当然如果你使用时需要频繁开关tls那么可以单独列出来 便于配置
#lazy = true #可选, 表示开启lazy功能; 只有vless支持, 且客户端和服务端的 vless都要开lazy,
# 而且 写明lazy的 [[dial]] 要放在所有 dial 中最前面的位置。
port = 4433 # 必填
version = 0 # 协议版本, 可省略, 省略则默认为最老版本

View File

@@ -18,6 +18,8 @@ key = "cert.key" # 如果 cert和key中 有一项没给出, 或者文件不
# ca = "ca.crt" # 可选, 用于验证客户端证书
#lazy = true
[[dial]]
protocol = "direct"

11
main.go
View File

@@ -178,7 +178,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy
}
iics.genID()
iics.isTlsLazyServerEnd = Tls_lazy_encrypt && CanLazyEncrypt(inServer)
iics.isTlsLazyServerEnd = inServer.IsLazyTls() && CanLazyEncrypt(inServer)
wrappedConn := thisLocalConnectionInstance
@@ -672,11 +672,12 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
if len(iics.firstPayload) > 0 && iics.inServer != nil && iics.inServer.Sniffing() {
tlsSniff = new(tlsLayer.ComSniff)
if Tls_lazy_encrypt && !iics.isTlsLazyServerEnd {
//if Tls_lazy_encrypt && !iics.isTlsLazyServerEnd {
if iics.defaultClient.IsLazyTls() && !iics.isTlsLazyServerEnd {
tlsSniff.Isclient = true
}
tlsSniff.CommonDetect(iics.firstPayload, true, !Tls_lazy_encrypt)
tlsSniff.CommonDetect(iics.firstPayload, true, !(iics.isTlsLazyServerEnd || iics.defaultClient.IsLazyTls()))
if sni := tlsSniff.SniffedServerName; sni != "" {
if ce := iics.CanLogDebug("Sniffed Sni"); ce != nil {
@@ -788,7 +789,7 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
iics.inServerTlsRawReadRecorder.StopRecord()
}
} else {
isTlsLazy_clientEnd = Tls_lazy_encrypt && CanLazyEncrypt(client) //比如dial是 tls+vless 这种
isTlsLazy_clientEnd = client.IsLazyTls() && CanLazyEncrypt(client) //比如dial是 tls+vless 这种
}
@@ -1305,7 +1306,7 @@ func dialClient_andRelay(iics incomingInserverConnState, targetAddr netLayer.Add
if !targetAddr.IsUDP() {
if Tls_lazy_encrypt && !iics.routedToDirect {
if !iics.routedToDirect {
// 我们加了回落之后,就无法确定 “未使用tls的outClient 一定是在服务端” 了
if isTlsLazy_clientEnd {

View File

@@ -17,15 +17,13 @@ import (
)
var (
Tls_lazy_encrypt bool
Tls_lazy_secure bool
Tls_lazy_secure bool
)
const tlslazy_willuseSystemCall = runtime.GOOS == "linux" || runtime.GOOS == "darwin"
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.")
}
@@ -52,7 +50,7 @@ func CanNetwork_tlsLazy(n string) bool {
// useSecureMethod仅用于 tls_lazy_secure
func tryTlsLazyRawCopy(identity uint32, useSecureMethod bool, proxy_client proxy.UserClient, proxy_server proxy.UserServer, targetAddr netLayer.Addr, wrc, wlc io.ReadWriteCloser, localConn net.Conn, isclient bool, theRecorder *tlsLayer.Recorder) {
if ce := utils.CanLogDebug("trying tls lazy copy"); ce != nil {
ce.Write()
ce.Write(zap.Uint32("id", identity))
}
if wlc != nil {
defer wlc.Close()
@@ -95,7 +93,7 @@ func tryTlsLazyRawCopy(identity uint32, useSecureMethod bool, proxy_client proxy
wrcVless := wrc.(*vless.UserTCPConn)
tlsConn := wrcVless.Conn.(*tlsLayer.Conn)
rawWRC = tlsConn.GetRaw(Tls_lazy_encrypt)
rawWRC = tlsConn.GetRaw(true)
} else {
rawWRC = wrc.(*net.TCPConn) //因为是direct
@@ -107,7 +105,7 @@ func tryTlsLazyRawCopy(identity uint32, useSecureMethod bool, proxy_client proxy
}
if Tls_lazy_encrypt {
if true {
theRecorder.StopRecord()
theRecorder.ReleaseBuffers()
}
@@ -160,7 +158,7 @@ func tryTlsLazyRawCopy(identity uint32, useSecureMethod bool, proxy_client proxy
tlsConn, err := proxy_client.GetTLS_Client().Handshake(teeConn)
if err != nil {
if ce := utils.CanLogErr("failed in handshake outClient tls"); ce != nil {
ce.Write(zap.Error(err))
ce.Write(zap.Uint32("id", identity), zap.Error(err))
}
return
@@ -169,7 +167,7 @@ func tryTlsLazyRawCopy(identity uint32, useSecureMethod bool, proxy_client proxy
wrc, err = proxy_client.Handshake(tlsConn, p[:n], targetAddr)
if err != nil {
if ce := utils.CanLogErr("failed in handshake"); ce != nil {
ce.Write(zap.String("target", targetAddr.String()), zap.Error(err))
ce.Write(zap.Uint32("id", identity), zap.String("target", targetAddr.String()), zap.Error(err))
}
return
}