77 "sync"
88 "unsafe"
99
10+ "github.com/sagernet/sing/common"
1011 "github.com/sagernet/sing/common/buf"
1112 M "github.com/sagernet/sing/common/metadata"
1213
@@ -28,13 +29,30 @@ func (w *SyscallVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error {
2829 }
2930 var innerErr unix.Errno
3031 err := w .rawConn .Write (func (fd uintptr ) (done bool ) {
31- //nolint:staticcheck
32- _ , _ , innerErr = unix .Syscall (unix .SYS_WRITEV , fd , uintptr (unsafe .Pointer (& iovecList [0 ])), uintptr (len (iovecList )))
33- return innerErr != unix .EAGAIN && innerErr != unix .EWOULDBLOCK
32+ for {
33+ var r0 uintptr
34+ //nolint:staticcheck
35+ r0 , _ , innerErr = unix .RawSyscall (unix .SYS_WRITEV , fd , uintptr (unsafe .Pointer (& iovecList [0 ])), uintptr (len (iovecList )))
36+ writeN := int (r0 )
37+ for writeN > 0 {
38+ if buffers [0 ].Len () > writeN {
39+ buffers [0 ].Advance (writeN )
40+ iovecList [0 ] = buffers [0 ].Iovec (buffers [0 ].Len ())
41+ break
42+ } else {
43+ writeN -= buffers [0 ].Len ()
44+ buffers [0 ].Release ()
45+ buffers = buffers [1 :]
46+ iovecList = iovecList [1 :]
47+ }
48+ }
49+ if innerErr == unix .EINTR || (innerErr == 0 && len (iovecList ) > 0 ) {
50+ continue
51+ }
52+ return innerErr != unix .EAGAIN
53+ }
3454 })
35- for i := range iovecList {
36- iovecList [i ] = unix.Iovec {}
37- }
55+ common .ClearArray (iovecList )
3856 if cap (iovecList ) > cap (w .iovecList ) {
3957 w .iovecList = iovecList [:0 ]
4058 }
@@ -62,12 +80,15 @@ func (w *SyscallVectorisedPacketWriter) WriteVectorisedPacket(buffers []*buf.Buf
6280 msg .Iov = & iovecList [0 ]
6381 msg .SetIovlen (len (iovecList ))
6482 }
65- _ , innerErr = sendmsg (int (fd ), & msg , 0 )
66- return innerErr != unix .EAGAIN && innerErr != unix .EWOULDBLOCK
83+ for {
84+ _ , _ , innerErr = unix .RawSyscall (unix .SYS_SENDMSG , fd , uintptr (unsafe .Pointer (& msg )), 0 )
85+ if innerErr == unix .EINTR {
86+ continue
87+ }
88+ return innerErr != unix .EAGAIN
89+ }
6790 })
68- for i := range iovecList {
69- iovecList [i ] = unix.Iovec {}
70- }
91+ common .ClearArray (iovecList )
7192 if cap (iovecList ) > cap (w .iovecList ) {
7293 w .iovecList = iovecList [:0 ]
7394 }
@@ -76,6 +97,3 @@ func (w *SyscallVectorisedPacketWriter) WriteVectorisedPacket(buffers []*buf.Buf
7697 }
7798 return err
7899}
79-
80- //go:linkname sendmsg golang.org/x/sys/unix.sendmsg
81- func sendmsg (s int , msg * unix.Msghdr , flags int ) (n int , err error )
0 commit comments