Exemplo n.º 1
0
        public static unsafe PosixResult GetSockName(int socket, sockaddr_storage *addr)
        {
            socklen_t sockLen = SizeOf.sockaddr_storage;
            int       rv      = getsockname(socket, (sockaddr *)addr, &sockLen);

            return(PosixResult.FromReturnValue(rv));
        }
Exemplo n.º 2
0
 /// <summary>
 /// Adds a connect to the Submission Queue without it being submitted.
 /// The actual submission can be deferred to avoid unnecessary memory barriers.
 /// </summary>
 /// <param name="fd">The socket to connect on</param>
 /// <param name="addr">The address to connect to</param>
 /// <param name="addrLen">The length of the address</param>
 /// <param name="userData">User data that will be returned with the respective <see cref="Completion"/></param>
 /// <param name="options">Options for the handling of the prepared Submission Queue Entry</param>
 /// <returns><code>false</code> if the submission queue is full. <code>true</code> otherwise.</returns>
 /// <exception cref="SubmissionQueueFullException">If no more free space in the Submission Queue is available</exception>
 public void PrepareConnect(int fd, sockaddr *addr, socklen_t addrLen, ulong userData = 0, SubmissionOption options = SubmissionOption.None)
 {
     if (!TryPrepareConnect(fd, addr, addrLen, userData, options))
     {
         ThrowSubmissionQueueFullException();
     }
 }
Exemplo n.º 3
0
        public int sceNetInetConnect(int SocketId, sockaddr_in *serv_addr, socklen_t addrlen)
        {
            var Socket = Sockets.Get(SocketId);

            Console.WriteLine("{0}", serv_addr->sin_addr);
            Socket.Connect(new IPEndPoint(serv_addr->sin_addr.Address, serv_addr->sin_port));
            return(0);
        }
Exemplo n.º 4
0
        public int sceNetInetSendto(int SocketId, void *BufferPointer, int BufferLength, SocketFlags SocketFlags,
                                    sockaddr_in *To, socklen_t ToLength)
        {
            var Socket = Sockets.Get(SocketId);

            return(Socket.SendTo(ArrayUtils.CreateArray <byte>(BufferPointer, BufferLength), SocketFlags,
                                 new IPEndPoint(To->sin_addr.Address, To->sin_port)));
        }
Exemplo n.º 5
0
        public unsafe EndPoint GetLocalAddress()
        {
            sockaddr_storage addr;
            socklen_t        length = SizeOf.sockaddr_storage;

            if (getsockname(_fd, (sockaddr *)&addr, &length) != 0)
            {
                throw new ErrnoException(errno);
            }
            return(IPEndPointFormatter.AddrToIpEndPoint(&addr));
        }
Exemplo n.º 6
0
        public unsafe PosixResult TryGetSocketOption(int level, int optname, ref int value)
        {
            int       v      = 0;
            socklen_t length = 4;
            var       rv     = SocketInterop.GetSockOpt(this, level, optname, (byte *)&v, &length);

            if (rv.IsSuccess)
            {
                value = v;
            }
            return(rv);
        }
Exemplo n.º 7
0
        public unsafe int GetOption(int level, int option)
        {
            int       value;
            socklen_t len = sizeof(int);
            var       rv  = getsockopt(_fd, level, option, &value, &len);

            if (rv == -1)
            {
                ThrowHelper.ThrowNewErrnoException();
            }

            return(value);
        }
Exemplo n.º 8
0
//C++ TO C# CONVERTER TODO TASK: The implementation of the following method could not be found:
//  uint read(uint8_t data, uint size);
//C++ TO C# CONVERTER TODO TASK: The implementation of the following method could not be found:
//  uint write(uint8_t data, uint size);
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: System.Tuple<Ipv4Address, uint16_t> getPeerAddressAndPort() const
        public Tuple <Ipv4Address, uint16_t> getPeerAddressAndPort()
        {
            sockaddr_in addr = new sockaddr_in();
            socklen_t   size = sizeof(sockaddr_in);

//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
            if (getpeername(connection, reinterpret_cast <sockaddr>(addr), size) != 0)
            {
                throw new System.Exception("TcpConnection::getPeerAddress, getpeername failed, " + lastErrorMessage());
            }

            Debug.Assert(size == sizeof(sockaddr_in));
            return(Tuple.Create(new Ipv4Address(htonl(addr.sin_addr.s_addr)), htons(addr.sin_port)));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Prepares this Submission Queue Entry as a connect.
        /// </summary>
        /// <param name="fd">The socket to connect on</param>
        /// <param name="addr">The address to connect to</param>
        /// <param name="addrLen">The length of the address</param>
        /// <param name="userData">User data that will be returned with the respective <see cref="Completion"/></param>
        /// <param name="options">Options for the handling of the prepared Submission Queue Entry</param>
        /// <param name="personality">The personality to impersonate for this submission</param>
        public void PrepareConnect(int fd, sockaddr *addr, socklen_t addrLen, ulong userData = 0, SubmissionOption options = SubmissionOption.None, ushort personality = 0)
        {
            var sqe = _sqe;

            unchecked
            {
                sqe->opcode      = IORING_OP_CONNECT;
                sqe->flags       = (byte)options;
                sqe->fd          = fd;
                sqe->off         = addrLen;
                sqe->addr        = (ulong)addr;
                sqe->user_data   = userData;
                sqe->personality = personality;
            }
        }
        public AcceptSocketContext(LinuxSocket socket, IPEndPoint endPoint, ChannelWriter <ConnectionContext> acceptQueue)
        {
            EndPoint    = endPoint;
            AcceptQueue = acceptQueue;
            Socket      = socket;

            sockaddr_storage storage = default;
            var addrHandle           = GCHandle.Alloc(storage, GCHandleType.Pinned);

            _addr       = (sockaddr_storage *)addrHandle.AddrOfPinnedObject();
            _addrHandle = addrHandle;

            socklen_t addrLen       = SizeOf.sockaddr_storage;
            var       addrLenHandle = GCHandle.Alloc(addrLen, GCHandleType.Pinned);

            _addLen        = (socklen_t *)addrLenHandle.AddrOfPinnedObject();
            _addrLenHandle = addrLenHandle;
        }
Exemplo n.º 11
0
        public unsafe LinuxSocket Accept(out IPEndPoint endPoint)
        {
            sockaddr_storage addr;
            socklen_t        len = SizeOf.sockaddr_storage;
            var rv = accept4(_fd, (sockaddr *)&addr, &len, SOCK_NONBLOCK);

            if (rv < 0)
            {
                var err = errno;
                if (err == EAGAIN || err == EWOULDBLOCK || err == EINTR)
                {
                    endPoint = default;
                    return(-1);
                }

                throw new ErrnoException(err);
            }

            endPoint = IPEndPointFormatter.AddrToIpEndPoint(&addr);
            return(rv);
        }
Exemplo n.º 12
0
        public TcpConnection accept()
        {
            Debug.Assert(dispatcher != null);
            Debug.Assert(context == null);
            if (dispatcher.interrupted())
            {
                throw InterruptedException();
            }

            ContextPair      contextPair     = new ContextPair();
            OperationContext listenerContext = new OperationContext();

            listenerContext.interrupted = false;
            listenerContext.context     = dispatcher.getCurrentContext();

            contextPair.writeContext = null;
            contextPair.readContext  = listenerContext;

            epoll_event listenEvent = new epoll_event();

            listenEvent.events   = EPOLLIN | EPOLLONESHOT;
            listenEvent.data.ptr = contextPair;
            string message;

            if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_MOD, listener, listenEvent) == -1)
            {
                message = "epoll_ctl failed, " + lastErrorMessage();
            }
            else
            {
                context = listenerContext;
                dispatcher.getCurrentContext().interruptProcedure = () =>
                {
                    Debug.Assert(dispatcher != null);
                    Debug.Assert(context != null);
                    OperationContext listenerContext = (OperationContext)context;
                    if (!listenerContext.interrupted)
                    {
                        epoll_event listenEvent = new epoll_event();
                        listenEvent.events   = EPOLLONESHOT;
                        listenEvent.data.ptr = null;

                        if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_MOD, listener, listenEvent) == -1)
                        {
                            throw new System.Exception("TcpListener::accept, interrupt procedure, epoll_ctl failed, " + lastErrorMessage());
                        }

                        listenerContext.interrupted = true;
                        dispatcher.pushContext(listenerContext.context);
                    }
                };

                dispatcher.dispatch();
                dispatcher.getCurrentContext().interruptProcedure = null;
                Debug.Assert(dispatcher != null);
                Debug.Assert(listenerContext.context == dispatcher.getCurrentContext());
                Debug.Assert(contextPair.writeContext == null);
                Debug.Assert(context == &listenerContext);
                context = null;
                listenerContext.context = null;
                if (listenerContext.interrupted)
                {
                    throw InterruptedException();
                }

                if ((listenerContext.events & (EPOLLERR | EPOLLHUP)) != 0)
                {
                    throw new System.Exception("TcpListener::accept, accepting failed");
                }

                sockaddr  inAddr     = new sockaddr();
                socklen_t inLen      = sizeof(sockaddr);
                int       connection = global::accept(listener, inAddr, inLen);
                if (connection == -1)
                {
                    message = "accept failed, " + lastErrorMessage();
                }
                else
                {
                    int flags = fcntl(connection, F_GETFL, 0);
                    if (flags == -1 || fcntl(connection, F_SETFL, flags | O_NONBLOCK) == -1)
                    {
                        message = "fcntl failed, " + lastErrorMessage();
                    }
                    else
                    {
                        return(new TcpConnection(dispatcher, connection));
                    }

                    int result = close(connection);
                    if (result != 0)
                    {
                    }
                    Debug.Assert(result != -1);
                }
            }

            throw new System.Exception("TcpListener::accept, " + message);
        }
Exemplo n.º 13
0
 /// <summary>
 /// Attempts to add a connect to the Submission Queue without it being submitted.
 /// The actual submission can be deferred to avoid unnecessary memory barriers.
 /// </summary>
 /// <param name="fd">The socket to connect on</param>
 /// <param name="addr">The address to connect to</param>
 /// <param name="addrLen">The length of the address</param>
 /// <param name="userData">User data that will be returned with the respective <see cref="Completion"/></param>
 /// <param name="options">Options for the handling of the prepared Submission Queue Entry</param>
 /// <returns><code>false</code> if the submission queue is full. <code>true</code> otherwise.</returns>
 public bool TryPrepareConnect(int fd, sockaddr *addr, socklen_t addrLen, ulong userData = 0, SubmissionOption options = SubmissionOption.None)
 {
     return(TryPrepareReadWrite(IORING_OP_CONNECT, fd, addr, 0, (uint)addrLen, 0, userData, options));
 }
Exemplo n.º 14
0
        public TcpConnection connect(Ipv4Address address, uint16_t port)
        {
            Debug.Assert(dispatcher != null);
            Debug.Assert(context == null);
            if (dispatcher.interrupted())
            {
                throw InterruptedException();
            }

            string message;
            int    connection = global::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

            if (connection == -1)
            {
                message = "socket failed, " + lastErrorMessage();
            }
            else
            {
                sockaddr_in bindAddress = new sockaddr_in();
                bindAddress.sin_family      = AF_INET;
                bindAddress.sin_port        = 0;
                bindAddress.sin_addr.s_addr = INADDR_ANY;
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                if (bind(connection, reinterpret_cast <sockaddr>(bindAddress), sizeof(sockaddr_in)) != 0)
                {
                    message = "bind failed, " + lastErrorMessage();
                }
                else
                {
                    int flags = fcntl(connection, F_GETFL, 0);
                    if (flags == -1 || fcntl(connection, F_SETFL, flags | O_NONBLOCK) == -1)
                    {
                        message = "fcntl failed, " + lastErrorMessage();
                    }
                    else
                    {
                        sockaddr_in addressData = new sockaddr_in();
                        addressData.sin_family      = AF_INET;
                        addressData.sin_port        = htons(port);
                        addressData.sin_addr.s_addr = htonl(address.getValue());
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                        int result = global::connect(connection, reinterpret_cast <sockaddr>(addressData), sizeof(sockaddr_in));
                        if (result == -1)
                        {
                            if (errno == EINPROGRESS)
                            {
                                ContextPair            contextPair      = new ContextPair();
                                TcpConnectorContextExt connectorContext = new TcpConnectorContextExt();
                                connectorContext.interrupted = false;
                                connectorContext.context     = dispatcher.getCurrentContext();
                                connectorContext.connection  = connection;

                                contextPair.readContext  = null;
                                contextPair.writeContext = connectorContext;

                                epoll_event connectEvent = new epoll_event();
                                connectEvent.events   = EPOLLOUT | EPOLLRDHUP | EPOLLERR | EPOLLONESHOT;
                                connectEvent.data.ptr = contextPair;
                                if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_ADD, connection, connectEvent) == -1)
                                {
                                    message = "epoll_ctl failed, " + lastErrorMessage();
                                }
                                else
                                {
                                    context = connectorContext;
                                    dispatcher.getCurrentContext().interruptProcedure = () =>
                                    {
                                        TcpConnectorContextExt connectorContext1 = (TcpConnectorContextExt)context;
                                        if (!connectorContext1.interrupted)
                                        {
                                            if (close(connectorContext1.connection) == -1)
                                            {
                                                throw new System.Exception("TcpListener::stop, close failed, " + lastErrorMessage());
                                            }

                                            connectorContext1.interrupted = true;
                                            dispatcher.pushContext(connectorContext1.context);
                                        }
                                    };

                                    dispatcher.dispatch();
                                    dispatcher.getCurrentContext().interruptProcedure = null;
                                    Debug.Assert(dispatcher != null);
                                    Debug.Assert(connectorContext.context == dispatcher.getCurrentContext());
                                    Debug.Assert(contextPair.readContext == null);
                                    Debug.Assert(context == connectorContext);
                                    context = null;
                                    connectorContext.context = null;
                                    if (connectorContext.interrupted)
                                    {
                                        throw InterruptedException();
                                    }

                                    if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_DEL, connection, null) == -1)
                                    {
                                        message = "epoll_ctl failed, " + lastErrorMessage();
                                    }
                                    else
                                    {
                                        if ((connectorContext.events & (EPOLLERR | EPOLLHUP)) != 0)
                                        {
                                            int result = close(connection);
                                            if (result != 0)
                                            {
                                            }
                                            Debug.Assert(result != -1);

                                            throw new System.Exception("TcpConnector::connect, connection failed");
                                        }

                                        int       retval    = -1;
                                        socklen_t retValLen = sizeof(int);
                                        int       s         = getsockopt(connection, SOL_SOCKET, SO_ERROR, retval, retValLen);
                                        if (s == -1)
                                        {
                                            message = "getsockopt failed, " + lastErrorMessage();
                                        }
                                        else
                                        {
                                            if (retval != 0)
                                            {
                                                message = "getsockopt failed, " + lastErrorMessage();
                                            }
                                            else
                                            {
                                                return(new TcpConnection(dispatcher, connection));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            return(new TcpConnection(dispatcher, connection));
                        }
                    }
                }

                int result = close(connection);
                if (result != 0)
                {
                }
                Debug.Assert(result != -1);
            }


            throw new System.Exception("TcpConnector::connect, " + message);
        }
Exemplo n.º 15
0
        public static unsafe PosixResult SetSockOpt(int socket, int level, int optname, void *optval, socklen_t optlen)
        {
            int rv = setsockopt(socket, level, optname, optval, optlen);

            return(PosixResult.FromReturnValue(rv));
        }
Exemplo n.º 16
0
        internal static unsafe void Run(int portNumber, bool executeOnEpollThread)
        {
            int socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0);

            if (socketFileDescriptor < 0)
            {
                Environment.FailFast($"Failed to create socket, socket returned {socketFileDescriptor}");
            }

            sockaddr_in socketAddress = new sockaddr_in
            {
                sin_family = AF_INET,
                sin_port   = htons((ushort)portNumber),
                sin_addr   = INADDR_ANY
            };
            int bindResult = bind(socketFileDescriptor, (sockaddr *)&socketAddress, sizeof(sockaddr_in));

            if (bindResult < 0)
            {
                Environment.FailFast($"Failed to bind, bind returned {bindResult}");
            }

            int listenResult = listen(socketFileDescriptor, BACKLOG);

            if (listenResult < 0)
            {
                Environment.FailFast($"Failed to start listening, listen returned {listenResult}");
            }

            int epollFileDescriptor = epoll_create(MAX_EVENTS);

            if (epollFileDescriptor < 0)
            {
                Environment.FailFast($"Failed to create epoll, epoll_create returned {epollFileDescriptor}");
            }

            epoll_event epollAddSocketEvent = new epoll_event
            {
                events = EPOLLIN,
                data   = new epoll_data_t
                {
                    fd = socketFileDescriptor
                }
            };

            if (epoll_ctl(epollFileDescriptor, EPOLL_CTL_ADD, socketFileDescriptor, &epollAddSocketEvent) == -1)
            {
                Environment.FailFast("Failed to add new socket file descriptor to epoll");
            }

            epoll_event[] epollEvents   = new epoll_event[MAX_EVENTS];
            byte[]        messageBuffer = new byte[MAX_MESSAGE_LENGTH];

            fixed(epoll_event *pinnedEvents = epollEvents)
            fixed(byte *pinnedMessageBuffer = messageBuffer)
            {
                while (true)
                {
                    int eventsCount = epoll_wait(epollFileDescriptor, pinnedEvents, MAX_EVENTS, -1);
                    if (eventsCount == -1)
                    {
                        Environment.FailFast("epoll_wait returned -1");
                    }

                    for (int i = 0; i < eventsCount; i++)
                    {
                        int currentSocketFileDescriptor = epollEvents[i].data.fd;
                        if (currentSocketFileDescriptor == socketFileDescriptor)
                        {
                            sockaddr_in clientAddress;
                            socklen_t   clientAddressSize = sizeof(sockaddr_in);
                            int         acceptResult      = accept4(socketFileDescriptor, (sockaddr *)&clientAddress, &clientAddressSize, SOCK_NONBLOCK);
                            if (acceptResult == -1)
                            {
                                Environment.FailFast($"accept4 returned {acceptResult}");
                            }

                            epollAddSocketEvent.events  = EPOLLIN | EPOLLET;
                            epollAddSocketEvent.data.fd = acceptResult;

                            if (epoll_ctl(epollFileDescriptor, EPOLL_CTL_ADD, acceptResult, &epollAddSocketEvent) == -1)
                            {
                                Environment.FailFast("Failed to add socket to epoll");
                            }
                        }
                        else if (executeOnEpollThread)
                        {
                            ssize_t bytesRead = recv(currentSocketFileDescriptor, pinnedMessageBuffer, MAX_MESSAGE_LENGTH, 0);
                            send(currentSocketFileDescriptor, pinnedMessageBuffer, (size_t)bytesRead, 0);
                        }
                        else
                        {
                            ThreadPool.UnsafeQueueUserWorkItem <int>(Copy, currentSocketFileDescriptor, false);
                        }
                    }
                }
            }
        }
Exemplo n.º 17
0
 public int sceNetInetBind(int SocketId, sockaddr *Address, socklen_t AddressLength)
 {
     throw(new NotImplementedException());
 }
Exemplo n.º 18
0
 public int sceNetInetConnect(int SocketId, sockaddr_in *serv_addr, socklen_t addrlen)
 {
     var Socket = Sockets.Get(SocketId);
     Console.WriteLine("{0}", serv_addr->sin_addr);
     Socket.Connect(new IPEndPoint(serv_addr->sin_addr.Address, serv_addr->sin_port));
     return 0;
 }
Exemplo n.º 19
0
 public int sceNetInetSendto(int SocketId, void *BufferPointer, int BufferLength, SocketFlags SocketFlags, sockaddr_in *To, socklen_t ToLength)
 {
     var Socket = Sockets.Get(SocketId);
     return Socket.SendTo(ArrayUtils.CreateArray<byte>(BufferPointer, BufferLength), SocketFlags, new IPEndPoint(To->sin_addr.Address, To->sin_port));
 }
Exemplo n.º 20
0
 public int sceNetInetRecvfrom(int SocketId, void* BufferPointer, int BufferLength, SocketFlags SocketFlags, sockaddr_in* From, socklen_t* FromLength)
 {
     var Socket = Sockets.Get(SocketId);
     EndPoint EndPoint = new IPEndPoint(From->sin_addr.Address, From->sin_port);
     return Socket.ReceiveFrom(ArrayUtils.CreateArray<byte>(BufferPointer, BufferLength), SocketFlags, ref EndPoint);
 }
Exemplo n.º 21
0
 public int sceNetInetGetsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
 {
     throw(new NotImplementedException());
 }
Exemplo n.º 22
0
 public static unsafe PosixResult SetSockOpt(Socket socket, int level, int optname, void *optval, socklen_t optlen)
 => SetSockOpt(socket.DangerousGetHandle().ToInt32(), level, optname, optval, optlen);
Exemplo n.º 23
0
 public int sceNetInetBind(int SocketId, sockaddr *Address, socklen_t AddressLength)
 {
     throw new NotImplementedException();
 }