Fix vectorised writer

This commit is contained in:
世界 2022-08-21 22:35:31 +08:00
parent 5945fd0457
commit cee85dcd30
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
7 changed files with 37 additions and 71 deletions

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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
}

View file

@ -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(),
}
}
}

2
go.mod
View file

@ -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

4
go.sum
View file

@ -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=