15ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/***************************************************************************
25ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                                  _   _ ____  _
35ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *  Project                     ___| | | |  _ \| |
45ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                             / __| | | | |_) | |
55ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                            | (__| |_| |  _ <| |___
65ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                             \___|\___/|_| \_\_____|
75ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
8d15eaac64ca1a7244824d660ea84e8815a23d058Alex 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
12d15eaac64ca1a7244824d660ea84e8815a23d058Alex 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#include <curl/curl.h>
265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_NETINET_IN_H
285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#  include <netinet/in.h>
295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_NETDB_H
315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#  include <netdb.h>
325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_ARPA_INET_H
345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#  include <arpa/inet.h>
355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
36e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef HAVE_SYS_UN_H
37e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#  include <sys/un.h>
38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef __VMS
415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#  include <in.h>
425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#  include <inet.h>
435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if defined(NETWARE) && defined(__NOVELL_LIBC__)
465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#  undef  in_addr_t
475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#  define in_addr_t unsigned long
485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "curl_addrinfo.h"
51e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "inet_pton.h"
52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "warnless.h"
53d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo/* The last 3 #include files should be in this order */
54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_printf.h"
555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "curl_memory.h"
565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "memdebug.h"
575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_freeaddrinfo()
605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This is used to free a linked list of Curl_addrinfo structs along
625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * with all its associated allocated storage. This function should be
635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * called once for each successful call to Curl_getaddrinfo_ex() or to
645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * any function call which actually allocates a Curl_addrinfo struct.
655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    defined(__OPTIMIZE__) && defined(__unix__) &&  defined(__i386__)
695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* workaround icc 9.1 optimizer issue */
705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen# define vqualifier volatile
715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#else
725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen# define vqualifier
735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenvoid
765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_freeaddrinfo(Curl_addrinfo *cahead)
775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *vqualifier canext;
795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *ca;
805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  for(ca = cahead; ca != NULL; ca = canext) {
82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    free(ca->ai_addr);
83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    free(ca->ai_canonname);
845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    canext = ca->ai_next;
855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    free(ca);
875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_GETADDRINFO
925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_getaddrinfo_ex()
945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This is a wrapper function around system's getaddrinfo(), with
965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * the only difference that instead of returning a linked list of
975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * addrinfo structs this one returns a linked list of Curl_addrinfo
985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * ones. The memory allocated by this function *MUST* be free'd with
995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_freeaddrinfo().  For each successful call to this function
1005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * there must be an associated call later to Curl_freeaddrinfo().
1015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
1025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * There should be no single call to system's getaddrinfo() in the
1035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * whole library, any such call should be 'routed' through this one.
1045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
1055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenint
1075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_getaddrinfo_ex(const char *nodename,
1085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                    const char *servname,
1095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                    const struct addrinfo *hints,
1105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                    Curl_addrinfo **result)
1115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
1125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  const struct addrinfo *ai;
1135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct addrinfo *aihead;
1145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *cafirst = NULL;
1155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *calast = NULL;
1165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *ca;
117e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  size_t ss_size;
1185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  int error;
1195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  *result = NULL; /* assume failure */
1215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  error = getaddrinfo(nodename, servname, hints, &aihead);
1235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(error)
1245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return error;
1255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
126e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  /* traverse the addrinfo list */
127e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
128e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  for(ai = aihead; ai != NULL; ai = ai->ai_next) {
129e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
130e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* ignore elements with unsupported address family, */
131e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* settle family-specific sockaddr structure size.  */
132e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(ai->ai_family == AF_INET)
133e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      ss_size = sizeof(struct sockaddr_in);
134e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef ENABLE_IPV6
135e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    else if(ai->ai_family == AF_INET6)
136e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      ss_size = sizeof(struct sockaddr_in6);
137e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
138e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    else
139e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      continue;
140e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
141e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* ignore elements without required address info */
142e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0))
143e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      continue;
144e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
145e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* ignore elements with bogus address size */
146e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if((size_t)ai->ai_addrlen < ss_size)
147e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      continue;
1485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
1505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      error = EAI_MEMORY;
1515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      break;
1525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
1535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* copy each structure member individually, member ordering, */
155e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* size, or padding might be different for each platform.    */
1565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ca->ai_flags     = ai->ai_flags;
1585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ca->ai_family    = ai->ai_family;
1595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ca->ai_socktype  = ai->ai_socktype;
1605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ca->ai_protocol  = ai->ai_protocol;
161e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    ca->ai_addrlen   = (curl_socklen_t)ss_size;
1625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ca->ai_addr      = NULL;
1635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ca->ai_canonname = NULL;
1645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ca->ai_next      = NULL;
1655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
166e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if((ca->ai_addr = malloc(ss_size)) == NULL) {
167e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      error = EAI_MEMORY;
168e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      free(ca);
169e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      break;
1705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
171e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    memcpy(ca->ai_addr, ai->ai_addr, ss_size);
1725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(ai->ai_canonname != NULL) {
1745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
1755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        error = EAI_MEMORY;
176e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        free(ca->ai_addr);
1775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        free(ca);
1785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        break;
1795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      }
1805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
1815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* if the return list is empty, this becomes the first element */
1835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(!cafirst)
1845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      cafirst = ca;
1855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* add this element last in the return list */
1875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(calast)
1885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      calast->ai_next = ca;
1895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    calast = ca;
1905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
1925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* destroy the addrinfo list */
1945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(aihead)
1955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    freeaddrinfo(aihead);
1965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* if we failed, also destroy the Curl_addrinfo list */
1985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(error) {
1995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    Curl_freeaddrinfo(cafirst);
2005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    cafirst = NULL;
2015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
202e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  else if(!cafirst) {
203e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef EAI_NONAME
204e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* rfc3493 conformant */
205e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    error = EAI_NONAME;
206e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#else
207e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* rfc3493 obsoleted */
208e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    error = EAI_NODATA;
209e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
210e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef USE_WINSOCK
211e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    SET_SOCKERRNO(error);
212e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
213e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
2145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  *result = cafirst;
2165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* This is not a CURLcode */
2185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return error;
2195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
2205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* HAVE_GETADDRINFO */
2215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
2245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_he2ai()
2255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
2265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This function returns a pointer to the first element of a newly allocated
2275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_addrinfo struct linked list filled with the data of a given hostent.
2285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6
2295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * stack, but usable also for IPv4, all hosts and environments.
2305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
2315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * The memory allocated by this function *MUST* be free'd later on calling
2325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_freeaddrinfo().  For each successful call to this function there
2335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * must be an associated call later to Curl_freeaddrinfo().
2345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
2355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *   Curl_addrinfo defined in "lib/curl_addrinfo.h"
2365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
2375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *     struct Curl_addrinfo {
2385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       int                   ai_flags;
2395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       int                   ai_family;
2405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       int                   ai_socktype;
2415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       int                   ai_protocol;
2425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       curl_socklen_t        ai_addrlen;   * Follow rfc3493 struct addrinfo *
2435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       char                 *ai_canonname;
2445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       struct sockaddr      *ai_addr;
2455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       struct Curl_addrinfo *ai_next;
2465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *     };
2475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *     typedef struct Curl_addrinfo Curl_addrinfo;
2485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
2495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *   hostent defined in <netdb.h>
2505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
2515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *     struct hostent {
2525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       char    *h_name;
2535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       char    **h_aliases;
2545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       int     h_addrtype;
2555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       int     h_length;
2565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *       char    **h_addr_list;
2575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *     };
2585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
2595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *   for backward compatibility:
2605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
2615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *     #define h_addr  h_addr_list[0]
2625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
2635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_addrinfo *
2655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_he2ai(const struct hostent *he, int port)
2665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
2675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *ai;
2685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *prevai = NULL;
2695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *firstai = NULL;
2705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct sockaddr_in *addr;
2715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef ENABLE_IPV6
2725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct sockaddr_in6 *addr6;
2735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
2745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  CURLcode result = CURLE_OK;
2755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  int i;
2765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  char *curr;
2775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(!he)
2795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* no input == no output! */
2805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return NULL;
2815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
2835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
2855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    size_t ss_size;
2875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef ENABLE_IPV6
288e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(he->h_addrtype == AF_INET6)
2895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      ss_size = sizeof (struct sockaddr_in6);
2905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    else
2915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
2925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      ss_size = sizeof (struct sockaddr_in);
2935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) {
2955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      result = CURLE_OUT_OF_MEMORY;
2965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      break;
2975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
2985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if((ai->ai_canonname = strdup(he->h_name)) == NULL) {
2995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      result = CURLE_OUT_OF_MEMORY;
3005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(ai);
3015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      break;
3025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
3035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if((ai->ai_addr = calloc(1, ss_size)) == NULL) {
3045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      result = CURLE_OUT_OF_MEMORY;
3055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(ai->ai_canonname);
3065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(ai);
3075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      break;
3085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
3095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(!firstai)
3115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* store the pointer we want to return from this function */
3125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      firstai = ai;
3135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(prevai)
3155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* make the previous entry point to this */
3165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      prevai->ai_next = ai;
3175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ai->ai_family = he->h_addrtype;
3195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* we return all names as STREAM, so when using this address for TFTP
3215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       the type must be ignored and conn->socktype be used instead! */
3225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ai->ai_socktype = SOCK_STREAM;
3235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ai->ai_addrlen = (curl_socklen_t)ss_size;
3255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* leave the rest of the struct filled with zero */
3275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    switch (ai->ai_family) {
3295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    case AF_INET:
3305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      addr = (void *)ai->ai_addr; /* storage area for this info */
3315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
3335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      addr->sin_family = (unsigned short)(he->h_addrtype);
3345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      addr->sin_port = htons((unsigned short)port);
3355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      break;
3365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef ENABLE_IPV6
3385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    case AF_INET6:
3395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      addr6 = (void *)ai->ai_addr; /* storage area for this info */
3405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
3425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      addr6->sin6_family = (unsigned short)(he->h_addrtype);
3435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      addr6->sin6_port = htons((unsigned short)port);
3445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      break;
3455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
3465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
3475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    prevai = ai;
3495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
3505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
351e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(result) {
3525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    Curl_freeaddrinfo(firstai);
3535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    firstai = NULL;
3545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
3555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return firstai;
3575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
3585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstruct namebuff {
3615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct hostent hostentry;
3625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  union {
3635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    struct in_addr  ina4;
3645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef ENABLE_IPV6
3655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    struct in6_addr ina6;
3665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
3675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  } addrentry;
3685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  char *h_addr_list[2];
3695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen};
3705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
3735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Curl_ip2addr()
3745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
3755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This function takes an internet address, in binary form, as input parameter
3765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * along with its address family and the string version of the address, and it
3775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * returns a Curl_addrinfo chain filled in correctly with information for the
3785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * given address/host
3795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
3805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_addrinfo *
3825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
3835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
3845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Curl_addrinfo *ai;
3855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if defined(__VMS) && \
3875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
3885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#pragma pointer_size save
3895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#pragma pointer_size short
3905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#pragma message disable PTRMISMATCH
3915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
3925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct hostent  *h;
3945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct namebuff *buf;
3955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  char  *addrentry;
3965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  char  *hoststr;
3975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  size_t addrsize;
3985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  DEBUGASSERT(inaddr && hostname);
4005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  buf = malloc(sizeof(struct namebuff));
4025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(!buf)
4035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return NULL;
4045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  hoststr = strdup(hostname);
4065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(!hoststr) {
4075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    free(buf);
4085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return NULL;
4095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
4105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  switch(af) {
4125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  case AF_INET:
4135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    addrsize = sizeof(struct in_addr);
4145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    addrentry = (void *)&buf->addrentry.ina4;
4155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    memcpy(addrentry, inaddr, sizeof(struct in_addr));
4165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    break;
4175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef ENABLE_IPV6
4185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  case AF_INET6:
4195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    addrsize = sizeof(struct in6_addr);
4205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    addrentry = (void *)&buf->addrentry.ina6;
4215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    memcpy(addrentry, inaddr, sizeof(struct in6_addr));
4225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    break;
4235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
4245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  default:
4255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    free(hoststr);
4265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    free(buf);
4275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return NULL;
4285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
4295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  h = &buf->hostentry;
4315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  h->h_name = hoststr;
4325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  h->h_aliases = NULL;
4335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  h->h_addrtype = (short)af;
4345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  h->h_length = (short)addrsize;
4355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  h->h_addr_list = &buf->h_addr_list[0];
4365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  h->h_addr_list[0] = addrentry;
4375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  h->h_addr_list[1] = NULL; /* terminate list of entries */
4385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if defined(__VMS) && \
4405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
4415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#pragma pointer_size restore
4425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#pragma message enable PTRMISMATCH
4435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
4445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  ai = Curl_he2ai(h, port);
4465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  free(hoststr);
4485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  free(buf);
4495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return ai;
4515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
4525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
453e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*
454e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Given an IPv4 or IPv6 dotted string address, this converts it to a proper
455e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * allocated Curl_addrinfo struct and returns it.
456e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */
457e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETCurl_addrinfo *Curl_str2addr(char *address, int port)
458e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
459e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct in_addr in;
460e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(Curl_inet_pton(AF_INET, address, &in) > 0)
461e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    /* This is a dotted IP address 123.123.123.123-style */
462e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return Curl_ip2addr(AF_INET, &in, address, port);
463e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef ENABLE_IPV6
464e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  else {
465e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    struct in6_addr in6;
466e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
467e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      /* This is a dotted IPv6 address ::1-style */
468e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET      return Curl_ip2addr(AF_INET6, &in6, address, port);
469e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
470e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
471e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return NULL; /* bad input format */
472e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
473e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
474e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef USE_UNIX_SOCKETS
475e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/**
476e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
477e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * struct initialized with this path.
478e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */
479e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETCurl_addrinfo *Curl_unix2addr(const char *path)
480e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
481e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  Curl_addrinfo *ai;
482e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct sockaddr_un *sa_un;
483e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  size_t path_len;
484e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
485e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  ai = calloc(1, sizeof(Curl_addrinfo));
486e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(!ai)
487e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return NULL;
488e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) {
489e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    free(ai);
490e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return NULL;
491e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
492e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  /* sun_path must be able to store the NUL-terminated path */
493e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  path_len = strlen(path);
494e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  if(path_len >= sizeof(sa_un->sun_path)) {
495e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    free(ai->ai_addr);
496e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    free(ai);
497e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    return NULL;
498e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  }
499e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
500e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  ai->ai_family = AF_UNIX;
501e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
502e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
503e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  sa_un = (void *) ai->ai_addr;
504e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  sa_un->sun_family = AF_UNIX;
505e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
506e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return ai;
507e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
508e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif
5095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
5105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
5115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
5125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * curl_dofreeaddrinfo()
5135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
5145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This is strictly for memory tracing and are using the same style as the
5155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * family otherwise present in memdebug.c. I put these ones here since they
516e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * require a bunch of structs I didn't want to include in memdebug.c
5175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
5185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
5195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenvoid
5205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsencurl_dofreeaddrinfo(struct addrinfo *freethis,
5215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                    int line, const char *source)
5225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
523d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo#ifdef USE_LWIPSOCK
524d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo  lwip_freeaddrinfo(freethis);
525d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo#else
5265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  (freeaddrinfo)(freethis);
527d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo#endif
5285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n",
5295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen              source, line, (void *)freethis);
5305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
5315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
5325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
5335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
5345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
5355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*
5365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * curl_dogetaddrinfo()
5375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
5385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This is strictly for memory tracing and are using the same style as the
5395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * family otherwise present in memdebug.c. I put these ones here since they
540e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * require a bunch of structs I didn't want to include in memdebug.c
5415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */
5425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
5435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenint
5445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsencurl_dogetaddrinfo(const char *hostname,
5455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                   const char *service,
5465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                   const struct addrinfo *hints,
5475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                   struct addrinfo **result,
5485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                   int line, const char *source)
5495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
550d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo#ifdef USE_LWIPSOCK
551d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo  int res=lwip_getaddrinfo(hostname, service, hints, result);
552d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo#else
5535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  int res=(getaddrinfo)(hostname, service, hints, result);
554d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo#endif
5555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(0 == res)
5565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* success */
5575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    curl_memlog("ADDR %s:%d getaddrinfo() = %p\n",
5585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                source, line, (void *)*result);
5595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  else
5605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    curl_memlog("ADDR %s:%d getaddrinfo() failed\n",
5615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                source, line);
5625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return res;
5635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
5645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
5655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
566e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo#if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS)
567e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo/*
568e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo * Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
569e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo * 10.11.5.
570e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo */
571e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymovoid Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port)
572e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo{
573e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo  Curl_addrinfo *ca;
574e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo  struct sockaddr_in *addr;
575e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo#ifdef ENABLE_IPV6
576e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo  struct sockaddr_in6 *addr6;
577e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo#endif
578e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo  for(ca = addrinfo; ca != NULL; ca = ca->ai_next) {
579e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo    switch (ca->ai_family) {
580e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo    case AF_INET:
581e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      addr = (void *)ca->ai_addr; /* storage area for this info */
582e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      addr->sin_port = htons((unsigned short)port);
583e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      break;
584e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo
585e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo#ifdef ENABLE_IPV6
586e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo    case AF_INET6:
587e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      addr6 = (void *)ca->ai_addr; /* storage area for this info */
588e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      addr6->sin6_port = htons((unsigned short)port);
589e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo      break;
590e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo#endif
591e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo    }
592e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo  }
593e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo}
594e3149cc1cf501b46caba8d47652ac90b95c78eacAlex Deymo#endif
595