Ejemplo n.º 1
0
            static public void configureNetwork()
            {
                // Network configuration
                UPnP upnp = new UPnP();

                if (Config.externalIp != "" && IPAddress.TryParse(Config.externalIp, out _))
                {
                    Config.publicServerIP = Config.externalIp;
                }
                else
                {
                    Config.publicServerIP = "";
                    List <IPAndMask> local_ips = CoreNetworkUtils.GetAllLocalIPAddressesAndMasks();
                    foreach (IPAndMask local_ip in local_ips)
                    {
                        if (IPv4Subnet.IsPublicIP(local_ip.Address))
                        {
                            Logging.info(String.Format("Public IP detected: {0}, mask {1}.", local_ip.Address.ToString(), local_ip.SubnetMask.ToString()));
                            Config.publicServerIP = local_ip.Address.ToString();
                        }
                    }
                    if (Config.publicServerIP == "")
                    {
                        IPAddress primary_local = CoreNetworkUtils.GetPrimaryIPAddress();
                        if (primary_local == null)
                        {
                            Logging.warn("Unable to determine primary IP address.");
                        }
                        else
                        {
                            Logging.warn(String.Format("None of the locally configured IP addresses are public. Attempting UPnP..."));
                            Task <IPAddress> public_ip = upnp.GetExternalIPAddress();
                            if (public_ip.Wait(1000))
                            {
                                if (public_ip.Result != null)
                                {
                                    Logging.info(String.Format("UPNP-determined public IP: {0}. Attempting to configure a port-forwarding rule.", public_ip.Result.ToString()));
                                    if (upnp.MapPublicPort(Config.serverPort, primary_local))
                                    {
                                        Config.publicServerIP = public_ip.Result.ToString(); //upnp.getMappedIP();
                                        Logging.info(string.Format("Network configured. Public IP is: {0}", Config.publicServerIP));
                                    }
                                }
                                else
                                {
                                    Logging.warn("UPnP configuration failed.");
                                }
                            }
                        }
                    }
                }
            }
Ejemplo n.º 2
0
        /// <summary>
        ///  Verifies that the given remote endpoint is reachable by connecting to it and sending a short message.
        /// </summary>
        /// <remarks>
        ///  This function is used to ensure that the remote endpoing has listed the correct IP and port information for their `PresenceList` entry.
        /// </remarks>
        /// <param name="endpoint">Target endpoint to verify for connectivity.</param>
        /// <returns>True, if the endpoing is connectable.</returns>
        public static bool checkNodeConnectivity(RemoteEndpoint endpoint)
        {
            // TODO TODO TODO TODO we should put this in a separate thread
            string hostname = endpoint.getFullAddress(true);

            if (CoreNetworkUtils.PingAddressReachable(hostname) == false)
            {
                Logging.warn("Node {0} was not reachable on the advertised address.", hostname);
                CoreProtocolMessage.sendBye(endpoint, ProtocolByeCode.notConnectable, "External " + hostname + " not reachable!", "");
                return(false);
            }
            return(true);
        }
        // Starts the Network Client Manager. First it connects to one of the seed nodes in order to fetch the Presence List.
        // Afterwards, it starts the reconnect and keepalive threads
        public static void start()
        {
            if (running)
            {
                return;
            }
            running        = true;
            networkClients = new List <NetworkClient>();

            PeerStorage.readPeersFile();

            // Now add the seed nodes to the list
            foreach (string[] addr in CoreNetworkUtils.getSeedNodes(Config.isTestNet))
            {
                byte[] wallet_addr = null;
                if (addr[1] != null)
                {
                    wallet_addr = Base58Check.Base58CheckEncoding.DecodePlain(addr[1]);
                }
                PeerStorage.addPeerToPeerList(addr[0], wallet_addr, false);
            }

            // Connect to a random node first
            bool firstSeedConnected = false;

            while (firstSeedConnected == false)
            {
                Peer p = PeerStorage.getRandomMasterNodeAddress();
                if (p != null)
                {
                    firstSeedConnected = connectTo(p.hostname, p.walletAddress);
                }
                if (firstSeedConnected == false)
                {
                    Thread.Sleep(1000);
                }
            }

            // Start the reconnect thread
            TLC                  = new ThreadLiveCheck();
            reconnectThread      = new Thread(reconnectClients);
            reconnectThread.Name = "Network_Client_Manager_Reconnect";
            autoReconnect        = true;
            reconnectThread.Start();
        }
Ejemplo n.º 4
0
        static public void synchronize()
        {
            // Clear everything and force a resynchronization
            Logging.info("\n\n\tSynchronizing to network...\n");

            blockProcessor.stopOperation();

            blockProcessor = new BlockProcessor();
            blockChain     = new BlockChain();
            walletState.clear();
            TransactionPool.clear();

            NetworkQueue.stop();
            NetworkQueue.start();

            // Finally, reconnect to the network
            CoreNetworkUtils.reconnect();
        }
Ejemplo n.º 5
0
        // Starts the Network Client Manager. First it connects to one of the seed nodes in order to fetch the Presence List.
        // Afterwards, it starts the reconnect and keepalive threads
        public static void start()
        {
            if (running)
            {
                return;
            }
            running        = true;
            networkClients = new List <NetworkClient>();

            PeerStorage.readPeersFile();

            // Now add the seed nodes to the list
            foreach (string addr in CoreNetworkUtils.getSeedNodes(Config.isTestNet))
            {
                PeerStorage.addPeerToPeerList(addr, null, false);
            }

            // Connect to a random node first
            bool firstSeedConnected = false;

            while (firstSeedConnected == false)
            {
                string address = PeerStorage.getRandomMasterNodeAddress();
                if (address != "")
                {
                    firstSeedConnected = connectTo(address);
                }
                if (firstSeedConnected == false)
                {
                    Thread.Sleep(1000);
                }
            }

            // Start the reconnect thread
            TLC                  = new ThreadLiveCheck();
            reconnectThread      = new Thread(reconnectClients);
            reconnectThread.Name = "Network_Client_Manager_Reconnect";
            autoReconnect        = true;
            reconnectThread.Start();
        }
        // Returns a random new potential neighbor. Returns null if no new neighbor is found.
        public static Peer scanForNeighbor()
        {
            Peer connectToPeer = null;

            // Find only masternodes
            while (connectToPeer == null)
            {
                bool addr_valid = true;
                Peer p          = PeerStorage.getRandomMasterNodeAddress();

                if (p == null)
                {
                    break;
                }

                // Next, check if we're connecting to a self address of this node
                string[] server = p.hostname.Split(':');

                if (server.Length < 2)
                {
                    break;
                }

                // Resolve the hostname first
                string resolved_server_name           = NetworkUtils.resolveHostname(server[0]);
                string resolved_server_name_with_port = resolved_server_name + ":" + server[1];

                // Check if we are already connected to this address
                lock (networkClients)
                {
                    foreach (NetworkClient client in networkClients)
                    {
                        if (client.getFullAddress(true).Equals(resolved_server_name_with_port, StringComparison.Ordinal))
                        {
                            // Address is already in the client list
                            addr_valid = false;
                            break;
                        }
                    }
                }

                // Check if node is already in the server list
                string[] connectedClients = NetworkServer.getConnectedClients(true);
                for (int i = 0; i < connectedClients.Length; i++)
                {
                    if (connectedClients[i].Equals(resolved_server_name_with_port, StringComparison.Ordinal))
                    {
                        // Address is already in the client list
                        addr_valid = false;
                        break;
                    }
                }

                if (addr_valid == false)
                {
                    continue;
                }

                // Check against connecting clients list as well
                lock (connectingClients)
                {
                    foreach (string client in connectingClients)
                    {
                        if (resolved_server_name_with_port.Equals(client, StringComparison.Ordinal))
                        {
                            // Address is already in the connecting client list
                            addr_valid = false;
                            break;
                        }
                    }
                }

                if (addr_valid == false)
                {
                    continue;
                }

                // Get all self addresses and run through them
                List <string> self_addresses = CoreNetworkUtils.GetAllLocalIPAddresses();
                foreach (string self_address in self_addresses)
                {
                    // Don't connect to self
                    if (resolved_server_name.Equals(self_address, StringComparison.Ordinal))
                    {
                        if (server[1].Equals(string.Format("{0}", Config.serverPort), StringComparison.Ordinal))
                        {
                            addr_valid = false;
                        }
                    }
                }

                // If the address is valid, add it to the candidates
                if (addr_valid)
                {
                    connectToPeer = p;
                }
            }

            return(connectToPeer);
        }
        // Connects to a specified node, with the syntax host:port
        public static bool connectTo(string host, byte[] wallet_address)
        {
            if (host == null || host.Length < 3)
            {
                Logging.error(String.Format("Invalid host address {0}", host));
                return(false);
            }

            string[] server = host.Split(':');
            if (server.Count() < 2)
            {
                Logging.warn(string.Format("Cannot connect to invalid hostname: {0}", host));
                return(false);
            }

            // Resolve the hostname first
            string resolved_server_name = NetworkUtils.resolveHostname(server[0]);

            // Skip hostnames we can't resolve
            if (resolved_server_name.Length < 1)
            {
                Logging.warn(string.Format("Cannot resolve IP for {0}, skipping connection.", server[0]));
                return(false);
            }

            string resolved_host = string.Format("{0}:{1}", resolved_server_name, server[1]);

            // Verify against the publicly disclosed ip
            // Don't connect to self
            if (resolved_server_name.Equals(Config.publicServerIP, StringComparison.Ordinal))
            {
                if (server[1].Equals(string.Format("{0}", Config.serverPort), StringComparison.Ordinal))
                {
                    Logging.info(string.Format("Skipping connection to public self seed node {0}", host));
                    return(false);
                }
            }

            // Get all self addresses and run through them
            List <string> self_addresses = CoreNetworkUtils.GetAllLocalIPAddresses();

            foreach (string self_address in self_addresses)
            {
                // Don't connect to self
                if (resolved_server_name.Equals(self_address, StringComparison.Ordinal))
                {
                    if (server[1].Equals(string.Format("{0}", Config.serverPort), StringComparison.Ordinal))
                    {
                        Logging.info(string.Format("Skipping connection to self seed node {0}", host));
                        return(false);
                    }
                }
            }

            lock (connectingClients)
            {
                foreach (string client in connectingClients)
                {
                    if (resolved_host.Equals(client, StringComparison.Ordinal))
                    {
                        // We're already connecting to this client
                        return(false);
                    }
                }

                // The the client to the connecting clients list
                connectingClients.Add(resolved_host);
            }

            // Check if node is already in the client list
            lock (networkClients)
            {
                foreach (NetworkClient client in networkClients)
                {
                    if (client.getFullAddress(true).Equals(resolved_host, StringComparison.Ordinal))
                    {
                        // Address is already in the client list
                        return(false);
                    }
                }
            }

            // Check if node is already in the server list
            string[] connectedClients = NetworkServer.getConnectedClients(true);
            for (int i = 0; i < connectedClients.Length; i++)
            {
                if (connectedClients[i].Equals(resolved_host, StringComparison.Ordinal))
                {
                    // Address is already in the client list
                    return(false);
                }
            }

            // Connect to the specified node
            NetworkClient new_client = new NetworkClient();
            // Recompose the connection address from the resolved IP and the original port
            bool result = new_client.connectToServer(resolved_server_name, Convert.ToInt32(server[1]), wallet_address);

            // Add this node to the client list if connection was successfull
            if (result == true)
            {
                // Add this node to the client list
                lock (networkClients)
                {
                    networkClients.Add(new_client);
                }
            }

            // Remove this node from the connecting clients list
            lock (connectingClients)
            {
                connectingClients.Remove(resolved_host);
            }

            return(result);
        }
Ejemplo n.º 8
0
        static public bool update()
        {
            if (serverStarted == false)
            {
                /*if(Node.blockProcessor.operating == true)
                 * {*/
                Logging.info("Starting Network Server now.");

                // Start the node server
                if (!isMasterNode())
                {
                    Logging.info("Network server is not enabled in modes other than master node.");
                }
                else
                {
                    NetworkServer.beginNetworkOperations();
                }

                serverStarted = true;
                //}
            }

            // Check for node deprecation
            if (checkCurrentBlockDeprecation(Node.blockChain.getLastBlockNum()) == false)
            {
                ConsoleHelpers.verboseConsoleOutput = true;
                Logging.consoleOutput = true;
                shutdownMessage       = string.Format("Your DLT node can only handle blocks up to #{0}. Please update to the latest version from www.ixian.io", Config.nodeDeprecationBlock);
                Logging.error(shutdownMessage);
                IxianHandler.forceShutdown = true;
                running = false;
                return(running);
            }

            // Check for sufficient node balance
            if (checkMasternodeBalance() == false)
            {
                //running = false;
            }

            TimeSpan last_isolate_time_diff = DateTime.UtcNow - lastIsolateTime;

            if (Node.blockChain.getTimeSinceLastBLock() > 900 && (last_isolate_time_diff.TotalSeconds < 0 || last_isolate_time_diff.TotalSeconds > 1800)) // if no block for over 900 seconds with cooldown of 1800 seconds
            {
                CoreNetworkUtils.isolate();
                lastIsolateTime = DateTime.UtcNow;
            }

            // TODO TODO TODO TODO this is a global flood control and should be also done per node to detect attacks
            // I propose getting average traffic from different types of nodes and detect a node that's sending
            // disproportionally more messages than the other nodes, provided thatthe network queue is over a certain limit
            int total_queued_messages = NetworkQueue.getQueuedMessageCount() + NetworkQueue.getTxQueuedMessageCount();

            if (floodPause == false && total_queued_messages > 5000)
            {
                Logging.warn("Flooding detected, isolating the node.");
                NetworkClientManager.stop();
                if (isMasterNode())
                {
                    NetworkServer.stopNetworkOperations();
                }
                floodPause = true;
            }
            else if (floodPause == true && total_queued_messages < 100)
            {
                Logging.warn("Data after flooding processed, reconnecting the node.");
                NetworkClientManager.start();
                if (isMasterNode())
                {
                    NetworkServer.beginNetworkOperations();
                }
                floodPause = false;
            }


            return(running);
        }