Files
v2ray_simple/tlsLayer/io.go
T
e1732a364fed e841d258b1 修订shadowTls代码;取消shadowTls的readv, 添加writev
经过思考,readv应该不会有什么性能提升,因为需要解析数据并重新分包;
通过实现writev,可以将从tcp流readv得到的数据写入,配合readv得到性能提升
2022-12-27 09:09:51 +08:00

131 lines
2.6 KiB
Go

package tlsLayer
import (
"bytes"
"crypto/tls"
"encoding/binary"
"errors"
"io"
"net"
"github.com/e1732a364fed/v2ray_simple/netLayer"
"github.com/e1732a364fed/v2ray_simple/utils"
"go.uber.org/zap"
)
// isSrcClient is only for debug logging.
func CopyTls12Handshake(isSrcClient bool, dst, src net.Conn) error {
var tls_plaintxt [5]byte
step := 0
thisChangeCipher := false
lastHandshakeTogo := false
for {
if ce := utils.CanLogDebug("copyTls12Handshake "); ce != nil {
ce.Write(zap.Int("step", step),
zap.Bool("isSrcClient", isSrcClient),
)
}
netLayer.SetCommonReadTimeout(src)
_, err := io.ReadFull(src, tls_plaintxt[:])
netLayer.PersistRead(src)
if err != nil {
return err
}
contentType := tls_plaintxt[0]
if ce := utils.CanLogDebug("copyTls12Handshake "); ce != nil {
ce.Write(zap.Int("step", step),
zap.Bool("isSrcClient", isSrcClient),
zap.Uint8("contentType", contentType),
)
}
if contentType != 22 {
if step == 0 {
return errors.New("copyTls12Handshake: tls_plaintxt[0]!=22")
} else {
if contentType == 20 {
thisChangeCipher = true
} else {
return utils.ErrInErr{ErrDesc: "copyTls12Handshake: contentType wrong, mustbe 20 or 22", Data: contentType}
}
}
}
length := binary.BigEndian.Uint16(tls_plaintxt[3:])
netLayer.SetCommonReadTimeout(src)
netLayer.SetCommonWriteTimeout(dst)
_, err = io.Copy(dst, io.MultiReader(bytes.NewReader(tls_plaintxt[:]), io.LimitReader(src, int64(length))))
netLayer.PersistRead(src)
netLayer.PersistWrite(dst)
if err != nil {
return err
}
if lastHandshakeTogo {
break
}
if thisChangeCipher {
lastHandshakeTogo = true
}
step += 1
if step > 6 {
return errors.New("shit, shadowTls copy loop > 6, maybe under attack")
}
}
return nil
}
func WriteAppData(conn io.Writer, buf *bytes.Buffer, d []byte) (n int, err error) {
shouldPut := false
if buf == nil {
buf = utils.GetBuf()
shouldPut = true
}
WriteAppDataHeader(buf, len(d))
buf.Write(d)
n, err = conn.Write(buf.Bytes())
if shouldPut {
utils.PutBuf(buf)
}
return
}
// 一般conn直接为tcp连接,而它是有系统缓存的,因此我们一般不需要特地创建一个缓存
// 写两遍之后在发出
func WriteAppDataNoBuf(w io.Writer, d []byte) (n int, err error) {
err = WriteAppDataHeader(w, len(d))
if err != nil {
return
}
return w.Write(d)
}
func WriteAppDataHeader(w io.Writer, len int) (err error) {
var h [5]byte
h[0] = 23
binary.BigEndian.PutUint16(h[1:3], tls.VersionTLS12)
binary.BigEndian.PutUint16(h[3:], uint16(len))
_, err = w.Write(h[:])
return
}