Ejemplo n.º 1
0
 /// <summary>
 /// Record the IPs in the state object for later use.
 /// </summary>
 private void GetHostEntryCallback(IAsyncResult ar)
 {
     try
     {
         DnsResponse dnsResponse = (DnsResponse)ar.AsyncState; // Turn the state object into the DnsResponse type
         dnsResponse.IpHostEntry = Dns.EndGetHostEntry(ar);    // Save the returned IpHostEntry and populate other fields based on its parameters
         dnsResponse.CallComplete.Set();                       // Set the wait handle so that the caller knows that the asynchronous call has completed and that the response has been updated
     }
     catch (SocketException ex)
     {
         LogMessage("GetHostEntryCallback", $"Socket Exception: {ex.Message}");
     }
     catch (Exception ex)
     {
         LogMessage("GetHostEntryCallback", $"Exception: {ex}");
     } // Log exceptions but don't throw them
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Resolve a host IP address to a host name
        /// </summary>
        /// <remarks>This first makes a DNS query and uses the result if found. If not found it then tries a Microsoft DNS call which also searches the local hosts and makes a netbios query.
        /// If this returns an answer it is use. Otherwise the IP address is returned as the host name</remarks>
        private void ResolveIpAddressToHostName(object deviceIpEndPointObject)
        {
            IPEndPoint deviceIpEndPoint = null;

            try
            {
                deviceIpEndPoint = deviceIpEndPointObject as IPEndPoint; // Get the supplied device endpoint as an IPEndPoint

                // test whether the cast was successful
                if (deviceIpEndPoint is object)          // The cast was successful so we can try to search for the host name
                {
                    var dnsResponse = new DnsResponse(); // Create a new DnsResponse to hold and return the

                    // Calculate the remaining time before this discovery needs to finish and only undertake DNS resolution if sufficient time remains
                    var timeOutTime = TimeSpan.FromSeconds(discoveryTime).Subtract(DateTime.Now - discoveryStartTime).Subtract(TimeSpan.FromSeconds(0.2d));
                    if (timeOutTime.TotalSeconds > Constants.MINIMUM_TIME_REMAINING_TO_UNDERTAKE_DNS_RESOLUTION) // We have more than the configured time left so we will attempt a reverse DNS name resolution
                    {
                        LogMessage("ResolveIpAddressToHostName", $"Resolving IP address: {deviceIpEndPoint.Address}, Timeout: {timeOutTime}");
                        Dns.BeginGetHostEntry(deviceIpEndPoint.Address.ToString(), new AsyncCallback(GetHostEntryCallback), dnsResponse);

                        // Wait here until the resolve completes and the callback calls .Set()
                        bool dnsWasResolved = dnsResponse.CallComplete.WaitOne(timeOutTime); // Wait for the remaining discovery time

                        // Execution continues here after either a DNS response is found or the request times out
                        if (dnsWasResolved) // A response was received rather than timing out
                        {
                            LogMessage("ResolveIpAddressToHostName", $"{deviceIpEndPoint} has host name: {dnsResponse.HostName} IP address count: {dnsResponse.AddressList.Length} Alias count: {dnsResponse.Aliases.Length}");
                            foreach (IPAddress address in dnsResponse.AddressList)
                            {
                                LogMessage("ResolveIpAddressToHostName", $"  Received {address.AddressFamily} address: {address}");
                            }
                            foreach (string hostAlias in dnsResponse.Aliases)
                            {
                                LogMessage("ResolveIpAddressToHostName", $"  Received alias: {hostAlias}");
                            }
                            if (dnsResponse.AddressList.Length > 0) // We got a reply that contains host addresses so there may be a valid host name
                            {
                                lock (deviceListLockObject)
                                {
                                    if (!string.IsNullOrEmpty(dnsResponse.HostName))
                                    {
                                        alpacaDeviceList[deviceIpEndPoint].HostName = dnsResponse.HostName;
                                    }
                                }

                                RaiseAnAlpacaDevicesChangedEvent(); // Device list was changed so set the changed flag
                            }
                            else
                            {
                                LogMessage("ResolveIpAddressToHostName", $"***** DNS responded with a name ({dnsResponse.HostName}) but this has no associated IP addresses and is probably a NETBIOS name *****");
                            }

                            foreach (IPAddress address in dnsResponse.AddressList)
                            {
                                LogMessage("ResolveIpAddressToHostName", $"Address: {address}");
                            }
                            foreach (string alias in dnsResponse.Aliases)
                            {
                                LogMessage("ResolveIpAddressToHostName", $"Alias: {alias}");
                            }
                        }
                        else // DNS did not respond in time
                        {
                            LogMessage("ResolveIpAddressToHostName", $"***** DNS did not respond within timeout - unable to resolve IP address to host name *****");
                        }
                    }
                    else // There was insufficient time to query DNS
                    {
                        LogMessage("ResolveIpAddressToHostName", $"***** Insufficient time remains ({timeOutTime.TotalSeconds} seconds) to conduct a DNS query, ignoring request *****");
                    }
                }
                else // The IPEndPoint cast was not successful so we cannot carry out a DNS name search because we don't have the device's IP address
                {
                    LogMessage("ResolveIpAddressToHostName", $"DNS resolution could not be undertaken - It was not possible to cast the supplied IPEndPoint object to an IPEndPoint type: {deviceIpEndPoint}.");
                }
            }
            catch (TimeoutException)
            {
                LogMessage("ResolveIpAddressToHostName", $"Timed out trying to resolve the DNS name for {(deviceIpEndPoint is null ? "Unknown IP address" : deviceIpEndPoint.ToString()) }");
            }
            catch (Exception ex)
            {
                // Something went wrong, so log the issue and sent a message to the user
                LogMessage("ResolveIpAddressToHostName", $"Exception: {ex}");
            }
        }