|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <sys/socket.h>
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <endian.h>
|
|
|
|
|
#include <errno.h>
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
#include "lookup.h"
|
|
|
|
|
|
|
|
|
|
int getaddrinfo(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict hint, struct addrinfo **restrict res)
|
|
|
|
|
{
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
struct service ports[MAXSERVS];
|
|
|
|
|
struct address addrs[MAXADDRS];
|
|
|
|
|
char canon[256], *outcanon;
|
|
|
|
|
int nservs, naddrs, nais, canon_len, i, j, k;
|
|
|
|
|
int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0;
|
allow freeaddrinfo of arbitrary sublists of addrinfo list
the specification for freeaddrinfo allows it to be used to free
"arbitrary sublists" of the list returned by getaddrinfo. it's not
clearly stated how such sublists come into existence, but the
interpretation seems to be that the application can edit the ai_next
pointers to cut off a portion of the list and then free it.
actual freeing of individual list slots is contrary to the design of
our getaddrinfo implementation, which has no failure paths after
making a single allocation, so that light callers can avoid linking
realloc/free. freeing individual slots is also incompatible with
sharing the string for ai_canonname, which the current implementation
does despite no requirement that it be present except on the first
result. so, rather than actually freeing individual slots, provide a
way to find the start of the allocated array, and reference-count it,
freeing the memory all at once after the last slot has been freed.
since the language in the spec is "arbitrary sublists", no provision
for handling other constructs like multiple lists glued together,
circular links, etc. is made. presumably passing such a construct to
freeaddrinfo produces undefined behavior.
8 years ago
|
|
|
struct aibuf *out;
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
|
|
|
|
|
if (!host && !serv) return EAI_NONAME;
|
|
|
|
|
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
if (hint) {
|
|
|
|
|
family = hint->ai_family;
|
|
|
|
|
flags = hint->ai_flags;
|
|
|
|
|
proto = hint->ai_protocol;
|
|
|
|
|
socktype = hint->ai_socktype;
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
|
|
|
|
|
const int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST |
|
|
|
|
|
AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_NUMERICSERV;
|
|
|
|
|
if ((flags & mask) != flags)
|
|
|
|
|
return EAI_BADFLAGS;
|
|
|
|
|
|
|
|
|
|
switch (family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
case AF_UNSPEC:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return EAI_FAMILY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flags & AI_ADDRCONFIG) {
|
|
|
|
|
/* Define the "an address is configured" condition for address
|
|
|
|
|
* families via ability to create a socket for the family plus
|
|
|
|
|
* routability of the loopback address for the family. */
|
|
|
|
|
static const struct sockaddr_in lo4 = {
|
|
|
|
|
.sin_family = AF_INET, .sin_port = 65535,
|
|
|
|
|
.sin_addr.s_addr = __BYTE_ORDER == __BIG_ENDIAN
|
|
|
|
|
? 0x7f000001 : 0x0100007f
|
|
|
|
|
};
|
|
|
|
|
static const struct sockaddr_in6 lo6 = {
|
|
|
|
|
.sin6_family = AF_INET6, .sin6_port = 65535,
|
|
|
|
|
.sin6_addr = IN6ADDR_LOOPBACK_INIT
|
|
|
|
|
};
|
|
|
|
|
int tf[2] = { AF_INET, AF_INET6 };
|
|
|
|
|
const void *ta[2] = { &lo4, &lo6 };
|
|
|
|
|
socklen_t tl[2] = { sizeof lo4, sizeof lo6 };
|
|
|
|
|
for (i=0; i<2; i++) {
|
|
|
|
|
if (family==tf[1-i]) continue;
|
|
|
|
|
int s = socket(tf[i], SOCK_CLOEXEC|SOCK_DGRAM,
|
|
|
|
|
IPPROTO_UDP);
|
|
|
|
|
if (s>=0) {
|
|
|
|
|
int cs;
|
|
|
|
|
pthread_setcancelstate(
|
|
|
|
|
PTHREAD_CANCEL_DISABLE, &cs);
|
|
|
|
|
int r = connect(s, ta[i], tl[i]);
|
|
|
|
|
pthread_setcancelstate(cs, 0);
|
|
|
|
|
close(s);
|
|
|
|
|
if (!r) continue;
|
|
|
|
|
}
|
|
|
|
|
switch (errno) {
|
|
|
|
|
case EADDRNOTAVAIL:
|
|
|
|
|
case EAFNOSUPPORT:
|
|
|
|
|
case EHOSTUNREACH:
|
|
|
|
|
case ENETDOWN:
|
|
|
|
|
case ENETUNREACH:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return EAI_SYSTEM;
|
|
|
|
|
}
|
|
|
|
|
if (family == tf[i]) return EAI_NONAME;
|
|
|
|
|
family = tf[1-i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nservs = __lookup_serv(ports, serv, proto, socktype, flags);
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
if (nservs < 0) return nservs;
|
|
|
|
|
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
naddrs = __lookup_name(addrs, canon, host, family, flags);
|
|
|
|
|
if (naddrs < 0) return naddrs;
|
|
|
|
|
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
nais = nservs * naddrs;
|
|
|
|
|
canon_len = strlen(canon);
|
|
|
|
|
out = calloc(1, nais * sizeof(*out) + canon_len + 1);
|
|
|
|
|
if (!out) return EAI_MEMORY;
|
|
|
|
|
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
if (canon_len) {
|
|
|
|
|
outcanon = (void *)&out[nais];
|
|
|
|
|
memcpy(outcanon, canon, canon_len+1);
|
|
|
|
|
} else {
|
|
|
|
|
outcanon = 0;
|
|
|
|
|
}
|
|
|
|
|
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++, k++) {
|
|
|
|
|
out[k].slot = k;
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
out[k].ai = (struct addrinfo){
|
|
|
|
|
.ai_family = addrs[i].family,
|
|
|
|
|
.ai_socktype = ports[j].socktype,
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
.ai_protocol = ports[j].proto,
|
|
|
|
|
.ai_addrlen = addrs[i].family == AF_INET
|
|
|
|
|
? sizeof(struct sockaddr_in)
|
|
|
|
|
: sizeof(struct sockaddr_in6),
|
|
|
|
|
.ai_addr = (void *)&out[k].sa,
|
|
|
|
|
.ai_canonname = outcanon,
|
|
|
|
|
.ai_next = &out[k+1].ai };
|
|
|
|
|
switch (addrs[i].family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
out[k].sa.sin.sin_family = AF_INET;
|
|
|
|
|
out[k].sa.sin.sin_port = htons(ports[j].port);
|
|
|
|
|
memcpy(&out[k].sa.sin.sin_addr, &addrs[i].addr, 4);
|
|
|
|
|
break;
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
out[k].sa.sin6.sin6_family = AF_INET6;
|
|
|
|
|
out[k].sa.sin6.sin6_port = htons(ports[j].port);
|
|
|
|
|
out[k].sa.sin6.sin6_scope_id = addrs[i].scopeid;
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
memcpy(&out[k].sa.sin6.sin6_addr, &addrs[i].addr, 16);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
allow freeaddrinfo of arbitrary sublists of addrinfo list
the specification for freeaddrinfo allows it to be used to free
"arbitrary sublists" of the list returned by getaddrinfo. it's not
clearly stated how such sublists come into existence, but the
interpretation seems to be that the application can edit the ai_next
pointers to cut off a portion of the list and then free it.
actual freeing of individual list slots is contrary to the design of
our getaddrinfo implementation, which has no failure paths after
making a single allocation, so that light callers can avoid linking
realloc/free. freeing individual slots is also incompatible with
sharing the string for ai_canonname, which the current implementation
does despite no requirement that it be present except on the first
result. so, rather than actually freeing individual slots, provide a
way to find the start of the allocated array, and reference-count it,
freeing the memory all at once after the last slot has been freed.
since the language in the spec is "arbitrary sublists", no provision
for handling other constructs like multiple lists glued together,
circular links, etc. is made. presumably passing such a construct to
freeaddrinfo produces undefined behavior.
8 years ago
|
|
|
out[0].ref = nais;
|
refactor getaddrinfo and add support for most remaining features
this is the first phase of the "resolver overhaul" project.
conceptually, the results of getaddrinfo are a direct product of a
list of address results and a list of service results. the new code
makes this explicit by computing these lists separately and combining
the results. this adds support for services that have both tcp and udp
versions, where the caller has not specified which it wants, and
eliminates a number of duplicate code paths which were all producing
the final output addrinfo structures, but in subtly different ways,
making it difficult to implement any of the features which were
missing.
in addition to the above benefits, the refactoring allows for legacy
functions like gethostbyname to be implemented without using the
getaddrinfo function itself. such changes to the legacy functions have
not yet been made, however.
further improvements include matching of service alias names from
/etc/services (previously only the primary name was supported),
returning multiple results from /etc/hosts (previously only the first
matching line was honored), and support for the AI_V4MAPPED and AI_ALL
flags.
features which remain unimplemented are IDN translations (encoding
non-ASCII hostnames for DNS lookup) and the AI_ADDRCONFIG flag.
at this point, the DNS-based name resolving code is still based on the
old interfaces in __dns.c, albeit somewhat simpler in its use of them.
there may be some dead code which could already be removed, but
changes to this layer will be a later phase of the resolver overhaul.
12 years ago
|
|
|
out[nais-1].ai.ai_next = 0;
|
|
|
|
|
*res = &out->ai;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|