BUG/MINOR: Fix name lookup ordering when compiled with USE_GETADDRINFO

When compiled with USE_GETADDRINFO, make sure we use getaddrinfo(3) to
perform name lookups. On default dual-stack setups this will change the
behavior of using IPv6 first. Global configuration option
'nogetaddrinfo' can be used to revert to deprecated gethostbyname(3).
This commit is contained in:
Nenad Merdanovic 2014-04-14 15:56:58 +02:00 committed by Willy Tarreau
parent 914c0d67b2
commit 88afe03778
4 changed files with 33 additions and 18 deletions

View File

@ -57,6 +57,7 @@
#define GTUNE_USE_KQUEUE (1<<3)
/* platform-specific options */
#define GTUNE_USE_SPLICE (1<<4)
#define GTUNE_USE_GAI (1<<5)
/* Access level for a stats socket */
#define ACCESS_LVL_NONE 0

View File

@ -506,6 +506,9 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
else if (!strcmp(args[0], "nosplice")) {
global.tune.options &= ~GTUNE_USE_SPLICE;
}
else if (!strcmp(args[0], "nogetaddrinfo")) {
global.tune.options &= ~GTUNE_USE_GAI;
}
else if (!strcmp(args[0], "quiet")) {
global.mode |= MODE_QUIET;
}

View File

@ -384,6 +384,9 @@ void usage(char *name)
#endif
#if defined(CONFIG_HAP_LINUX_SPLICE)
" -dS disables splice usage (broken on old kernels)\n"
#endif
#if defined(USE_GETADDRINFO)
" -dG disables getaddrinfo() usage\n"
#endif
" -dV disables SSL verify on servers side\n"
" -sf/-st [pid ]* finishes/terminates old pids. Must be last arguments.\n"
@ -553,6 +556,9 @@ void init(int argc, char **argv)
#if defined(CONFIG_HAP_LINUX_SPLICE)
global.tune.options |= GTUNE_USE_SPLICE;
#endif
#if defined(USE_GETADDRINFO)
global.tune.options |= GTUNE_USE_GAI;
#endif
pid = getpid();
progname = *argv;
@ -591,6 +597,10 @@ void init(int argc, char **argv)
#if defined(CONFIG_HAP_LINUX_SPLICE)
else if (*flag == 'd' && flag[1] == 'S')
global.tune.options &= ~GTUNE_USE_SPLICE;
#endif
#if defined(USE_GETADDRINFO)
else if (*flag == 'd' && flag[1] == 'G')
global.tune.options &= ~GTUNE_USE_GAI;
#endif
else if (*flag == 'd' && flag[1] == 'V')
global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;

View File

@ -552,25 +552,8 @@ static struct sockaddr_storage *str2ip(const char *str, struct sockaddr_storage
return sa;
}
/* try to resolve an IPv4/IPv6 hostname */
he = gethostbyname(str);
if (he) {
if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
sa->ss_family = he->h_addrtype;
else if (sa->ss_family != he->h_addrtype)
goto fail;
switch (sa->ss_family) {
case AF_INET:
((struct sockaddr_in *)sa)->sin_addr = *(struct in_addr *) *(he->h_addr_list);
return sa;
case AF_INET6:
((struct sockaddr_in6 *)sa)->sin6_addr = *(struct in6_addr *) *(he->h_addr_list);
return sa;
}
}
#ifdef USE_GETADDRINFO
else {
if (global.tune.options & GTUNE_USE_GAI) {
struct addrinfo hints, *result;
memset(&result, 0, sizeof(result));
@ -600,6 +583,24 @@ static struct sockaddr_storage *str2ip(const char *str, struct sockaddr_storage
freeaddrinfo(result);
}
#endif
/* try to resolve an IPv4/IPv6 hostname */
he = gethostbyname(str);
if (he) {
if (!sa->ss_family || sa->ss_family == AF_UNSPEC)
sa->ss_family = he->h_addrtype;
else if (sa->ss_family != he->h_addrtype)
goto fail;
switch (sa->ss_family) {
case AF_INET:
((struct sockaddr_in *)sa)->sin_addr = *(struct in_addr *) *(he->h_addr_list);
return sa;
case AF_INET6:
((struct sockaddr_in6 *)sa)->sin6_addr = *(struct in6_addr *) *(he->h_addr_list);
return sa;
}
}
/* unsupported address family */
fail:
return NULL;