System.Net.NameResolutionPal.TryGetAddrInfo C# (CSharp) Method

TryGetAddrInfo() public static method

public static TryGetAddrInfo ( string name, IPHostEntry &hostinfo, int &nativeErrorCode ) : SocketError
name string
hostinfo IPHostEntry
nativeErrorCode int
return SocketError
        public static unsafe SocketError TryGetAddrInfo(string name, out IPHostEntry hostinfo, out int nativeErrorCode)
        {
            //
            // Use SocketException here to show operation not supported
            // if, by some nefarious means, this method is called on an
            // unsupported platform.
            //
            SafeFreeAddrInfo root = null;
            var addresses = new List<IPAddress>();
            string canonicalname = null;

            AddressInfo hints = new AddressInfo();
            hints.ai_flags = AddressInfoHints.AI_CANONNAME;
            hints.ai_family = AddressFamily.Unspecified;   // gets all address families

            nativeErrorCode = 0;

            //
            // Use try / finally so we always get a shot at freeaddrinfo
            //
            try
            {
                SocketError errorCode = (SocketError)SafeFreeAddrInfo.GetAddrInfo(name, null, ref hints, out root);
                if (errorCode != SocketError.Success)
                { // Should not throw, return mostly blank hostentry
                    hostinfo = NameResolutionUtilities.GetUnresolvedAnswer(name);
                    return errorCode;
                }

                AddressInfo* pAddressInfo = (AddressInfo*)root.DangerousGetHandle();
                //
                // Process the results
                //
                while (pAddressInfo != null)
                {
                    SocketAddress sockaddr;
                    //
                    // Retrieve the canonical name for the host - only appears in the first AddressInfo
                    // entry in the returned array.
                    //
                    if (canonicalname == null && pAddressInfo->ai_canonname != null)
                    {
                        canonicalname = Marshal.PtrToStringUni((IntPtr)pAddressInfo->ai_canonname);
                    }
                    //
                    // Only process IPv4 or IPv6 Addresses. Note that it's unlikely that we'll
                    // ever get any other address families, but better to be safe than sorry.
                    // We also filter based on whether IPv6 is supported on the current
                    // platform / machine.
                    //
                    if ((pAddressInfo->ai_family == AddressFamily.InterNetwork) || // Never filter v4
                        (pAddressInfo->ai_family == AddressFamily.InterNetworkV6 && SocketProtocolSupportPal.OSSupportsIPv6))
                    {
                        sockaddr = new SocketAddress(pAddressInfo->ai_family, pAddressInfo->ai_addrlen);
                        //
                        // Push address data into the socket address buffer
                        //
                        for (int d = 0; d < pAddressInfo->ai_addrlen; d++)
                        {
                            sockaddr[d] = *(pAddressInfo->ai_addr + d);
                        }
                        //
                        // NOTE: We need an IPAddress now, the only way to create it from a
                        //       SocketAddress is via IPEndPoint. This ought to be simpler.
                        //
                        if (pAddressInfo->ai_family == AddressFamily.InterNetwork)
                        {
                            addresses.Add(((IPEndPoint)IPEndPointStatics.Any.Create(sockaddr)).Address);
                        }
                        else
                        {
                            addresses.Add(((IPEndPoint)IPEndPointStatics.IPv6Any.Create(sockaddr)).Address);
                        }
                    }
                    //
                    // Next addressinfo entry
                    //
                    pAddressInfo = pAddressInfo->ai_next;
                }
            }
            finally
            {
                if (root != null)
                {
                    root.Dispose();
                }
            }

            //
            // Finally, put together the IPHostEntry
            //
            hostinfo = new IPHostEntry();

            hostinfo.HostName = canonicalname != null ? canonicalname : name;
            hostinfo.Aliases = Array.Empty<string>();
            hostinfo.AddressList = addresses.ToArray();

            return SocketError.Success;
        }

Usage Example

Example #1
0
        private static IPHostEntry InternalGetHostByName(string hostName, bool includeIPv6)
        {
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Enter(NetEventSource.ComponentType.Socket, "DNS", "GetHostByName", hostName);
            }
            IPHostEntry ipHostEntry = null;

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Print("Dns.GetHostByName: " + hostName);
            }

            if (hostName.Length > MaxHostName || // If 255 chars, the last one must be a dot.
                hostName.Length == MaxHostName && hostName[MaxHostName - 1] != '.')
            {
                throw new ArgumentOutOfRangeException(nameof(hostName), SR.Format(SR.net_toolong,
                                                                                  nameof(hostName), MaxHostName.ToString(NumberFormatInfo.CurrentInfo)));
            }

            //
            // IPv6 Changes: IPv6 requires the use of getaddrinfo() rather
            //               than the traditional IPv4 gethostbyaddr() / gethostbyname().
            //               getaddrinfo() is also protocol independent in that it will also
            //               resolve IPv4 names / addresses. As a result, it is the preferred
            //               resolution mechanism on platforms that support it (Windows 5.1+).
            //               If getaddrinfo() is unsupported, IPv6 resolution does not work.
            //
            // Consider    : If IPv6 is disabled, we could detect IPv6 addresses
            //               and throw an unsupported platform exception.
            //
            // Note        : Whilst getaddrinfo is available on WinXP+, we only
            //               use it if IPv6 is enabled (platform is part of that
            //               decision). This is done to minimize the number of
            //               possible tests that are needed.
            //
            if (includeIPv6 || SocketProtocolSupportPal.OSSupportsIPv6)
            {
                //
                // IPv6 enabled: use getaddrinfo() to obtain DNS information.
                //
                int         nativeErrorCode;
                SocketError errorCode = NameResolutionPal.TryGetAddrInfo(hostName, out ipHostEntry, out nativeErrorCode);
                if (errorCode != SocketError.Success)
                {
                    throw SocketExceptionFactory.CreateSocketException(errorCode, nativeErrorCode);
                }
            }
            else
            {
                ipHostEntry = NameResolutionPal.GetHostByName(hostName);
            }

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Exit(NetEventSource.ComponentType.Socket, "DNS", "GetHostByName", ipHostEntry);
            }
            return(ipHostEntry);
        } // GetHostByName
All Usage Examples Of System.Net.NameResolutionPal::TryGetAddrInfo