mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-03 20:07:38 +03:00
Fix vectorised writer
This commit is contained in:
parent
5945fd0457
commit
cee85dcd30
7 changed files with 37 additions and 71 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
2
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
|
||||
|
|
4
go.sum
4
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=
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue