github.com/pawelgaczynski/giouring@v0.0.0-20230826085535-69588b89acb9/recvmsg.go (about) 1 // MIT License 2 // 3 // Copyright (c) 2023 Paweł Gaczyński 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a 6 // copy of this software and associated documentation files (the 7 // "Software"), to deal in the Software without restriction, including 8 // without limitation the rights to use, copy, modify, merge, publish, 9 // distribute, sublicense, and/or sell copies of the Software, and to 10 // permit persons to whom the Software is furnished to do so, subject to 11 // the following conditions: 12 // 13 // The above copyright notice and this permission notice shall be included 14 // in all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24 package giouring 25 26 import ( 27 "syscall" 28 "unsafe" 29 ) 30 31 // liburing: CMSG_ALIGN 32 func cmsgAlign(length uint64) uint64 { 33 return (length + uint64(unsafe.Sizeof(uintptr(0))) - 1) & ^(uint64(unsafe.Sizeof(uintptr(0))) - 1) 34 } 35 36 // liburing: io_uring_recvmsg_cmsg_nexthdr - https://manpages.debian.org/unstable/liburing-dev/io_uring_recvmsg_cmsg_nexthdr.3.en.html 37 func (o *RecvmsgOut) CmsgNexthdr(msgh *syscall.Msghdr, cmsg *syscall.Cmsghdr) *syscall.Cmsghdr { 38 if cmsg.Len < syscall.SizeofCmsghdr { 39 return nil 40 } 41 end := (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(o.CmsgFirsthdr(msgh))) + uintptr(o.ControlLen))) 42 cmsg = (*syscall.Cmsghdr)(unsafe.Pointer(uintptr(unsafe.Pointer(cmsg)) + uintptr(cmsgAlign(cmsg.Len)))) 43 if uintptr(unsafe.Pointer(cmsg))+unsafe.Sizeof(*cmsg) > uintptr(unsafe.Pointer(end)) { 44 return nil 45 } 46 if uintptr(unsafe.Pointer(cmsg))+uintptr(cmsgAlign(cmsg.Len)) > uintptr(unsafe.Pointer(end)) { 47 return nil 48 } 49 50 return cmsg 51 } 52 53 // liburing: io_uring_recvmsg_name - https://manpages.debian.org/unstable/liburing-dev/io_uring_recvmsg_name.3.en.html 54 func (o *RecvmsgOut) Name() unsafe.Pointer { 55 return unsafe.Pointer(uintptr(unsafe.Pointer(o)) + unsafe.Sizeof(*o)) 56 } 57 58 // liburing: io_uring_recvmsg_cmsg_firsthdr - https://manpages.debian.org/unstable/liburing-dev/io_uring_recvmsg_cmsg_firsthdr.3.en.html 59 func (o *RecvmsgOut) CmsgFirsthdr(msgh *syscall.Msghdr) *syscall.Cmsghdr { 60 if o.ControlLen < syscall.SizeofCmsghdr { 61 return nil 62 } 63 64 return (*syscall.Cmsghdr)(unsafe.Pointer(uintptr(o.Name()) + uintptr(msgh.Namelen))) 65 } 66 67 // liburing: io_uring_recvmsg_payload - https://manpages.debian.org/unstable/liburing-dev/io_uring_recvmsg_payload.3.en.html 68 func (o *RecvmsgOut) Payload(msgh *syscall.Msghdr) unsafe.Pointer { 69 return unsafe.Pointer(uintptr(unsafe.Pointer(o)) + 70 unsafe.Sizeof(*o) + 71 uintptr(msgh.Namelen) + 72 uintptr(msgh.Controllen)) 73 } 74 75 // liburing: io_uring_recvmsg_payload_length - https://manpages.debian.org/unstable/liburing-dev/io_uring_recvmsg_payload_length.3.en.html 76 func (o *RecvmsgOut) PayloadLength(bufLen int, msgh *syscall.Msghdr) uint32 { 77 payloadStart := uintptr(o.Payload(msgh)) 78 payloadEnd := uintptr(unsafe.Pointer(o)) + uintptr(bufLen) 79 80 return uint32(payloadEnd - payloadStart) 81 } 82 83 // liburing: io_uring_recvmsg_validate - https://manpages.debian.org/unstable/liburing-dev/io_uring_recvmsg_validate.3.en.html 84 func RecvmsgValidate(buf unsafe.Pointer, bufLen int, msgh *syscall.Msghdr) *RecvmsgOut { 85 header := uintptr(msgh.Controllen) + uintptr(msgh.Namelen) + unsafe.Sizeof(RecvmsgOut{}) 86 if bufLen < 0 || uintptr(bufLen) < header { 87 return nil 88 } 89 90 return (*RecvmsgOut)(buf) 91 }