Exemple #1
0
        internal IDictionary <NetworkAddress, NetworkAddress> CreateMapFromConfiguration()
        {
            var addresses = new Dictionary <NetworkAddress, NetworkAddress>();

            foreach (var configurationAddressString in _configurationAddresses)
            {
                if (!NetworkAddress.TryParse(configurationAddressString, out var configurationAddress))
                {
                    throw new FormatException($"The string \"{configurationAddressString}\" does not represent a valid network address.");
                }

                // got to be v6 - cannot get IPAddress to parse anything that would not be v4 or v6
                //if (!address.IsIpV6)
                //    throw new NotSupportedException($"Address family {address.IPAddress.AddressFamily} is not supported.");

                // see https://4sysops.com/archives/ipv6-tutorial-part-6-site-local-addresses-and-link-local-addresses/
                // loopback - is ::1 exclusively
                // site-local - equivalent to private IP addresses in v4 = fe:c0:...
                // link-local - hosts on the link
                // global - globally route-able addresses

                IEnumerable <NetworkAddress> networkAddresses;
                if (configurationAddress.IsIpV4 || configurationAddress.IsIpV6GlobalOrScoped)
                {
                    // v4, or v6 global or has a scope = qualified, can return
                    networkAddresses = ExpandPorts(configurationAddress);
                }
                else
                {
                    // address is v6 site-local or link-local, and has no scopeId
                    // get localhost addresses
                    networkAddresses = GetV6LocalAddresses()
                                       .SelectMany(x => ExpandPorts(configurationAddress, x));
                }

                foreach (var networkAddress in networkAddresses)
                {
                    addresses.Add(networkAddress, networkAddress);
                }
            }

            return(addresses);
        }
Exemple #2
0
        private IDictionary <NetworkAddress, NetworkAddress> CreateMapFromConfiguration()
        {
            var addresses = new Dictionary <NetworkAddress, NetworkAddress>();

            foreach (var configurationAddress in _configurationAddresses)
            {
                if (!NetworkAddress.TryParse(configurationAddress, out IEnumerable <NetworkAddress> networkAddresses))
                {
                    throw new FormatException($"The string \"{configurationAddress}\" does not represent a valid network address.");
                }

                foreach (var networkAddress in networkAddresses)
                {
                    addresses.Add(networkAddress, networkAddress);
                }
            }

            return(addresses);
        }
Exemple #3
0
        private static Dictionary <NetworkAddress, NetworkAddress> ParseResponse(string jsonResult)
        {
            var regexPrivate   = new Regex(RegexPrivateStr, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            var regexPublic    = new Regex(RegexPublicStr, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            var matchesPrivate = regexPrivate.Matches(jsonResult);
            var matchesPublic  = regexPublic.Matches(jsonResult);

            var privateToPublicAddresses = new Dictionary <NetworkAddress, NetworkAddress>();

            for (var i = 0; i < matchesPrivate.Count; i++)
            {
                var privateAddressStr = matchesPrivate[i].Value;
                var publicAddressStr  = matchesPublic[i].Value;

                var publicAddress = NetworkAddress.Parse(publicAddressStr);
                privateToPublicAddresses.Add(new NetworkAddress(privateAddressStr, publicAddress.Port), publicAddress);
            }
            return(privateToPublicAddresses);
        }
Exemple #4
0
 internal IEnumerable <NetworkAddress> ExpandPorts(NetworkAddress address, IPAddress ipAddress = null)
 {
     if (address.Port > 0)
     {
         // qualified with a port = can only be this address
         yield return(address);
     }
     else
     {
         // not qualified with a port = can be a port range
         for (var port = _networkingOptions.DefaultPort;
              port < _networkingOptions.DefaultPort + _networkingOptions.PortRange;
              port++)
         {
             yield return(ipAddress == null
                 ? new NetworkAddress(address, port)
                 : new NetworkAddress(address.HostName, ipAddress, port));
         }
     }
 }
Exemple #5
0
        /// <summary>
        /// Maps a private address to a public address.
        /// </summary>
        /// <param name="address">The private address.</param>
        /// <returns>The public address, or null if no address was found.</returns>
        public NetworkAddress Map(NetworkAddress address)
        {
            if (address == null || !_isMapping)
            {
                return(address);
            }

            var fresh = false;

            if (_privateToPublic == null)
            {
                _privateToPublic = _createMap() ?? throw new HazelcastException("Failed to obtain an address map.");

                fresh = true;
            }

            // if we can map, return
            if (_privateToPublic.TryGetValue(address, out var publicAddress))
            {
                return(publicAddress);
            }

            // if the map is not 'fresh' recreate the map and try again, else give up
            // TODO: throttle?
            if (fresh)
            {
                return(null);
            }
            _privateToPublic = _createMap();

            if (_privateToPublic == null)
            {
                throw new HazelcastException("Failed to obtain an address map.");
            }

            return(_privateToPublic.TryGetValue(address, out publicAddress) ? publicAddress : null);
        }
        /// <summary>
        /// Tries to parse a string into a <see cref="NetworkAddress"/> instance.
        /// </summary>
        /// <param name="s">The string.</param>
        /// <param name="address">The network address.</param>
        /// <param name="defaultPort">The default port.</param>
        /// <returns>Whether the string could be parsed into an address.</returns>
        private static bool TryParse(string s, out NetworkAddress address, int defaultPort)
        {
            address = null;

            var span   = s.AsSpan();
            var colon1 = span.IndexOf(':');
            var colon2 = span.LastIndexOf(':');
            var brket1 = span.IndexOf('[');
            var brket2 = span.IndexOf(']');
            var port   = defaultPort;

            // opening bracket must be first
            if (brket1 > 0)
            {
                return(false);
            }

            // must have both brackets, or none
            if (brket1 == 0 != brket2 >= 0)
            {
                return(false);
            }

            // brackets => colon if any *must* be right after closing bracket
            if (brket1 == 0 && colon2 > brket2 + 1)
            {
                return(false);
            }

            // no bracket and single colon, or one colon after brackets
            // => parse port
            if ((brket2 < 0 && colon2 > 0 && colon1 == colon2) ||
                (brket2 > 0 && colon2 > brket2))
            {
#if NETSTANDARD2_0
                if (!int.TryParse(span.Slice(colon2 + 1).ToString(), out port))
                {
                    return(false);
                }
#endif
#if NETSTANDARD2_1
                if (!int.TryParse(span.Slice(colon2 + 1), out port))
                {
                    return(false);
                }
#endif
            }

            ReadOnlySpan <char> hostName;

#pragma warning disable IDE0057 // Slice can be simplified

            if (brket1 == 0)
            {
                // if we have brackets, they must contain colons
                if (colon2 < 0 || colon1 > brket2)
                {
                    return(false);
                }

                // hostname is in-between brackets
                // (and has to be parseable as an ip address)
                hostName = span.Slice(1, brket2 - 1);
            }
            else
            {
                // one single colon = hostname is whatever is before
                // otherwise, hostname is the whole string
                hostName = (colon2 > 0 && colon1 == colon2) ? span.Slice(0, colon2) : span;
            }

#pragma warning restore IDE0057 // Slice can be simplified

            // must have a hostname - look at the code above, hostname cannot be empty here
            //if (hostName.Length == 0)
            //    return false;

            // note that in IPv6 case, hostname can contain a % followed by a scope id
            // which is fine, IPAddress.TryParse handles it

            string hostNameString;

#if NET462 || NETSTANDARD2_0
            if (IPAddress.TryParse(hostName.ToString(), out var ipAddress))
#endif
#if NETSTANDARD2_1
            if (IPAddress.TryParse(hostName, out var ipAddress))
#endif
            {
                // if the hostname parses to an ip address, fine
                hostNameString = ipAddress.ToString();
            }
            else
            {
                // if we have brackets, hostname must be parseable
                if (brket1 == 0)
                {
                    return(false);
                }

                hostNameString = hostName.ToString();

                // else, try to get the ip via DNS
                try
                {
                    ipAddress = GetIPAddressByName(hostNameString);
                }
                catch
                {
                    return(false);
                }
            }

            address = new NetworkAddress(hostNameString, ipAddress, port);
            return(true);
        }
 /// <summary>
 /// Tries to parse a string into a <see cref="NetworkAddress"/> instance.
 /// </summary>
 /// <param name="s">The string.</param>
 /// <param name="address">The network address.</param>
 /// <returns>Whether the string could be parsed into an address.</returns>
 public static bool TryParse(string s, out NetworkAddress address)
 => TryParse(s, out address, DefaultPort);