113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci/*********************************************************************** 2813498266Sopenharmony_ci * Only for plain IPv4 builds 2913498266Sopenharmony_ci **********************************************************************/ 3013498266Sopenharmony_ci#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */ 3113498266Sopenharmony_ci 3213498266Sopenharmony_ci#ifdef HAVE_NETINET_IN_H 3313498266Sopenharmony_ci#include <netinet/in.h> 3413498266Sopenharmony_ci#endif 3513498266Sopenharmony_ci#ifdef HAVE_NETDB_H 3613498266Sopenharmony_ci#include <netdb.h> 3713498266Sopenharmony_ci#endif 3813498266Sopenharmony_ci#ifdef HAVE_ARPA_INET_H 3913498266Sopenharmony_ci#include <arpa/inet.h> 4013498266Sopenharmony_ci#endif 4113498266Sopenharmony_ci#ifdef __VMS 4213498266Sopenharmony_ci#include <in.h> 4313498266Sopenharmony_ci#include <inet.h> 4413498266Sopenharmony_ci#endif 4513498266Sopenharmony_ci 4613498266Sopenharmony_ci#include "urldata.h" 4713498266Sopenharmony_ci#include "sendf.h" 4813498266Sopenharmony_ci#include "hostip.h" 4913498266Sopenharmony_ci#include "hash.h" 5013498266Sopenharmony_ci#include "share.h" 5113498266Sopenharmony_ci#include "url.h" 5213498266Sopenharmony_ci/* The last 3 #include files should be in this order */ 5313498266Sopenharmony_ci#include "curl_printf.h" 5413498266Sopenharmony_ci#include "curl_memory.h" 5513498266Sopenharmony_ci#include "memdebug.h" 5613498266Sopenharmony_ci 5713498266Sopenharmony_ci/* 5813498266Sopenharmony_ci * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've 5913498266Sopenharmony_ci * been set and returns TRUE if they are OK. 6013498266Sopenharmony_ci */ 6113498266Sopenharmony_cibool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn) 6213498266Sopenharmony_ci{ 6313498266Sopenharmony_ci (void)data; 6413498266Sopenharmony_ci if(conn->ip_version == CURL_IPRESOLVE_V6) 6513498266Sopenharmony_ci /* An IPv6 address was requested and we can't get/use one */ 6613498266Sopenharmony_ci return FALSE; 6713498266Sopenharmony_ci 6813498266Sopenharmony_ci return TRUE; /* OK, proceed */ 6913498266Sopenharmony_ci} 7013498266Sopenharmony_ci 7113498266Sopenharmony_ci#ifdef CURLRES_SYNCH 7213498266Sopenharmony_ci 7313498266Sopenharmony_ci/* 7413498266Sopenharmony_ci * Curl_getaddrinfo() - the IPv4 synchronous version. 7513498266Sopenharmony_ci * 7613498266Sopenharmony_ci * The original code to this function was from the Dancer source code, written 7713498266Sopenharmony_ci * by Bjorn Reese, it has since been patched and modified considerably. 7813498266Sopenharmony_ci * 7913498266Sopenharmony_ci * gethostbyname_r() is the thread-safe version of the gethostbyname() 8013498266Sopenharmony_ci * function. When we build for plain IPv4, we attempt to use this 8113498266Sopenharmony_ci * function. There are _three_ different gethostbyname_r() versions, and we 8213498266Sopenharmony_ci * detect which one this platform supports in the configure script and set up 8313498266Sopenharmony_ci * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or 8413498266Sopenharmony_ci * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME 8513498266Sopenharmony_ci * has the corresponding rules. This is primarily on *nix. Note that some unix 8613498266Sopenharmony_ci * flavours have thread-safe versions of the plain gethostbyname() etc. 8713498266Sopenharmony_ci * 8813498266Sopenharmony_ci */ 8913498266Sopenharmony_cistruct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, 9013498266Sopenharmony_ci const char *hostname, 9113498266Sopenharmony_ci int port, 9213498266Sopenharmony_ci int *waitp) 9313498266Sopenharmony_ci{ 9413498266Sopenharmony_ci struct Curl_addrinfo *ai = NULL; 9513498266Sopenharmony_ci 9613498266Sopenharmony_ci#ifdef CURL_DISABLE_VERBOSE_STRINGS 9713498266Sopenharmony_ci (void)data; 9813498266Sopenharmony_ci#endif 9913498266Sopenharmony_ci 10013498266Sopenharmony_ci *waitp = 0; /* synchronous response only */ 10113498266Sopenharmony_ci 10213498266Sopenharmony_ci ai = Curl_ipv4_resolve_r(hostname, port); 10313498266Sopenharmony_ci if(!ai) 10413498266Sopenharmony_ci infof(data, "Curl_ipv4_resolve_r failed for %s", hostname); 10513498266Sopenharmony_ci 10613498266Sopenharmony_ci return ai; 10713498266Sopenharmony_ci} 10813498266Sopenharmony_ci#endif /* CURLRES_SYNCH */ 10913498266Sopenharmony_ci#endif /* CURLRES_IPV4 */ 11013498266Sopenharmony_ci 11113498266Sopenharmony_ci#if defined(CURLRES_IPV4) && \ 11213498266Sopenharmony_ci !defined(CURLRES_ARES) && !defined(CURLRES_AMIGA) 11313498266Sopenharmony_ci 11413498266Sopenharmony_ci/* 11513498266Sopenharmony_ci * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function. 11613498266Sopenharmony_ci * 11713498266Sopenharmony_ci * This is used for both synchronous and asynchronous resolver builds, 11813498266Sopenharmony_ci * implying that only threadsafe code and function calls may be used. 11913498266Sopenharmony_ci * 12013498266Sopenharmony_ci */ 12113498266Sopenharmony_cistruct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, 12213498266Sopenharmony_ci int port) 12313498266Sopenharmony_ci{ 12413498266Sopenharmony_ci#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)) && \ 12513498266Sopenharmony_ci defined(HAVE_GETHOSTBYNAME_R_3) 12613498266Sopenharmony_ci int res; 12713498266Sopenharmony_ci#endif 12813498266Sopenharmony_ci struct Curl_addrinfo *ai = NULL; 12913498266Sopenharmony_ci struct hostent *h = NULL; 13013498266Sopenharmony_ci struct hostent *buf = NULL; 13113498266Sopenharmony_ci 13213498266Sopenharmony_ci#if defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE) 13313498266Sopenharmony_ci struct addrinfo hints; 13413498266Sopenharmony_ci char sbuf[12]; 13513498266Sopenharmony_ci char *sbufptr = NULL; 13613498266Sopenharmony_ci 13713498266Sopenharmony_ci memset(&hints, 0, sizeof(hints)); 13813498266Sopenharmony_ci hints.ai_family = PF_INET; 13913498266Sopenharmony_ci hints.ai_socktype = SOCK_STREAM; 14013498266Sopenharmony_ci if(port) { 14113498266Sopenharmony_ci msnprintf(sbuf, sizeof(sbuf), "%d", port); 14213498266Sopenharmony_ci sbufptr = sbuf; 14313498266Sopenharmony_ci } 14413498266Sopenharmony_ci 14513498266Sopenharmony_ci (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai); 14613498266Sopenharmony_ci 14713498266Sopenharmony_ci#elif defined(HAVE_GETHOSTBYNAME_R) 14813498266Sopenharmony_ci /* 14913498266Sopenharmony_ci * gethostbyname_r() is the preferred resolve function for many platforms. 15013498266Sopenharmony_ci * Since there are three different versions of it, the following code is 15113498266Sopenharmony_ci * somewhat #ifdef-ridden. 15213498266Sopenharmony_ci */ 15313498266Sopenharmony_ci int h_errnop; 15413498266Sopenharmony_ci 15513498266Sopenharmony_ci buf = calloc(1, CURL_HOSTENT_SIZE); 15613498266Sopenharmony_ci if(!buf) 15713498266Sopenharmony_ci return NULL; /* major failure */ 15813498266Sopenharmony_ci /* 15913498266Sopenharmony_ci * The clearing of the buffer is a workaround for a gethostbyname_r bug in 16013498266Sopenharmony_ci * qnx nto and it is also _required_ for some of these functions on some 16113498266Sopenharmony_ci * platforms. 16213498266Sopenharmony_ci */ 16313498266Sopenharmony_ci 16413498266Sopenharmony_ci#if defined(HAVE_GETHOSTBYNAME_R_5) 16513498266Sopenharmony_ci /* Solaris, IRIX and more */ 16613498266Sopenharmony_ci h = gethostbyname_r(hostname, 16713498266Sopenharmony_ci (struct hostent *)buf, 16813498266Sopenharmony_ci (char *)buf + sizeof(struct hostent), 16913498266Sopenharmony_ci CURL_HOSTENT_SIZE - sizeof(struct hostent), 17013498266Sopenharmony_ci &h_errnop); 17113498266Sopenharmony_ci 17213498266Sopenharmony_ci /* If the buffer is too small, it returns NULL and sets errno to 17313498266Sopenharmony_ci * ERANGE. The errno is thread safe if this is compiled with 17413498266Sopenharmony_ci * -D_REENTRANT as then the 'errno' variable is a macro defined to get 17513498266Sopenharmony_ci * used properly for threads. 17613498266Sopenharmony_ci */ 17713498266Sopenharmony_ci 17813498266Sopenharmony_ci if(h) { 17913498266Sopenharmony_ci ; 18013498266Sopenharmony_ci } 18113498266Sopenharmony_ci else 18213498266Sopenharmony_ci#elif defined(HAVE_GETHOSTBYNAME_R_6) 18313498266Sopenharmony_ci /* Linux */ 18413498266Sopenharmony_ci 18513498266Sopenharmony_ci (void)gethostbyname_r(hostname, 18613498266Sopenharmony_ci (struct hostent *)buf, 18713498266Sopenharmony_ci (char *)buf + sizeof(struct hostent), 18813498266Sopenharmony_ci CURL_HOSTENT_SIZE - sizeof(struct hostent), 18913498266Sopenharmony_ci &h, /* DIFFERENCE */ 19013498266Sopenharmony_ci &h_errnop); 19113498266Sopenharmony_ci /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a 19213498266Sopenharmony_ci * sudden this function returns EAGAIN if the given buffer size is too 19313498266Sopenharmony_ci * small. Previous versions are known to return ERANGE for the same 19413498266Sopenharmony_ci * problem. 19513498266Sopenharmony_ci * 19613498266Sopenharmony_ci * This wouldn't be such a big problem if older versions wouldn't 19713498266Sopenharmony_ci * sometimes return EAGAIN on a common failure case. Alas, we can't 19813498266Sopenharmony_ci * assume that EAGAIN *or* ERANGE means ERANGE for any given version of 19913498266Sopenharmony_ci * glibc. 20013498266Sopenharmony_ci * 20113498266Sopenharmony_ci * For now, we do that and thus we may call the function repeatedly and 20213498266Sopenharmony_ci * fail for older glibc versions that return EAGAIN, until we run out of 20313498266Sopenharmony_ci * buffer size (step_size grows beyond CURL_HOSTENT_SIZE). 20413498266Sopenharmony_ci * 20513498266Sopenharmony_ci * If anyone has a better fix, please tell us! 20613498266Sopenharmony_ci * 20713498266Sopenharmony_ci * ------------------------------------------------------------------- 20813498266Sopenharmony_ci * 20913498266Sopenharmony_ci * On October 23rd 2003, Dan C dug up more details on the mysteries of 21013498266Sopenharmony_ci * gethostbyname_r() in glibc: 21113498266Sopenharmony_ci * 21213498266Sopenharmony_ci * In glibc 2.2.5 the interface is different (this has also been 21313498266Sopenharmony_ci * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't 21413498266Sopenharmony_ci * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32 21513498266Sopenharmony_ci * (shipped/upgraded by Redhat 7.2) don't show this behavior! 21613498266Sopenharmony_ci * 21713498266Sopenharmony_ci * In this "buggy" version, the return code is -1 on error and 'errno' 21813498266Sopenharmony_ci * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a 21913498266Sopenharmony_ci * thread-safe variable. 22013498266Sopenharmony_ci */ 22113498266Sopenharmony_ci 22213498266Sopenharmony_ci if(!h) /* failure */ 22313498266Sopenharmony_ci#elif defined(HAVE_GETHOSTBYNAME_R_3) 22413498266Sopenharmony_ci /* AIX, Digital Unix/Tru64, HPUX 10, more? */ 22513498266Sopenharmony_ci 22613498266Sopenharmony_ci /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of 22713498266Sopenharmony_ci * the plain fact that it does not return unique full buffers on each 22813498266Sopenharmony_ci * call, but instead several of the pointers in the hostent structs will 22913498266Sopenharmony_ci * point to the same actual data! This have the unfortunate down-side that 23013498266Sopenharmony_ci * our caching system breaks down horribly. Luckily for us though, AIX 4.3 23113498266Sopenharmony_ci * and more recent versions have a "completely thread-safe"[*] libc where 23213498266Sopenharmony_ci * all the data is stored in thread-specific memory areas making calls to 23313498266Sopenharmony_ci * the plain old gethostbyname() work fine even for multi-threaded 23413498266Sopenharmony_ci * programs. 23513498266Sopenharmony_ci * 23613498266Sopenharmony_ci * This AIX 4.3 or later detection is all made in the configure script. 23713498266Sopenharmony_ci * 23813498266Sopenharmony_ci * Troels Walsted Hansen helped us work this out on March 3rd, 2003. 23913498266Sopenharmony_ci * 24013498266Sopenharmony_ci * [*] = much later we've found out that it isn't at all "completely 24113498266Sopenharmony_ci * thread-safe", but at least the gethostbyname() function is. 24213498266Sopenharmony_ci */ 24313498266Sopenharmony_ci 24413498266Sopenharmony_ci if(CURL_HOSTENT_SIZE >= 24513498266Sopenharmony_ci (sizeof(struct hostent) + sizeof(struct hostent_data))) { 24613498266Sopenharmony_ci 24713498266Sopenharmony_ci /* August 22nd, 2000: Albert Chin-A-Young brought an updated version 24813498266Sopenharmony_ci * that should work! September 20: Richard Prescott worked on the buffer 24913498266Sopenharmony_ci * size dilemma. 25013498266Sopenharmony_ci */ 25113498266Sopenharmony_ci 25213498266Sopenharmony_ci res = gethostbyname_r(hostname, 25313498266Sopenharmony_ci (struct hostent *)buf, 25413498266Sopenharmony_ci (struct hostent_data *)((char *)buf + 25513498266Sopenharmony_ci sizeof(struct hostent))); 25613498266Sopenharmony_ci h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */ 25713498266Sopenharmony_ci } 25813498266Sopenharmony_ci else 25913498266Sopenharmony_ci res = -1; /* failure, too smallish buffer size */ 26013498266Sopenharmony_ci 26113498266Sopenharmony_ci if(!res) { /* success */ 26213498266Sopenharmony_ci 26313498266Sopenharmony_ci h = buf; /* result expected in h */ 26413498266Sopenharmony_ci 26513498266Sopenharmony_ci /* This is the worst kind of the different gethostbyname_r() interfaces. 26613498266Sopenharmony_ci * Since we don't know how big buffer this particular lookup required, 26713498266Sopenharmony_ci * we can't realloc down the huge alloc without doing closer analysis of 26813498266Sopenharmony_ci * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every 26913498266Sopenharmony_ci * name lookup. Fixing this would require an extra malloc() and then 27013498266Sopenharmony_ci * calling Curl_addrinfo_copy() that subsequent realloc()s down the new 27113498266Sopenharmony_ci * memory area to the actually used amount. 27213498266Sopenharmony_ci */ 27313498266Sopenharmony_ci } 27413498266Sopenharmony_ci else 27513498266Sopenharmony_ci#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */ 27613498266Sopenharmony_ci { 27713498266Sopenharmony_ci h = NULL; /* set return code to NULL */ 27813498266Sopenharmony_ci free(buf); 27913498266Sopenharmony_ci } 28013498266Sopenharmony_ci#else /* (HAVE_GETADDRINFO && HAVE_GETADDRINFO_THREADSAFE) || 28113498266Sopenharmony_ci HAVE_GETHOSTBYNAME_R */ 28213498266Sopenharmony_ci /* 28313498266Sopenharmony_ci * Here is code for platforms that don't have a thread safe 28413498266Sopenharmony_ci * getaddrinfo() nor gethostbyname_r() function or for which 28513498266Sopenharmony_ci * gethostbyname() is the preferred one. 28613498266Sopenharmony_ci */ 28713498266Sopenharmony_ci h = gethostbyname((void *)hostname); 28813498266Sopenharmony_ci#endif /* (HAVE_GETADDRINFO && HAVE_GETADDRINFO_THREADSAFE) || 28913498266Sopenharmony_ci HAVE_GETHOSTBYNAME_R */ 29013498266Sopenharmony_ci 29113498266Sopenharmony_ci if(h) { 29213498266Sopenharmony_ci ai = Curl_he2ai(h, port); 29313498266Sopenharmony_ci 29413498266Sopenharmony_ci if(buf) /* used a *_r() function */ 29513498266Sopenharmony_ci free(buf); 29613498266Sopenharmony_ci } 29713498266Sopenharmony_ci 29813498266Sopenharmony_ci return ai; 29913498266Sopenharmony_ci} 30013498266Sopenharmony_ci#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) && 30113498266Sopenharmony_ci !defined(CURLRES_AMIGA) */ 302