예제 #1
0
        private unsafe static SocketError TryGetAddrInfo(string name, AddressInfoHints flags, 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
            SafeFreeAddrInfo root = null;
            ArrayList addresses = new ArrayList();
            string canonicalname = null;

            AddressInfo hints = new AddressInfo();
            hints.ai_flags = flags; 
            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 = Marshal.PtrToStringUni((IntPtr)pAddressInfo->ai_canonname);
                    }
                    //
                    // Only process IPv4 or IPv6 Addresses. Note that it's unlikely that we'll
                    // ever get any other address families, but better to be safe than sorry.
                    // We also filter based on whether IPv6 is supported on the current
                    // platform / machine.
                    //
                    if ( ( pAddressInfo->ai_family == AddressFamily.InterNetwork ) || // Never filter v4
                        (pAddressInfo->ai_family == AddressFamily.InterNetworkV6 && 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
        }
예제 #2
0
        private static unsafe SocketError TryGetAddrInfo(string name, out IPHostEntry hostinfo)
        {
            if (!ComNetOS.IsPostWin2K)
            {
                throw new SocketException(SocketError.OperationNotSupported);
            }
            SafeFreeAddrInfo outAddrInfo = null;
            ArrayList        list        = new ArrayList();
            string           str         = null;
            AddressInfo      hints       = new AddressInfo {
                ai_flags  = AddressInfoHints.AI_CANONNAME,
                ai_family = AddressFamily.Unspecified
            };

            try
            {
                SocketError error = (SocketError)SafeFreeAddrInfo.GetAddrInfo(name, null, ref hints, out outAddrInfo);
                if (error != SocketError.Success)
                {
                    hostinfo             = new IPHostEntry();
                    hostinfo.HostName    = name;
                    hostinfo.Aliases     = new string[0];
                    hostinfo.AddressList = new IPAddress[0];
                    return(error);
                }
                for (AddressInfo *infoPtr = (AddressInfo *)outAddrInfo.DangerousGetHandle(); infoPtr != null; infoPtr = infoPtr->ai_next)
                {
                    if ((str == null) && (infoPtr->ai_canonname != null))
                    {
                        str = new string(infoPtr->ai_canonname);
                    }
                    if ((infoPtr->ai_family == AddressFamily.InterNetwork) || ((infoPtr->ai_family == AddressFamily.InterNetworkV6) && Socket.OSSupportsIPv6))
                    {
                        SocketAddress socketAddress = new SocketAddress(infoPtr->ai_family, infoPtr->ai_addrlen);
                        for (int i = 0; i < infoPtr->ai_addrlen; i++)
                        {
                            socketAddress.m_Buffer[i] = infoPtr->ai_addr[i];
                        }
                        if (infoPtr->ai_family == AddressFamily.InterNetwork)
                        {
                            list.Add(((IPEndPoint)IPEndPoint.Any.Create(socketAddress)).Address);
                        }
                        else
                        {
                            list.Add(((IPEndPoint)IPEndPoint.IPv6Any.Create(socketAddress)).Address);
                        }
                    }
                }
            }
            finally
            {
                if (outAddrInfo != null)
                {
                    outAddrInfo.Close();
                }
            }
            hostinfo             = new IPHostEntry();
            hostinfo.HostName    = (str != null) ? str : name;
            hostinfo.Aliases     = new string[0];
            hostinfo.AddressList = new IPAddress[list.Count];
            list.CopyTo(hostinfo.AddressList);
            return(SocketError.Success);
        }