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); }
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); }
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); }
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)); } } }
/// <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);