15ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/***************************************************************************
25ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                                  _   _ ____  _
35ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *  Project                     ___| | | |  _ \| |
45ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                             / __| | | | |_) | |
55ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                            | (__| |_| |  _ <| |___
65ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                             \___|\___/|_| \_\_____|
75ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
88f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
95ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is licensed as described in the file COPYING, which
115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * you should have received as part of this distribution. The terms
128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html.
135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * You may opt to use, copy, modify, merge, publish, distribute and/or sell
155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * copies of the Software, and permit persons to whom the Software is
165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * furnished to do so, under the terms of the COPYING file.
175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * KIND, either express or implied.
205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen ***************************************************************************/
225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h"
245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_NETINET_IN_H
265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <netinet/in.h>
275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_NETDB_H
295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <netdb.h>
305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_ARPA_INET_H
325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <arpa/inet.h>
335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef __VMS
355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <in.h>
365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <inet.h>
375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_PROCESS_H
405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <process.h>
415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "urldata.h"
445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "sendf.h"
455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "hostip.h"
465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "hash.h"
475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "share.h"
485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "strerror.h"
495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "url.h"
505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "inet_pton.h"
518f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo/* The last 3 #include files should be in this order */
52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_printf.h"
535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "curl_memory.h"
545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "memdebug.h"
555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/***********************************************************************
57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Only for plain IPv4 builds
585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen **********************************************************************/
59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */
605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * been set and returns TRUE if they are OK.
635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETbool Curl_ipvalid(struct connectdata *conn)
655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
66e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(conn->ip_version == CURL_IPRESOLVE_V6)
67e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* An IPv6 address was requested and we can't get/use one */
685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return FALSE;
695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return TRUE; /* OK, proceed */
715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef CURLRES_SYNCH
74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Curl_getaddrinfo() - the IPv4 synchronous version.
775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * The original code to this function was from the Dancer source code, written
795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * by Bjorn Reese, it has since been patched and modified considerably.
805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * gethostbyname_r() is the thread-safe version of the gethostbyname()
825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * function. When we build for plain IPv4, we attempt to use this
835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * function. There are _three_ different gethostbyname_r() versions, and we
845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * detect which one this platform supports in the configure script and set up
855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or
865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME
875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * has the corresponding rules. This is primarily on *nix. Note that some unix
885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * flavours have thread-safe versions of the plain gethostbyname() etc.
895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                                const char *hostname,
935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                                int port,
945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                                int *waitp)
955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *ai = NULL;
975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef CURL_DISABLE_VERBOSE_STRINGS
995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  (void)conn;
1005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
1015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  *waitp = 0; /* synchronous response only */
1035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  ai = Curl_ipv4_resolve_r(hostname, port);
1055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(!ai)
1065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    infof(conn->data, "Curl_ipv4_resolve_r failed for %s\n", hostname);
1075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return ai;
1095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
1105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* CURLRES_SYNCH */
1115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* CURLRES_IPV4 */
1125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
113e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES)
114e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
1155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
1165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function.
1175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
1185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This is used for both synchronous and asynchronous resolver builds,
1195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * implying that only threadsafe code and function calls may be used.
1205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
1215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
1225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
1235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                                   int port)
1245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
1255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3)
1265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  int res;
1275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
1285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *ai = NULL;
1295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct hostent *h = NULL;
1305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct in_addr in;
1315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct hostent *buf = NULL;
1325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
1345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* This is a dotted IP address 123.123.123.123-style */
1355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return Curl_ip2addr(AF_INET, &in, hostname, port);
1365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if defined(HAVE_GETADDRINFO_THREADSAFE)
1385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  else {
1395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    struct addrinfo hints;
140e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    char sbuf[12];
1415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    char *sbufptr = NULL;
1425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    memset(&hints, 0, sizeof(hints));
1445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    hints.ai_family = PF_INET;
1455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    hints.ai_socktype = SOCK_STREAM;
1465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(port) {
1475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      snprintf(sbuf, sizeof(sbuf), "%d", port);
1485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      sbufptr = sbuf;
1495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
1509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai);
1525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#elif defined(HAVE_GETHOSTBYNAME_R)
1545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /*
1555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * gethostbyname_r() is the preferred resolve function for many platforms.
1565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * Since there are three different versions of it, the following code is
1575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * somewhat #ifdef-ridden.
1585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   */
1595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  else {
1605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    int h_errnop;
1615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    buf = calloc(1, CURL_HOSTENT_SIZE);
1635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(!buf)
1645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return NULL; /* major failure */
1655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /*
1665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * The clearing of the buffer is a workaround for a gethostbyname_r bug in
1675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * qnx nto and it is also _required_ for some of these functions on some
1685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * platforms.
1695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     */
1705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if defined(HAVE_GETHOSTBYNAME_R_5)
1725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Solaris, IRIX and more */
1735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    h = gethostbyname_r(hostname,
1745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        (struct hostent *)buf,
1755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        (char *)buf + sizeof(struct hostent),
1765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
1775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        &h_errnop);
1785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* If the buffer is too small, it returns NULL and sets errno to
1805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * ERANGE. The errno is thread safe if this is compiled with
1815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * -D_REENTRANT as then the 'errno' variable is a macro defined to get
1825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * used properly for threads.
1835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     */
1845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(h) {
1865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      ;
1875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
1885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    else
1895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#elif defined(HAVE_GETHOSTBYNAME_R_6)
1905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Linux */
1915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    (void)gethostbyname_r(hostname,
1935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        (struct hostent *)buf,
1945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        (char *)buf + sizeof(struct hostent),
1955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
1965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        &h, /* DIFFERENCE */
1975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                        &h_errnop);
1985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
1995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * sudden this function returns EAGAIN if the given buffer size is too
2005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * small. Previous versions are known to return ERANGE for the same
2015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * problem.
2025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * This wouldn't be such a big problem if older versions wouldn't
2045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * sometimes return EAGAIN on a common failure case. Alas, we can't
2055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
2065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * glibc.
2075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * For now, we do that and thus we may call the function repeatedly and
2095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * fail for older glibc versions that return EAGAIN, until we run out of
2105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
2115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * If anyone has a better fix, please tell us!
2135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * -------------------------------------------------------------------
2155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * On October 23rd 2003, Dan C dug up more details on the mysteries of
2175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * gethostbyname_r() in glibc:
2185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * In glibc 2.2.5 the interface is different (this has also been
2205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
2215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
2225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * (shipped/upgraded by Redhat 7.2) don't show this behavior!
2235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * In this "buggy" version, the return code is -1 on error and 'errno'
2255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
2265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * thread-safe variable.
2275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     */
2285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(!h) /* failure */
2305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#elif defined(HAVE_GETHOSTBYNAME_R_3)
2315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* AIX, Digital Unix/Tru64, HPUX 10, more? */
2325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
2345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * the plain fact that it does not return unique full buffers on each
2355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * call, but instead several of the pointers in the hostent structs will
2365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * point to the same actual data! This have the unfortunate down-side that
2375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * our caching system breaks down horribly. Luckily for us though, AIX 4.3
2385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * and more recent versions have a "completely thread-safe"[*] libc where
2395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * all the data is stored in thread-specific memory areas making calls to
2405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * the plain old gethostbyname() work fine even for multi-threaded
2415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * programs.
2425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * This AIX 4.3 or later detection is all made in the configure script.
2445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
2465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     *
2475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * [*] = much later we've found out that it isn't at all "completely
2485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * thread-safe", but at least the gethostbyname() function is.
2495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     */
2505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(CURL_HOSTENT_SIZE >=
2525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       (sizeof(struct hostent)+sizeof(struct hostent_data))) {
2535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
2555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * that should work! September 20: Richard Prescott worked on the buffer
2565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * size dilemma.
2575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       */
2585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      res = gethostbyname_r(hostname,
2605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                            (struct hostent *)buf,
2615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                            (struct hostent_data *)((char *)buf +
2625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                                                    sizeof(struct hostent)));
2635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */
2645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
2655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    else
2665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      res = -1; /* failure, too smallish buffer size */
2675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(!res) { /* success */
2695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      h = buf; /* result expected in h */
2715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* This is the worst kind of the different gethostbyname_r() interfaces.
2735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * Since we don't know how big buffer this particular lookup required,
2745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * we can't realloc down the huge alloc without doing closer analysis of
2755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
2765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * name lookup. Fixing this would require an extra malloc() and then
2775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
2785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * memory area to the actually used amount.
2795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       */
2805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
2815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    else
2825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */
2835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    {
2845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      h = NULL; /* set return code to NULL */
2855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(buf);
2865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
2875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
2885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /*
2895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * Here is code for platforms that don't have a thread safe
2905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * getaddrinfo() nor gethostbyname_r() function or for which
2915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     * gethostbyname() is the preferred one.
2925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     */
2935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  else {
2945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    h = gethostbyname((void*)hostname);
2955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
2965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
2975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(h) {
2995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ai = Curl_he2ai(h, port);
3005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(buf) /* used a *_r() function */
3025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(buf);
3035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
3045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return ai;
3065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
307e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */
308