github.com/sagernet/sing@v0.2.6/common/bufio/vectorised_windows.go (about)

     1  package bufio
     2  
     3  import (
     4  	"github.com/sagernet/sing/common/buf"
     5  	M "github.com/sagernet/sing/common/metadata"
     6  
     7  	"golang.org/x/sys/windows"
     8  )
     9  
    10  func (w *SyscallVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error {
    11  	defer buf.ReleaseMulti(buffers)
    12  	iovecList := make([]*windows.WSABuf, len(buffers))
    13  	for i, buffer := range buffers {
    14  		iovecList[i] = &windows.WSABuf{
    15  			Len: uint32(buffer.Len()),
    16  			Buf: &buffer.Bytes()[0],
    17  		}
    18  	}
    19  	var n uint32
    20  	var innerErr error
    21  	err := w.rawConn.Write(func(fd uintptr) (done bool) {
    22  		innerErr = windows.WSASend(windows.Handle(fd), iovecList[0], uint32(len(iovecList)), &n, 0, nil, nil)
    23  		return innerErr != windows.WSAEWOULDBLOCK
    24  	})
    25  	if innerErr != nil {
    26  		err = innerErr
    27  	}
    28  	return err
    29  }
    30  
    31  func (w *SyscallVectorisedPacketWriter) WriteVectorisedPacket(buffers []*buf.Buffer, destination M.Socksaddr) error {
    32  	defer buf.ReleaseMulti(buffers)
    33  	iovecList := make([]*windows.WSABuf, len(buffers))
    34  	for i, buffer := range buffers {
    35  		iovecList[i] = &windows.WSABuf{
    36  			Len: uint32(buffer.Len()),
    37  			Buf: &buffer.Bytes()[0],
    38  		}
    39  	}
    40  	var sockaddr windows.Sockaddr
    41  	if destination.IsIPv4() {
    42  		sockaddr = &windows.SockaddrInet4{
    43  			Port: int(destination.Port),
    44  			Addr: destination.Addr.As4(),
    45  		}
    46  	} else {
    47  		sockaddr = &windows.SockaddrInet6{
    48  			Port: int(destination.Port),
    49  			Addr: destination.Addr.As16(),
    50  		}
    51  	}
    52  	var n uint32
    53  	var innerErr error
    54  	err := w.rawConn.Write(func(fd uintptr) (done bool) {
    55  		innerErr = windows.WSASendto(windows.Handle(fd), iovecList[0], uint32(len(iovecList)), &n, 0, sockaddr, nil, nil)
    56  		return innerErr != windows.WSAEWOULDBLOCK
    57  	})
    58  	if innerErr != nil {
    59  		err = innerErr
    60  	}
    61  	return err
    62  }