/// <summary>
        /// Resolves the contact point according to its type. If it is not an IP address, then considers it a hostname and
        /// attempts to resolve it with DNS.
        /// </summary>
        private async Task <IEnumerable <IConnectionEndPoint> > ResolveContactPointAsync(bool refreshCache)
        {
            if (!refreshCache && !_keepContactPointsUnresolved && _cachedEndpoints.Any())
            {
                return(_cachedEndpoints);
            }

            IPHostEntry hostEntry = null;

            try
            {
                hostEntry = await _dns.GetHostEntryAsync(_hostname).ConfigureAwait(false);
            }
            catch (Exception)
            {
                Cluster.Logger.Warning("Contact point '{0}' could not be resolved.", _hostname);
            }

            var connectionEndPoints = new List <IConnectionEndPoint>();

            if (hostEntry != null && hostEntry.AddressList.Length > 0)
            {
                Cluster.Logger.Info("Contact point '{0}' resolved to multiple addresses. Will attempt to use them all if necessary: '{1}'",
                                    _hostname,
                                    string.Join(",", hostEntry.AddressList.Select(resolvedAddress => resolvedAddress.ToString())));

                connectionEndPoints.AddRange(
                    hostEntry.AddressList.Select(resolvedAddress =>
                                                 new ConnectionEndPoint(new IPEndPoint(resolvedAddress, _protocolOptions.Port), _serverNameResolver, this)));
            }

            _cachedEndpoints = connectionEndPoints;
            return(_cachedEndpoints);
        }
示例#2
0
        private async Task RefreshProxyResolutionAsync()
        {
            if (_endPoint != null)
            {
                return;
            }

            IPHostEntry hostEntry = null;
            Exception   exception = null;

            try
            {
                hostEntry = await _dns.GetHostEntryAsync(_sniOptions.Name).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            if (hostEntry != null && hostEntry.AddressList.Length > 0)
            {
                _resolvedProxyEndPoints =
                    hostEntry.AddressList
                    .Where(address => address.AddressFamily != AddressFamily.InterNetworkV6 || address.IsIPv4MappedToIPv6)
                    .Select(address => address.IsIPv4MappedToIPv6
                                 ? new IPEndPoint(address.MapToIPv4(), _sniOptions.Port)
                                 : new IPEndPoint(address, _sniOptions.Port))
                    .OrderBy(e => _random.Next())          // shuffle
                    .ToList();
                _index = 0;
                return;
            }

            if (_resolvedProxyEndPoints != null)
            {
                var logMsg =
                    exception == null
                        ? $"DNS resolution of endpoint \"{_sniOptions.Name}\" did not return any host entries. " +
                    "Falling back to the result of the previous DNS resolution."
                        : $"Could not resolve endpoint \"{_sniOptions.Name}\". " +
                    "Falling back to the result of the previous DNS resolution.";

                SniEndPointResolver.Logger.Error(logMsg, exception);
                _index = 0;
                return;
            }

            var error = exception == null
                ? new DriverInternalError($"DNS resolution of endpoint \"{_sniOptions.Name}\" did not return any host entries.")
                : new DriverInternalError($"Could not resolve endpoint \"{_sniOptions.Name}\"", exception);

            throw error;
        }
示例#3
0
        /// <summary>
        /// Resolves the contact point according to its type. If it is not an IP address, then considers it a hostname and
        /// attempts to resolve it with DNS.
        /// </summary>
        private async Task <IEnumerable <IConnectionEndPoint> > ResolveContactPointAsync(string contactPointText)
        {
            if (_resolvedContactPoints.TryGetValue(contactPointText, out var ipEndPoints))
            {
                return(ipEndPoints);
            }

            if (IPAddress.TryParse(contactPointText, out var ipAddress))
            {
                var ipEndpoint                = new IPEndPoint(ipAddress, _protocolOptions.Port);
                var connectionEndPoint        = new ConnectionEndPoint(ipEndpoint, GetServerName);
                var listOfConnectionEndPoints = new List <IConnectionEndPoint> {
                    connectionEndPoint
                };
                _resolvedContactPoints.AddOrUpdate(
                    contactPointText,
                    key => listOfConnectionEndPoints,
                    (key, list) => listOfConnectionEndPoints);
                return(listOfConnectionEndPoints);
            }

            IPHostEntry hostEntry = null;

            try
            {
                hostEntry = await _dns.GetHostEntryAsync(contactPointText).ConfigureAwait(false);
            }
            catch (Exception)
            {
                Cluster.Logger.Warning($"Host '{contactPointText}' could not be resolved");
            }

            var connectionEndPoints = new List <IConnectionEndPoint>();

            if (hostEntry != null && hostEntry.AddressList.Length > 0)
            {
                connectionEndPoints.AddRange(
                    hostEntry.AddressList.Select(resolvedAddress =>
                                                 new ConnectionEndPoint(new IPEndPoint(resolvedAddress, _protocolOptions.Port), GetServerName)));
            }

            _resolvedContactPoints.AddOrUpdate(
                contactPointText,
                key => connectionEndPoints,
                (key, list) => connectionEndPoints);

            return(connectionEndPoints);
        }