From a540cdd1839b10a6e516c3d794fd3709282b73b1 Mon Sep 17 00:00:00 2001 From: hahahrfool <75717694+hahahrfool@users.noreply.github.com> Date: Wed, 23 Mar 2022 10:41:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E8=AE=A2=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- netLayer/netlayer.go | 32 +++++++++++++++++++++++++------- netLayer/readv.go | 28 +++++----------------------- utils/buffers.go | 22 +++++++++++++--------- utils/readv_posix.go | 7 ++++--- utils/readv_windows.go | 6 +++--- 6 files changed, 51 insertions(+), 46 deletions(-) diff --git a/Makefile b/Makefile index c173c51..5258f61 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ ifdef PACK define compile GOOS=$(2) GOARCH=$(3) $(cmd) $(1) mv $(1) verysimple$(4) - tar -czf $(1).tgz verysimple$(4) vlesss.server.toml vlesss.client.toml z_multi.client.toml z_multi.server.toml + tar -czf $(1).tgz verysimple$(4) examples/ rm verysimple$(4) endef diff --git a/netLayer/netlayer.go b/netLayer/netlayer.go index 7e5d017..aebf06e 100644 --- a/netLayer/netlayer.go +++ b/netLayer/netlayer.go @@ -8,17 +8,35 @@ Package netLayer contains definitions in network layer AND transport layer. */ package netLayer -import "net" +import ( + "io" + "log" + "syscall" + "github.com/hahahrfool/v2ray_simple/utils" +) + +//net.IPConn, net.TCPConn, net.UDPConn, net.UnixConn func IsBasicConn(r interface{}) bool { - switch r.(type) { - case *net.TCPConn: - return true - case *net.UDPConn: - return true - case *net.UnixConn: + if _, ok := r.(syscall.Conn); ok { return true } return false } + +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 + } + return rawConn + + } + + return nil +} diff --git a/netLayer/readv.go b/netLayer/readv.go index ad3accd..aae533e 100644 --- a/netLayer/readv.go +++ b/netLayer/readv.go @@ -2,7 +2,6 @@ package netLayer import ( "io" - "log" "net" "syscall" @@ -14,27 +13,11 @@ import ( // 16个1500那就是 24000, 23.4375 KB, 不算小了; var readv_buffer_allocLen = 16 -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 -} - /* ReadFromMultiReader 用于读端实现了 readv但是写端的情况,比如 从socks5读取 数据, 等裸协议的情况。 若allocedBuffers未给出,会使用 utils.AllocMTUBuffers 来初始化 缓存。 -返回错误时,依然会返回 原buffer 或者 在函数内部新分配的buffer. 本函数不负责 释放分配的内存. 这样有时可以重复利用缓存。 +返回错误时,依然会返回 原buffer 或者 在函数内部新分配的buffer. 本函数不负责 释放分配的内存. 因为有时需要重复利用缓存。 小贴士:将该 net.Buffers 写入io.Writer的话,只需使用 其WriteTo方法, 即可自动适配writev。 @@ -46,10 +29,10 @@ func ReadFromMultiReader(rawReadConn syscall.RawConn, mr utils.MultiReader, allo allocedBuffers = utils.AllocMTUBuffers(mr, readv_buffer_allocLen) } - var nBytes int32 + var nBytes uint32 err := rawReadConn.Read(func(fd uintptr) bool { - n := mr.Read(fd) - if n < 0 { + n, e := mr.Read(fd) + if e != nil { return false } @@ -61,7 +44,6 @@ func ReadFromMultiReader(rawReadConn syscall.RawConn, mr utils.MultiReader, allo return allocedBuffers, err } if nBytes == 0 { - err = io.EOF return allocedBuffers, io.EOF } @@ -69,7 +51,7 @@ func ReadFromMultiReader(rawReadConn syscall.RawConn, mr utils.MultiReader, allo /* if utils.CanLogDebug() { // 可用于查看到底用了几个buf, 便于我们调整buf最大长度 - log.Println("release buf", len(bs)-nBuf) + log.Println("release buf", len(allocedBuffers)-nBuf) } */ diff --git a/utils/buffers.go b/utils/buffers.go index 450251b..b8e5063 100644 --- a/utils/buffers.go +++ b/utils/buffers.go @@ -6,9 +6,9 @@ import "log" // 该 MultiReader 的用例请参照 netLayer.ReadFromMultiReader , 在 netLayer/readv.go中 //具体实现见 readv_*.go; 用 GetReadVReader() 函数来获取本平台的对应实现。 type MultiReader interface { - Init([][]byte) //将 给出的buffer 放入内部实际数据中 - Read(fd uintptr) int32 //读取一次文件,并放入 buffer中 - Clear() //清理内部buffer + Init([][]byte) //将 给出的buffer 放入内部实际数据中 + Read(fd uintptr) (uint32, error) //读取一次文件,并放入 buffer中 + Clear() //清理内部buffer } // 因为 net.Buffers 的 WriteTo方法只会查看其是否实现了net包私有的 writeBuffers 接口 @@ -41,6 +41,7 @@ type MultiWriter interface { WriteBuffers([][]byte) (int64, error) } +//获取所有子[]byte 长度总和 func BuffersLen(bs [][]byte) (allnum int) { if len(bs) < 1 { return 0 @@ -57,6 +58,7 @@ func PrintBuffers(bs [][]byte) { } } +// AllocMTUBuffers 获取指定 子[]byte 数量的 [][]byte, 并用 mr.Init 给mr里的缓存指针赋值. // 每个子[]byte 长度固定为 StandardBytesLenth func AllocMTUBuffers(mr MultiReader, len int) [][]byte { bs := make([][]byte, len) @@ -68,6 +70,7 @@ func AllocMTUBuffers(mr MultiReader, len int) [][]byte { return bs } +//将mb恢复原先长度后,将mb的所有子[]byte 放回Pool中 func ReleaseBuffers(mb [][]byte, oldLen int) { if mb == nil { return @@ -78,10 +81,10 @@ func ReleaseBuffers(mb [][]byte, oldLen int) { } } -//删减buffer内部的子[]byte 到合适的长度 +//削减buffer内部的子[]byte 到合适的长度;返回削减后 bs应有的长度. func ShrinkBuffers(bs [][]byte, all_len int) int { - nBuf := 0 - for nBuf < len(bs) { + curIndex := 0 + for curIndex < len(bs) { if all_len <= 0 { break } @@ -89,13 +92,14 @@ func ShrinkBuffers(bs [][]byte, all_len int) int { if end > StandardBytesLength { end = StandardBytesLength } - bs[nBuf] = bs[nBuf][:end] + bs[curIndex] = bs[curIndex][:end] all_len -= end - nBuf++ + curIndex++ } - return nBuf + return curIndex } +//通过reslice 方式将 bs的长度以及 子 []byte 的长度 恢复至指定长度 func RecoverBuffers(bs [][]byte, oldLen, old_sub_len int) [][]byte { bs = bs[:oldLen] for i, v := range bs { diff --git a/utils/readv_posix.go b/utils/readv_posix.go index 63764d2..e4ee7b7 100644 --- a/utils/readv_posix.go +++ b/utils/readv_posix.go @@ -30,12 +30,13 @@ func (r *posixReader) Init(bs [][]byte) { r.iovecs = iovecs } -func (r *posixReader) Read(fd uintptr) int32 { +//正常readv返回的应该是 ssize_t, 在64位机器上应该是 int64, 但是负数只用于返回-1错误,而且我们提供的buffer长度远远小于 uint32的上限;所以uint32可以 +func (r *posixReader) Read(fd uintptr) (uint32, error) { n, _, e := syscall.Syscall(syscall.SYS_READV, fd, uintptr(unsafe.Pointer(&r.iovecs[0])), uintptr(len(r.iovecs))) if e != 0 { - return -1 + return 0, e } - return int32(n) + return uint32(n), nil } func (r *posixReader) Clear() { diff --git a/utils/readv_windows.go b/utils/readv_windows.go index 6af563f..2eb3c65 100644 --- a/utils/readv_windows.go +++ b/utils/readv_windows.go @@ -28,12 +28,12 @@ func (r *windowsReader) Clear() { r.bufs = r.bufs[:0] } -func (r *windowsReader) Read(fd uintptr) int32 { +func (r *windowsReader) Read(fd uintptr) (uint32, error) { var nBytes uint32 var flags uint32 err := syscall.WSARecv(syscall.Handle(fd), &r.bufs[0], uint32(len(r.bufs)), &nBytes, &flags, nil, nil) if err != nil { - return -1 + return 0, err } - return int32(nBytes) + return nBytes, nil }