public bool TryCompleteReceive(Ring ring, int result, [NotNullWhen(true)] out InboundConnection connection)
        {
            // Start work-around for https://github.com/axboe/liburing/issues/128
            _iov.AsSpan().Clear();
            _dummyBuffer.AsSpan().Clear();
            _control.AsSpan().Clear();
            _header.AsSpan().Clear();

            iovec* iov = (iovec*) MemoryHelper.UnsafeGetAddressOfPinnedArrayData(_iov);
            iov->iov_base = (byte*) MemoryHelper.UnsafeGetAddressOfPinnedArrayData(_dummyBuffer);
            iov->iov_len = 1;

            byte* control = (byte*) MemoryHelper.UnsafeGetAddressOfPinnedArrayData(_control);

            msghdr* header = (msghdr*) MemoryHelper.UnsafeGetAddressOfPinnedArrayData(_header);
            header->msg_iov = iov;
            header->msg_iovlen = 1;
            header->msg_control = control;
            header->msg_controllen = _control.Length;

            result = _recipient.RecvMsg(header, (MSG_NOSIGNAL | MSG_CMSG_CLOEXEC));
            // End of work-around for https://github.com/axboe/liburing/issues/128

            connection = default;
            if (result < 0)
            {
                HandleCompleteReceiveError(ring, result);
                return false;
            }

            bool receivedSocket = false;
            LinuxSocket socket = default;
            for (cmsghdr* cmsg = CMSG_FIRSTHDR(header); cmsg != null; cmsg = CMSG_NXTHDR(header, cmsg))
            {
                if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
                {
                    int* fdptr = (int*) CMSG_DATA(cmsg);
                    socket = *fdptr;
                    socket.SetFlag(O_NONBLOCK);

                    receivedSocket = true;
                    break;
                }
            }

            if (!receivedSocket)
            {
                if (result != 0)
                {
                    PollReceive(ring);
                }

                return false;
            }

            connection = new InboundConnection(socket, _endPoint, null, _memoryPool, _options, _scheduler);
            return true;
        }
Example #2
0
        public bool TryCompleteAccept(Ring ring, int result, [NotNullWhen(true)] out InboundConnection connection)
        {
            connection = default;
            if (!TryCompleteAcceptSocket(ring, result, out var socket))
            {
                return(false);
            }

            EndPoint remoteEndPoint = null;

            if (IsIpSocket)
            {
                if (_options.TcpNoDelay)
                {
                    socket.SetOption(SOL_TCP, TCP_NODELAY, 1);
                }

                remoteEndPoint = EndPointFormatter.AddrToIpEndPoint((sockaddr_storage *)Addr);
            }

            connection = new InboundConnection(socket, EndPoint, remoteEndPoint, _memoryPool, _options, _scheduler);
            return(true);
        }