public void Resolve(string host, int port, EndpointSelectionType selType, IPEndpoint endpoint, IEndpointConnectors callback) { // // Try to get the addresses without DNS lookup. If this doesn't work, we queue a resolve // entry and the thread will take care of getting the endpoint addresses. // INetworkProxy?networkProxy = NetworkProxy; if (networkProxy == null) { try { List <EndPoint> addrs = Network.GetAddresses(host, port, IPVersion, selType, PreferIPv6, false); if (addrs.Count > 0) { callback.Connectors(endpoint.Connectors(addrs, null)); return; } } catch (System.Exception ex) { callback.Exception(ex); return; } } lock (_endpointHostResolverThread) { Debug.Assert(!_endpointHostResolverDestroyed); var entry = new ResolveEntry(host, port, selType, endpoint, callback); Instrumentation.ICommunicatorObserver?obsv = Observer; if (obsv != null) { entry.Observer = obsv.GetEndpointLookupObserver(endpoint); if (entry.Observer != null) { entry.Observer.Attach(); } } _enpointHostResolverQueue.AddLast(entry); Monitor.Pulse(_endpointHostResolverThread); } }
internal static IEnumerable <IPEndPoint> GetAddresses( string host, int port, int ipVersion, EndpointSelectionType selType) { try { ValueTask <IEnumerable <IPEndPoint> > task = GetAddressesAsync(host, port, ipVersion, selType); return(task.IsCompleted ? task.Result : task.AsTask().Result); } catch (AggregateException ex) { Debug.Assert(ex.InnerException != null); throw ExceptionUtil.Throw(ex.InnerException); } }
public override async ValueTask <IEnumerable <IConnector> > ConnectorsAsync(EndpointSelectionType endptSelection) { Instrumentation.IObserver?observer = Communicator.Observer?.GetEndpointLookupObserver(this); observer?.Attach(); try { INetworkProxy?networkProxy = Communicator.NetworkProxy; int ipVersion = Communicator.IPVersion; if (networkProxy != null) { networkProxy = await networkProxy.ResolveHostAsync(ipVersion).ConfigureAwait(false); if (networkProxy != null) { ipVersion = networkProxy.GetIPVersion(); } } IEnumerable <IPEndPoint> addrs = await Network.GetAddressesForClientEndpointAsync(Host, Port, ipVersion, endptSelection, Communicator.PreferIPv6).ConfigureAwait(false); return(addrs.Select(item => CreateConnector(item, networkProxy))); } catch (Exception ex) { observer?.Failed(ex.GetType().FullName ?? "System.Exception"); throw; } finally { observer?.Detach(); } }
// Returns a connector for this endpoint, or empty list if no connector is available. public abstract void ConnectorsAsync(EndpointSelectionType endpointSelection, IEndpointConnectors callback);
public static async ValueTask <IEnumerable <IPEndPoint> > GetAddressesAsync(string host, int port, int ipVersion, EndpointSelectionType selType, bool preferIPv6) { Debug.Assert(host.Length > 0); int retry = 5; while (true) { try { var addresses = new List <IPEndPoint>(); foreach (IPAddress a in await Dns.GetHostAddressesAsync(host).ConfigureAwait(false)) { if ((a.AddressFamily == AddressFamily.InterNetwork && ipVersion != EnableIPv6) || (a.AddressFamily == AddressFamily.InterNetworkV6 && ipVersion != EnableIPv4)) { addresses.Add(new IPEndPoint(a, port)); } } // // No InterNetwork/InterNetworkV6 available. // if (addresses.Count == 0) { throw new DNSException(host); } IEnumerable <IPEndPoint> addrs = addresses; if (selType == EndpointSelectionType.Random) { addrs = addrs.Shuffle(); } if (ipVersion == EnableBoth) { if (preferIPv6) { return(addrs.OrderByDescending(addr => addr.AddressFamily)); } else { return(addrs.OrderBy(addr => addr.AddressFamily)); } } return(addrs); } catch (DNSException) { throw; } catch (SocketException ex) { if (SocketErrorCode(ex) == SocketError.TryAgain && --retry >= 0) { continue; } throw new DNSException(host, ex); } catch (Exception ex) { throw new DNSException(host, ex); } } }
public static async ValueTask <IEnumerable <IPEndPoint> > GetAddressesForClientEndpointAsync(string host, int port, int ipVersion, EndpointSelectionType selType, bool preferIPv6) { // For client endpoints, an empty host is the same as the loopback address if (host.Length == 0) { var addresses = new List <IPEndPoint>(); foreach (IPAddress a in GetLoopbackAddresses(ipVersion)) { addresses.Add(new IPEndPoint(a, port)); } if (ipVersion == EnableBoth) { if (preferIPv6) { return(addresses.OrderByDescending(addr => addr.AddressFamily)); } else { return(addresses.OrderBy(addr => addr.AddressFamily)); } } return(addresses); } return(await GetAddressesAsync(host, port, ipVersion, selType, preferIPv6).ConfigureAwait(false)); }
public override void ConnectorsAsync(EndpointSelectionType endpointSelection, IEndpointConnectors callback) => Instance.Resolve(Host, Port, endpointSelection, this, callback);
// Returns a connector for this endpoint, or empty list if no connector is available. public abstract ValueTask <IEnumerable <IConnector> > ConnectorsAsync(EndpointSelectionType endpointSelection);
/// <summary> /// Creates a new proxy that is identical to this proxy, except for the endpoint selection policy. /// </summary> /// <param name="newType">The new endpoint selection policy.</param> /// <returns>The new proxy with the specified endpoint selection policy.</returns> public ObjectPrx ice_endpointSelection(EndpointSelectionType newType) { if(newType == _reference.getEndpointSelection()) { return this; } else { return newInstance(_reference.changeEndpointSelection(newType)); } }
internal static async ValueTask <IEnumerable <IPEndPoint> > GetAddressesAsync( string host, int port, int ipVersion, EndpointSelectionType selType, bool preferIPv6, CancellationToken cancel = default) { Debug.Assert(host.Length > 0); int retry = 5; while (true) { var addresses = new List <IPEndPoint>(); try { // Trying to parse the IP address is necessary to handle wildcard addresses such as 0.0.0.0 or ::0 // since GetHostAddressesAsync fails to resolve them. var a = IPAddress.Parse(host); if ((a.AddressFamily == AddressFamily.InterNetwork && ipVersion != EnableIPv6) || (a.AddressFamily == AddressFamily.InterNetworkV6 && ipVersion != EnableIPv4)) { addresses.Add(new IPEndPoint(a, port)); return(addresses); } else { throw new DNSException(host); } } catch (FormatException) { } try { foreach (IPAddress a in await Dns.GetHostAddressesAsync(host).WaitAsync(cancel).ConfigureAwait(false)) { if ((a.AddressFamily == AddressFamily.InterNetwork && ipVersion != EnableIPv6) || (a.AddressFamily == AddressFamily.InterNetworkV6 && ipVersion != EnableIPv4)) { addresses.Add(new IPEndPoint(a, port)); } } // No InterNetwork/InterNetworkV6 available. if (addresses.Count == 0) { throw new DNSException(host); } IEnumerable <IPEndPoint> addrs = addresses; if (selType == EndpointSelectionType.Random) { addrs = addrs.Shuffle(); } if (ipVersion == EnableBoth) { if (preferIPv6) { return(addrs.OrderByDescending(addr => addr.AddressFamily)); } else { return(addrs.OrderBy(addr => addr.AddressFamily)); } } return(addrs); } catch (DNSException) { throw; } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.TryAgain && --retry >= 0) { continue; } throw new DNSException(host, ex); } catch (Exception ex) { throw new DNSException(host, ex); } } }
public override ValueTask <IEnumerable <IConnector> > ConnectorsAsync(EndpointSelectionType endSel) => new ValueTask <IEnumerable <IConnector> >(new List <IConnector>());