diff --git a/include/netdb.h b/include/netdb.h index adde2c5e..73d850f6 100644 --- a/include/netdb.h +++ b/include/netdb.h @@ -44,6 +44,7 @@ struct addrinfo { #define EAI_NONAME -2 #define EAI_AGAIN -3 #define EAI_FAIL -4 +#define EAI_NODATA -5 #define EAI_FAMILY -6 #define EAI_SOCKTYPE -7 #define EAI_SERVICE -8 diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c index b9439f77..2bfba18f 100644 --- a/src/network/getaddrinfo.c +++ b/src/network/getaddrinfo.c @@ -19,6 +19,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru struct sockaddr_in6 sin6; } sa; } *out; + struct addrconfig addrconfig; if (!host && !serv) return EAI_NONAME; @@ -33,6 +34,10 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru if ((flags & mask) != flags) return EAI_BADFLAGS; + if (flags & AI_ADDRCONFIG) { + __lookup_addrconfig(&addrconfig); + } + switch (family) { case AF_INET: case AF_INET6: @@ -61,30 +66,43 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru outcanon = 0; } - for (k=i=0; iai; diff --git a/src/network/lookup.h b/src/network/lookup.h index 0468edbc..32afd545 100644 --- a/src/network/lookup.h +++ b/src/network/lookup.h @@ -1,6 +1,7 @@ #ifndef LOOKUP_H #define LOOKUP_H +#include #include #include @@ -30,9 +31,15 @@ struct resolvconf { #define MAXADDRS 48 #define MAXSERVS 2 +struct addrconfig { + bool af_inet : 1; + bool af_inet6 : 1; +}; + int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags); int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags); int __lookup_ipliteral(struct address buf[static 1], const char *name, int family); +void __lookup_addrconfig( struct addrconfig *cfg ); int __get_resolv_conf(struct resolvconf *, char *, size_t); diff --git a/src/network/lookup_addrconfig.c b/src/network/lookup_addrconfig.c new file mode 100644 index 00000000..427d9299 --- /dev/null +++ b/src/network/lookup_addrconfig.c @@ -0,0 +1,40 @@ +#include "lookup.h" + +#include +#include +#include +#include +#include + +void __lookup_addrconfig( struct addrconfig *cfg ) { + int r; + int fd; + + struct sockaddr_in sai = { + .sin_family = AF_INET, + .sin_port = htons( 42 ), + .sin_addr.s_addr = INADDR_LOOPBACK, + }; + cfg->af_inet = false; + r = socket( AF_INET, SOCK_DGRAM, 0 ); + if ( -1 != r ) { + fd = r; + r = connect( fd, (struct sockaddr *) & sai, sizeof( sai ) ); + cfg->af_inet = 0 == r; + close( fd ); + } + + struct sockaddr_in6 sai6 = { + .sin6_family = AF_INET6, + .sin6_port = htons( 42 ), + .sin6_addr = IN6ADDR_LOOPBACK_INIT, + }; + cfg->af_inet6 = false; + r = socket( AF_INET6, SOCK_DGRAM, 0 ); + if ( -1 != r ) { + fd = r; + r = connect( fd, (struct sockaddr *) & sai6, sizeof( sai6 ) ); + cfg->af_inet6 = 0 == r; + close( fd ); + } +}