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).
diff --git a/include/types/global.h b/include/types/global.h
index 669ec23..022c1b5 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -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
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 611ea8d..124ad24 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -506,6 +506,9 @@
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;
}
diff --git a/src/haproxy.c b/src/haproxy.c
index fb8c8a1..67798b4 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -385,6 +385,9 @@
#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"
"\n",
@@ -553,6 +556,9 @@
#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;
@@ -592,6 +598,10 @@
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;
else if (*flag == 'V')
diff --git a/src/standard.c b/src/standard.c
index 75a0389..305c09e 100644
--- a/src/standard.c
+++ b/src/standard.c
@@ -552,25 +552,8 @@
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 @@
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;