mirror of https://github.com/mkerrisk/man-pages
855 lines
22 KiB
Groff
855 lines
22 KiB
Groff
.\" 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>
|
|
.\"
|
|
.\" %%%LICENSE_START(VERBATIM)
|
|
.\" Permission is granted to make and distribute verbatim copies of this
|
|
.\" manual provided the copyright notice and this permission notice are
|
|
.\" preserved on all copies.
|
|
.\"
|
|
.\" Permission is granted to copy and distribute modified versions of this
|
|
.\" manual under the conditions for verbatim copying, provided that the
|
|
.\" entire resulting derived work is distributed under the terms of a
|
|
.\" permission notice identical to this one.
|
|
.\"
|
|
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
.\" responsibility for errors or omissions, or for damages resulting from
|
|
.\" the use of the information contained herein. The author(s) may not
|
|
.\" have taken the same level of care in the production of this manual,
|
|
.\" which is licensed free of charge, as they might when working
|
|
.\" professionally.
|
|
.\"
|
|
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
.\" the source, must acknowledge the copyright and authors of this work.
|
|
.\" %%%LICENSE_END
|
|
.\"
|
|
.\" 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 2019-03-06 "GNU" "Linux Programmer's Manual"
|
|
.SH NAME
|
|
getaddrinfo, freeaddrinfo, gai_strerror \- network address and
|
|
service translation
|
|
.SH SYNOPSIS
|
|
.nf
|
|
.B #include <sys/types.h>
|
|
.B #include <sys/socket.h>
|
|
.B #include <netdb.h>
|
|
.PP
|
|
.BI "int getaddrinfo(const char *" "node" ", const char *" "service" ,
|
|
.BI " const struct addrinfo *" "hints" ,
|
|
.BI " struct addrinfo **" "res" );
|
|
.PP
|
|
.BI "void freeaddrinfo(struct addrinfo *" "res" );
|
|
.PP
|
|
.BI "const char *gai_strerror(int " "errcode" );
|
|
.fi
|
|
.PP
|
|
.in -4n
|
|
Feature Test Macro Requirements for glibc (see
|
|
.BR feature_test_macros (7)):
|
|
.ad l
|
|
.in
|
|
.PP
|
|
.BR getaddrinfo (),
|
|
.BR freeaddrinfo (),
|
|
.BR gai_strerror ():
|
|
Since glibc 2.22: _POSIX_C_SOURCE >= 200112L
|
|
Glibc 2.21 and earlier: _POSIX_C_SOURCE
|
|
.ad b
|
|
.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
|
|
.BR 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
|
|
.BR 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,
|
|
.BR 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,
|
|
.BR 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
|
|
.BR 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
|
|
.IR /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.
|
|
.\" In glibc prior to 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 * 2
|
|
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 *
|
|
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
|
|
.PP
|
|
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
|
|
.BR 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.,
|
|
.BR SOCK_DGRAM
|
|
and
|
|
.BR IPPROTO_TCP ,
|
|
respectively).
|
|
.TP
|
|
.B EAI_SYSTEM
|
|
Other system error, check
|
|
.I errno
|
|
for details.
|
|
.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;
|
|
lbw15 lb lb
|
|
l l l.
|
|
Interface Attribute Value
|
|
T{
|
|
.BR getaddrinfo ()
|
|
T} Thread safety MT-Safe env locale
|
|
T{
|
|
.BR freeaddrinfo (),
|
|
.BR gai_strerror ()
|
|
T} Thread safety MT-Safe
|
|
.TE
|
|
.sp 1
|
|
.SH CONFORMING TO
|
|
POSIX.1-2001, POSIX.1-2008.
|
|
The
|
|
.BR getaddrinfo ()
|
|
function is documented in RFC\ 2553.
|
|
.SH NOTES
|
|
.BR getaddrinfo ()
|
|
supports the
|
|
.IB address % scope-id
|
|
notation for specifying the IPv6 scope-ID.
|
|
.PP
|
|
.BR AI_ADDRCONFIG ,
|
|
.BR AI_ALL ,
|
|
and
|
|
.B AI_V4MAPPED
|
|
are available since glibc 2.3.3.
|
|
.B AI_NUMERICSERV
|
|
is available since glibc 2.3.4.
|
|
.PP
|
|
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
|
|
.BR "(AI_V4MAPPED\ |\ AI_ADDRCONFIG)"
|
|
for this case,
|
|
since this value is considered an improvement on the specification.
|
|
.SH EXAMPLE
|
|
.\" 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
|
|
\&
|
|
.EX
|
|
#include <sys/types.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
|
|
#define BUF_SIZE 500
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
struct addrinfo hints;
|
|
struct addrinfo *result, *rp;
|
|
int sfd, s;
|
|
struct sockaddr_storage peer_addr;
|
|
socklen_t peer_addr_len;
|
|
ssize_t nread;
|
|
char buf[BUF_SIZE];
|
|
|
|
if (argc != 2) {
|
|
fprintf(stderr, "Usage: %s port\en", argv[0]);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
memset(&hints, 0, sizeof(struct addrinfo));
|
|
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);
|
|
}
|
|
|
|
if (rp == NULL) { /* No address succeeded */
|
|
fprintf(stderr, "Could not bind\en");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
freeaddrinfo(result); /* No longer needed */
|
|
|
|
/* Read datagrams and echo them back to sender */
|
|
|
|
for (;;) {
|
|
peer_addr_len = sizeof(struct sockaddr_storage);
|
|
nread = recvfrom(sfd, buf, BUF_SIZE, 0,
|
|
(struct sockaddr *) &peer_addr, &peer_addr_len);
|
|
if (nread == \-1)
|
|
continue; /* Ignore failed request */
|
|
|
|
char host[NI_MAXHOST], service[NI_MAXSERV];
|
|
|
|
s = getnameinfo((struct sockaddr *) &peer_addr,
|
|
peer_addr_len, 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_addr_len) != nread)
|
|
fprintf(stderr, "Error sending response\en");
|
|
}
|
|
}
|
|
.EE
|
|
.SS Client program
|
|
\&
|
|
.EX
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
#define BUF_SIZE 500
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
struct addrinfo hints;
|
|
struct addrinfo *result, *rp;
|
|
int sfd, s, j;
|
|
size_t len;
|
|
ssize_t nread;
|
|
char buf[BUF_SIZE];
|
|
|
|
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(struct addrinfo));
|
|
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);
|
|
}
|
|
|
|
if (rp == NULL) { /* No address succeeded */
|
|
fprintf(stderr, "Could not connect\en");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
freeaddrinfo(result); /* No longer needed */
|
|
|
|
/* Send remaining command\-line arguments as separate
|
|
datagrams, and read responses from server */
|
|
|
|
for (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 %d\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
|
|
.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)
|