|
|
@@ -796,6 +796,75 @@ func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesS
|
|
|
return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
|
|
|
}
|
|
|
|
|
|
+var sendRecvMsgFunc struct {
|
|
|
+ once sync.Once
|
|
|
+ sendAddr uintptr
|
|
|
+ recvAddr uintptr
|
|
|
+ err error
|
|
|
+}
|
|
|
+
|
|
|
+func loadWSASendRecvMsg() error {
|
|
|
+ sendRecvMsgFunc.once.Do(func() {
|
|
|
+ var s Handle
|
|
|
+ s, sendRecvMsgFunc.err = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
|
|
+ if sendRecvMsgFunc.err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ defer CloseHandle(s)
|
|
|
+ var n uint32
|
|
|
+ sendRecvMsgFunc.err = WSAIoctl(s,
|
|
|
+ SIO_GET_EXTENSION_FUNCTION_POINTER,
|
|
|
+ (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)),
|
|
|
+ uint32(unsafe.Sizeof(WSAID_WSARECVMSG)),
|
|
|
+ (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)),
|
|
|
+ uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)),
|
|
|
+ &n, nil, 0)
|
|
|
+ if sendRecvMsgFunc.err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sendRecvMsgFunc.err = WSAIoctl(s,
|
|
|
+ SIO_GET_EXTENSION_FUNCTION_POINTER,
|
|
|
+ (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)),
|
|
|
+ uint32(unsafe.Sizeof(WSAID_WSASENDMSG)),
|
|
|
+ (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)),
|
|
|
+ uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)),
|
|
|
+ &n, nil, 0)
|
|
|
+ })
|
|
|
+ return sendRecvMsgFunc.err
|
|
|
+}
|
|
|
+
|
|
|
+func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *Overlapped, croutine *byte) error {
|
|
|
+ err := loadWSASendRecvMsg()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
|
|
|
+ if r1 == socket_error {
|
|
|
+ if e1 != 0 {
|
|
|
+ err = errnoErr(e1)
|
|
|
+ } else {
|
|
|
+ err = syscall.EINVAL
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return err
|
|
|
+}
|
|
|
+
|
|
|
+func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overlapped, croutine *byte) error {
|
|
|
+ err := loadWSASendRecvMsg()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0)
|
|
|
+ if r1 == socket_error {
|
|
|
+ if e1 != 0 {
|
|
|
+ err = errnoErr(e1)
|
|
|
+ } else {
|
|
|
+ err = syscall.EINVAL
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return err
|
|
|
+}
|
|
|
+
|
|
|
// Invented structures to support what package os expects.
|
|
|
type Rusage struct {
|
|
|
CreationTime Filetime
|