DNS.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Net / System / Net / DNS.cs / 1305376 / DNS.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

 
namespace System.Net { 
    using System.Text;
    using System.Collections; 
    using System.Net.Sockets;
    using System.Runtime.InteropServices;
    using System.Security.Permissions;
    using System.Threading; 
    using System.Globalization;
    using System.Net.NetworkInformation; 
 
    /// 
    ///    Provides simple 
    ///       domain name resolution functionality.
    /// 

    public static class Dns 
    {
        // 
        // used by GetHostName() to preallocate a buffer for the call to gethostname. 
        //
        private const int HostNameBufferLength = 256; 

        //also used as a lock object
        private static DnsPermission s_DnsPermission = new DnsPermission(PermissionState.Unrestricted);
 
        // Host names any longer than this automatically fail at the winsock level.
        // If the host name is 255 chars, the last char must be a dot. 
        private const int MaxHostName = 255; 

        /*++ 

        Routine Description:

            Takes a native pointer (expressed as an int) to a hostent structure, 
            and converts the information in their to an IPHostEntry class. This
            involves walking through an array of native pointers, and a temporary 
            ArrayList object is used in doing this. 

        Arguments: 

            nativePointer   - Native pointer to hostent structure.

 

        Return Value: 
 
            An IPHostEntry structure.
 
        --*/

#if !FEATURE_PAL
        private static IPHostEntry NativeToHostEntry(IntPtr nativePointer) { 
#else
        internal static IPHostEntry NativeToHostEntry(IntPtr nativePointer) { 
#endif 
            //
            // marshal pointer to struct 
            //

            hostent Host = (hostent)Marshal.PtrToStructure(nativePointer, typeof(hostent));
            IPHostEntry HostEntry = new IPHostEntry(); 

            if (Host.h_name != IntPtr.Zero) { 
                HostEntry.HostName = Marshal.PtrToStringAnsi(Host.h_name); 
                GlobalLog.Print("HostEntry.HostName: " + HostEntry.HostName);
            } 

            // decode h_addr_list to ArrayList of IP addresses.
            // The h_addr_list field is really a pointer to an array of pointers
            // to IP addresses. Loop through the array, and while the pointer 
            // isn't NULL read the IP address, convert it to an IPAddress class,
            // and add it to the list. 
 
            ArrayList TempList = new ArrayList();
            int IPAddressToAdd; 
            string AliasToAdd;
            IntPtr currentArrayElement;

            // 
            // get the first pointer in the array
            // 
            currentArrayElement = Host.h_addr_list; 
            nativePointer = Marshal.ReadIntPtr(currentArrayElement);
 
            while (nativePointer != IntPtr.Zero) {
                //
                // if it's not null it points to an IPAddress,
                // read it... 
                //
                IPAddressToAdd = Marshal.ReadInt32(nativePointer); 
#if BIGENDIAN 
                // IP addresses from native code are always a byte array
                // converted to int.  We need to convert the address into 
                // a uniform integer value.
                IPAddressToAdd = (int)( ((uint)IPAddressToAdd << 24) |
                                        (((uint)IPAddressToAdd & 0x0000FF00) << 8) |
                                        (((uint)IPAddressToAdd >> 8) & 0x0000FF00) | 
                                        ((uint)IPAddressToAdd >> 24) );
#endif 
 
                GlobalLog.Print("currentArrayElement: " + currentArrayElement.ToString() + " nativePointer: " + nativePointer.ToString() + " IPAddressToAdd:" + IPAddressToAdd.ToString());
 
                //
                // ...and add it to the list
                //
                TempList.Add(new IPAddress(IPAddressToAdd)); 

                // 
                // now get the next pointer in the array and start over 
                //
                currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size); 
                nativePointer = Marshal.ReadIntPtr(currentArrayElement);
            }

            HostEntry.AddressList = new IPAddress[TempList.Count]; 
            TempList.CopyTo(HostEntry.AddressList, 0);
 
            // 
            // Now do the same thing for the aliases.
            // 

            TempList.Clear();

            currentArrayElement = Host.h_aliases; 
            nativePointer = Marshal.ReadIntPtr(currentArrayElement);
 
            while (nativePointer != IntPtr.Zero) { 

                GlobalLog.Print("currentArrayElement: " + ((long)currentArrayElement).ToString() + "nativePointer: " + ((long)nativePointer).ToString()); 

                //
                // if it's not null it points to an Alias,
                // read it... 
                //
                AliasToAdd = Marshal.PtrToStringAnsi(nativePointer); 
 
                //
                // ...and add it to the list 
                //
                TempList.Add(AliasToAdd);

                // 
                // now get the next pointer in the array and start over
                // 
                currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size); 
                nativePointer = Marshal.ReadIntPtr(currentArrayElement);
 
            }

            HostEntry.Aliases = new string[TempList.Count];
            TempList.CopyTo(HostEntry.Aliases, 0); 

            return HostEntry; 
 
        } // NativeToHostEntry
 
        /*****************************************************************************
         Function :    gethostbyname

         Abstract:     Queries DNS for hostname address 

         Input Parameters: str (String to query) 
 
         Returns: Void
        ******************************************************************************/ 

        /// 
        /// Retrieves the 
        /// information 
        /// corresponding to the DNS name provided in the host
        /// parameter. 
        ///  

 
        [Obsolete("GetHostByName is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry GetHostByName(string hostName) {
            if (hostName == null) {
                throw new ArgumentNullException("hostName"); 
            }
            // 
            // demand Unrestricted DnsPermission for this call 
            //
            s_DnsPermission.Demand(); 

            // See if it's an IP Address.
            IPAddress address;
            if (IPAddress.TryParse(hostName, out address)) 
            {
                return GetUnresolveAnswer(address); 
            } 
            return InternalGetHostByName(hostName, false);
        } 
        //


        internal static IPHostEntry InternalGetHostByName(string hostName) { 
            return InternalGetHostByName(hostName,true);
        } 
 
        internal static IPHostEntry InternalGetHostByName(string hostName, bool includeIPv6) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostByName", hostName); 
            IPHostEntry ipHostEntry = null;

            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("hostName", SR.GetString(SR.net_toolong, 
                    "hostName", MaxHostName.ToString(NumberFormatInfo.CurrentInfo)));
            } 

            //
            // IPv6 Changes: IPv6 requires the use of getaddrinfo() rather
            //               than the traditional IPv4 gethostbyaddr() / gethostbyname(). 
            //               getaddrinfo() is also protocol independant 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 ( Socket.LegacySupportsIPv6 || (includeIPv6 && ComNetOS.IsPostWin2K)) { 
                //
                // IPv6 enabled: use getaddrinfo() to obtain DNS information.
                //
                ipHostEntry = Dns.GetAddrInfo(hostName); 
            }
            else { 
                // 
                // IPv6 disabled: use gethostbyname() to obtain DNS information.
                // 
                IntPtr nativePointer =
                    UnsafeNclNativeMethods.OSSOCK.gethostbyname(
                        hostName);
 
                if (nativePointer == IntPtr.Zero) {
                    // This is for compatiblity with NT4/Win2k 
                    // Need to do this first since if we wait the last error code might be overwritten. 
                    SocketException socketException = new SocketException();
 
                    //This block supresses "unknown error" on NT4 when input is
                    //arbitrary IP address. It simulates same result as on Win2K.
                    // For Everett compat, we allow this to parse and return IPv6 even when it's disabled.
                    IPAddress address; 
                    if (IPAddress.TryParse(hostName, out address))
                    { 
                        ipHostEntry = GetUnresolveAnswer(address); 
                        if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByName", ipHostEntry);
                        return ipHostEntry; 
                    }

                    throw socketException;
                } 
                ipHostEntry = NativeToHostEntry(nativePointer);
            } 
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByName", ipHostEntry);
            return ipHostEntry; 

        } // GetHostByName

 

        /***************************************************************************** 
         Function :    gethostbyaddr 

         Abstract:     Queries IP address string and tries to match with a host name 

         Input Parameters: str (String to query)

         Returns: IPHostEntry 
        ******************************************************************************/
 
        ///  
        /// Creates an 
        /// instance from an IP dotted address. 
        /// 

        [Obsolete("GetHostByAddress is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry GetHostByAddress(string address) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostByAddress", address);
            // 
            // demand Unrestricted DnsPermission for this call 
            //
            s_DnsPermission.Demand(); 

            if (address == null) {
                throw new ArgumentNullException("address");
            } 

            GlobalLog.Print("Dns.GetHostByAddress: " + address); 
 
            IPHostEntry ipHostEntry = InternalGetHostByAddress(IPAddress.Parse(address), false);
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByAddress", ipHostEntry); 
            return ipHostEntry;
        } // GetHostByAddress

        /****************************************************************************** 
         Function :    gethostbyaddr
 
         Abstract:     Queries IP address and tries to match with a host name 

         Input Parameters: address (address to query) 

         Returns: IPHostEntry
        ******************************************************************************/
 
        /// 
        /// Creates an  instance from an  
        /// instance. 
        /// 
 
        [Obsolete("GetHostByAddress is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry GetHostByAddress(IPAddress address) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostByAddress", "");
            // 
            // demand Unrestricted DnsPermission for this call
            // 
            s_DnsPermission.Demand(); 

            if (address == null) { 
                throw new ArgumentNullException("address");
            }

            IPHostEntry ipHostEntry = InternalGetHostByAddress(address, false); 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByAddress", ipHostEntry);
            return ipHostEntry; 
        } // GetHostByAddress 

        // Does internal IPAddress reverse and then forward lookups (for Legacy and current public methods). 
        // Legacy methods do not include IPv6, unless configed to by Socket.LegacySupportsIPv6 and Socket.OSSupportsIPv6.
        internal static IPHostEntry InternalGetHostByAddress(IPAddress address, bool includeIPv6)
        {
            GlobalLog.Print("Dns.InternalGetHostByAddress: " + address.ToString()); 
            //
            // IPv6 Changes: We need to use the new getnameinfo / getaddrinfo functions 
            //               for resolution of IPv6 addresses. 
            //
 
            SocketError errorCode = SocketError.Success;
            Exception exception = null;
            if ( Socket.LegacySupportsIPv6 || (includeIPv6 && ComNetOS.IsPostWin2K)) {
                // 
                // Try to get the data for the host from it's address
                // 
                // We need to call getnameinfo first, because getaddrinfo w/ the ipaddress string 
                // will only return that address and not the full list.
 
                // Do a reverse lookup to get the host name.
                string name = TryGetNameInfo(address, out errorCode);
                if(errorCode == SocketError.Success) {
 
                    // Do the forward lookup to get the IPs for that host name
                    IPHostEntry hostEntry; 
                    errorCode = TryGetAddrInfo(name, out hostEntry); 
                    if (errorCode == SocketError.Success)
                        return hostEntry; 

                    // Log failure
                    if (Logging.On) Logging.Exception(Logging.Sockets, "DNS",
                        "InternalGetHostByAddress", new SocketException(errorCode)); 

                    // One of two things happened: 
                    // 1. There was a ptr record in dns, but not a corollary A/AAA record. 
                    // 2. The IP was a local (non-loopback) IP that resolved to a connection specific dns suffix.
                    //    - Workaround, Check "Use this connection's dns suffix in dns registration" on that network 
                    //      adapter's advanced dns settings.

                    // Just return the resolved host name and no IPs.
                    return hostEntry; 
                }
                exception = new SocketException(errorCode); 
            } 

            // 
            // If IPv6 is not enabled (maybe config switch) but we've been
            // given an IPv6 address then we need to bail out now.
            //
            else { 
                if ( address.AddressFamily == AddressFamily.InterNetworkV6 ) {
                    // 
                    // Protocol not supported 
                    //
                    throw new SocketException(SocketError.ProtocolNotSupported); 
                }
                //
                // Use gethostbyaddr() to try to resolve the IP address
                // 
                // End IPv6 Changes
                // 
                int addressAsInt = unchecked((int)address.m_Address); 

    #if BIGENDIAN 
                addressAsInt = (int)( ((uint)addressAsInt << 24) | (((uint)addressAsInt & 0x0000FF00) << 8) |
                    (((uint)addressAsInt >> 8) & 0x0000FF00) | ((uint)addressAsInt >> 24) );
    #endif
 
                IntPtr nativePointer =
                    UnsafeNclNativeMethods.OSSOCK.gethostbyaddr( 
                        ref addressAsInt, 
                        Marshal.SizeOf(typeof(int)),
                        ProtocolFamily.InterNetwork); 


                if (nativePointer != IntPtr.Zero) {
                    return NativeToHostEntry(nativePointer); 
                }
                exception = new SocketException(); 
            } 

            if (Logging.On) Logging.Exception(Logging.Sockets, "DNS", "InternalGetHostByAddress", exception); 
            throw exception;
        } // InternalGetHostByAddress

 
        /*****************************************************************************
         Function :    gethostname 
 
         Abstract:     Queries the hostname from DNS
 
         Input Parameters:

         Returns: String
        ******************************************************************************/ 

        ///  
        ///    Gets the host name of the local machine. 
        /// 
        // UEUE: note that this method is not threadsafe!! 
        public static string GetHostName() {
            //
            // demand Unrestricted DnsPermission for this call
            // 
            s_DnsPermission.Demand();
 
            GlobalLog.Print("Dns.GetHostName"); 

            // 
            // note that we could cache the result ourselves since you
            // wouldn't expect the hostname of the machine to change during
            // execution, but this might still happen and we would want to
            // react to that change. 
            //
 
            Socket.InitializeSockets(); 
            StringBuilder sb = new StringBuilder(HostNameBufferLength);
            SocketError errorCode = 
                UnsafeNclNativeMethods.OSSOCK.gethostname(
                    sb,
                    HostNameBufferLength);
 
            //
            // if the call failed throw a SocketException() 
            // 
            if (errorCode!=SocketError.Success) {
                throw new SocketException(); 
            }
            return sb.ToString();
        }
 

        /****************************************************************************** 
         Function :    resolve 

         Abstract:     Converts IP/hostnames to IP numerical address using DNS 
                       Additional methods provided for convenience
                       (These methods will resolve strings and hostnames. In case of
                       multiple IP addresses, the address returned is chosen arbitrarily.)
 
         Input Parameters: host/IP
 
         Returns: IPAddress 
        ******************************************************************************/
 
        /// 
        /// Creates an 
        /// instance from a DNS hostname.
        ///  
        // UEUE
 
 
        [Obsolete("Resolve is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry Resolve(string hostName) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "Resolve", hostName);
            //
            // demand Unrestricted DnsPermission for this call
            // 
            s_DnsPermission.Demand();
 
            if (hostName == null) { 
                throw new ArgumentNullException("hostName");
            } 

            // See if it's an IP Address.
            IPAddress address;
            IPHostEntry ipHostEntry; 

            // Everett Compat (#497786). 
            // Everett.Resolve() returns the IPv6 address, even when IPv6 is off.  Everett.GetHostByAddress() throws.  So 
            // if IPv6 is off and they passed one in, call InternalGetHostByName which (also for compat) just returns it.
            if (IPAddress.TryParse(hostName, out address) && (address.AddressFamily != AddressFamily.InterNetworkV6 || Socket.LegacySupportsIPv6)) 
            {
                try
                {
                    ipHostEntry = InternalGetHostByAddress(address, false); 
                }
                catch (SocketException ex) 
                { 
                    if (Logging.On) Logging.PrintWarning(Logging.Sockets, "DNS", "DNS.Resolve", ex.Message);
 
                    ipHostEntry = GetUnresolveAnswer(address);
                }
            }
            else 
            {
                ipHostEntry = InternalGetHostByName(hostName, false); 
            } 

            if (Logging.On) Logging.Exit(Logging.Sockets, "DNS", "Resolve", ipHostEntry); 
            return ipHostEntry;
        }

        private static IPHostEntry GetUnresolveAnswer(IPAddress address) 
        {
            IPHostEntry ipHostEntry = new IPHostEntry(); 
            ipHostEntry.HostName = address.ToString(); 
            ipHostEntry.Aliases = new string[0];
            ipHostEntry.AddressList = new IPAddress[] { address }; 
            return ipHostEntry;
        }

 
        //Caution, this will return ipv6 addresses if the OS supports it.  This shouldn't be called by the public apis.
        internal static IPHostEntry InternalResolveFast(string hostName, int timeout, out bool timedOut) { 
            GlobalLog.Assert(hostName != null, "hostName == null"); 
            GlobalLog.Print("Dns.InternalResolveFase: " + hostName);
 
            //
            // the differences between this method and the previous InternalResolve() are:
            //
            // 1) we don't throw any exceptions 
            // 2) we don't do a reverse lookup for address strings, we just use them
            // 
            // IPv6 Changes: It is not practical to embed the code for GetAddrInfo here, instead 
            //               we call it and catch any exceptions.
            // 
            // Timeout: Supports a timeout by offloading work to another thread if necessary.
            //

            // We can't abort a DNS lookup so if we think might need to, run it on another thread. 
            // According to MSDN the max time is 17 seconds.  Use 18 and say 20.
            // Also: MSDN describes how one lookup can result in a string of queries.  It's unclear whether 
            // those would be run in series, extending the possible time this will take, or whether it will always 
            // give up after 17 seconds.  For now assume that 17 seconds is the absolute max.
            bool mightTimeOut = 18000 >= (uint) timeout && timeout != Timeout.Infinite; 
            timedOut = false;

            if (hostName.Length > 0 && hostName.Length <= MaxHostName)
            { 
                // IP Address?
                IPAddress address; 
                if (IPAddress.TryParse(hostName, out address)) 
                {
                    GlobalLog.Print("Dns::InternalResolveFast() returned address:" + address.ToString()); 
                    return GetUnresolveAnswer(address);
                }

                // Looks like a hostname (or failed address parsing) 
                if (Socket.OSSupportsIPv6)
                { 
                    try 
                    {
                       // we will no longer offload to a thread, due to the consequence of having a threadpool thread 
                       //block on another threadpool thread.  In addition, even w/ the DNS server functioning, we run
                       // the risk of having too many of these queued up, causing requests to fail w/ an unable to resolve
                       //exception.
 
                       //I'm leaving the code commented out to possibly reuse in our async case.
 
                       // if (!mightTimeOut) 
                       // {
                            return GetAddrInfo(hostName); 
                       // }
                       /* else
                        {
                            AsyncDnsContext dnsContext = new AsyncDnsContext(hostName); 
                            dnsContext.Offload(new WaitCallback(OffloadedGetAddrInfo));
                            return (IPHostEntry) dnsContext.Wait(timeout, out timedOut); 
                        } 
                        */
                    } 
                    catch ( Exception e )
                    {
                        GlobalLog.Print("Dns::InternalResolveFast() GetAddrInfo() threw: " + e.Message);
                    } 
                }
                else { 
                    // 
                    // we duplicate the code in GetHostByName() to avoid
                    // having to catch the thrown exception 
                    //
                    IntPtr nativePointer;
                    //if (!mightTimeOut)
                    //{ 
                        nativePointer = UnsafeNclNativeMethods.OSSOCK.gethostbyname(hostName);
                    //} 
                    /* 
                    else
                    { 
                        AsyncDnsContext dnsContext = new AsyncDnsContext(hostName);
                        dnsContext.Offload(new WaitCallback(OffloadedGetHostByName));
                        object result = dnsContext.Wait(timeout, out timedOut);
                        nativePointer = result == null ? IntPtr.Zero : (IntPtr) result; 
                    }
                    */ 
                    if (nativePointer != IntPtr.Zero) { 
                        GlobalLog.Print("Dns::InternalResolveFast() gethostbyname() returned nativePointer:" + nativePointer.ToString());
                        return NativeToHostEntry(nativePointer); 
                    }
                }
            }
 
            GlobalLog.Print("Dns::InternalResolveFast() returning null");
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "InternalResolveFast", null); 
            return null; 
        }
 

        private static WaitCallback resolveCallback = new WaitCallback(ResolveCallback);

        private class ResolveAsyncResult : ContextAwareResult 
        {
            // Forward lookup 
            internal ResolveAsyncResult(string hostName, object myObject, bool includeIPv6, object myState, AsyncCallback myCallBack) : 
                base(myObject, myState, myCallBack)
            { 
                this.hostName = hostName;
                this.includeIPv6 = includeIPv6;
            }
 
            // Reverse lookup
            internal ResolveAsyncResult(IPAddress address, object myObject, bool includeIPv6, object myState, AsyncCallback myCallBack) : 
                base(myObject, myState, myCallBack) 
            {
                this.includeIPv6 = includeIPv6; 
                this.address = address;
            }

            internal readonly string hostName; 
            internal bool includeIPv6;
            internal IPAddress address; 
        } 

        private static void ResolveCallback(object context) 
        {
            ResolveAsyncResult result = (ResolveAsyncResult)context;
            IPHostEntry hostEntry;
            try 
            {
                if(result.address != null){ 
                    hostEntry = InternalGetHostByAddress(result.address, result.includeIPv6); 
                }
                else{ 
                    hostEntry = InternalGetHostByName(result.hostName, result.includeIPv6);
                }
            }
            catch (Exception exception) 
            {
                if (exception is OutOfMemoryException || exception is ThreadAbortException || exception is StackOverflowException) 
                    throw; 

                result.InvokeCallback(exception); 
                return;
            }

            result.InvokeCallback(hostEntry); 
        }
 
 
        // Helpers for async GetHostByName, ResolveToAddresses, and Resolve - they're almost identical
        // If hostName is an IPString and justReturnParsedIP==true then no reverse lookup will be attempted, but the orriginal address is returned. 
        private static IAsyncResult HostResolutionBeginHelper(string hostName, bool justReturnParsedIp, bool flowContext, bool includeIPv6, bool throwOnIPAny, AsyncCallback requestCallback, object state)
        {
            //
            // demand Unrestricted DnsPermission for this call 
            //
 
            s_DnsPermission.Demand(); 

            if (hostName == null) { 
                throw new ArgumentNullException("hostName");
            }

            GlobalLog.Print("Dns.HostResolutionBeginHelper: " + hostName); 

            // See if it's an IP Address. 
            IPAddress address; 
            ResolveAsyncResult asyncResult;
            if (IPAddress.TryParse(hostName, out address)) 
            {
                if (throwOnIPAny && (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any)))
                {
                    throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "hostNameOrAddress"); 
                }
 
                asyncResult = new ResolveAsyncResult(address, null, includeIPv6, state, requestCallback); 

                if (justReturnParsedIp) 
                {
                    IPHostEntry hostEntry = GetUnresolveAnswer(address);
                    asyncResult.StartPostingAsyncOp(false);
                    asyncResult.InvokeCallback(hostEntry); 
                    asyncResult.FinishPostingAsyncOp();
                    return asyncResult; 
                } 
            }
            else 
            {
                asyncResult = new ResolveAsyncResult(hostName, null, includeIPv6, state, requestCallback);
            }
 
            // Set up the context, possibly flow.
            if (flowContext) 
            { 
                asyncResult.StartPostingAsyncOp(false);
            } 

            // Start the resolve.
            ThreadPool.UnsafeQueueUserWorkItem(resolveCallback, asyncResult);
 
            // Finish the flowing, maybe it completed?  This does nothing if we didn't initiate the flowing above.
            asyncResult.FinishPostingAsyncOp(); 
            return asyncResult; 
        }
 

        private static IAsyncResult HostResolutionBeginHelper(IPAddress address, bool flowContext, bool includeIPv6, AsyncCallback requestCallback, object state)
        {
            // 
            // demand Unrestricted DnsPermission for this call
            // 
 
            s_DnsPermission.Demand();
 
            if (address == null) {
                throw new ArgumentNullException("address");
            }
 
            if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
            { 
                throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "address"); 
            }
 
            GlobalLog.Print("Dns.HostResolutionBeginHelper: " + address);

            // Set up the context, possibly flow.
            ResolveAsyncResult asyncResult = new ResolveAsyncResult(address, null, includeIPv6, state, requestCallback); 
            if (flowContext)
            { 
                asyncResult.StartPostingAsyncOp(false); 
            }
 
            // Start the resolve.
            ThreadPool.UnsafeQueueUserWorkItem(resolveCallback, asyncResult);

            // Finish the flowing, maybe it completed?  This does nothing if we didn't initiate the flowing above. 
            asyncResult.FinishPostingAsyncOp();
            return asyncResult; 
        } 

 
        private static IPHostEntry HostResolutionEndHelper(IAsyncResult asyncResult)
        {
            //
            // parameter validation 
            //
            if (asyncResult == null) { 
                throw new ArgumentNullException("asyncResult"); 
            }
            ResolveAsyncResult castedResult = asyncResult as ResolveAsyncResult; 
            if (castedResult == null)
            {
                throw new ArgumentException(SR.GetString(SR.net_io_invalidasyncresult), "asyncResult");
            } 
            if (castedResult.EndCalled)
            { 
                throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndResolve")); 
            }
 
            GlobalLog.Print("Dns.HostResolutionEndHelper");

            castedResult.InternalWaitForCompletion();
            castedResult.EndCalled = true; 

            Exception exception = castedResult.Result as Exception; 
            if (exception != null) 
            {
                throw exception; 
            }

            return (IPHostEntry) castedResult.Result;
        } 

        ///  
        ///    [To be supplied.] 
        /// 
        [HostProtection(ExternalThreading=true)] 
        [Obsolete("BeginGetHostByName is obsoleted for this type, please use BeginGetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IAsyncResult BeginGetHostByName(string hostName, AsyncCallback requestCallback, object stateObject) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginGetHostByName", hostName);
 
            IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, true, true, false, false, requestCallback, stateObject);
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginGetHostByName", asyncResult); 
            return asyncResult;
        } // BeginGetHostByName 

        /// 
        ///    [To be supplied.]
        ///  

 
        [Obsolete("EndGetHostByName is obsoleted for this type, please use EndGetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")] 
        public static IPHostEntry EndGetHostByName(IAsyncResult asyncResult) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndGetHostByName", asyncResult); 

            IPHostEntry ipHostEntry = HostResolutionEndHelper(asyncResult);

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndGetHostByName", ipHostEntry); 
            return ipHostEntry;
        } // EndGetHostByName() 
 

 
        //************************************************************************
        //*************   New Whidbey Apis  *************************************
        //***********************************************************************
 

 
        public static IPHostEntry GetHostEntry(string hostNameOrAddress) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostEntry", hostNameOrAddress);
            // 
            // demand Unrestricted DnsPermission for this call
            //
            s_DnsPermission.Demand();
 
            if (hostNameOrAddress == null) {
                throw new ArgumentNullException("hostNameOrAddress"); 
            } 

            // See if it's an IP Address. 
            IPAddress address;
            IPHostEntry ipHostEntry;
            if (IPAddress.TryParse(hostNameOrAddress, out address))
            { 
                if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
                { 
                    throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "hostNameOrAddress"); 
                }
 
                ipHostEntry = InternalGetHostByAddress(address, true);
            }
            else
            { 
                ipHostEntry = InternalGetHostByName(hostNameOrAddress, true);
            } 
 
            if (Logging.On) Logging.Exit(Logging.Sockets, "DNS", "GetHostEntry", ipHostEntry);
            return ipHostEntry; 
        }


        public static IPHostEntry GetHostEntry(IPAddress address) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostEntry", "");
 
            // 
            // demand Unrestricted DnsPermission for this call
            // 
            s_DnsPermission.Demand();

            if (address == null) {
                throw new ArgumentNullException("address"); 
            }
 
            if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any)) 
            {
                throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "address"); 
            }

            IPHostEntry ipHostEntry = InternalGetHostByAddress(address, true);
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostEntry", ipHostEntry); 
            return ipHostEntry;
        } // GetHostByAddress 
 

 
        public static IPAddress[] GetHostAddresses(string hostNameOrAddress) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostAddresses", hostNameOrAddress);
            //
            // demand Unrestricted DnsPermission for this call 
            //
            s_DnsPermission.Demand(); 
 
            if (hostNameOrAddress == null) {
                throw new ArgumentNullException("hostNameOrAddress"); 
            }

            // See if it's an IP Address.
            IPAddress address; 
            IPAddress[] addresses;
            if (IPAddress.TryParse(hostNameOrAddress, out address)) 
            { 
                if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
                { 
                    throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "hostNameOrAddress");
                }
                addresses = new IPAddress[] { address };
            } 
            else
            { 
                // InternalGetHostByName works with IP addresses (and avoids a reverse-lookup), but we need 
                // explicit handling in order to do the ArgumentException and guarantee the behavior.
                addresses = InternalGetHostByName(hostNameOrAddress, true).AddressList; 
            }

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostAddresses", addresses);
            return addresses; 
        }
 
 
        [HostProtection(ExternalThreading=true)]
        public static IAsyncResult BeginGetHostEntry(string hostNameOrAddress, AsyncCallback requestCallback, object stateObject) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginGetHostEntry", hostNameOrAddress);

            IAsyncResult asyncResult = HostResolutionBeginHelper(hostNameOrAddress, false, true, true, true, requestCallback, stateObject);
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginGetHostEntry", asyncResult);
            return asyncResult; 
        } // BeginResolve 

 

        [HostProtection(ExternalThreading=true)]
        public static IAsyncResult BeginGetHostEntry(IPAddress address, AsyncCallback requestCallback, object stateObject) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginGetHostEntry", address); 

            IAsyncResult asyncResult = HostResolutionBeginHelper(address, true, true, requestCallback, stateObject); 
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginGetHostEntry", asyncResult);
            return asyncResult; 
        } // BeginResolve


        public static IPHostEntry EndGetHostEntry(IAsyncResult asyncResult) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndGetHostEntry", asyncResult);
 
            IPHostEntry ipHostEntry = HostResolutionEndHelper(asyncResult); 

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndGetHostEntry", ipHostEntry); 
            return ipHostEntry;
        } // EndResolve()

 
        [HostProtection(ExternalThreading=true)]
        public static IAsyncResult BeginGetHostAddresses(string hostNameOrAddress, AsyncCallback requestCallback, object state) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginGetHostAddresses", hostNameOrAddress); 

            IAsyncResult asyncResult = HostResolutionBeginHelper(hostNameOrAddress, true, true, true, true, requestCallback, state); 

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginGetHostAddresses", asyncResult);
            return asyncResult;
        } // BeginResolve 

 
        public static IPAddress[] EndGetHostAddresses(IAsyncResult asyncResult) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndGetHostAddresses", asyncResult);
 
            IPHostEntry ipHostEntry = HostResolutionEndHelper(asyncResult);

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndGetHostAddresses", ipHostEntry);
            return ipHostEntry.AddressList; 
        } // EndResolveToAddresses
 
 
        internal static IAsyncResult UnsafeBeginGetHostAddresses(string hostName, AsyncCallback requestCallback, object state)
        { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "UnsafeBeginGetHostAddresses", hostName);

            IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, true, false, true, true, requestCallback, state);
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "UnsafeBeginGetHostAddresses", asyncResult);
            return asyncResult; 
        } // UnsafeBeginResolveToAddresses 

 
        /// 
        ///    [To be supplied.]
        /// 
        [HostProtection(ExternalThreading=true)] 
        [Obsolete("BeginResolve is obsoleted for this type, please use BeginGetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IAsyncResult BeginResolve(string hostName, AsyncCallback requestCallback, object stateObject) 
        { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginResolve", hostName);
 
            IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, false, true, false, false, requestCallback, stateObject);

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginResolve", asyncResult);
            return asyncResult; 
        } // BeginResolve
 
 
        [Obsolete("EndResolve is obsoleted for this type, please use EndGetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry EndResolve(IAsyncResult asyncResult) 
        {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndResolve", asyncResult);

            IPHostEntry ipHostEntry; 

            try 
            { 
                ipHostEntry = HostResolutionEndHelper(asyncResult);
            } 
            catch (SocketException ex)
            {
                IPAddress address = ((ResolveAsyncResult)asyncResult).address;
                if (address == null) 
                    throw; // BeginResolve was called with a HostName, not an IPAddress
 
                if (Logging.On) Logging.PrintWarning(Logging.Sockets, "DNS", "DNS.EndResolve", ex.Message); 

                ipHostEntry = GetUnresolveAnswer(address); 
            }

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndResolve", ipHostEntry);
            return ipHostEntry; 
        } // EndResolve()
 
        private unsafe static IPHostEntry GetAddrInfo(string name) { 
            IPHostEntry hostEntry;
            SocketError errorCode = TryGetAddrInfo(name, out hostEntry); 
            if (errorCode != SocketError.Success) {
                throw new SocketException(errorCode);
            }
            return hostEntry; 
        }
 
        // 
        // IPv6 Changes: Add getaddrinfo and getnameinfo methods.
        // 
        private unsafe static SocketError TryGetAddrInfo(string name, out IPHostEntry hostinfo)
        {
            //
            // Use SocketException here to show operation not supported 
            // if, by some nefarious means, this method is called on an
            // unsupported platform. 
            // 
#if FEATURE_PAL
            throw new SocketException(SocketError.OperationNotSupported); 
#else
            if ( !ComNetOS.IsPostWin2K ) {
                throw new SocketException(SocketError.OperationNotSupported);
            } 

            SafeFreeAddrInfo root = null; 
            ArrayList addresses = new ArrayList(); 
            string canonicalname = null;
 
            AddressInfo hints = new AddressInfo();
            hints.ai_flags = AddressInfoHints.AI_CANONNAME;// gets the resolved name
            hints.ai_family = AddressFamily.Unspecified;   // gets all address families
            // 
            // 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 = new IPHostEntry();
                    hostinfo.HostName = name;
                    hostinfo.Aliases = new string[0];
                    hostinfo.AddressList = new IPAddress[0]; 
                    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 = new string(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 && Socket.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.m_Buffer[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)IPEndPoint.Any.Create(sockaddr)).Address ); 
                        }
                        else { 
                            addresses.Add( ((IPEndPoint)IPEndPoint.IPv6Any.Create(sockaddr)).Address );
                        }
                    }
                    // 
                    // Next addressinfo entry
                    // 
                    pAddressInfo = pAddressInfo->ai_next; 
                }
            } 
            finally {
                if (root != null) {
                    root.Close();
                } 
            }
 
            // 
            // Finally, put together the IPHostEntry
            // 
            hostinfo = new IPHostEntry();

            hostinfo.HostName = canonicalname!=null ? canonicalname : name;
            hostinfo.Aliases = new string[0]; 
            hostinfo.AddressList = new IPAddress[addresses.Count];
            addresses.CopyTo(hostinfo.AddressList); 
 
            return SocketError.Success;
#endif // FEATURE_PAL 
        }

        internal static string TryGetNameInfo(IPAddress addr, out SocketError errorCode) {
            // 
            // Use SocketException here to show operation not supported
            // if, by some nefarious means, this method is called on an 
            // unsupported platform. 
            //
#if FEATURE_PAL 
            throw new SocketException(SocketError.OperationNotSupported);
#else
            if ( !ComNetOS.IsPostWin2K ) {
                throw new SocketException(SocketError.OperationNotSupported); 
            }
 
            SocketAddress address  = (new IPEndPoint(addr,0)).Serialize(); 
            StringBuilder hostname = new StringBuilder(1025); // NI_MAXHOST
 
            int flags = (int)NameInfoFlags.NI_NAMEREQD;

            Socket.InitializeSockets();
            errorCode = 
                UnsafeNclNativeMethods.OSSOCK.getnameinfo(
                    address.m_Buffer, 
                    address.m_Size, 
                    hostname,
                    hostname.Capacity, 
                    null, // We don't want a service name
                    0, // so no need for buffer or length
                    flags);
 
            if (errorCode!=SocketError.Success) {
                return null; 
            } 

            return hostname.ToString(); 
#endif // FEATURE_PAL
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

 
namespace System.Net { 
    using System.Text;
    using System.Collections; 
    using System.Net.Sockets;
    using System.Runtime.InteropServices;
    using System.Security.Permissions;
    using System.Threading; 
    using System.Globalization;
    using System.Net.NetworkInformation; 
 
    /// 
    ///    Provides simple 
    ///       domain name resolution functionality.
    /// 

    public static class Dns 
    {
        // 
        // used by GetHostName() to preallocate a buffer for the call to gethostname. 
        //
        private const int HostNameBufferLength = 256; 

        //also used as a lock object
        private static DnsPermission s_DnsPermission = new DnsPermission(PermissionState.Unrestricted);
 
        // Host names any longer than this automatically fail at the winsock level.
        // If the host name is 255 chars, the last char must be a dot. 
        private const int MaxHostName = 255; 

        /*++ 

        Routine Description:

            Takes a native pointer (expressed as an int) to a hostent structure, 
            and converts the information in their to an IPHostEntry class. This
            involves walking through an array of native pointers, and a temporary 
            ArrayList object is used in doing this. 

        Arguments: 

            nativePointer   - Native pointer to hostent structure.

 

        Return Value: 
 
            An IPHostEntry structure.
 
        --*/

#if !FEATURE_PAL
        private static IPHostEntry NativeToHostEntry(IntPtr nativePointer) { 
#else
        internal static IPHostEntry NativeToHostEntry(IntPtr nativePointer) { 
#endif 
            //
            // marshal pointer to struct 
            //

            hostent Host = (hostent)Marshal.PtrToStructure(nativePointer, typeof(hostent));
            IPHostEntry HostEntry = new IPHostEntry(); 

            if (Host.h_name != IntPtr.Zero) { 
                HostEntry.HostName = Marshal.PtrToStringAnsi(Host.h_name); 
                GlobalLog.Print("HostEntry.HostName: " + HostEntry.HostName);
            } 

            // decode h_addr_list to ArrayList of IP addresses.
            // The h_addr_list field is really a pointer to an array of pointers
            // to IP addresses. Loop through the array, and while the pointer 
            // isn't NULL read the IP address, convert it to an IPAddress class,
            // and add it to the list. 
 
            ArrayList TempList = new ArrayList();
            int IPAddressToAdd; 
            string AliasToAdd;
            IntPtr currentArrayElement;

            // 
            // get the first pointer in the array
            // 
            currentArrayElement = Host.h_addr_list; 
            nativePointer = Marshal.ReadIntPtr(currentArrayElement);
 
            while (nativePointer != IntPtr.Zero) {
                //
                // if it's not null it points to an IPAddress,
                // read it... 
                //
                IPAddressToAdd = Marshal.ReadInt32(nativePointer); 
#if BIGENDIAN 
                // IP addresses from native code are always a byte array
                // converted to int.  We need to convert the address into 
                // a uniform integer value.
                IPAddressToAdd = (int)( ((uint)IPAddressToAdd << 24) |
                                        (((uint)IPAddressToAdd & 0x0000FF00) << 8) |
                                        (((uint)IPAddressToAdd >> 8) & 0x0000FF00) | 
                                        ((uint)IPAddressToAdd >> 24) );
#endif 
 
                GlobalLog.Print("currentArrayElement: " + currentArrayElement.ToString() + " nativePointer: " + nativePointer.ToString() + " IPAddressToAdd:" + IPAddressToAdd.ToString());
 
                //
                // ...and add it to the list
                //
                TempList.Add(new IPAddress(IPAddressToAdd)); 

                // 
                // now get the next pointer in the array and start over 
                //
                currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size); 
                nativePointer = Marshal.ReadIntPtr(currentArrayElement);
            }

            HostEntry.AddressList = new IPAddress[TempList.Count]; 
            TempList.CopyTo(HostEntry.AddressList, 0);
 
            // 
            // Now do the same thing for the aliases.
            // 

            TempList.Clear();

            currentArrayElement = Host.h_aliases; 
            nativePointer = Marshal.ReadIntPtr(currentArrayElement);
 
            while (nativePointer != IntPtr.Zero) { 

                GlobalLog.Print("currentArrayElement: " + ((long)currentArrayElement).ToString() + "nativePointer: " + ((long)nativePointer).ToString()); 

                //
                // if it's not null it points to an Alias,
                // read it... 
                //
                AliasToAdd = Marshal.PtrToStringAnsi(nativePointer); 
 
                //
                // ...and add it to the list 
                //
                TempList.Add(AliasToAdd);

                // 
                // now get the next pointer in the array and start over
                // 
                currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size); 
                nativePointer = Marshal.ReadIntPtr(currentArrayElement);
 
            }

            HostEntry.Aliases = new string[TempList.Count];
            TempList.CopyTo(HostEntry.Aliases, 0); 

            return HostEntry; 
 
        } // NativeToHostEntry
 
        /*****************************************************************************
         Function :    gethostbyname

         Abstract:     Queries DNS for hostname address 

         Input Parameters: str (String to query) 
 
         Returns: Void
        ******************************************************************************/ 

        /// 
        /// Retrieves the 
        /// information 
        /// corresponding to the DNS name provided in the host
        /// parameter. 
        ///  

 
        [Obsolete("GetHostByName is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry GetHostByName(string hostName) {
            if (hostName == null) {
                throw new ArgumentNullException("hostName"); 
            }
            // 
            // demand Unrestricted DnsPermission for this call 
            //
            s_DnsPermission.Demand(); 

            // See if it's an IP Address.
            IPAddress address;
            if (IPAddress.TryParse(hostName, out address)) 
            {
                return GetUnresolveAnswer(address); 
            } 
            return InternalGetHostByName(hostName, false);
        } 
        //


        internal static IPHostEntry InternalGetHostByName(string hostName) { 
            return InternalGetHostByName(hostName,true);
        } 
 
        internal static IPHostEntry InternalGetHostByName(string hostName, bool includeIPv6) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostByName", hostName); 
            IPHostEntry ipHostEntry = null;

            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("hostName", SR.GetString(SR.net_toolong, 
                    "hostName", MaxHostName.ToString(NumberFormatInfo.CurrentInfo)));
            } 

            //
            // IPv6 Changes: IPv6 requires the use of getaddrinfo() rather
            //               than the traditional IPv4 gethostbyaddr() / gethostbyname(). 
            //               getaddrinfo() is also protocol independant 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 ( Socket.LegacySupportsIPv6 || (includeIPv6 && ComNetOS.IsPostWin2K)) { 
                //
                // IPv6 enabled: use getaddrinfo() to obtain DNS information.
                //
                ipHostEntry = Dns.GetAddrInfo(hostName); 
            }
            else { 
                // 
                // IPv6 disabled: use gethostbyname() to obtain DNS information.
                // 
                IntPtr nativePointer =
                    UnsafeNclNativeMethods.OSSOCK.gethostbyname(
                        hostName);
 
                if (nativePointer == IntPtr.Zero) {
                    // This is for compatiblity with NT4/Win2k 
                    // Need to do this first since if we wait the last error code might be overwritten. 
                    SocketException socketException = new SocketException();
 
                    //This block supresses "unknown error" on NT4 when input is
                    //arbitrary IP address. It simulates same result as on Win2K.
                    // For Everett compat, we allow this to parse and return IPv6 even when it's disabled.
                    IPAddress address; 
                    if (IPAddress.TryParse(hostName, out address))
                    { 
                        ipHostEntry = GetUnresolveAnswer(address); 
                        if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByName", ipHostEntry);
                        return ipHostEntry; 
                    }

                    throw socketException;
                } 
                ipHostEntry = NativeToHostEntry(nativePointer);
            } 
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByName", ipHostEntry);
            return ipHostEntry; 

        } // GetHostByName

 

        /***************************************************************************** 
         Function :    gethostbyaddr 

         Abstract:     Queries IP address string and tries to match with a host name 

         Input Parameters: str (String to query)

         Returns: IPHostEntry 
        ******************************************************************************/
 
        ///  
        /// Creates an 
        /// instance from an IP dotted address. 
        /// 

        [Obsolete("GetHostByAddress is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry GetHostByAddress(string address) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostByAddress", address);
            // 
            // demand Unrestricted DnsPermission for this call 
            //
            s_DnsPermission.Demand(); 

            if (address == null) {
                throw new ArgumentNullException("address");
            } 

            GlobalLog.Print("Dns.GetHostByAddress: " + address); 
 
            IPHostEntry ipHostEntry = InternalGetHostByAddress(IPAddress.Parse(address), false);
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByAddress", ipHostEntry); 
            return ipHostEntry;
        } // GetHostByAddress

        /****************************************************************************** 
         Function :    gethostbyaddr
 
         Abstract:     Queries IP address and tries to match with a host name 

         Input Parameters: address (address to query) 

         Returns: IPHostEntry
        ******************************************************************************/
 
        /// 
        /// Creates an  instance from an  
        /// instance. 
        /// 
 
        [Obsolete("GetHostByAddress is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry GetHostByAddress(IPAddress address) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostByAddress", "");
            // 
            // demand Unrestricted DnsPermission for this call
            // 
            s_DnsPermission.Demand(); 

            if (address == null) { 
                throw new ArgumentNullException("address");
            }

            IPHostEntry ipHostEntry = InternalGetHostByAddress(address, false); 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostByAddress", ipHostEntry);
            return ipHostEntry; 
        } // GetHostByAddress 

        // Does internal IPAddress reverse and then forward lookups (for Legacy and current public methods). 
        // Legacy methods do not include IPv6, unless configed to by Socket.LegacySupportsIPv6 and Socket.OSSupportsIPv6.
        internal static IPHostEntry InternalGetHostByAddress(IPAddress address, bool includeIPv6)
        {
            GlobalLog.Print("Dns.InternalGetHostByAddress: " + address.ToString()); 
            //
            // IPv6 Changes: We need to use the new getnameinfo / getaddrinfo functions 
            //               for resolution of IPv6 addresses. 
            //
 
            SocketError errorCode = SocketError.Success;
            Exception exception = null;
            if ( Socket.LegacySupportsIPv6 || (includeIPv6 && ComNetOS.IsPostWin2K)) {
                // 
                // Try to get the data for the host from it's address
                // 
                // We need to call getnameinfo first, because getaddrinfo w/ the ipaddress string 
                // will only return that address and not the full list.
 
                // Do a reverse lookup to get the host name.
                string name = TryGetNameInfo(address, out errorCode);
                if(errorCode == SocketError.Success) {
 
                    // Do the forward lookup to get the IPs for that host name
                    IPHostEntry hostEntry; 
                    errorCode = TryGetAddrInfo(name, out hostEntry); 
                    if (errorCode == SocketError.Success)
                        return hostEntry; 

                    // Log failure
                    if (Logging.On) Logging.Exception(Logging.Sockets, "DNS",
                        "InternalGetHostByAddress", new SocketException(errorCode)); 

                    // One of two things happened: 
                    // 1. There was a ptr record in dns, but not a corollary A/AAA record. 
                    // 2. The IP was a local (non-loopback) IP that resolved to a connection specific dns suffix.
                    //    - Workaround, Check "Use this connection's dns suffix in dns registration" on that network 
                    //      adapter's advanced dns settings.

                    // Just return the resolved host name and no IPs.
                    return hostEntry; 
                }
                exception = new SocketException(errorCode); 
            } 

            // 
            // If IPv6 is not enabled (maybe config switch) but we've been
            // given an IPv6 address then we need to bail out now.
            //
            else { 
                if ( address.AddressFamily == AddressFamily.InterNetworkV6 ) {
                    // 
                    // Protocol not supported 
                    //
                    throw new SocketException(SocketError.ProtocolNotSupported); 
                }
                //
                // Use gethostbyaddr() to try to resolve the IP address
                // 
                // End IPv6 Changes
                // 
                int addressAsInt = unchecked((int)address.m_Address); 

    #if BIGENDIAN 
                addressAsInt = (int)( ((uint)addressAsInt << 24) | (((uint)addressAsInt & 0x0000FF00) << 8) |
                    (((uint)addressAsInt >> 8) & 0x0000FF00) | ((uint)addressAsInt >> 24) );
    #endif
 
                IntPtr nativePointer =
                    UnsafeNclNativeMethods.OSSOCK.gethostbyaddr( 
                        ref addressAsInt, 
                        Marshal.SizeOf(typeof(int)),
                        ProtocolFamily.InterNetwork); 


                if (nativePointer != IntPtr.Zero) {
                    return NativeToHostEntry(nativePointer); 
                }
                exception = new SocketException(); 
            } 

            if (Logging.On) Logging.Exception(Logging.Sockets, "DNS", "InternalGetHostByAddress", exception); 
            throw exception;
        } // InternalGetHostByAddress

 
        /*****************************************************************************
         Function :    gethostname 
 
         Abstract:     Queries the hostname from DNS
 
         Input Parameters:

         Returns: String
        ******************************************************************************/ 

        ///  
        ///    Gets the host name of the local machine. 
        /// 
        // UEUE: note that this method is not threadsafe!! 
        public static string GetHostName() {
            //
            // demand Unrestricted DnsPermission for this call
            // 
            s_DnsPermission.Demand();
 
            GlobalLog.Print("Dns.GetHostName"); 

            // 
            // note that we could cache the result ourselves since you
            // wouldn't expect the hostname of the machine to change during
            // execution, but this might still happen and we would want to
            // react to that change. 
            //
 
            Socket.InitializeSockets(); 
            StringBuilder sb = new StringBuilder(HostNameBufferLength);
            SocketError errorCode = 
                UnsafeNclNativeMethods.OSSOCK.gethostname(
                    sb,
                    HostNameBufferLength);
 
            //
            // if the call failed throw a SocketException() 
            // 
            if (errorCode!=SocketError.Success) {
                throw new SocketException(); 
            }
            return sb.ToString();
        }
 

        /****************************************************************************** 
         Function :    resolve 

         Abstract:     Converts IP/hostnames to IP numerical address using DNS 
                       Additional methods provided for convenience
                       (These methods will resolve strings and hostnames. In case of
                       multiple IP addresses, the address returned is chosen arbitrarily.)
 
         Input Parameters: host/IP
 
         Returns: IPAddress 
        ******************************************************************************/
 
        /// 
        /// Creates an 
        /// instance from a DNS hostname.
        ///  
        // UEUE
 
 
        [Obsolete("Resolve is obsoleted for this type, please use GetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry Resolve(string hostName) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "Resolve", hostName);
            //
            // demand Unrestricted DnsPermission for this call
            // 
            s_DnsPermission.Demand();
 
            if (hostName == null) { 
                throw new ArgumentNullException("hostName");
            } 

            // See if it's an IP Address.
            IPAddress address;
            IPHostEntry ipHostEntry; 

            // Everett Compat (#497786). 
            // Everett.Resolve() returns the IPv6 address, even when IPv6 is off.  Everett.GetHostByAddress() throws.  So 
            // if IPv6 is off and they passed one in, call InternalGetHostByName which (also for compat) just returns it.
            if (IPAddress.TryParse(hostName, out address) && (address.AddressFamily != AddressFamily.InterNetworkV6 || Socket.LegacySupportsIPv6)) 
            {
                try
                {
                    ipHostEntry = InternalGetHostByAddress(address, false); 
                }
                catch (SocketException ex) 
                { 
                    if (Logging.On) Logging.PrintWarning(Logging.Sockets, "DNS", "DNS.Resolve", ex.Message);
 
                    ipHostEntry = GetUnresolveAnswer(address);
                }
            }
            else 
            {
                ipHostEntry = InternalGetHostByName(hostName, false); 
            } 

            if (Logging.On) Logging.Exit(Logging.Sockets, "DNS", "Resolve", ipHostEntry); 
            return ipHostEntry;
        }

        private static IPHostEntry GetUnresolveAnswer(IPAddress address) 
        {
            IPHostEntry ipHostEntry = new IPHostEntry(); 
            ipHostEntry.HostName = address.ToString(); 
            ipHostEntry.Aliases = new string[0];
            ipHostEntry.AddressList = new IPAddress[] { address }; 
            return ipHostEntry;
        }

 
        //Caution, this will return ipv6 addresses if the OS supports it.  This shouldn't be called by the public apis.
        internal static IPHostEntry InternalResolveFast(string hostName, int timeout, out bool timedOut) { 
            GlobalLog.Assert(hostName != null, "hostName == null"); 
            GlobalLog.Print("Dns.InternalResolveFase: " + hostName);
 
            //
            // the differences between this method and the previous InternalResolve() are:
            //
            // 1) we don't throw any exceptions 
            // 2) we don't do a reverse lookup for address strings, we just use them
            // 
            // IPv6 Changes: It is not practical to embed the code for GetAddrInfo here, instead 
            //               we call it and catch any exceptions.
            // 
            // Timeout: Supports a timeout by offloading work to another thread if necessary.
            //

            // We can't abort a DNS lookup so if we think might need to, run it on another thread. 
            // According to MSDN the max time is 17 seconds.  Use 18 and say 20.
            // Also: MSDN describes how one lookup can result in a string of queries.  It's unclear whether 
            // those would be run in series, extending the possible time this will take, or whether it will always 
            // give up after 17 seconds.  For now assume that 17 seconds is the absolute max.
            bool mightTimeOut = 18000 >= (uint) timeout && timeout != Timeout.Infinite; 
            timedOut = false;

            if (hostName.Length > 0 && hostName.Length <= MaxHostName)
            { 
                // IP Address?
                IPAddress address; 
                if (IPAddress.TryParse(hostName, out address)) 
                {
                    GlobalLog.Print("Dns::InternalResolveFast() returned address:" + address.ToString()); 
                    return GetUnresolveAnswer(address);
                }

                // Looks like a hostname (or failed address parsing) 
                if (Socket.OSSupportsIPv6)
                { 
                    try 
                    {
                       // we will no longer offload to a thread, due to the consequence of having a threadpool thread 
                       //block on another threadpool thread.  In addition, even w/ the DNS server functioning, we run
                       // the risk of having too many of these queued up, causing requests to fail w/ an unable to resolve
                       //exception.
 
                       //I'm leaving the code commented out to possibly reuse in our async case.
 
                       // if (!mightTimeOut) 
                       // {
                            return GetAddrInfo(hostName); 
                       // }
                       /* else
                        {
                            AsyncDnsContext dnsContext = new AsyncDnsContext(hostName); 
                            dnsContext.Offload(new WaitCallback(OffloadedGetAddrInfo));
                            return (IPHostEntry) dnsContext.Wait(timeout, out timedOut); 
                        } 
                        */
                    } 
                    catch ( Exception e )
                    {
                        GlobalLog.Print("Dns::InternalResolveFast() GetAddrInfo() threw: " + e.Message);
                    } 
                }
                else { 
                    // 
                    // we duplicate the code in GetHostByName() to avoid
                    // having to catch the thrown exception 
                    //
                    IntPtr nativePointer;
                    //if (!mightTimeOut)
                    //{ 
                        nativePointer = UnsafeNclNativeMethods.OSSOCK.gethostbyname(hostName);
                    //} 
                    /* 
                    else
                    { 
                        AsyncDnsContext dnsContext = new AsyncDnsContext(hostName);
                        dnsContext.Offload(new WaitCallback(OffloadedGetHostByName));
                        object result = dnsContext.Wait(timeout, out timedOut);
                        nativePointer = result == null ? IntPtr.Zero : (IntPtr) result; 
                    }
                    */ 
                    if (nativePointer != IntPtr.Zero) { 
                        GlobalLog.Print("Dns::InternalResolveFast() gethostbyname() returned nativePointer:" + nativePointer.ToString());
                        return NativeToHostEntry(nativePointer); 
                    }
                }
            }
 
            GlobalLog.Print("Dns::InternalResolveFast() returning null");
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "InternalResolveFast", null); 
            return null; 
        }
 

        private static WaitCallback resolveCallback = new WaitCallback(ResolveCallback);

        private class ResolveAsyncResult : ContextAwareResult 
        {
            // Forward lookup 
            internal ResolveAsyncResult(string hostName, object myObject, bool includeIPv6, object myState, AsyncCallback myCallBack) : 
                base(myObject, myState, myCallBack)
            { 
                this.hostName = hostName;
                this.includeIPv6 = includeIPv6;
            }
 
            // Reverse lookup
            internal ResolveAsyncResult(IPAddress address, object myObject, bool includeIPv6, object myState, AsyncCallback myCallBack) : 
                base(myObject, myState, myCallBack) 
            {
                this.includeIPv6 = includeIPv6; 
                this.address = address;
            }

            internal readonly string hostName; 
            internal bool includeIPv6;
            internal IPAddress address; 
        } 

        private static void ResolveCallback(object context) 
        {
            ResolveAsyncResult result = (ResolveAsyncResult)context;
            IPHostEntry hostEntry;
            try 
            {
                if(result.address != null){ 
                    hostEntry = InternalGetHostByAddress(result.address, result.includeIPv6); 
                }
                else{ 
                    hostEntry = InternalGetHostByName(result.hostName, result.includeIPv6);
                }
            }
            catch (Exception exception) 
            {
                if (exception is OutOfMemoryException || exception is ThreadAbortException || exception is StackOverflowException) 
                    throw; 

                result.InvokeCallback(exception); 
                return;
            }

            result.InvokeCallback(hostEntry); 
        }
 
 
        // Helpers for async GetHostByName, ResolveToAddresses, and Resolve - they're almost identical
        // If hostName is an IPString and justReturnParsedIP==true then no reverse lookup will be attempted, but the orriginal address is returned. 
        private static IAsyncResult HostResolutionBeginHelper(string hostName, bool justReturnParsedIp, bool flowContext, bool includeIPv6, bool throwOnIPAny, AsyncCallback requestCallback, object state)
        {
            //
            // demand Unrestricted DnsPermission for this call 
            //
 
            s_DnsPermission.Demand(); 

            if (hostName == null) { 
                throw new ArgumentNullException("hostName");
            }

            GlobalLog.Print("Dns.HostResolutionBeginHelper: " + hostName); 

            // See if it's an IP Address. 
            IPAddress address; 
            ResolveAsyncResult asyncResult;
            if (IPAddress.TryParse(hostName, out address)) 
            {
                if (throwOnIPAny && (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any)))
                {
                    throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "hostNameOrAddress"); 
                }
 
                asyncResult = new ResolveAsyncResult(address, null, includeIPv6, state, requestCallback); 

                if (justReturnParsedIp) 
                {
                    IPHostEntry hostEntry = GetUnresolveAnswer(address);
                    asyncResult.StartPostingAsyncOp(false);
                    asyncResult.InvokeCallback(hostEntry); 
                    asyncResult.FinishPostingAsyncOp();
                    return asyncResult; 
                } 
            }
            else 
            {
                asyncResult = new ResolveAsyncResult(hostName, null, includeIPv6, state, requestCallback);
            }
 
            // Set up the context, possibly flow.
            if (flowContext) 
            { 
                asyncResult.StartPostingAsyncOp(false);
            } 

            // Start the resolve.
            ThreadPool.UnsafeQueueUserWorkItem(resolveCallback, asyncResult);
 
            // Finish the flowing, maybe it completed?  This does nothing if we didn't initiate the flowing above.
            asyncResult.FinishPostingAsyncOp(); 
            return asyncResult; 
        }
 

        private static IAsyncResult HostResolutionBeginHelper(IPAddress address, bool flowContext, bool includeIPv6, AsyncCallback requestCallback, object state)
        {
            // 
            // demand Unrestricted DnsPermission for this call
            // 
 
            s_DnsPermission.Demand();
 
            if (address == null) {
                throw new ArgumentNullException("address");
            }
 
            if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
            { 
                throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "address"); 
            }
 
            GlobalLog.Print("Dns.HostResolutionBeginHelper: " + address);

            // Set up the context, possibly flow.
            ResolveAsyncResult asyncResult = new ResolveAsyncResult(address, null, includeIPv6, state, requestCallback); 
            if (flowContext)
            { 
                asyncResult.StartPostingAsyncOp(false); 
            }
 
            // Start the resolve.
            ThreadPool.UnsafeQueueUserWorkItem(resolveCallback, asyncResult);

            // Finish the flowing, maybe it completed?  This does nothing if we didn't initiate the flowing above. 
            asyncResult.FinishPostingAsyncOp();
            return asyncResult; 
        } 

 
        private static IPHostEntry HostResolutionEndHelper(IAsyncResult asyncResult)
        {
            //
            // parameter validation 
            //
            if (asyncResult == null) { 
                throw new ArgumentNullException("asyncResult"); 
            }
            ResolveAsyncResult castedResult = asyncResult as ResolveAsyncResult; 
            if (castedResult == null)
            {
                throw new ArgumentException(SR.GetString(SR.net_io_invalidasyncresult), "asyncResult");
            } 
            if (castedResult.EndCalled)
            { 
                throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndResolve")); 
            }
 
            GlobalLog.Print("Dns.HostResolutionEndHelper");

            castedResult.InternalWaitForCompletion();
            castedResult.EndCalled = true; 

            Exception exception = castedResult.Result as Exception; 
            if (exception != null) 
            {
                throw exception; 
            }

            return (IPHostEntry) castedResult.Result;
        } 

        ///  
        ///    [To be supplied.] 
        /// 
        [HostProtection(ExternalThreading=true)] 
        [Obsolete("BeginGetHostByName is obsoleted for this type, please use BeginGetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IAsyncResult BeginGetHostByName(string hostName, AsyncCallback requestCallback, object stateObject) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginGetHostByName", hostName);
 
            IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, true, true, false, false, requestCallback, stateObject);
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginGetHostByName", asyncResult); 
            return asyncResult;
        } // BeginGetHostByName 

        /// 
        ///    [To be supplied.]
        ///  

 
        [Obsolete("EndGetHostByName is obsoleted for this type, please use EndGetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")] 
        public static IPHostEntry EndGetHostByName(IAsyncResult asyncResult) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndGetHostByName", asyncResult); 

            IPHostEntry ipHostEntry = HostResolutionEndHelper(asyncResult);

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndGetHostByName", ipHostEntry); 
            return ipHostEntry;
        } // EndGetHostByName() 
 

 
        //************************************************************************
        //*************   New Whidbey Apis  *************************************
        //***********************************************************************
 

 
        public static IPHostEntry GetHostEntry(string hostNameOrAddress) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostEntry", hostNameOrAddress);
            // 
            // demand Unrestricted DnsPermission for this call
            //
            s_DnsPermission.Demand();
 
            if (hostNameOrAddress == null) {
                throw new ArgumentNullException("hostNameOrAddress"); 
            } 

            // See if it's an IP Address. 
            IPAddress address;
            IPHostEntry ipHostEntry;
            if (IPAddress.TryParse(hostNameOrAddress, out address))
            { 
                if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
                { 
                    throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "hostNameOrAddress"); 
                }
 
                ipHostEntry = InternalGetHostByAddress(address, true);
            }
            else
            { 
                ipHostEntry = InternalGetHostByName(hostNameOrAddress, true);
            } 
 
            if (Logging.On) Logging.Exit(Logging.Sockets, "DNS", "GetHostEntry", ipHostEntry);
            return ipHostEntry; 
        }


        public static IPHostEntry GetHostEntry(IPAddress address) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostEntry", "");
 
            // 
            // demand Unrestricted DnsPermission for this call
            // 
            s_DnsPermission.Demand();

            if (address == null) {
                throw new ArgumentNullException("address"); 
            }
 
            if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any)) 
            {
                throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "address"); 
            }

            IPHostEntry ipHostEntry = InternalGetHostByAddress(address, true);
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostEntry", ipHostEntry); 
            return ipHostEntry;
        } // GetHostByAddress 
 

 
        public static IPAddress[] GetHostAddresses(string hostNameOrAddress) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "GetHostAddresses", hostNameOrAddress);
            //
            // demand Unrestricted DnsPermission for this call 
            //
            s_DnsPermission.Demand(); 
 
            if (hostNameOrAddress == null) {
                throw new ArgumentNullException("hostNameOrAddress"); 
            }

            // See if it's an IP Address.
            IPAddress address; 
            IPAddress[] addresses;
            if (IPAddress.TryParse(hostNameOrAddress, out address)) 
            { 
                if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
                { 
                    throw new ArgumentException(SR.GetString(SR.net_invalid_ip_addr), "hostNameOrAddress");
                }
                addresses = new IPAddress[] { address };
            } 
            else
            { 
                // InternalGetHostByName works with IP addresses (and avoids a reverse-lookup), but we need 
                // explicit handling in order to do the ArgumentException and guarantee the behavior.
                addresses = InternalGetHostByName(hostNameOrAddress, true).AddressList; 
            }

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "GetHostAddresses", addresses);
            return addresses; 
        }
 
 
        [HostProtection(ExternalThreading=true)]
        public static IAsyncResult BeginGetHostEntry(string hostNameOrAddress, AsyncCallback requestCallback, object stateObject) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginGetHostEntry", hostNameOrAddress);

            IAsyncResult asyncResult = HostResolutionBeginHelper(hostNameOrAddress, false, true, true, true, requestCallback, stateObject);
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginGetHostEntry", asyncResult);
            return asyncResult; 
        } // BeginResolve 

 

        [HostProtection(ExternalThreading=true)]
        public static IAsyncResult BeginGetHostEntry(IPAddress address, AsyncCallback requestCallback, object stateObject) {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginGetHostEntry", address); 

            IAsyncResult asyncResult = HostResolutionBeginHelper(address, true, true, requestCallback, stateObject); 
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginGetHostEntry", asyncResult);
            return asyncResult; 
        } // BeginResolve


        public static IPHostEntry EndGetHostEntry(IAsyncResult asyncResult) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndGetHostEntry", asyncResult);
 
            IPHostEntry ipHostEntry = HostResolutionEndHelper(asyncResult); 

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndGetHostEntry", ipHostEntry); 
            return ipHostEntry;
        } // EndResolve()

 
        [HostProtection(ExternalThreading=true)]
        public static IAsyncResult BeginGetHostAddresses(string hostNameOrAddress, AsyncCallback requestCallback, object state) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginGetHostAddresses", hostNameOrAddress); 

            IAsyncResult asyncResult = HostResolutionBeginHelper(hostNameOrAddress, true, true, true, true, requestCallback, state); 

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginGetHostAddresses", asyncResult);
            return asyncResult;
        } // BeginResolve 

 
        public static IPAddress[] EndGetHostAddresses(IAsyncResult asyncResult) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndGetHostAddresses", asyncResult);
 
            IPHostEntry ipHostEntry = HostResolutionEndHelper(asyncResult);

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndGetHostAddresses", ipHostEntry);
            return ipHostEntry.AddressList; 
        } // EndResolveToAddresses
 
 
        internal static IAsyncResult UnsafeBeginGetHostAddresses(string hostName, AsyncCallback requestCallback, object state)
        { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "UnsafeBeginGetHostAddresses", hostName);

            IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, true, false, true, true, requestCallback, state);
 
            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "UnsafeBeginGetHostAddresses", asyncResult);
            return asyncResult; 
        } // UnsafeBeginResolveToAddresses 

 
        /// 
        ///    [To be supplied.]
        /// 
        [HostProtection(ExternalThreading=true)] 
        [Obsolete("BeginResolve is obsoleted for this type, please use BeginGetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IAsyncResult BeginResolve(string hostName, AsyncCallback requestCallback, object stateObject) 
        { 
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "BeginResolve", hostName);
 
            IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, false, true, false, false, requestCallback, stateObject);

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "BeginResolve", asyncResult);
            return asyncResult; 
        } // BeginResolve
 
 
        [Obsolete("EndResolve is obsoleted for this type, please use EndGetHostEntry instead. http://go.microsoft.com/fwlink/?linkid=14202")]
        public static IPHostEntry EndResolve(IAsyncResult asyncResult) 
        {
            if(Logging.On)Logging.Enter(Logging.Sockets, "DNS", "EndResolve", asyncResult);

            IPHostEntry ipHostEntry; 

            try 
            { 
                ipHostEntry = HostResolutionEndHelper(asyncResult);
            } 
            catch (SocketException ex)
            {
                IPAddress address = ((ResolveAsyncResult)asyncResult).address;
                if (address == null) 
                    throw; // BeginResolve was called with a HostName, not an IPAddress
 
                if (Logging.On) Logging.PrintWarning(Logging.Sockets, "DNS", "DNS.EndResolve", ex.Message); 

                ipHostEntry = GetUnresolveAnswer(address); 
            }

            if(Logging.On)Logging.Exit(Logging.Sockets, "DNS", "EndResolve", ipHostEntry);
            return ipHostEntry; 
        } // EndResolve()
 
        private unsafe static IPHostEntry GetAddrInfo(string name) { 
            IPHostEntry hostEntry;
            SocketError errorCode = TryGetAddrInfo(name, out hostEntry); 
            if (errorCode != SocketError.Success) {
                throw new SocketException(errorCode);
            }
            return hostEntry; 
        }
 
        // 
        // IPv6 Changes: Add getaddrinfo and getnameinfo methods.
        // 
        private unsafe static SocketError TryGetAddrInfo(string name, out IPHostEntry hostinfo)
        {
            //
            // Use SocketException here to show operation not supported 
            // if, by some nefarious means, this method is called on an
            // unsupported platform. 
            // 
#if FEATURE_PAL
            throw new SocketException(SocketError.OperationNotSupported); 
#else
            if ( !ComNetOS.IsPostWin2K ) {
                throw new SocketException(SocketError.OperationNotSupported);
            } 

            SafeFreeAddrInfo root = null; 
            ArrayList addresses = new ArrayList(); 
            string canonicalname = null;
 
            AddressInfo hints = new AddressInfo();
            hints.ai_flags = AddressInfoHints.AI_CANONNAME;// gets the resolved name
            hints.ai_family = AddressFamily.Unspecified;   // gets all address families
            // 
            // 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 = new IPHostEntry();
                    hostinfo.HostName = name;
                    hostinfo.Aliases = new string[0];
                    hostinfo.AddressList = new IPAddress[0]; 
                    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 = new string(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 && Socket.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.m_Buffer[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)IPEndPoint.Any.Create(sockaddr)).Address ); 
                        }
                        else { 
                            addresses.Add( ((IPEndPoint)IPEndPoint.IPv6Any.Create(sockaddr)).Address );
                        }
                    }
                    // 
                    // Next addressinfo entry
                    // 
                    pAddressInfo = pAddressInfo->ai_next; 
                }
            } 
            finally {
                if (root != null) {
                    root.Close();
                } 
            }
 
            // 
            // Finally, put together the IPHostEntry
            // 
            hostinfo = new IPHostEntry();

            hostinfo.HostName = canonicalname!=null ? canonicalname : name;
            hostinfo.Aliases = new string[0]; 
            hostinfo.AddressList = new IPAddress[addresses.Count];
            addresses.CopyTo(hostinfo.AddressList); 
 
            return SocketError.Success;
#endif // FEATURE_PAL 
        }

        internal static string TryGetNameInfo(IPAddress addr, out SocketError errorCode) {
            // 
            // Use SocketException here to show operation not supported
            // if, by some nefarious means, this method is called on an 
            // unsupported platform. 
            //
#if FEATURE_PAL 
            throw new SocketException(SocketError.OperationNotSupported);
#else
            if ( !ComNetOS.IsPostWin2K ) {
                throw new SocketException(SocketError.OperationNotSupported); 
            }
 
            SocketAddress address  = (new IPEndPoint(addr,0)).Serialize(); 
            StringBuilder hostname = new StringBuilder(1025); // NI_MAXHOST
 
            int flags = (int)NameInfoFlags.NI_NAMEREQD;

            Socket.InitializeSockets();
            errorCode = 
                UnsafeNclNativeMethods.OSSOCK.getnameinfo(
                    address.m_Buffer, 
                    address.m_Size, 
                    hostname,
                    hostname.Capacity, 
                    null, // We don't want a service name
                    0, // so no need for buffer or length
                    flags);
 
            if (errorCode!=SocketError.Success) {
                return null; 
            } 

            return hostname.ToString(); 
#endif // FEATURE_PAL
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK