From cee85dcd3013b8ed7f8453d1e83c5ede479de10b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 21 Aug 2022 22:35:31 +0800 Subject: [PATCH] Fix vectorised writer --- common/buf/buffer.go | 6 ++++++ common/bufio/vectorised_unix.go | 30 ++++++++++++++--------------- common/bufio/vectorised_windows.go | 14 +++++++++++++- common/metadata/addr_posix.go | 31 ------------------------------ common/metadata/addr_windows.go | 21 -------------------- go.mod | 2 +- go.sum | 4 ++-- 7 files changed, 37 insertions(+), 71 deletions(-) delete mode 100644 common/metadata/addr_posix.go delete mode 100644 common/metadata/addr_windows.go diff --git a/common/buf/buffer.go b/common/buf/buffer.go index 73116e5..cbfb2aa 100644 --- a/common/buf/buffer.go +++ b/common/buf/buffer.go @@ -327,6 +327,12 @@ func ReleaseMulti(buffers []*Buffer) { } } +func ToSliceMulti(buffers []*Buffer) [][]byte { + return common.Map(buffers, func(it *Buffer) []byte { + return it.Bytes() + }) +} + func (b *Buffer) Cut(start int, end int) *Buffer { b.start += start b.end = len(b.data) - end diff --git a/common/bufio/vectorised_unix.go b/common/bufio/vectorised_unix.go index b2ba806..f3379d0 100644 --- a/common/bufio/vectorised_unix.go +++ b/common/bufio/vectorised_unix.go @@ -32,25 +32,25 @@ func (w *SyscallVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error { } func (w *SyscallVectorisedPacketWriter) WriteVectorisedPacket(buffers []*buf.Buffer, destination M.Socksaddr) error { - iovecList := make([]unix.Iovec, 0, len(buffers)) - for _, buffer := range buffers { - var iovec unix.Iovec - iovec.Base = &buffer.Bytes()[0] - iovec.SetLen(buffer.Len()) - iovecList = append(iovecList, iovec) + defer buf.ReleaseMulti(buffers) + var sockaddr unix.Sockaddr + if destination.IsIPv4() { + sockaddr = &unix.SockaddrInet4{ + Port: int(destination.Port), + Addr: destination.Addr.As4(), + } + } else { + sockaddr = &unix.SockaddrInet6{ + Port: int(destination.Port), + Addr: destination.Addr.As16(), + } } - name, nameLen := destination.Sockaddr() - var msgHdr unix.Msghdr - msgHdr.Name = (*byte)(name) - msgHdr.Namelen = nameLen - msgHdr.Iov = &iovecList[0] - msgHdr.SetIovlen(len(iovecList)) - var innerErr unix.Errno + var innerErr error err := w.rawConn.Write(func(fd uintptr) (done bool) { - _, _, innerErr = unix.Syscall(unix.SYS_SENDMSG, fd, uintptr(unsafe.Pointer(&msgHdr)), 0) + _, innerErr = unix.SendmsgBuffers(int(fd), buf.ToSliceMulti(buffers), nil, sockaddr, 0) return innerErr != unix.EAGAIN && innerErr != unix.EWOULDBLOCK }) - if innerErr != 0 { + if innerErr != nil { err = innerErr } return err diff --git a/common/bufio/vectorised_windows.go b/common/bufio/vectorised_windows.go index 1a31c55..3223052 100644 --- a/common/bufio/vectorised_windows.go +++ b/common/bufio/vectorised_windows.go @@ -37,10 +37,22 @@ func (w *SyscallVectorisedPacketWriter) WriteVectorisedPacket(buffers []*buf.Buf Buf: &buffer.Bytes()[0], } } + var sockaddr windows.Sockaddr + if destination.IsIPv4() { + sockaddr = &windows.SockaddrInet4{ + Port: int(destination.Port), + Addr: destination.Addr.As4(), + } + } else { + sockaddr = &windows.SockaddrInet6{ + Port: int(destination.Port), + Addr: destination.Addr.As16(), + } + } var n uint32 var innerErr error err := w.rawConn.Write(func(fd uintptr) (done bool) { - innerErr = windows.WSASendto(windows.Handle(fd), iovecList[0], uint32(len(iovecList)), &n, 0, destination.Sockaddr(), nil, nil) + innerErr = windows.WSASendto(windows.Handle(fd), iovecList[0], uint32(len(iovecList)), &n, 0, sockaddr, nil, nil) return innerErr != windows.WSAEWOULDBLOCK }) if innerErr != nil { diff --git a/common/metadata/addr_posix.go b/common/metadata/addr_posix.go deleted file mode 100644 index a0e9a3f..0000000 --- a/common/metadata/addr_posix.go +++ /dev/null @@ -1,31 +0,0 @@ -//go:build !windows - -package metadata - -import ( - "syscall" - "unsafe" -) - -func (ap Socksaddr) Sockaddr() (name unsafe.Pointer, nameLen uint32) { - if ap.IsFqdn() { - panic("bad sockaddr") - } else if ap.IsIPv4() { - rsa4 := syscall.RawSockaddrInet4{ - Family: syscall.AF_INET, - Port: ap.Port, - Addr: ap.Addr.As4(), - } - name = unsafe.Pointer(&rsa4) - nameLen = syscall.SizeofSockaddrInet4 - } else { - rsa6 := syscall.RawSockaddrInet6{ - Family: syscall.AF_INET6, - Port: ap.Port, - Addr: ap.Addr.As16(), - } - name = unsafe.Pointer(&rsa6) - nameLen = syscall.SizeofSockaddrInet6 - } - return -} diff --git a/common/metadata/addr_windows.go b/common/metadata/addr_windows.go deleted file mode 100644 index 1aa1eef..0000000 --- a/common/metadata/addr_windows.go +++ /dev/null @@ -1,21 +0,0 @@ -package metadata - -import ( - "golang.org/x/sys/windows" -) - -func (ap Socksaddr) Sockaddr() windows.Sockaddr { - if ap.IsFqdn() { - panic("bad sockaddr") - } else if ap.IsIPv4() { - return &windows.SockaddrInet4{ - Port: int(ap.Port), - Addr: ap.Addr.As4(), - } - } else { - return &windows.SockaddrInet6{ - Port: int(ap.Port), - Addr: ap.Addr.As16(), - } - } -} diff --git a/go.mod b/go.mod index 228feda..d83e689 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/sagernet/sing go 1.18 -require golang.org/x/sys v0.0.0-20220731174439-a90be440212d +require golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 diff --git a/go.sum b/go.sum index b7c2d11..65066cc 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80= -golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U= +golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=