Esempio n. 1
0
        public Ipv4Address resolve(string host)
        {
            Debug.Assert(dispatcher != null);
            if (dispatcher.interrupted())
            {
                throw InterruptedException();
            }

            addrinfo hints = new addrinfo(0, AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, null, null, null);
            addrinfo addressInfos;
            int      result = getaddrinfo(host, null, hints, addressInfos);

            if (result != 0)
            {
                throw new System.Exception("Ipv4Resolver::resolve, getaddrinfo failed, " + errorMessage(result));
            }

            uint count = 0;

            for (addrinfo *addressInfo = addressInfos; addressInfo != null; addressInfo = addressInfo.ai_next)
            {
                ++count;
            }

            std::mt19937 generator   = new std::mt19937(std::random_device()());
            uint         index       = std::uniform_int_distribution <uint>(0, count - 1)(generator);
            addrinfo     addressInfo = addressInfos;

            for (uint i = 0; i < index; ++i)
            {
                addressInfo = addressInfo.ai_next;
            }

//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
            Ipv4Address address = new Ipv4Address(ntohl(reinterpret_cast <sockaddr_in>(addressInfo.ai_addr).sin_addr.s_addr));

            freeaddrinfo(addressInfo);
            return(address);
        }
Esempio n. 2
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);
        }
Esempio n. 3
0
        public TcpListener(Dispatcher dispatcher, Ipv4Address addr, uint16_t port)
        {
            this.dispatcher = dispatcher;
            string message;

            listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            if (listener == -1)
            {
                message = "socket failed, " + lastErrorMessage();
            }
            else
            {
                int flags = fcntl(listener, F_GETFL, 0);
                if (flags == -1 || fcntl(listener, F_SETFL, flags | O_NONBLOCK) == -1)
                {
                    message = "fcntl failed, " + lastErrorMessage();
                }
                else
                {
                    int on = 1;
                    if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, on, sizeof(int)) == -1)
                    {
                        message = "setsockopt failed, " + lastErrorMessage();
                    }
                    else
                    {
                        sockaddr_in address = new sockaddr_in();
                        address.sin_family      = AF_INET;
                        address.sin_port        = htons(port);
                        address.sin_addr.s_addr = htonl(addr.getValue());
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                        if (bind(listener, reinterpret_cast <sockaddr>(address), sizeof(sockaddr_in)) != 0)
                        {
                            message = "bind failed, " + lastErrorMessage();
                        }
                        else if (listen(listener, SOMAXCONN) != 0)
                        {
                            message = "listen failed, " + lastErrorMessage();
                        }
                        else
                        {
                            epoll_event listenEvent = new epoll_event();
                            listenEvent.events   = EPOLLONESHOT;
                            listenEvent.data.ptr = null;

                            if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_ADD, listener, listenEvent) == -1)
                            {
                                message = "epoll_ctl failed, " + lastErrorMessage();
                            }
                            else
                            {
                                context = null;
                                return;
                            }
                        }
                    }
                }

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

            throw new System.Exception("TcpListener::TcpListener, " + message);
        }