mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-10-25 01:30:30 +08:00
初步实现 tls lazy encrypt 功能 (splice)
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,6 @@
|
||||
*.DS_Store
|
||||
v2ray_simple
|
||||
v2ray_simple_linux*
|
||||
v2ray_simple_win*
|
||||
client.json
|
||||
server.json
|
||||
|
||||
@@ -111,6 +111,13 @@ verysimple 继承 v2simple的一个优点,就是服务端的配置也可以用
|
||||
|
||||
此问题有待考证解决。也不知道是不是只有我自己有这个问题。。
|
||||
|
||||
## 交叉编译
|
||||
|
||||
```sh
|
||||
GOARCH=amd64 GOOS=linux go build -trimpath -ldflags "-s -w -buildid=" -o v2ray_simple_linux_amd64_v1.0.0
|
||||
GOARCH=arm64 GOOS=linux go build -trimpath -ldflags "-s -w -buildid=" -o v2ray_simple_linux_arm64_v1.0.0
|
||||
GOARCH=amd64 GOOS=windows go build -trimpath -ldflags "-s -w -buildid=" -o v2ray_simple_win10_v1.0.0.exe
|
||||
```
|
||||
|
||||
## 交流
|
||||
|
||||
|
||||
@@ -6,9 +6,13 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
standardBytesPool sync.Pool //1500
|
||||
standardBytesPool sync.Pool //1500
|
||||
|
||||
// 实际上tcp默认是 16384, 16k,实际上范围是1k~128k之间,我们64k已经够了
|
||||
//而 udp则最大还不到 64k。(65535-20-8)
|
||||
standardPacketPool sync.Pool //64*1024
|
||||
customBytesPool sync.Pool // >1500
|
||||
|
||||
customBytesPool sync.Pool // >1500
|
||||
|
||||
bufPool sync.Pool
|
||||
)
|
||||
|
||||
132
main.go
132
main.go
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/hahahrfool/v2ray_simple/proxy/direct"
|
||||
"github.com/hahahrfool/v2ray_simple/proxy/socks5"
|
||||
"github.com/hahahrfool/v2ray_simple/proxy/vless"
|
||||
"github.com/hahahrfool/v2ray_simple/tlsLayer"
|
||||
|
||||
"github.com/hahahrfool/v2ray_simple/proxy"
|
||||
)
|
||||
@@ -31,6 +32,9 @@ var (
|
||||
|
||||
conf *Config
|
||||
directClient proxy.Client
|
||||
|
||||
tls_lazy_encryptPtr = flag.Bool("lazy", false, "tls lazy encrypt (splice)")
|
||||
tls_lazy_encrypt bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -74,6 +78,7 @@ func main() {
|
||||
printVersion()
|
||||
|
||||
flag.Parse()
|
||||
tls_lazy_encrypt = *tls_lazy_encryptPtr
|
||||
|
||||
var err error
|
||||
|
||||
@@ -135,10 +140,19 @@ func main() {
|
||||
|
||||
func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Client, thisLocalConnectionInstance net.Conn) {
|
||||
|
||||
//log.Println("got new", thisLocalConnectionInstance.RemoteAddr().String())
|
||||
baseLocalConn := thisLocalConnectionInstance
|
||||
|
||||
log.Println("got new", thisLocalConnectionInstance.RemoteAddr().String())
|
||||
|
||||
var err error
|
||||
|
||||
//此时,baseLocalConn里面 正常情况下, 服务端看到的是 客户端的golang的tls 拨号发出的 tls数据
|
||||
// 客户端看到的是 socks5的数据, 我们首先就是要看看socks5里的数据是不是tls,而socks5自然 IsUseTLS 是false
|
||||
|
||||
// 如果是服务端的话,那就是 localServer.IsUseTLS == true, 此时,我们正常握手,然后我们需要判断的是它承载的数据
|
||||
|
||||
if localServer.IsUseTLS() {
|
||||
|
||||
tlsConn, err := localServer.GetTLS_Server().Handshake(thisLocalConnectionInstance)
|
||||
if err != nil {
|
||||
log.Println("failed in handshake localServer tls", localServer.AddrStr(), err)
|
||||
@@ -147,6 +161,7 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
}
|
||||
|
||||
thisLocalConnectionInstance = tlsConn
|
||||
|
||||
}
|
||||
|
||||
wlc, targetAddr, err := localServer.Handshake(thisLocalConnectionInstance)
|
||||
@@ -156,6 +171,21 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
return
|
||||
}
|
||||
|
||||
// 我们在客户端 lazy_encrypt 探测时,读取socks5 传来的信息,因为这个和要发送到tls的信息时一模一样的,所以就不需要等包上vless、tls后再判断了, 直接解包 socks5进行判断
|
||||
//
|
||||
// 而在服务端探测时,因为包了 tls,所以要在tls解包后, vless 解包后,再进行判断;
|
||||
// 所以总之都是要在 localServer判断 wlc,只不过理由不一样
|
||||
|
||||
var thecc *tlsLayer.CopyConn
|
||||
|
||||
if tls_lazy_encrypt {
|
||||
|
||||
thecc = tlsLayer.NewDetectConn(baseLocalConn, wlc)
|
||||
|
||||
wlc = thecc
|
||||
//clientConn = cc
|
||||
}
|
||||
|
||||
if targetAddr.IsUDP {
|
||||
|
||||
switch localServer.Name() {
|
||||
@@ -267,7 +297,7 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
var realTargetAddr *proxy.Addr = targetAddr //direct的话自己是没有目的地址的,直接使用 请求的地址
|
||||
|
||||
if client.AddrStr() != "" {
|
||||
log.Println("will dial", client.AddrStr())
|
||||
//log.Println("will dial", client.AddrStr())
|
||||
|
||||
realTargetAddr, _ = proxy.NewAddr(client.AddrStr())
|
||||
}
|
||||
@@ -279,6 +309,7 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
}
|
||||
|
||||
if client.IsUseTLS() {
|
||||
|
||||
tlsConn, err := client.GetTLS_Client().Handshake(clientConn)
|
||||
if err != nil {
|
||||
log.Println("failed in handshake remoteClient tls", targetAddr.String(), ", Reason: ", err)
|
||||
@@ -306,7 +337,104 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
log.Println("远程->本地 转发结束", realTargetAddr.String(), n, e)
|
||||
*/
|
||||
|
||||
if tls_lazy_encrypt {
|
||||
tryRaw(wrc, wlc, client.IsUseTLS())
|
||||
return
|
||||
}
|
||||
|
||||
go io.Copy(wrc, wlc)
|
||||
io.Copy(wlc, wrc)
|
||||
|
||||
}
|
||||
|
||||
//和 xtls的splice 含义相同
|
||||
func tryRaw(wrc, wlc io.ReadWriter, isclient bool) {
|
||||
|
||||
//如果用了 lazy_encrypt, 则不直接利用Copy,因为有两个阶段:判断阶段和直连阶段
|
||||
// 在判断阶段,因为还没确定是否是 tls,所以是要继续用tls加密的,
|
||||
// 而直连阶段,只要能让 Copy使用 ReadFrom, 就能一步一步最终使用splice了
|
||||
|
||||
//首先判断我们的wlc(*tlsLayer.CopyConn) 是否得出来 IsTLS
|
||||
wlccc := wlc.(*tlsLayer.CopyConn)
|
||||
wlccc_raw := wlccc.RawConn
|
||||
|
||||
var rawWRC *net.TCPConn
|
||||
|
||||
//wrc 有两种情况,如果客户端那就是tls,服务端那就是direct。我们不讨论服务端 处于中间层的情况
|
||||
|
||||
if isclient {
|
||||
// 不过实际上 wrc 是 vless的 UserConn, 而UserConn的底层连接才是TLS
|
||||
|
||||
wrcVless := wrc.(*vless.UserConn)
|
||||
|
||||
tlsConn := wrcVless.Conn.(*tlsLayer.Conn)
|
||||
|
||||
rawWRC = tlsConn.GetRaw()
|
||||
|
||||
} else {
|
||||
rawWRC = wrc.(*net.TCPConn)
|
||||
}
|
||||
|
||||
if rawWRC == nil {
|
||||
log.Println("splice fail reason 3 ")
|
||||
io.Copy(wrc, wlc)
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
//从 wlccc 读取,向 wrc 写入
|
||||
// 此时如果ReadFrom,那就是 wrc.ReadFrom(wlccc)
|
||||
//wrc 要实现 ReaderFrom才行, 或者把最底层TCPConn暴露,然后 wlccc 也要把最底层 TCPConn暴露出来
|
||||
|
||||
p := common.GetPacket()
|
||||
isgood := false
|
||||
for {
|
||||
|
||||
if isgood {
|
||||
break
|
||||
}
|
||||
|
||||
n, err := wlccc.Read(p)
|
||||
if err != nil {
|
||||
|
||||
break
|
||||
}
|
||||
wrc.Write(p[:n])
|
||||
|
||||
if wlccc.R.IsTls && wlccc.RawConn != nil {
|
||||
isgood = true
|
||||
|
||||
}
|
||||
}
|
||||
if isgood {
|
||||
|
||||
log.Println("成功SpliceRead 方向1")
|
||||
rawWRC.ReadFrom(wlccc_raw)
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
isgood2 := false
|
||||
p := common.GetPacket()
|
||||
|
||||
//从 wrc 读取,向 wlccc 写入
|
||||
for {
|
||||
if isgood2 {
|
||||
break
|
||||
}
|
||||
n, err := wrc.Read(p)
|
||||
if err != nil {
|
||||
|
||||
break
|
||||
}
|
||||
wlccc.Write(p[:n])
|
||||
if wlccc.W.IsTls && wlccc.RawConn != nil {
|
||||
isgood2 = true
|
||||
|
||||
}
|
||||
}
|
||||
if isgood2 {
|
||||
log.Println("成功SpliceRead 方向2")
|
||||
wlccc_raw.ReadFrom(rawWRC)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ ws和grpc文件夹(第七层)
|
||||
|
||||
# proxy 文件夹内容
|
||||
|
||||
接口 ProxyCommonFuncs 和 结构 ProxyCommonStruct 给 这个架构定义了标准
|
||||
接口 ProxyCommon 和 结构 ProxyCommonStruct 给 这个架构定义了标准
|
||||
|
||||
而 Client 和 Server 接口 是 具体利用该架构的 客户端 和 服务端,都位于VSI中的第八层
|
||||
|
||||
@@ -112,7 +112,7 @@ type UserConn interface {
|
||||
}
|
||||
|
||||
// 给一个节点 提供 VSI中 第 5-7层 的支持
|
||||
type ProxyCommonFuncs interface {
|
||||
type ProxyCommon interface {
|
||||
AddrStr() string //地址,在server就是监听地址,在client就是拨号地址
|
||||
SetAddrStr(string)
|
||||
|
||||
@@ -128,7 +128,7 @@ type ProxyCommonFuncs interface {
|
||||
GetTLS_Client() *tlsLayer.Client
|
||||
}
|
||||
|
||||
func PrepareTLS_forProxyCommon(u *url.URL, isclient bool, com ProxyCommonFuncs) error {
|
||||
func PrepareTLS_forProxyCommon(u *url.URL, isclient bool, com ProxyCommon) error {
|
||||
insecureStr := u.Query().Get("insecure")
|
||||
insecure := false
|
||||
if insecureStr != "" && insecureStr != "false" && insecureStr != "0" {
|
||||
@@ -201,7 +201,7 @@ func (s *ProxyCommonStruct) SetUseTLS() {
|
||||
|
||||
// Client 用于向 服务端 拨号
|
||||
type Client interface {
|
||||
ProxyCommonFuncs
|
||||
ProxyCommon
|
||||
|
||||
Name() string
|
||||
|
||||
@@ -261,7 +261,7 @@ func ClientFromURL(s string) (Client, error) {
|
||||
|
||||
// Server 用于监听 客户端 的连接
|
||||
type Server interface {
|
||||
ProxyCommonFuncs
|
||||
ProxyCommon
|
||||
|
||||
Name() string
|
||||
|
||||
|
||||
@@ -57,10 +57,11 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error
|
||||
}
|
||||
defer underlay.SetReadDeadline(time.Time{})
|
||||
|
||||
buf := common.GetBytes(512)
|
||||
defer common.PutBytes(buf)
|
||||
buf := common.GetPacket()
|
||||
defer common.PutPacket(buf)
|
||||
|
||||
// Read hello message
|
||||
// 一般握手包发来的是 [5 1 0]
|
||||
n, err := underlay.Read(buf)
|
||||
if err != nil || n == 0 {
|
||||
return nil, nil, fmt.Errorf("failed to read hello: %w", err)
|
||||
@@ -70,19 +71,22 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriter, *proxy.Addr, error
|
||||
return nil, nil, fmt.Errorf("unsupported socks version %v", version)
|
||||
}
|
||||
|
||||
// Write hello response
|
||||
// Write hello response, [5 0]
|
||||
// TODO: Support Auth
|
||||
_, err = underlay.Write([]byte{Version5, AuthNone})
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to write hello response: %w", err)
|
||||
}
|
||||
|
||||
// Read command message
|
||||
// Read command message,
|
||||
n, err = underlay.Read(buf)
|
||||
if err != nil || n < 7 { // Shortest length is 7
|
||||
return nil, nil, fmt.Errorf("failed to read command: %w", err)
|
||||
return nil, nil, fmt.Errorf("read socks5 failed, msgTooShort: %w", err)
|
||||
}
|
||||
|
||||
// 一般可以为 5 1 0 3 n,3表示域名,n是域名长度,然后域名很可能是 119 119 119 46 开头,表示 www.
|
||||
// 比如百度就是 [5 1 0 3 13 119 119 119 46 98]
|
||||
|
||||
cmd := buf[1]
|
||||
switch cmd {
|
||||
case CmdBind:
|
||||
|
||||
@@ -21,8 +21,17 @@ func NewTlsClient(host string, insecure bool) *Client {
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) Handshake(underlay net.Conn) (tlsConn *tls.Conn, err error) {
|
||||
tlsConn = tls.Client(underlay, c.tlsConfig)
|
||||
err = tlsConn.Handshake()
|
||||
func (c *Client) Handshake(underlay net.Conn) (tlsConn *Conn, err error) {
|
||||
rawConn := tls.Client(underlay, c.tlsConfig)
|
||||
err = rawConn.Handshake()
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tlsConn = &Conn{
|
||||
Conn: rawConn,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
29
tlsLayer/conn.go
Normal file
29
tlsLayer/conn.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package tlsLayer
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"log"
|
||||
"net"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
*tls.Conn
|
||||
}
|
||||
|
||||
type faketlsconn struct {
|
||||
// constant
|
||||
conn net.Conn
|
||||
isClient bool
|
||||
}
|
||||
|
||||
func (c *Conn) GetRaw() *net.TCPConn {
|
||||
rc := (*faketlsconn)(unsafe.Pointer(uintptr(unsafe.Pointer(c.Conn))))
|
||||
if rc != nil {
|
||||
if rc.conn != nil {
|
||||
log.Println("成功获取到 *net.TCPConn!", rc.conn.(*net.TCPConn))
|
||||
return rc.conn.(*net.TCPConn)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
195
tlsLayer/detect.go
Normal file
195
tlsLayer/detect.go
Normal file
@@ -0,0 +1,195 @@
|
||||
package tlsLayer
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CopyConn struct {
|
||||
net.Conn //这个 Conn本包中不会用到,只是为了能让CopyConn支持 net.Conn
|
||||
io.ReadWriter
|
||||
W *DetectWriter
|
||||
R *DetectReader
|
||||
|
||||
RawConn *net.TCPConn // 这个是为了让外界能够直接拿到底层的连接
|
||||
}
|
||||
|
||||
func (cc *CopyConn) Read(p []byte) (int, error) {
|
||||
return cc.R.Read(p)
|
||||
}
|
||||
|
||||
func (cc *CopyConn) Write(p []byte) (int, error) {
|
||||
return cc.W.Write(p)
|
||||
}
|
||||
|
||||
func (cc *CopyConn) ReadFrom(r io.Reader) (int64, error) {
|
||||
if cc.RawConn != nil {
|
||||
return cc.RawConn.ReadFrom(r)
|
||||
}
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
func NewDetectConn(oldConn net.Conn, rw io.ReadWriter) *CopyConn {
|
||||
|
||||
var validOne io.ReadWriter = rw
|
||||
if rw == nil {
|
||||
validOne = oldConn
|
||||
}
|
||||
|
||||
cc := &CopyConn{
|
||||
Conn: oldConn,
|
||||
ReadWriter: rw,
|
||||
W: &DetectWriter{
|
||||
Writer: validOne,
|
||||
},
|
||||
R: &DetectReader{
|
||||
Reader: validOne,
|
||||
},
|
||||
}
|
||||
|
||||
if netConn := oldConn.(*net.TCPConn); netConn != nil {
|
||||
//log.Println("get netConn!") // 如果是客户端的socks5,网页浏览的话这里一定能转成 TCPConn
|
||||
cc.RawConn = netConn
|
||||
}
|
||||
|
||||
return cc
|
||||
}
|
||||
|
||||
// DetectReader 对每个Read的数据进行分析,判断是否是tls流量
|
||||
type DetectReader struct {
|
||||
io.Reader
|
||||
IsTls bool
|
||||
|
||||
packetCount int
|
||||
}
|
||||
|
||||
func init() {
|
||||
log.SetOutput(os.Stdout)
|
||||
}
|
||||
|
||||
// 总之,我们在客户端的 Read 操作,就是 我们试图使用 Read 读取客户的请求,然后试图发往 外界
|
||||
// 所以在socks5后面 使用的这个 Read,是读取客户端发送的请求,比如 clienthello之类
|
||||
//
|
||||
// 我们直接判断23 3 3字节,然后直接推定tls!不管三七二十一,判断错误就错误吧!快就得了!
|
||||
func (dr *DetectReader) Read(p []byte) (n int, err error) {
|
||||
n, err = dr.Reader.Read(p)
|
||||
if dr.IsTls {
|
||||
return
|
||||
}
|
||||
|
||||
if dr.packetCount > 8 {
|
||||
//都8个包了还没断定tls?直接推定不是!
|
||||
return
|
||||
}
|
||||
|
||||
if n > 3 {
|
||||
dr.packetCount++
|
||||
p0 := p[0]
|
||||
p1 := p[1]
|
||||
p2 := p[2]
|
||||
|
||||
/*
|
||||
if p0 == 22 || p0 == 23 || p0 == 20 || (p0 == 21 && n == 31) {
|
||||
//少数情况首部会有21,首部为 [21 3 3 0 26 0 0 0 0 0], 一般总长度为31
|
||||
// 其它都是 能被捕捉到的。
|
||||
if p[1] == 3 {
|
||||
min := 5
|
||||
if n < 5 {
|
||||
min = n
|
||||
}
|
||||
log.Println(" TLS R,", n, err, p[:min])
|
||||
dr.IsTls = true
|
||||
return
|
||||
}
|
||||
}*/
|
||||
|
||||
if p0 == 23 && p1 == 3 && p2 == 3 {
|
||||
log.Println("R got TLS!")
|
||||
dr.IsTls = true
|
||||
return
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
eStr := err.Error()
|
||||
if strings.Contains(eStr, "use of closed") || strings.Contains(eStr, "reset by peer") || strings.Contains(eStr, "EOF") {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
min := 10
|
||||
if n < 10 {
|
||||
min = n
|
||||
}
|
||||
log.Println(" ======== Read,", n, err, p[:min], string(p[:min]))
|
||||
return
|
||||
}
|
||||
|
||||
// DetectReader 对每个Read的数据进行分析,判断是否是tls流量
|
||||
type DetectWriter struct {
|
||||
io.Writer
|
||||
IsTls bool
|
||||
|
||||
packetCount int
|
||||
}
|
||||
|
||||
//我发现,数据基本就是 23 3 3, 22 3 3,22 3 1 , 20 3 3
|
||||
// 一个首包不为23 3 3 的包往往会出现在 1184长度的包的后面,而且一般 1184长度的包 的开头是 22 3 3 0 122,且总是在Write里面发生
|
||||
// 所以可以直接推测这个就是握手包; 实测 22 3 3 0 122 开头的,无一例外都是 1184长度,且后面接多个 开头任意的 Write
|
||||
// 也有一些特殊情况,比如 22 3 1 首部的包,往往是 517 长度,后面也会紧跟着一些首部不为 22/23 的 Write
|
||||
//
|
||||
// 23 3 3 也是有可能 发生后面不为22/23的write,长度 不等
|
||||
//
|
||||
// 总之,我们在客户端的 Write 操作,就是 外界试图使用我们的 Write 写入数据
|
||||
// 所以在socks5后面 使用的这个Write,应该是把 服务端的响应 写回 socks5,比如 serverhello之类
|
||||
//
|
||||
// 根据之前讨论,23 3 3 就是 数据部分,TLSCiphertext
|
||||
// https://halfrost.com/https_record_layer/
|
||||
// 总之我们依然判断 23 3 3 好了,但是不循环判断了,没那么多技巧,先判断是否存在握手包,握手完成后,遇到23 3 3 后,直接就
|
||||
// 进入direct模式; 目前从简,连握手包都不检测!测错就测错!
|
||||
func (dr *DetectWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = dr.Writer.Write(p)
|
||||
if dr.IsTls {
|
||||
return
|
||||
}
|
||||
|
||||
if dr.packetCount > 8 {
|
||||
//都8个包了还没断定tls?直接推定不是!
|
||||
return
|
||||
}
|
||||
|
||||
if n > 3 {
|
||||
dr.packetCount++
|
||||
|
||||
p0 := p[0]
|
||||
p1 := p[1]
|
||||
p2 := p[2]
|
||||
|
||||
/*
|
||||
if p0 == 22 || p0 == 23 || p0 == 20 {
|
||||
if p[1] == 3 {
|
||||
min := 5
|
||||
if n < 5 {
|
||||
min = n
|
||||
}
|
||||
log.Println(" TLS W,", n, err, p[:min])
|
||||
return
|
||||
}
|
||||
}*/
|
||||
|
||||
if p0 == 23 && p1 == 3 && p2 == 3 {
|
||||
log.Println("W got TLS!")
|
||||
dr.IsTls = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
min := 10
|
||||
if n < 10 {
|
||||
min = n
|
||||
}
|
||||
log.Println(" ======== Write,", n, err, p[:min], string(p[:min]))
|
||||
return
|
||||
}
|
||||
@@ -30,11 +30,18 @@ func NewServer(hostAndPort, host, certFile, keyFile string, isInsecure bool) (*S
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Server) Handshake(underlay net.Conn) (tlsConn *tls.Conn, err error) {
|
||||
tlsConn = tls.Server(underlay, s.tlsConfig)
|
||||
err = tlsConn.Handshake()
|
||||
func (s *Server) Handshake(underlay net.Conn) (tlsConn *Conn, err error) {
|
||||
rawConn := tls.Server(underlay, s.tlsConfig)
|
||||
err = rawConn.Handshake()
|
||||
if err != nil {
|
||||
return tlsConn, common.NewErr("tls握手失败", err)
|
||||
//return tlsConn,
|
||||
err = common.NewErr("tls握手失败", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
tlsConn = &Conn{
|
||||
Conn: rawConn,
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user