You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.4 KiB

#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>
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;
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 aibuf {
struct addrinfo ai;
union sa {
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} sa;
} *out;
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;
}
}
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].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;
}
}
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;
}