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 }
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); }