示例#1
0
        /// <summary>
        /// Verify that a host alias references a valid node.
        /// </summary>
        public void ValidateNode(Cluster cluster, Host host)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout);
            Exception   exception = null;

            foreach (IPAddress address in addresses)
            {
                try
                {
                    ValidateAddress(cluster, address, host.tlsName, host.port, false);
                    SetAliases(address, host.tlsName, host.port);
                    return;
                }
                catch (Exception e)
                {
                    // Log exception and continue to next alias.
                    if (Log.DebugEnabled())
                    {
                        Log.Debug("Address " + address + ' ' + host.port + " failed: " + Util.GetErrorMessage(e));
                    }

                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            // Exception can't be null here because Connection.GetHostAddresses()
            // will throw exception if aliases length is zero.
            throw exception;
        }
示例#2
0
        /// <summary>
        /// Get default info from the specified database server node, using host name and port.
        /// This method does not support user authentication.
        /// </summary>
        /// <param name="hostname">host name</param>
        /// <param name="port">host port</param>
        public static Dictionary <string, string> Request(string hostname, int port)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(hostname, DEFAULT_TIMEOUT);
            IPEndPoint  ipe       = new IPEndPoint(addresses[0], port);

            return(Request(ipe));
        }
示例#3
0
        /// <summary>
        /// Return first valid node referenced by seed host aliases. In most cases, aliases
        /// reference a single node.  If round robin DNS configuration is used, the seed host
        /// may have several addresses that reference different nodes in the cluster.
        /// </summary>
        public Node SeedNode(Cluster cluster, Host host, Peers peers)
        {
            name              = null;
            aliases           = null;
            primaryHost       = null;
            primaryAddress    = null;
            primaryConn       = null;
            sessionToken      = null;
            sessionExpiration = null;
            features          = 0;

            IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout);
            Exception   exception = null;

            // Try all addresses because they might point to different nodes.
            foreach (IPAddress address in addresses)
            {
                try
                {
                    ValidateAddress(cluster, address, host.tlsName, host.port, true);

                    // Only set aliases when they were not set by load balancer detection logic.
                    if (this.aliases == null)
                    {
                        SetAliases(address, host.tlsName, host.port);
                    }

                    Node node = cluster.CreateNode(this, false);

                    if (ValidatePeers(peers, node))
                    {
                        return(node);
                    }
                }
                catch (Exception e)
                {
                    // Log exception and continue to next alias.
                    if (Log.DebugEnabled())
                    {
                        Log.Debug("Address " + address + ' ' + host.port + " failed: " + Util.GetErrorMessage(e));
                    }

                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            // Fallback signifies node exists, but is suspect.
            // Return null so other seeds can be tried.
            if (fallback != null)
            {
                return(null);
            }

            // Exception can't be null here because Connection.GetHostAddresses()
            // will throw exception if aliases length is zero.
            throw exception;
        }
示例#4
0
        // Switch from TLS connection to non-TLS connection.
        internal SwitchClear(Cluster cluster, Connection conn, byte[] sessionToken)
        {
            // Obtain non-TLS addresses.
            string      command = cluster.useServicesAlternate ? "service-clear-alt" : "service-clear-std";
            string      result  = Info.Request(conn, command);
            List <Host> hosts   = Host.ParseServiceHosts(result);
            Host        clearHost;

            // Find first valid non-TLS host.
            foreach (Host host in hosts)
            {
                try
                {
                    clearHost = host;

                    string alternativeHost;
                    if (cluster.ipMap != null && cluster.ipMap.TryGetValue(clearHost.name, out alternativeHost))
                    {
                        clearHost = new Host(alternativeHost, clearHost.port);
                    }

                    IPAddress[] addresses = Connection.GetHostAddresses(clearHost.name, cluster.connectionTimeout);

                    foreach (IPAddress ia in addresses)
                    {
                        try
                        {
                            clearAddress       = ia;
                            clearSocketAddress = new IPEndPoint(ia, clearHost.port);
                            clearConn          = new Connection(clearSocketAddress, cluster.connectionTimeout, null);

                            try
                            {
                                AdminCommand admin = new AdminCommand(ThreadLocalData.GetBuffer(), 0);

                                if (!admin.Authenticate(cluster, clearConn, sessionToken))
                                {
                                    throw new AerospikeException("Authentication failed");
                                }
                                return;                                 // Authenticated clear connection.
                            }
                            catch (Exception)
                            {
                                clearConn.Close();
                            }
                        }
                        catch (Exception)
                        {
                            // Try next address.
                        }
                    }
                }
                catch (Exception)
                {
                    // Try next host.
                }
            }
            throw new AerospikeException("Invalid non-TLS address: " + result);
        }
        private IPAddress[] SetAliases(Cluster cluster, Host host)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout);
            aliases = new Host[addresses.Length];

            for (int i = 0; i < addresses.Length; i++)
            {
                aliases[i] = new Host(addresses[i].ToString(), host.port);
            }
            return(addresses);
        }
        /// <summary>
        /// Add node(s) referenced by seed host aliases. In most cases, aliases reference
        /// a single node.  If round robin DNS configuration is used, the seed host may have
        /// several addresses that reference different nodes in the cluster.
        /// </summary>
        public void SeedNodes(Cluster cluster, Host host, Dictionary <string, Node> nodesToAdd)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout);
            Exception   exception = null;
            bool        found     = false;

            // Try all addresses because they might point to different nodes.
            foreach (IPAddress address in addresses)
            {
                try
                {
                    ValidateAddress(cluster, address, host.tlsName, host.port, true);
                    found = true;

                    if (!nodesToAdd.ContainsKey(name))
                    {
                        // New node found.
                        // Only set aliases when they were not set by load balancer detection logic.
                        if (this.aliases == null)
                        {
                            SetAliases(addresses, host.tlsName, host.port);
                        }
                        Node node = cluster.CreateNode(this);
                        nodesToAdd[name] = node;
                    }
                    else
                    {
                        // Node already referenced. Close connection.
                        primaryConn.Close();
                    }
                }
                catch (Exception e)
                {
                    // Log and continue to next address.
                    if (Log.DebugEnabled())
                    {
                        Log.Debug("Address " + address + ' ' + host.port + " failed: " + Util.GetErrorMessage(e));
                    }

                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            if (!found)
            {
                // Exception can't be null here because Connection.GetHostAddresses()
                // will throw exception if aliases length is zero.
                throw exception;
            }
        }
示例#7
0
        private IPAddress[] SetAliases(Cluster cluster, Host host)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout);

            // Add capacity for current address aliases plus IPV6 address and hostname.
            aliases = new List <Host>(addresses.Length + 2);

            foreach (IPAddress address in addresses)
            {
                aliases.Add(new Host(address.ToString(), host.tlsName, host.port));
            }
            return(addresses);
        }
        /// <summary>
        /// Return first valid node referenced by seed host aliases. In most cases, aliases
        /// reference a single node.  If round robin DNS configuration is used, the seed host
        /// may have several addresses that reference different nodes in the cluster.
        /// </summary>
        public Node SeedNode(Cluster cluster, Host host)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout);
            Exception   exception = null;

            // Try all addresses because they might point to different nodes.
            foreach (IPAddress address in addresses)
            {
                try
                {
                    ValidateAddress(cluster, address, host.tlsName, host.port, true);

                    // Only set aliases when they were not set by load balancer detection logic.
                    if (this.aliases == null)
                    {
                        SetAliases(address, host.tlsName, host.port);
                    }
                    return(cluster.CreateNode(this));
                }
                catch (Exception e)
                {
                    // Log exception and continue to next alias.
                    if (Log.DebugEnabled())
                    {
                        Log.Debug("Address " + address + ' ' + host.port + " failed: " + Util.GetErrorMessage(e));
                    }

                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            // Exception can't be null here because Connection.GetHostAddresses()
            // will throw exception if aliases length is zero.
            throw exception;
        }
示例#9
0
        private void SetAddress(Cluster cluster, Dictionary <string, string> map, string addressCommand, string tlsName)
        {
            string result;

            if (!map.TryGetValue(addressCommand, out result) || result == null || result.Length == 0)
            {
                // Server does not support service level call (service-clear-std, ...).
                // Load balancer detection is not possible.
                return;
            }

            List <Host> hosts = Host.ParseServiceHosts(result);
            Host        h;

            // Search real hosts for seed.
            foreach (Host host in hosts)
            {
                h = host;

                string alt;
                if (cluster.ipMap != null && cluster.ipMap.TryGetValue(h.name, out alt))
                {
                    h = new Host(alt, h.port);
                }

                if (h.Equals(this.primaryHost))
                {
                    // Found seed which is not a load balancer.
                    return;
                }
            }

            // Seed not found, so seed is probably a load balancer.
            // Find first valid real host.
            foreach (Host host in hosts)
            {
                try
                {
                    h = host;

                    string alt;
                    if (cluster.ipMap != null && cluster.ipMap.TryGetValue(h.name, out alt))
                    {
                        h = new Host(alt, h.port);
                    }

                    IPAddress[] addresses = Connection.GetHostAddresses(h.name, cluster.connectionTimeout);

                    foreach (IPAddress address in addresses)
                    {
                        try
                        {
                            IPEndPoint socketAddress = new IPEndPoint(address, h.port);
                            Connection conn          = (cluster.tlsPolicy != null) ?
                                                       new TlsConnection(cluster.tlsPolicy, tlsName, socketAddress, cluster.connectionTimeout, null) :
                                                       new Connection(socketAddress, cluster.connectionTimeout, null);

                            try
                            {
                                if (cluster.user != null)
                                {
                                    AdminCommand admin = new AdminCommand(ThreadLocalData.GetBuffer(), 0);

                                    if (!admin.Authenticate(cluster, conn, this.sessionToken))
                                    {
                                        throw new AerospikeException("Authentication failed");
                                    }
                                }

                                // Authenticated connection.  Set real host.
                                SetAliases(address, tlsName, h.port);
                                this.primaryHost    = new Host(address.ToString(), tlsName, h.port);
                                this.primaryAddress = socketAddress;
                                this.primaryConn.Close();
                                this.primaryConn = conn;
                                return;
                            }
                            catch (Exception)
                            {
                                conn.Close();
                            }
                        }
                        catch (Exception)
                        {
                            // Try next address.
                        }
                    }
                }
                catch (Exception)
                {
                    // Try next host.
                }
            }

            // Failed to find a valid address. IP Address is probably internal on the cloud
            // because the server access-address is not configured.  Log warning and continue
            // with original seed.
            if (Log.InfoEnabled())
            {
                Log.Info("Invalid address " + result + ". access-address is probably not configured on server.");
            }
        }
        public NodeValidator(Cluster cluster, Host host)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(host.name, DEFAULT_TIMEOUT);
            aliases = new Host[addresses.Length];

            for (int i = 0; i < addresses.Length; i++)
            {
                aliases[i] = new Host(addresses[i].ToString(), host.port);
            }

            Exception exception = null;

            for (int i = 0; i < addresses.Length; i++)
            {
                try
                {
                    IPEndPoint address = new IPEndPoint(addresses[i], host.port);
                    Connection conn    = new Connection(address, cluster.connectionTimeout);

                    try
                    {
                        if (cluster.user != null)
                        {
                            AdminCommand command = new AdminCommand();
                            command.Authenticate(conn, cluster.user, cluster.password);
                        }
                        Dictionary <string, string> map = Info.Request(conn, "node", "features");
                        string nodeName;

                        if (map.TryGetValue("node", out nodeName))
                        {
                            this.name    = nodeName;
                            this.address = address;
                            SetFeatures(map);
                            return;
                        }
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
                catch (Exception e)
                {
                    // Try next address.
                    if (Log.DebugEnabled())
                    {
                        Log.Debug("Alias " + addresses[i] + " failed: " + Util.GetErrorMessage(e));
                    }

                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            if (exception == null)
            {
                throw new AerospikeException.Connection("Failed to find addresses for " + host);
            }
            throw exception;
        }
        private void SetAddress(Cluster cluster, Dictionary <string, string> map, string addressCommand, string tlsName)
        {
            string      result = map[addressCommand];
            List <Host> hosts  = Host.ParseServiceHosts(result);
            Host        h;

            // Search real hosts for seed.
            foreach (Host host in hosts)
            {
                h = host;

                string alt;
                if (cluster.ipMap != null && cluster.ipMap.TryGetValue(h.name, out alt))
                {
                    h = new Host(alt, h.port);
                }

                if (h.Equals(this.primaryHost))
                {
                    // Found seed which is not a load balancer.
                    return;
                }
            }

            // Seed not found, so seed is probably a load balancer.
            // Find first valid real host.
            foreach (Host host in hosts)
            {
                try
                {
                    h = host;

                    string alt;
                    if (cluster.ipMap != null && cluster.ipMap.TryGetValue(h.name, out alt))
                    {
                        h = new Host(alt, h.port);
                    }

                    IPAddress[] addresses = Connection.GetHostAddresses(h.name, cluster.connectionTimeout);

                    foreach (IPAddress address in addresses)
                    {
                        try
                        {
                            IPEndPoint socketAddress = new IPEndPoint(address, h.port);
                            Connection conn          = (cluster.tlsPolicy != null) ?
                                                       new TlsConnection(cluster.tlsPolicy, tlsName, socketAddress, cluster.connectionTimeout, cluster.maxSocketIdleMillis, null) :
                                                       new Connection(socketAddress, cluster.connectionTimeout, cluster.maxSocketIdleMillis, null);

                            try
                            {
                                if (cluster.user != null)
                                {
                                    AdminCommand admin = new AdminCommand(ThreadLocalData.GetBuffer(), 0);

                                    if (!admin.Authenticate(cluster, conn, this.sessionToken))
                                    {
                                        throw new AerospikeException("Authentication failed");
                                    }
                                }

                                // Authenticated connection.  Set real host.
                                SetAliases(addresses, tlsName, h.port);
                                this.primaryHost    = new Host(address.ToString(), tlsName, h.port);
                                this.primaryAddress = socketAddress;
                                this.primaryConn.Close();
                                this.primaryConn = conn;
                                return;
                            }
                            catch (Exception)
                            {
                                conn.Close();
                            }
                        }
                        catch (Exception)
                        {
                            // Try next address.
                        }
                    }
                }
                catch (Exception)
                {
                    // Try next host.
                }
            }

            // Failed to find a valid host.
            throw new AerospikeException("Invalid address: " + result);
        }