diff options
Diffstat (limited to 'man3/getaddrinfo.3')
-rw-r--r-- | man3/getaddrinfo.3 | 853 |
1 files changed, 853 insertions, 0 deletions
diff --git a/man3/getaddrinfo.3 b/man3/getaddrinfo.3 new file mode 100644 index 0000000..1bbbb23 --- /dev/null +++ b/man3/getaddrinfo.3 @@ -0,0 +1,853 @@ +'\" t +.\" Copyright (c) 2007, 2008 Michael Kerrisk <mtk.manpages@gmail.com> +.\" and Copyright (c) 2006 Ulrich Drepper <drepper@redhat.com> +.\" A few pieces of an earlier version remain: +.\" Copyright 2000, Sam Varshavchik <mrsam@courier-mta.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.\" References: RFC 2553 +.\" +.\" 2005-08-09, mtk, added AI_ALL, AI_ADDRCONFIG, AI_V4MAPPED, +.\" and AI_NUMERICSERV. +.\" 2006-11-25, Ulrich Drepper <drepper@redhat.com> +.\" Add text describing Internationalized Domain Name extensions. +.\" 2007-06-08, mtk: added example programs +.\" 2008-02-26, mtk; clarify discussion of NULL 'hints' argument; other +.\" minor rewrites. +.\" 2008-06-18, mtk: many parts rewritten +.\" 2008-12-04, Petr Baudis <pasky@suse.cz> +.\" Describe results ordering and reference /etc/gai.conf. +.\" +.\" FIXME . glibc's 2.9 NEWS file documents DCCP and UDP-lite support +.\" and is SCTP support now also there? +.\" +.TH getaddrinfo 3 2023-07-20 "Linux man-pages 6.05.01" +.SH NAME +getaddrinfo, freeaddrinfo, gai_strerror \- network address and +service translation +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include <sys/types.h> +.B #include <sys/socket.h> +.B #include <netdb.h> +.PP +.BI "int getaddrinfo(const char *restrict " node , +.BI " const char *restrict " service , +.BI " const struct addrinfo *restrict " hints , +.BI " struct addrinfo **restrict " res ); +.PP +.BI "void freeaddrinfo(struct addrinfo *" res ); +.PP +.BI "const char *gai_strerror(int " errcode ); +.fi +.PP +.RS -4 +Feature Test Macro Requirements for glibc (see +.BR feature_test_macros (7)): +.RE +.PP +.BR getaddrinfo (), +.BR freeaddrinfo (), +.BR gai_strerror (): +.nf + Since glibc 2.22: + _POSIX_C_SOURCE >= 200112L + glibc 2.21 and earlier: + _POSIX_C_SOURCE +.fi +.SH DESCRIPTION +Given +.I node +and +.IR service , +which identify an Internet host and a service, +.BR getaddrinfo () +returns one or more +.I addrinfo +structures, each of which contains an Internet address +that can be specified in a call to +.BR bind (2) +or +.BR connect (2). +The +.BR getaddrinfo () +function combines the functionality provided by the +.\" .BR getipnodebyname (3), +.\" .BR getipnodebyaddr (3), +.BR gethostbyname (3) +and +.BR getservbyname (3) +functions into a single interface, but unlike the latter functions, +.BR getaddrinfo () +is reentrant and allows programs to eliminate IPv4-versus-IPv6 dependencies. +.PP +The +.I addrinfo +structure used by +.BR getaddrinfo () +contains the following fields: +.PP +.in +4n +.EX +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; +}; +.EE +.in +.PP +The +.I hints +argument points to an +.I addrinfo +structure that specifies criteria for selecting the socket address +structures returned in the list pointed to by +.IR res . +If +.I hints +is not NULL it points to an +.I addrinfo +structure whose +.IR ai_family , +.IR ai_socktype , +and +.I ai_protocol +specify criteria that limit the set of socket addresses returned by +.BR getaddrinfo (), +as follows: +.TP +.I ai_family +This field specifies the desired address family for the returned addresses. +Valid values for this field include +.B AF_INET +and +.BR AF_INET6 . +The value +.B AF_UNSPEC +indicates that +.BR getaddrinfo () +should return socket addresses for any address family +(either IPv4 or IPv6, for example) that can be used with +.I node +and +.IR service . +.TP +.I ai_socktype +This field specifies the preferred socket type, for example +.B SOCK_STREAM +or +.BR SOCK_DGRAM . +Specifying 0 in this field indicates that socket addresses of any type +can be returned by +.BR getaddrinfo (). +.TP +.I 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 +.BR getaddrinfo (). +.TP +.I ai_flags +This field specifies additional options, described below. +Multiple flags are specified by bitwise OR-ing them together. +.PP +All the other fields in the structure pointed to by +.I hints +must contain either 0 or a null pointer, as appropriate. +.PP +Specifying +.I hints +as NULL is equivalent to setting +.I ai_socktype +and +.I ai_protocol +to 0; +.I ai_family +to +.BR AF_UNSPEC ; +and +.I ai_flags +to +.BR "(AI_V4MAPPED\ |\ AI_ADDRCONFIG)" . +(POSIX specifies different defaults for +.IR ai_flags ; +see NOTES.) +.I node +specifies either a numerical network address +(for IPv4, numbers-and-dots notation as supported by +.BR inet_aton (3); +for IPv6, hexadecimal string format as supported by +.BR inet_pton (3)), +or a network hostname, whose network addresses are looked up and resolved. +If +.I hints.ai_flags +contains the +.B AI_NUMERICHOST +flag, then +.I node +must be a numerical network address. +The +.B AI_NUMERICHOST +flag suppresses any potentially lengthy network host address lookups. +.PP +If the +.B AI_PASSIVE +flag is specified in +.IR hints.ai_flags , +and +.I node +is NULL, +then the returned socket addresses will be suitable for +.BR bind (2)ing +a socket that will +.BR accept (2) +connections. +The returned socket address will contain the "wildcard address" +.RB ( INADDR_ANY +for IPv4 addresses, +.B 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 +.I node +is not NULL, then the +.B AI_PASSIVE +flag is ignored. +.PP +If the +.B AI_PASSIVE +flag is not set in +.IR hints.ai_flags , +then the returned socket addresses will be suitable for use with +.BR connect (2), +.BR sendto (2), +or +.BR sendmsg (2). +If +.I node +is NULL, +then the network address will be set to the loopback interface address +.RB ( INADDR_LOOPBACK +for IPv4 addresses, +.B IN6ADDR_LOOPBACK_INIT +for IPv6 address); +this is used by applications that intend to communicate +with peers running on the same host. +.PP +.I service +sets the port in each returned address structure. +If this argument is a service name (see +.BR 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 +.I service +is NULL, then the port number of the returned socket addresses +will be left uninitialized. +If +.B AI_NUMERICSERV +is specified in +.I hints.ai_flags +and +.I service +is not NULL, then +.I 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. +.PP +Either +.I node +or +.IR service , +but not both, may be NULL. +.PP +The +.BR getaddrinfo () +function allocates and initializes a linked list of +.I addrinfo +structures, one for each network address that matches +.I node +and +.IR service , +subject to any restrictions imposed by +.IR hints , +and returns a pointer to the start of the list in +.IR res . +The items in the linked list are linked by the +.I ai_next +field. +.PP +There are several reasons why +the linked list may have more than one +.I addrinfo +structure, including: the network host is multihomed, accessible +over multiple protocols (e.g., both +.B AF_INET +and +.BR AF_INET6 ); +or the same service is available from multiple socket types (one +.B SOCK_STREAM +address and another +.B 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 +.BR getaddrinfo () +is defined in RFC\ 3484; the order can be tweaked for a particular +system by editing +.I /etc/gai.conf +(available since glibc 2.5). +.PP +If +.I hints.ai_flags +includes the +.B AI_CANONNAME +flag, then the +.I ai_canonname +field of the first of the +.I addrinfo +structures in the returned list is set to point to the +official name of the host. +.\" Prior to glibc 2.3.4, the ai_canonname of each addrinfo +.\" structure was set pointing to the canonical name; that was +.\" more than POSIX.1-2001 specified, or other implementations provided. +.\" MTK, Aug 05 +.PP +The remaining fields of each returned +.I addrinfo +structure are initialized as follows: +.IP \[bu] 3 +The +.IR ai_family , +.IR ai_socktype , +and +.I ai_protocol +fields return the socket creation parameters (i.e., these fields have +the same meaning as the corresponding arguments of +.BR socket (2)). +For example, +.I ai_family +might return +.B AF_INET +or +.BR AF_INET6 ; +.I ai_socktype +might return +.B SOCK_DGRAM +or +.BR SOCK_STREAM ; +and +.I ai_protocol +returns the protocol for the socket. +.IP \[bu] +A pointer to the socket address is placed in the +.I ai_addr +field, and the length of the socket address, in bytes, +is placed in the +.I ai_addrlen +field. +.PP +If +.I hints.ai_flags +includes the +.B AI_ADDRCONFIG +flag, then IPv4 addresses are returned in the list pointed to by +.I 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 +.BR getaddrinfo () +does not return IPv6 socket addresses that would always fail in +.BR connect (2) +or +.BR bind (2). +.PP +If +.I hints.ai_flags +specifies the +.B AI_V4MAPPED +flag, and +.I hints.ai_family +was specified as +.BR AF_INET6 , +and no matching IPv6 addresses could be found, +then return IPv4-mapped IPv6 addresses in the list pointed to by +.IR res . +If both +.B AI_V4MAPPED +and +.B AI_ALL +are specified in +.IR hints.ai_flags , +then return both IPv6 and IPv4-mapped IPv6 addresses +in the list pointed to by +.IR res . +.B AI_ALL +is ignored if +.B AI_V4MAPPED +is not also specified. +.PP +The +.BR freeaddrinfo () +function frees the memory that was allocated +for the dynamically allocated linked list +.IR res . +.SS Extensions to getaddrinfo() for Internationalized Domain Names +Starting with glibc 2.3.4, +.BR 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, +.IR "Internationalizing Domain Names in Applications (IDNA)" ). +Four new flags are defined: +.TP +.B AI_IDN +If this flag is specified, then the node name given in +.I node +is converted to IDN format if necessary. +The source encoding is that of the current locale. +.IP +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. +.\" Implementation Detail: +.\" To minimize effects on system performance the implementation might +.\" want to check whether the input string contains any non-ASCII +.\" characters. If there are none the IDN step can be skipped completely. +.\" On systems which allow not-ASCII safe encodings for a locale this +.\" might be a problem. +.TP +.B AI_CANONIDN +After a successful name lookup, and if the +.B AI_CANONNAME +flag was specified, +.BR getaddrinfo () +will return the canonical name of the +node corresponding to the +.I addrinfo +structure value passed back. +The return value is an exact copy of the value returned by the name +resolution function. +.IP +If the name is encoded using ACE, then it will contain the +.I xn\-\- +prefix for one or more components of the name. +To convert these components into a readable form the +.B AI_CANONIDN +flag can be passed in addition to +.BR AI_CANONNAME . +The resulting string is encoded using the current locale's encoding. +.\" +.\"Implementation Detail: +.\"If no component of the returned name starts with xn\-\- the IDN +.\"step can be skipped, therefore avoiding unnecessary slowdowns. +.TP +.BR 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. +.SH RETURN VALUE +.\" FIXME glibc defines the following additional errors, some which +.\" can probably be returned by getaddrinfo(); they need to +.\" be documented. +.\" #ifdef __USE_GNU +.\" #define EAI_INPROGRESS -100 /* Processing request in progress. */ +.\" #define EAI_CANCELED -101 /* Request canceled. */ +.\" #define EAI_NOTCANCELED -102 /* Request not canceled. */ +.\" #define EAI_ALLDONE -103 /* All requests done. */ +.\" #define EAI_INTR -104 /* Interrupted by a signal. */ +.\" #define EAI_IDN_ENCODE -105 /* IDN encoding failed. */ +.\" #endif +.BR getaddrinfo () +returns 0 if it succeeds, or one of the following nonzero error codes: +.TP +.B EAI_ADDRFAMILY +.\" Not in SUSv3 +The specified network host does not have any network addresses in the +requested address family. +.TP +.B EAI_AGAIN +The name server returned a temporary failure indication. +Try again later. +.TP +.B EAI_BADFLAGS +.I hints.ai_flags +contains invalid flags; or, +.I hints.ai_flags +included +.B AI_CANONNAME +and +.I name +was NULL. +.TP +.B EAI_FAIL +The name server returned a permanent failure indication. +.TP +.B EAI_FAMILY +The requested address family is not supported. +.TP +.B EAI_MEMORY +Out of memory. +.TP +.B EAI_NODATA +.\" Not in SUSv3 +The specified network host exists, but does not have any +network addresses defined. +.TP +.B EAI_NONAME +The +.I node +or +.I service +is not known; or both +.I node +and +.I service +are NULL; or +.B AI_NUMERICSERV +was specified in +.I hints.ai_flags +and +.I service +was not a numeric port-number string. +.TP +.B 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 +.I service +was "shell" (a service available only on stream sockets), and either +.I hints.ai_protocol +was +.BR IPPROTO_UDP , +or +.I hints.ai_socktype +was +.BR SOCK_DGRAM ; +or the error could occur if +.I service +was not NULL, and +.I hints.ai_socktype +was +.B SOCK_RAW +(a socket type that does not support the concept of services). +.TP +.B EAI_SOCKTYPE +The requested socket type is not supported. +This could occur, for example, if +.I hints.ai_socktype +and +.I hints.ai_protocol +are inconsistent (e.g., +.B SOCK_DGRAM +and +.BR IPPROTO_TCP , +respectively). +.TP +.B EAI_SYSTEM +Other system error; +.I errno +is set to indicate the error. +.PP +The +.BR gai_strerror () +function translates these error codes to a human readable string, +suitable for error reporting. +.SH FILES +.I /etc/gai.conf +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lbx lb lb +l l l. +Interface Attribute Value +T{ +.na +.nh +.BR getaddrinfo () +T} Thread safety MT-Safe env locale +T{ +.na +.nh +.BR freeaddrinfo (), +.BR gai_strerror () +T} Thread safety MT-Safe +.TE +.sp 1 +.SH VERSIONS +According to POSIX.1, specifying +.\" POSIX.1-2001, POSIX.1-2008 +.I hints +as NULL should cause +.I ai_flags +to be assumed as 0. +The GNU C library instead assumes a value of +.B (AI_V4MAPPED\~|\~AI_ADDRCONFIG) +for this case, +since this value is considered an improvement on the specification. +.SH STANDARDS +POSIX.1-2008. +.TP +.BR getaddrinfo () +RFC\ 2553. +.SH HISTORY +POSIX.1-2001. +.TP +.B AI_ADDRCONFIG +.TQ +.B AI_ALL +.TQ +.B AI_V4MAPPED +glibc 2.3.3. +.TP +.B AI_NUMERICSERV +glibc 2.3.4. +.SH NOTES +.BR getaddrinfo () +supports the +.IB address % scope-id +notation for specifying the IPv6 scope-ID. +.SH EXAMPLES +.\" getnameinfo.3 refers to this example +.\" socket.2 refers to this example +.\" bind.2 refers to this example +.\" connect.2 refers to this example +.\" recvfrom.2 refers to this example +.\" sendto.2 refers to this example +The following programs demonstrate the use of +.BR getaddrinfo (), +.BR gai_strerror (), +.BR freeaddrinfo (), +and +.BR getnameinfo (3). +The programs are an echo server and client for UDP datagrams. +.SS Server program +\& +.\" SRC BEGIN (server.c) +.EX +#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\en", 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\en", 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\en"); + 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\en", + nread, host, service); + else + fprintf(stderr, "getnameinfo: %s\en", gai_strerror(s)); +\& + if (sendto(sfd, buf, nread, 0, (struct sockaddr *) &peer_addr, + peer_addrlen) != nread) + { + fprintf(stderr, "Error sending response\en"); + } + } +} +.EE +.\" SRC END +.SS Client program +\& +.\" SRC BEGIN (client.c) +.EX +#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 len; + ssize_t nread; + struct addrinfo hints; + struct addrinfo *result, *rp; +\& + if (argc < 3) { + fprintf(stderr, "Usage: %s host port msg...\en", 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\en", 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\en"); + exit(EXIT_FAILURE); + } +\& + /* Send remaining command\-line arguments as separate + datagrams, and read responses from server. */ +\& + for (size_t j = 3; j < argc; j++) { + len = strlen(argv[j]) + 1; + /* +1 for terminating null byte */ +\& + if (len > BUF_SIZE) { + fprintf(stderr, + "Ignoring long message in argument %zu\en", j); + continue; + } +\& + if (write(sfd, argv[j], len) != len) { + fprintf(stderr, "partial/failed write\en"); + exit(EXIT_FAILURE); + } +\& + nread = read(sfd, buf, BUF_SIZE); + if (nread == \-1) { + perror("read"); + exit(EXIT_FAILURE); + } +\& + printf("Received %zd bytes: %s\en", nread, buf); + } +\& + exit(EXIT_SUCCESS); +} +.EE +.\" SRC END +.SH SEE ALSO +.\" .BR getipnodebyaddr (3), +.\" .BR getipnodebyname (3), +.BR getaddrinfo_a (3), +.BR gethostbyname (3), +.BR getnameinfo (3), +.BR inet (3), +.BR gai.conf (5), +.BR hostname (7), +.BR ip (7) |