getaddrinfo freeaddrinfo - socket address structure to host and service name
The Fa hostname and Fa servname arguments are either pointers to NUL-terminated strings or the null pointer. An acceptable value for Fa hostname is either a valid host name or a numeric host address string consisting of a dotted decimal IPv4 address or an IPv6 address. The Fa servname is either a decimal port number or a service name listed in services(5). At least one of Fa hostname and Fa servname must be non-null.
Fa hints is an optional pointer to a struct addrinfo as defined by Aq Pa netdb.h :
struct addrinfo { int ai_flags; /* input flags */ int ai_family; /* protocol family for socket */ int ai_socktype; /* socket type */ int ai_protocol; /* protocol for socket */ socklen_t ai_addrlen; /* length of socket-address */ struct sockaddr *ai_addr; /* socket-address for socket */ char *ai_canonname; /* canonical name for service location */ struct addrinfo *ai_next; /* pointer to next in list */ };
This structure can be used to provide hints concerning the type of socket that the caller supports or wishes to use. The caller can supply the following structure elements in Fa hints :
If the AI_PASSIVE bit is not set, the returned socket address structure will be ready for use in a call to connect(2) for a connection-oriented protocol or connect(2), sendto(2), or sendmsg(2) if a connectionless protocol was chosen. The IP address portion of the socket address structure will be set to the loopback address if Fa hostname is the null pointer and AI_PASSIVE is not set.
All other elements of the addrinfo structure passed via Fa hints must be zero or the null pointer.
If
Fa hints
is the null pointer,
getaddrinfo ();
behaves as if the caller provided a
struct addrinfo
with
Fa ai_family
set to
PF_UNSPEC
and all other elements set to zero or
NULL
After a successful call to
getaddrinfo (,);
Fa *res
is a pointer to a linked list of one or more
addrinfo
structures.
The list can be traversed by following the
Fa ai_next
pointer in each
addrinfo
structure until a null pointer is encountered.
The three members
Fa ai_family,
Fa ai_socktype,
and
Fa ai_protocol
in each returned
addrinfo
structure are suitable for a call to
socket(2).
For each
addrinfo
structure in the list, the
Fa ai_addr
member points to a filled-in socket address structure of length
Fa ai_addrlen .
This implementation of
getaddrinfo ();
allows numeric IPv6 address notation with scope identifier,
as documented in chapter 11 of draft-ietf-ipv6-scoping-arch-02.txt.
By appending the percent character and scope identifier to addresses,
one can fill the
sin6_scope_id
field for addresses.
This would make management of scoped addresses easier
and allows cut-and-paste input of scoped addresses.
At this moment the code supports only link-local addresses with the format. The scope identifier is hardcoded to the name of the hardware interface associated with the link Po such as ne0 Pc . An example is ``fe80::1%ne0 '' which means Do fe80::1 on the link associated with the ne0 interface Dc .
The current implementation assumes a one-to-one relationship between the interface and link, which is not necessarily true from the specification.
All of the information returned by
getaddrinfo ();
is dynamically allocated: the
addrinfo
structures themselves as well as the socket address structures and
the canonical host name strings included in the
addrinfo
structures.
Memory allocated for the dynamically allocated structures created by
a successful call to
getaddrinfo ();
is released by the
freeaddrinfo ();
function.
The
Fa ai
pointer should be a
addrinfo
structure created by a call to
getaddrinfo (.);
struct addrinfo hints, *res, *res0; int error; int s; const char *cause = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo("www.kame.net", "http", &hints, &res0); if (error) { errx(1, "%s", gai_strerror(error)); /*NOTREACHED*/ } s = -1; for (res = res0; res; res = res->ai_next) { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) { cause = "socket"; continue; } if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { cause = "connect"; close(s); s = -1; continue; } break; /* okay we got one */ } if (s < 0) { err(1, "%s", cause); /*NOTREACHED*/ } freeaddrinfo(res0);
The following example tries to open a wildcard listening socket onto service ``http '' for all the address families available.
struct addrinfo hints, *res, *res0; int error; int s[MAXSOCK]; int nsock; const char *cause = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; error = getaddrinfo(NULL, "http", &hints, &res0); if (error) { errx(1, "%s", gai_strerror(error)); /*NOTREACHED*/ } nsock = 0; for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) { s[nsock] = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s[nsock] < 0) { cause = "socket"; continue; } if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) { cause = "bind"; close(s[nsock]); continue; } (void) listen(s[nsock], 5); nsock++; } if (nsock == 0) { err(1, "%s", cause); /*NOTREACHED*/ } freeaddrinfo(res0);
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |