]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: Fix name lookup ordering when compiled with USE_GETADDRINFO
authorNenad Merdanovic <nimzo@nimzo.info>
Mon, 14 Apr 2014 13:56:58 +0000 (15:56 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 14 Apr 2014 13:56:58 +0000 (15:56 +0200)
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).

include/types/global.h
src/cfgparse.c
src/haproxy.c
src/standard.c

index 669ec236e443ab57477afaf0521ee9bfad1885c1..022c1b524032677f078f26aa9608d35bbb6c014f 100644 (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
index 611ea8dd9d6d505466db62884b3f6d9b5d95361a..124ad242eca3b62c122b87cc7e368f7caedd735f 100644 (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;
        }
index fb8c8a1352b8e92c55a5f1e0a8b4b627235e3366..67798b4089755ea89938e7644ed03cbe2f24a6da 100644 (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;
index 75a0389b8c64a315bc39f6f168b8fecb5d219adc..305c09e7f426c2ba63a2c96de9839c703fc59d6d 100644 (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;