The
getaddrinfo function provides protocol-independent translation from an ANSI host name to an address.
Syntax
int WSAAPI getaddrinfo(
__in const char *nodename,
__in const char *servname,
__in const struct addrinfo *hints,
__out struct addrinfo **res
);
Parameters
- nodename [in]
-
A pointer to a NULL-terminated ANSI string that contains a host (node) name or a numeric host address string. For the Internet protocol, the numeric host address string is a dotted-decimal IPv4 address or an IPv6 hex address.
- servname [in]
-
A pointer to a NULL-terminated ANSI string that contains either a service name or port number represented as a string.
- hints [in]
-
A pointer to an
addrinfo structure that provides hints about the type of socket the caller supports. See Remarks for more details.
- res [out]
-
A pointer to a linked list of one or more
addrinfo structures that contains response information about the host.
Return Value
Success returns zero. Failure returns a nonzero Windows Sockets error code, as found in the
Windows Sockets Error Codes.
Nonzero error codes returned by the
getaddrinfo function also map to the set of errors outlined by Internet Engineering Task Force (IETF) recommendations. The following table lists these error codes and their WSA equivalents. It is recommended that the WSA error codes be used, as they offer familiar and comprehensive error information for Winsock programmers.
| Error value | WSA equivalent | Description |
| EAI_AGAIN | WSATRY_AGAIN | A temporary failure in name resolution occurred. |
| EAI_BADFLAGS | WSAEINVAL | An invalid value was provided for the ai_flags member of the hints parameter. |
| EAI_FAIL | WSANO_RECOVERY | A nonrecoverable failure in name resolution occurred. |
| EAI_FAMILY | WSAEAFNOSUPPORT | The ai_family member of the hints parameter is not supported. |
| EAI_MEMORY | WSA_NOT_ENOUGH_MEMORY | A memory allocation failure occurred. |
| EAI_NONAME | WSAHOST_NOT_FOUND | The name does not resolve for the supplied parameters or the nodename and servname parameters were not provided. |
| EAI_SERVICE | WSATYPE_NOT_FOUND | The servname parameter is not supported for the specified ai_socktype member of the hints parameter. |
| EAI_SOCKTYPE | WSAESOCKTNOSUPPORT | The ai_socktype member of the hints parameter is not supported. |
Use the
gai_strerror function to print error messages based on the EAI codes returned by the
getaddrinfo function. The
gai_strerror function is provided for compliance with IETF recommendations, but it is not thread safe. Therefore, use of traditional Windows Sockets functions such as
WSAGetLastError is recommended.
Remarks
The getaddrinfo function is the ANSI version of a function that provides protocol-independent translation from host name to address. The getaddrinfo function aggregates all responses if more than
one namespace provider returns information.
For use with the IPv6 and IPv4 protocol, name resolution can be by the Domain Name System (DNS), a local hosts file, or by other naming mechanisms.
Another name that can be used for the getaddrinfo function is GetAddrInfoA. Macros in the Ws2tcpip.h header file define GetAddrInfoA to getaddrinfo.
The Unicode version of this function is GetAddrInfoW.
Macros in the Ws2tcpip.h header file define a mixed-case function name of GetAddrInfo and a ADDRINFOT structure. This GetAddrInfo function should be called with the nodename and servname parameters of a pointer of type TCHAR and the hints and res parameters of a pointer of type ADDRINFOT. When UNICODE or _UNICODE is not defined, GetAddrInfo is defined to getaddrinfo, the ANSI version of the function, and ADDRINFOT is defined to the addrinfo structure. When UNICODE or _UNICODE is defined, GetAddrInfo is defined to GetAddrInfoW, the Unicode version of the function, and ADDRINFOT is defined to the addrinfoW structure.
One or both of the nodename or servname parameters must point to a NULL-terminated ANSI string; generally both are provided.
Upon success, a linked list of
addrinfo structures is returned in the res parameter. The list can be processed by following the pointer provided in the ai_next member of each returned
addrinfo structure until a NULL pointer is encountered. In each returned
addrinfo structure, the ai_family, ai_socktype, and ai_protocol members correspond to respective arguments in a
socket or WSASocket function call. Also, the ai_addr member in each returned
addrinfo structure points to a filled-in socket address structure, the length of which is specified in its ai_addrlen member.
If nodename is a computer name, the permanent addresses for the computer are returned. If nodename contains the string "..localmachine" or "localhost", all registered addresses are returned. If nodename refers to a cluster virtual server name, only virtual server addresses are returned. See Windows Clustering for more information about clustering.
Callers of the
getaddrinfo function can provide hints about the type of socket supported through an
addrinfo structure pointed to by the hints parameter. When the hints parameter is used, the following rules apply to its associated
addrinfo structure:
- A value of AF_UNSPEC for ai_family indicates the caller will accept any protocol family. Note that AF_UNSPEC and PF_UNSPEC are the same.
- A value of zero for ai_socktype indicates the caller will accept any socket type.
- A value of zero for ai_protocol indicates the caller will accept any protocol.
- The ai_addrlen member must be set to zero.
- The ai_canonname member must be set to NULL.
- The ai_addr member must be set to NULL.
- The ai_next member must be set to NULL.
A value of AF_UNSPEC for ai_family indicates the caller will accept any protocol family. This value can be used to return both IPv4 and IPv6 addresses for the host name pointed to by the nodename parameter. On Windows Server 2003 and Windows XP, IPv6 addresses are returned only if IPv6 is installed on the local computer.
Other values in the
addrinfo structure provided in the hints parameter indicate specific requirements. For example, if the caller handles only IPv4 and does not handle IPv6, the ai_family member should be set to AF_INET. For another example, if the caller handles only TCP and does not handle UDP, the ai_socktype member should be set to SOCK_STREAM.
If the hints parameter is a NULL pointer, the
getaddrinfo function treats it as if the
addrinfo structure in hints were initialized with its ai_family member set to AF_UNSPEC and all other members set to zero.
On Windows Vista and later when getaddrinfo is called from a service, if the operation is the result of a user process calling the service, then the service should impersonate the user. This is to allow security to be properly enforced.
The
getaddrinfo function can be used to convert a text string representation of an IP address to an addrinfo
structure that contains a sockaddr structure for the IP address and other information. To be used in this way, the string pointed to by the nodename parameter must contain a text representation of an IP address and the addrinfo
structure pointed to by the hints parameter must have the AI_NUMERICHOST flag set in the ai_flags member. The string pointed to by the nodename parameter may contain a text representation of either an IPv4 or an IPv6 address. The text IP address is converted to an addrinfo
structure pointed to by the res parameter. The returned addrinfo
structure contains a sockaddr structure for the IP address along with addition information about the IP address. For this method to work with an IPv6 address string on Windows Server 2003 and Windows XP, the IPv6 protocol must be installed on the local computer. Otherwise, the WSAHOST_NOT_FOUND error is returned.
Freeing Address Information from Dynamic Allocation
All information returned by the
getaddrinfo function pointed to by the res parameter is dynamically allocated, including all
addrinfo structures, socket address structures, and canonical host name strings pointed to by
addrinfo structures. Memory allocated by a successful call to this function must be released with a subsequent call to freeaddrinfo.
Example Code
The following code example shows how to use the getaddrinfo function.
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// link with Ws2_32.lib
int __cdecl main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
DWORD dwRetval;
int i = 1;
char *port = "27015";
struct addrinfo *result = NULL;
struct addrinfo *ptr = NULL;
struct addrinfo hints;
// Validate the parameters
if (argc != 2) {
printf("usage: %s <hostname>\n", argv[0]);
printf(" getaddrinfo provides protocol-independent translation\n");
printf( " from an ANSI host name to an IP address\n");
printf(" %s www.contoso.com\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
//--------------------------------
// Setup the hints address info structure
// which is passed to the getaddrinfo() function
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
dwRetval = getaddrinfo(argv[1], port, &hints, &result);
if ( dwRetval != 0 ) {
printf("getaddrinfo failed with error: %d\n", dwRetval);
WSACleanup();
return 1;
}
printf("getaddrinfo returned success\n");
// Retrieve each address and print out the hex bytes
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
printf("getaddrinfo response %d\n", i++);
printf("\tFlags: 0x%x\n", ptr->ai_flags);
printf("\tFamily: ");
switch (ptr->ai_family) {
case AF_UNSPEC:
printf("Unspecified\n");
break;
case AF_INET:
printf("AF_INET (IPv4)\n");
break;
case AF_INET6:
printf("AF_INET6 (IPv6)\n");
break;
case AF_NETBIOS:
printf("AF_NETBIOS (NetBIOS)\n");
break;
default:
printf("Other %ld\n", ptr->ai_family);
break;
}
printf("\tSocket type: ");
switch (ptr->ai_socktype) {
case 0:
printf("Unspecified\n");
break;
case SOCK_STREAM:
printf("SOCK_STREAM (stream)\n");
break;
case SOCK_DGRAM:
printf("SOCK_DGRAM (datagram) \n");
break;
case SOCK_RAW:
printf("SOCK_RAW (raw) \n");
break;
case SOCK_RDM:
printf("SOCK_RDM (reliable message datagram)\n");
break;
case SOCK_SEQPACKET:
printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
break;
default:
printf("Other %ld\n", ptr->ai_socktype);
break;
}
printf("\tProtocol: ");
switch (ptr->ai_protocol) {
case 0:
printf("Unspecified\n");
break;
case IPPROTO_TCP:
printf("IPPROTO_TCP (TCP)\n");
break;
case IPPROTO_UDP:
printf("IPPROTO_UDP (UDP) \n");
break;
default:
printf("Other %ld\n", ptr->ai_protocol);
break;
}
printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
printf("\tCanonical name: %s\n", ptr->ai_canonname);
}
freeaddrinfo(result);
WSACleanup();
return 0;
}
Note Ensure that the development environment targets the newest version of Ws2tcpip.h which includes structure and function definitions for addrinfo and getaddrinfo, respectively.
International Resource Identifiers
Web addresses are typically expressed using uniform resource identifiers (URIs) that consist of a very restricted set of characters:
- Upper and lower case ASCII letters from the English alphabet.
- Digits from 0 to 9.
- A small number of other ASCII symbols.
The specifications for URIs are documented in RFC 2396 and RFC 3986 published by the Internet Engineering Task Force (IETF).
With the growth of the Internet, there is a growing need to identify resources using languages other than English. Identifiers which facilitate this need and allow non-ASCII characters (characters in the Unicode/ISO 10646 character set) are known as International Resource Identifiers (IRIs). The specifications for IRIs are documented in RFC 3987 published by IETF. Using IRIs allows a URL to contain Unicode characters.
The existing getaddrinfo function does not currently provide support for IRI or Internationalized Domain Name (IDN) parsing applied to the name passed in the nodename parameter. Winsock does not perform any punycode/IDN conversion for any version of Windows including Windows 7. The GetAddrInfoW function queries for the Unicode name in the UTF-8 format and as per RFC 3490 and does not convert the Unicode name to Punycode.
Several functions on Windows Vista and later support the conversion between Unicode labels in a domain name that represent International Domain Names to their Punycode equivalents. Punycode names contain only ASCII characters and always start with the xn-- prefix. The reason for this is to support existing DNS servers on the Internet, since most DNS servers only support ASCII characters (see RFC 3940).
The IdnToAscii function converts an internationalized domain name or other internationalized label to a wide character representation of the ASCII string that represents the name in the Punycode transfer encoding syntax. The IdnToUnicode function converts the Punycode form of an internationalized domain name or another internationalized label to the normal Unicode UTF-16 encoding syntax. For more information and links to related draft standards, see Handling Internationalized Domain Names (IDNs).
The IdnToAscii function can be used to convert an IDN name to a wide character Punycode form that then can be passed in the pNodeName parameter to the GetAddrInfoW function. The IdnToAscii function can also be used to convert an IDN name to a Punycode form that can then be passed in the pName parameter to the GetAddrInfoEx function and the nodename parameter to the getaddrinfo when the wide chartacter versions of these functions are used (when UNICODE or _UNICODE is defined).
Use of ai_flags in the hints parameter
Flags in the ai_flags member of the optional
addrinfo structure provided in the hints parameter modify the behavior of the function.
These flag bits are defined in the Ws2def.h header file on the Microsoft Windows Software Development Kit (SDK) for Windows 7. These flag bits are defined in the Ws2tcpip.h header file on the Windows SDK for Windows Server 2008 and Windows Vista. These flag bits are defined in the Ws2tcpip.h header file on the Platform Software Development Kit (SDK) for Windows Server 2003, and Windows XP.
The flag bits can be a combination of the following:
| Flag Bits | Description |
|---|
AI_PASSIVE | Setting the AI_PASSIVE flag indicates the caller intends to use the returned socket address structure in a call to the
bind function. When the AI_PASSIVE flag is set and nodename is a NULL pointer, the IP address portion of the socket address structure is set to INADDR_ANY for IPv4 addresses and IN6ADDR_ANY_INIT for IPv6 addresses.
When the AI_PASSIVE flag is not set, the returned socket address structure is ready for a call to the
connect function for a connection-oriented protocol, or ready for a call to either the
connect,
sendto, or
send functions for a connectionless protocol. If the nodename parameter is a NULL pointer in this case, the IP address portion of the socket address structure is set to the loopback address.
|
AI_CANONNAME | If neither AI_CANONNAME nor AI_NUMERICHOST is used, the
getaddrinfo function attempts resolution. If a literal string is passed
getaddrinfo attempts to convert the string, and if a host name is passed the
getaddrinfo function attempts to resolve the name to an address or multiple addresses.
When the AI_CANONNAME bit is set and the
getaddrinfo function returns success, the ai_canonname member in the res parameter points to a NULL-terminated string that contains the canonical name of the specified node.
Note The getaddrinfo function can return success when the AI_CANONNAME flag is set, yet the ai_canonname member in the associated
addrinfo structure is NULL. Therefore, the recommended use of the AI_CANONNAME flag includes testing whether the ai_canonname member in the associated
addrinfo structure is NULL.
|
AI_NUMERICHOST | When the AI_NUMERICHOST bit is set, the nodename parameter must contain a non-NULL numeric host address string, otherwise the EAI_NONAME error is returned. This flag prevents a name resolution service from being called.
|
AI_NUMERICSERV | When the AI_NUMERICSERV bit is set, the servname parameter must contain a non-NULL numeric port number, otherwise the EAI_NONAME error is returned. This flag prevents a name resolution service from being called.
The AI_NUMERICSERV flag is defined on Windows SDK for Windows Vista and later. The AI_NUMERICSERV flag is not supported by Microsoft providers.
|
AI_ALL | If the AI_ALL bit is set, a request is made for IPv6 addresses and IPv4 addressses with AI_V4MAPPED.
The AI_ALL flag is defined on the Windows SDK for Windows Vista and later. The AI_ALL flag is supported on Windows Vista and later.
|
AI_ADDRCONFIG | If the AI_ADDRCONFIG bit is set, getaddrinfo will resolve only if a global address is configured. If AI_ADDRCONFIG flag is specified, IPv4 addresses shall be
returned only if an IPv4 address is configured on the local system,
and IPv6 addresses shall be returned only if an IPv6 address is
configured on the local system. The IPv4 or IPv6 loopback address is not
considered a valid global address.
The AI_ADDRCONFIG flag is defined on the Windows SDK for Windows Vista and later. The AI_ADDRCONFIG flag is supported on Windows Vista and later.
|
AI_V4MAPPED | If the AI_V4MAPPED bit is set and a request for IPv6 addresses fails, a name service request is made for IPv4 addresses and these addresses are converted to IPv4-mapped IPv6 address format.
The AI_V4MAPPED flag is defined on the Windows SDK for Windows Vista and later. The AI_V4MAPPED flag is supported on Windows Vista and later.
|
AI_NON_AUTHORITATIVE | If the AI_NON_AUTHORITATIVE bit is set, the NS_EMAIL namespace provider returns both authoritative and non-authoritative results. If the AI_NON_AUTHORITATIVE bit is not set, the NS_EMAIL namespace provider returns only authoritative results.
The AI_NON_AUTHORITATIVE flag is defined on the Windows SDK for Windows Vista and later. The AI_NON_AUTHORITATIVE flag is supported on Windows Vista and later and applies only to the NS_EMAIL namespace.
|
AI_SECURE | If the AI_SECURE bit is set, the NS_EMAIL namespace provider will return results that were obtained with enhanced security to minimize possible spoofing.
The AI_SECURE flag is defined on the Windows SDK for Windows Vista and later. The AI_SECURE flag is supported on Windows Vista and later and applies only to the NS_EMAIL namespace.
|
AI_RETURN_PREFERRED_NAMES | If the AI_RETURN_PREFERRED_NAMES is set, then no name should be provided in the nodename parameter. The NS_EMAIL namespace provider will return preferred names for publication.
The AI_RETURN_PREFERRED_NAMES flag is defined on the Windows SDK for Windows Vista and later. The AI_RETURN_PREFERRED_NAMES flag is supported on Windows Vista and later and applies only to the NS_EMAIL namespace.
|
AI_FQDN | If the AI_FQDN is set and a flat name (single label) is specified, getaddrinfo will return the fully qualified domain name that the name eventually resolved to. The fully qualified domain name is returned in the ai_canonname member in the associated
addrinfo structure. This is different than AI_CANONNAME bit flag that returns the canonical name registered in DNS which may be different than the fully qualified domain name that the flat name resolved to. Only one of the AI_FQDN and AI_CANONNAME bits can be set. The getaddrinfo function will fail if both flags are present with EAI_BADFLAGS.
Windows 7: The AI_FQDN flag is defined on the Windows SDK for Windows 7 and later. The AI_FQDN flag is supported on Windows 7 and later.
|
AI_FILESERVER | If the AI_FILESERVER is set, this is a hint to the namespace provider that the hostname being queried is being used in file share scenario. The namespace provider may ignore this hint.
Windows 7: The AI_FILESERVER flag is defined on the Windows SDK for Windows 7 and later. The AI_FQDN flag is supported on Windows 7 and later.
|
Example code using AI_NUMERICHOST
The following code example shows how to use the getaddrinfo function to convert a text string representation of an IP address to an addrinfo
structure that contains a sockaddr structure for the IP address and other information.
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// link with Ws2_32.lib
int __cdecl main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
DWORD dwRetval;
int i = 1;
struct addrinfo *result = NULL;
struct addrinfo *ptr = NULL;
struct addrinfo hints;
// Validate the parameters
if (argc != 2) {
printf("usage: %s <IP Address String>\n", argv[0]);
printf(" getaddrinfo determines the IP binary network address\n");
printf(" %s 207.46.197.32\n", argv[0]); /* www.contoso.com */
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
//--------------------------------
// Setup the hints address info structure
// which is passed to the getaddrinfo() function
ZeroMemory( &hints, sizeof(hints) );
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
// hints.ai_socktype = SOCK_STREAM;
// hints.ai_protocol = IPPROTO_TCP;
//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
dwRetval = getaddrinfo(argv[1], NULL, &hints, &result);
if ( dwRetval != 0 ) {
printf("getaddrinfo failed with error: %d\n", dwRetval);
WSACleanup();
return 1;
}
printf("getaddrinfo returned success\n");
// Retrieve each address and print out the hex bytes
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
printf("getaddrinfo response %d\n", i++);
printf("\tFlags: 0x%x\n", ptr->ai_flags);
printf("\tFamily: ");
switch (ptr->ai_family) {
case AF_UNSPEC:
printf("Unspecified\n");
break;
case AF_INET:
printf("AF_INET (IPv4)\n");
break;
case AF_INET6:
printf("AF_INET6 (IPv6)\n");
break;
case AF_NETBIOS:
printf("AF_NETBIOS (NetBIOS)\n");
break;
default:
printf("Other %ld\n", ptr->ai_family);
break;
}
printf("\tSocket type: ");
switch (ptr->ai_socktype) {
case 0:
printf("Unspecified\n");
break;
case SOCK_STREAM:
printf("SOCK_STREAM (stream)\n");
break;
case SOCK_DGRAM:
printf("SOCK_DGRAM (datagram) \n");
break;
case SOCK_RAW:
printf("SOCK_RAW (raw) \n");
break;
case SOCK_RDM:
printf("SOCK_RDM (reliable message datagram)\n");
break;
case SOCK_SEQPACKET:
printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
break;
default:
printf("Other %ld\n", ptr->ai_socktype);
break;
}
printf("\tProtocol: ");
switch (ptr->ai_protocol) {
case 0:
printf("Unspecified\n");
break;
case IPPROTO_TCP:
printf("IPPROTO_TCP (TCP)\n");
break;
case IPPROTO_UDP:
printf("IPPROTO_UDP (UDP) \n");
break;
default:
printf("Other %ld\n", ptr->ai_protocol);
break;
}
printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
printf("\tCanonical name: %s\n", ptr->ai_canonname);
}
freeaddrinfo(result);
WSACleanup();
return 0;
}
Support for getaddrinfo on older versions of Windows
The getaddrinfo function was added to the Ws2_32.dll on Windows XP and later. To execute an application that uses this function on earlier versions of Windows, then you need to include the Ws2tcpip.h and Wspiapi.h files. When the Wspiapi.h include file is added, the getaddrinfo function is defined to the WspiapiGetAddrInfo inline function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo function is implemented in such a way that if the Ws2_32.dll or the Wship6.dll (the file containing getaddrinfo in the IPv6 Technology Preview for Windows 2000) does not include getaddrinfo, then a version of getaddrinfo is implemented inline based on code in the Wspiapi.h header file. This inline code will be used on older Windows platforms that do not natively support the getaddrinfo function.
The IPv6 protocol is supported on Windows 2000 when the IPv6 Technology Preview for Windows 2000 is installed. Otherwise getaddrinfo support on versions of Windows earlier than Windows XP is limited to handling IPv4 name resolution.
The GetAddrInfoW function is the Unicode version of getaddrinfo. The GetAddrInfoW function was added to the Ws2_32.dll in Windows XP with Service Pack 2 (SP2). The GetAddrInfoW function cannot be used on versions of Windows earlier than Windows XP with SP2.
Requirements
| Minimum supported client | Windows 2000 Professional |
| Minimum supported server | Windows 2000 Server |
| Header | Ws2tcpip.h, Ws2tcpip.h on Windows 2000 (include Wspiapi.h) |
| Library | Ws2_32.lib |
| DLL | Ws2_32.dll |
See Also
- addrinfo
- addrinfoW
- bind
- connect
- freeaddrinfo
- gai_strerror
- GetAddrInfoW
- IdnToAscii
- IdnToUnicode
- send
- sendto
- socket
- Winsock Functions
- Winsock Reference
- WSAGetLastError
- WSASocket
Send comments about this topic to Microsoft
Build date: 10/29/2009