Files
v2ray_simple/netLayer/readv.go
2022-03-22 16:46:05 +08:00

109 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package netLayer
import (
"io"
"log"
"net"
"syscall"
"github.com/hahahrfool/v2ray_simple/utils"
)
func GetRawConn(reader io.Reader) syscall.RawConn {
if sc, ok := reader.(syscall.Conn); ok {
rawConn, err := sc.SyscallConn()
if err != nil {
if utils.CanLogDebug() {
log.Println("can't convert syscall.Conn to syscall.RawConn", reader, err)
}
return nil
} else {
return rawConn
}
}
return nil
}
// 用于读端实现了 readv但是写端的情况比如 从socks5读取 数据, 等裸协议的情况
// 小贴士:将该 net.Buffers 写入io.Writer的话只需使用 其WriteTo方法, 即可自动适配writev。
/*
使用方式
var readConn, writeConn net.Conn
//想办法初始化这两个Conn
rawConn:= netLayer.GetRawConn(readConn)
mr:=utils.GetReadVReader()
buffers,err:= netLayer.ReadFromMultiReader(rawConn,mr)
if err!=nil{
log.Fatal("sfdfdaf")
}
buffers.WriteTo(writeConn)
包装的代码见 TryCopy 函数; Relay函数也用到了
*/
func ReadFromMultiReader(rawReadConn syscall.RawConn, mr utils.MultiReader) (net.Buffers, error) {
//v2ray里还使用了动态分配的方式我们为了简便先啥也不做
bs := make([][]byte, 16)
// 实测16个buf已经完全够用平时也就偶尔遇到5个buf的情况, 极速测速时会占用更多;
// 16个1500那就是 24000, 23.4375 KB, 不算小了;
for i := range bs {
bs[i] = utils.GetMTU()
}
mr.Init(bs)
var nBytes int32
err := rawReadConn.Read(func(fd uintptr) bool {
n := mr.Read(fd)
if n < 0 {
return false
}
nBytes = n
return true
})
mr.Clear()
if err != nil {
ReleaseNetBuffers(bs)
return nil, err
}
if nBytes == 0 {
ReleaseNetBuffers(bs)
return nil, io.EOF
}
//删减buffer 到合适的长度并释放没用到的buf
nBuf := 0
for nBuf < len(bs) {
if nBytes <= 0 {
break
}
end := nBytes
if end > int32(utils.StandardBytesLength) {
end = int32(utils.StandardBytesLength)
}
bs[nBuf] = bs[nBuf][:end]
nBytes -= end
nBuf++
}
/*
if utils.CanLogDebug() {
// 可用于查看到底用了几个buf, 便于我们调整buf最大长度
log.Println("release buf", len(bs)-nBuf)
}
*/
ReleaseNetBuffers(bs[nBuf:])
return bs[:nBuf], nil
}
func ReleaseNetBuffers(mb [][]byte) {
for i := range mb {
utils.PutBytes(mb[i])
}
}