# getaddrinfo

## NAME



           getaddrinfo, freeaddrinfo, gai_strerror - network address and
           service translation
    


## LIBRARY



           Standard C library (_libc_ , _-lc_)
    


## SYNOPSIS



           **#include <sys/types.h>**
           **#include <sys/socket.h>**
           **#include <netdb.h>**
    
           **int getaddrinfo(const char *restrict** _node_**,**
                           **const char *restrict** _service_**,**
                           **const struct addrinfo *restrict** _hints_**,**
                           **struct addrinfo **restrict** _res_**);**
    
           **void freeaddrinfo(struct addrinfo ***_res_**);**
    
           **const char *gai_strerror(int** _errcode_**);**
    
       Feature Test Macro Requirements for glibc (see
       feature_test_macros(7)):
    
           **getaddrinfo**(), **freeaddrinfo**(), **gai_strerror**():
               Since glibc 2.22:
                   _POSIX_C_SOURCE >= 200112L
               glibc 2.21 and earlier:
                   _POSIX_C_SOURCE
    


## DESCRIPTION



           Given _node_ and _service_ , which identify an Internet host and a
           service, **getaddrinfo**() returns one or more _addrinfo_ structures,
           each of which contains an Internet address that can be specified
           in a call to bind(2) or connect(2).  The **getaddrinfo**() function
           combines the functionality provided by the gethostbyname(3) and
           getservbyname(3) functions into a single interface, but unlike the
           latter functions, **getaddrinfo**() is reentrant and allows programs
           to eliminate IPv4-versus-IPv6 dependencies.
    
           The _addrinfo_ structure used by **getaddrinfo**() contains the
           following fields:
    
               struct addrinfo {
                   int              ai_flags;
                   int              ai_family;
                   int              ai_socktype;
                   int              ai_protocol;
                   socklen_t        ai_addrlen;
                   struct sockaddr *ai_addr;
                   char            *ai_canonname;
                   struct addrinfo *ai_next;
               };
    
           The _hints_ argument points to an _addrinfo_ structure that specifies
           criteria for selecting the socket address structures returned in
           the list pointed to by _res_.  If _hints_ is not NULL it points to an
           _addrinfo_ structure whose _ai_family_ , _ai_socktype_ , and _ai_protocol_
           specify criteria that limit the set of socket addresses returned
           by **getaddrinfo**(), as follows:
    
           _ai_family_
                  This field specifies the desired address family for the
                  returned addresses.  Valid values for this field include
                  **AF_INET** and **AF_INET6**.  The value **AF_UNSPEC** indicates that
                  **getaddrinfo**() should return socket addresses for any
                  address family (either IPv4 or IPv6, for example) that can
                  be used with _node_ and _service_.
    
           _ai_socktype_
                  This field specifies the preferred socket type, for example
                  **SOCK_STREAM** or **SOCK_DGRAM**.  Specifying 0 in this field
                  indicates that socket addresses of any type can be returned
                  by **getaddrinfo**().
    
           _ai_protocol_
                  This field specifies the protocol for the returned socket
                  addresses.  Specifying 0 in this field indicates that
                  socket addresses with any protocol can be returned by
                  **getaddrinfo**().
    
           _ai_flags_
                  This field specifies additional options, described below.
                  Multiple flags are specified by bitwise OR-ing them
                  together.
    
           All the other fields in the structure pointed to by _hints_ must
           contain either 0 or a null pointer, as appropriate.
    
           Specifying _hints_ as NULL is equivalent to setting _ai_socktype_ and
           _ai_protocol_ to 0; _ai_family_ to **AF_UNSPEC** ; and _ai_flags_ to
           **(AI_V4MAPPED | AI_ADDRCONFIG)**.  (POSIX specifies different
           defaults for _ai_flags_ ; see NOTES.)  _node_ specifies either a
           numerical network address (for IPv4, numbers-and-dots notation as
           supported by inet_aton(3); for IPv6, hexadecimal string format as
           supported by inet_pton(3)), or a network hostname, whose network
           addresses are looked up and resolved.  If _hints.ai_flags_ contains
           the **AI_NUMERICHOST** flag, then _node_ must be a numerical network
           address.  The **AI_NUMERICHOST** flag suppresses any potentially
           lengthy network host address lookups.
    
           If the **AI_PASSIVE** flag is specified in _hints.ai_flags_ , and _node_ is
           NULL, then the returned socket addresses will be suitable for
           bind(2)ing a socket that will accept(2) connections.  The returned
           socket address will contain the "wildcard address" (**INADDR_ANY** for
           IPv4 addresses, **IN6ADDR_ANY_INIT** for IPv6 address).  The wildcard
           address is used by applications (typically servers) that intend to
           accept connections on any of the host's network addresses.  If
           _node_ is not NULL, then the **AI_PASSIVE** flag is ignored.
    
           If the **AI_PASSIVE** flag is not set in _hints.ai_flags_ , then the
           returned socket addresses will be suitable for use with
           connect(2), sendto(2), or sendmsg(2).  If _node_ is NULL, then the
           network address will be set to the loopback interface address
           (**INADDR_LOOPBACK** for IPv4 addresses, **IN6ADDR_LOOPBACK_INIT** for
           IPv6 address); this is used by applications that intend to
           communicate with peers running on the same host.
    
           _service_ sets the port in each returned address structure.  If this
           argument is a service name (see services(5)), it is translated to
           the corresponding port number.  This argument can also be
           specified as a decimal number, which is simply converted to
           binary.  If _service_ is NULL, then the port number of the returned
           socket addresses will be left uninitialized.  If **AI_NUMERICSERV** is
           specified in _hints.ai_flags_ and _service_ is not NULL, then _service_
           must point to a string containing a numeric port number.  This
           flag is used to inhibit the invocation of a name resolution
           service in cases where it is known not to be required.
    
           Either _node_ or _service_ , but not both, may be NULL.
    
           The **getaddrinfo**() function allocates and initializes a linked list
           of _addrinfo_ structures, one for each network address that matches
           _node_ and _service_ , subject to any restrictions imposed by _hints_ ,
           and returns a pointer to the start of the list in _res_.  The items
           in the linked list are linked by the _ai_next_ field.
    
           There are several reasons why the linked list may have more than
           one _addrinfo_ structure, including: the network host is multihomed,
           accessible over multiple protocols (e.g., both **AF_INET** and
           **AF_INET6**); or the same service is available from multiple socket
           types (one **SOCK_STREAM** address and another **SOCK_DGRAM** address, for
           example).  Normally, the application should try using the
           addresses in the order in which they are returned.  The sorting
           function used within **getaddrinfo**() is defined in RFC 3484; the
           order can be tweaked for a particular system by editing
           _/etc/gai.conf_ (available since glibc 2.5).
    
           If _hints.ai_flags_ includes the **AI_CANONNAME** flag, then the
           _ai_canonname_ field of the first of the _addrinfo_ structures in the
           returned list is set to point to the official name of the host.
    
           The remaining fields of each returned _addrinfo_ structure are
           initialized as follows:
    
           •  The _ai_family_ , _ai_socktype_ , and _ai_protocol_ fields return the
              socket creation parameters (i.e., these fields have the same
              meaning as the corresponding arguments of socket(2)).  For
              example, _ai_family_ might return **AF_INET** or **AF_INET6** ;
              _ai_socktype_ might return **SOCK_DGRAM** or **SOCK_STREAM** ; and
              _ai_protocol_ returns the protocol for the socket.
    
           •  A pointer to the socket address is placed in the _ai_addr_ field,
              and the size of the socket address, in bytes, is placed in the
              _ai_addrlen_ field.
    
           If _hints.ai_flags_ includes the **AI_ADDRCONFIG** flag, then IPv4
           addresses are returned in the list pointed to by _res_ only if the
           local system has at least one IPv4 address configured, and IPv6
           addresses are returned only if the local system has at least one
           IPv6 address configured.  The loopback address is not considered
           for this case as valid as a configured address.  This flag is
           useful on, for example, IPv4-only systems, to ensure that
           **getaddrinfo**() does not return IPv6 socket addresses that would
           always fail in connect(2) or bind(2).
    
           If _hints.ai_flags_ specifies the **AI_V4MAPPED** flag, and
           _hints.ai_family_ was specified as **AF_INET6** , and no matching IPv6
           addresses could be found, then return IPv4-mapped IPv6 addresses
           in the list pointed to by _res_.  If both **AI_V4MAPPED** and **AI_ALL** are
           specified in _hints.ai_flags_ , then return both IPv6 and IPv4-mapped
           IPv6 addresses in the list pointed to by _res_.  **AI_ALL** is ignored
           if **AI_V4MAPPED** is not also specified.
    
           The **freeaddrinfo**() function frees the memory that was allocated
           for the dynamically allocated linked list _res_.
    
       **Extensions to getaddrinfo() for Internationalized Domain Names**
           Starting with glibc 2.3.4, **getaddrinfo**() has been extended to
           selectively allow the incoming and outgoing hostnames to be
           transparently converted to and from the Internationalized Domain
           Name (IDN) format (see RFC 3490, _Internationalizing Domain Names_
           _in Applications (IDNA)_).  Four new flags are defined:
    
           **AI_IDN** If this flag is specified, then the node name given in _node_
                  is converted to IDN format if necessary.  The source
                  encoding is that of the current locale.
    
                  If the input name contains non-ASCII characters, then the
                  IDN encoding is used.  Those parts of the node name
                  (delimited by dots) that contain non-ASCII characters are
                  encoded using ASCII Compatible Encoding (ACE) before being
                  passed to the name resolution functions.
    
           **AI_CANONIDN**
                  After a successful name lookup, and if the **AI_CANONNAME**
                  flag was specified, **getaddrinfo**() will return the canonical
                  name of the node corresponding to the _addrinfo_ structure
                  value passed back.  The return value is an exact copy of
                  the value returned by the name resolution function.
    
                  If the name is encoded using ACE, then it will contain the
                  _xn--_ prefix for one or more components of the name.  To
                  convert these components into a readable form the
                  **AI_CANONIDN** flag can be passed in addition to **AI_CANONNAME**.
                  The resulting string is encoded using the current locale's
                  encoding.
    
           **AI_IDN_ALLOW_UNASSIGNED**
           **AI_IDN_USE_STD3_ASCII_RULES**
                  Setting these flags will enable the IDNA_ALLOW_UNASSIGNED
                  (allow unassigned Unicode code points) and
                  IDNA_USE_STD3_ASCII_RULES (check output to make sure it is
                  a STD3 conforming hostname) flags respectively to be used
                  in the IDNA handling.
    


## RETURN VALUE



           **getaddrinfo**() returns 0 if it succeeds, or one of the following
           nonzero error codes:
    
           **EAI_ADDRFAMILY**
                  The specified network host does not have any network
                  addresses in the requested address family.
    
           **EAI_AGAIN**
                  The name server returned a temporary failure indication.
                  Try again later.
    
           **EAI_BADFLAGS**
                  _hints.ai_flags_ contains invalid flags; or, _hints.ai_flags_
                  included **AI_CANONNAME** and _node_ was NULL.
    
           **EAI_FAIL**
                  The name server returned a permanent failure indication.
    
           **EAI_FAMILY**
                  The requested address family is not supported.
    
           **EAI_MEMORY**
                  Out of memory.
    
           **EAI_NODATA**
                  The specified network host exists, but does not have any
                  network addresses defined.
    
           **EAI_NONAME**
                  The _node_ or _service_ is not known; or both _node_ and _service_
                  are NULL; or **AI_NUMERICSERV** was specified in _hints.ai_flags_
                  and _service_ was not a numeric port-number string.
    
           **EAI_SERVICE**
                  The requested service is not available for the requested
                  socket type.  It may be available through another socket
                  type.  For example, this error could occur if _service_ was
                  "shell" (a service available only on stream sockets), and
                  either _hints.ai_protocol_ was **IPPROTO_UDP** , or
                  _hints.ai_socktype_ was **SOCK_DGRAM** ; or the error could occur
                  if _service_ was not NULL, and _hints.ai_socktype_ was **SOCK_RAW**
                  (a socket type that does not support the concept of
                  services).
    
           **EAI_SOCKTYPE**
                  The requested socket type is not supported.  This could
                  occur, for example, if _hints.ai_socktype_ and
                  _hints.ai_protocol_ are inconsistent (e.g., **SOCK_DGRAM** and
                  **IPPROTO_TCP** , respectively).
    
           **EAI_SYSTEM**
                  Other system error; _errno_ is set to indicate the error.
    
           The **gai_strerror**() function translates these error codes to a
           human readable string, suitable for error reporting.
    


## FILES



           _/etc/gai.conf_
    


## ATTRIBUTES



           For an explanation of the terms used in this section, see
           attributes(7).
           ┌───────────────────────────┬───────────────┬────────────────────┐
           │ **Interface** │ **Attribute** │ **Value** │
           ├───────────────────────────┼───────────────┼────────────────────┤
           │ **getaddrinfo**()             │ Thread safety │ MT-Safe env locale │
           ├───────────────────────────┼───────────────┼────────────────────┤
           │ **freeaddrinfo**(),           │ Thread safety │ MT-Safe            │
           │ **gai_strerror**()            │               │                    │
           └───────────────────────────┴───────────────┴────────────────────┘
    


## VERSIONS



           According to POSIX.1, specifying _hints_ as NULL should cause
           _ai_flags_ to be assumed as 0.  The GNU C library instead assumes a
           value of **(AI_V4MAPPED | AI_ADDRCONFIG)** for this case, since this
           value is considered an improvement on the specification.
    


## STANDARDS



           POSIX.1-2008.
    
           **getaddrinfo**()
                  RFC 2553.
    


## NOTES



           **getaddrinfo**() supports the _address_**%**_scope-id_ notation for
           specifying the IPv6 scope-ID.
    


## EXAMPLES



           The following programs demonstrate the use of **getaddrinfo**(),
           **gai_strerror**(), **freeaddrinfo**(), and getnameinfo(3).  The programs
           are an echo server and client for UDP datagrams.
    
       **Server program**
    
           #include <netdb.h>
           #include <stdio.h>
           #include <stdlib.h>
           #include <string.h>
           #include <sys/socket.h>
           #include <sys/types.h>
           #include <unistd.h>
    
           #define BUF_SIZE 500
    
           int
           main(int argc, char *argv[])
           {
               int                      sfd, s;
               char                     buf[BUF_SIZE];
               ssize_t                  nread;
               socklen_t                peer_addrlen;
               struct addrinfo          hints;
               struct addrinfo          *result, *rp;
               struct sockaddr_storage  peer_addr;
    
               if (argc != 2) {
                   fprintf(stderr, "Usage: %s port\n", argv[0]);
                   exit(EXIT_FAILURE);
               }
    
               memset(&hints, 0, sizeof(hints));
               hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
               hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
               hints.ai_flags = AI_PASSIVE;    /* For wildcard IP address */
               hints.ai_protocol = 0;          /* Any protocol */
               hints.ai_canonname = NULL;
               hints.ai_addr = NULL;
               hints.ai_next = NULL;
    
               s = getaddrinfo(NULL, argv[1], &hints, &result);
               if (s != 0) {
                   fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
                   exit(EXIT_FAILURE);
               }
    
               /* getaddrinfo() returns a list of address structures.
                  Try each address until we successfully bind(2).
                  If socket(2) (or bind(2)) fails, we (close the socket
                  and) try the next address. */
    
               for (rp = result; rp != NULL; rp = rp->ai_next) {
                   sfd = socket(rp->ai_family, rp->ai_socktype,
                                rp->ai_protocol);
                   if (sfd == -1)
                       continue;
    
                   if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
                       break;                  /* Success */
    
                   close(sfd);
               }
    
               freeaddrinfo(result);           /* No longer needed */
    
               if (rp == NULL) {               /* No address succeeded */
                   fprintf(stderr, "Could not bind\n");
                   exit(EXIT_FAILURE);
               }
    
               /* Read datagrams and echo them back to sender. */
    
               for (;;) {
                   char host[NI_MAXHOST], service[NI_MAXSERV];
    
                   peer_addrlen = sizeof(peer_addr);
                   nread = recvfrom(sfd, buf, BUF_SIZE, 0,
                                    (struct sockaddr *) &peer_addr, &peer_addrlen);
                   if (nread == -1)
                       continue;               /* Ignore failed request */
    
                   s = getnameinfo((struct sockaddr *) &peer_addr,
                                   peer_addrlen, host, NI_MAXHOST,
                                   service, NI_MAXSERV, NI_NUMERICSERV);
                   if (s == 0)
                       printf("Received %zd bytes from %s:%s\n",
                              nread, host, service);
                   else
                       fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
    
                   if (sendto(sfd, buf, nread, 0, (struct sockaddr *) &peer_addr,
                              peer_addrlen) != nread)
                   {
                       fprintf(stderr, "Error sending response\n");
                   }
               }
           }
    
       **Client program**
    
           #include <netdb.h>
           #include <stdio.h>
           #include <stdlib.h>
           #include <string.h>
           #include <sys/socket.h>
           #include <sys/types.h>
           #include <unistd.h>
    
           #define BUF_SIZE 500
    
           int
           main(int argc, char *argv[])
           {
               int              sfd, s;
               char             buf[BUF_SIZE];
               size_t           size;
               ssize_t          nread;
               struct addrinfo  hints;
               struct addrinfo  *result, *rp;
    
               if (argc < 3) {
                   fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
                   exit(EXIT_FAILURE);
               }
    
               /* Obtain address(es) matching host/port. */
    
               memset(&hints, 0, sizeof(hints));
               hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
               hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
               hints.ai_flags = 0;
               hints.ai_protocol = 0;          /* Any protocol */
    
               s = getaddrinfo(argv[1], argv[2], &hints, &result);
               if (s != 0) {
                   fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
                   exit(EXIT_FAILURE);
               }
    
               /* getaddrinfo() returns a list of address structures.
                  Try each address until we successfully connect(2).
                  If socket(2) (or connect(2)) fails, we (close the socket
                  and) try the next address. */
    
               for (rp = result; rp != NULL; rp = rp->ai_next) {
                   sfd = socket(rp->ai_family, rp->ai_socktype,
                                rp->ai_protocol);
                   if (sfd == -1)
                       continue;
    
                   if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
                       break;                  /* Success */
    
                   close(sfd);
               }
    
               freeaddrinfo(result);           /* No longer needed */
    
               if (rp == NULL) {               /* No address succeeded */
                   fprintf(stderr, "Could not connect\n");
                   exit(EXIT_FAILURE);
               }
    
               /* Send remaining command-line arguments as separate
                  datagrams, and read responses from server. */
    
               for (size_t j = 3; j < argc; j++) {
                   size = strlen(argv[j]) + 1;
                           /* +1 for terminating null byte */
    
                   if (size > BUF_SIZE) {
                       fprintf(stderr,
                               "Ignoring long message in argument %zu\n", j);
                       continue;
                   }
    
                   if (write(sfd, argv[j], size) != size) {
                       fprintf(stderr, "partial/failed write\n");
                       exit(EXIT_FAILURE);
                   }
    
                   nread = read(sfd, buf, BUF_SIZE);
                   if (nread == -1) {
                       perror("read");
                       exit(EXIT_FAILURE);
                   }
    
                   printf("Received %zd bytes: %s\n", nread, buf);
               }
    
               exit(EXIT_SUCCESS);
           }
    


* * *