Commit b7361239 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

ares awareness/usage/support added. If configure --enable-ares is used, we

build libcurl to use ares for asynch name resolves.
parent f85935f0
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -12,10 +12,16 @@ EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \

lib_LTLIBRARIES = libcurl.la

if ARES
ARESINC = -I$(top_srcdir)/ares
endif

# we use srcdir/include for the static global include files
# we use builddir/lib for the generated lib/config.h file to get found
# we use srcdir/lib for the lib-private header files
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/lib -I$(top_srcdir)/lib
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/lib -I$(top_srcdir)/lib $(ARESINC)

LDFLAGS = -L$(top_srcdir)/lib

VERSION=-version-info 2:2:0

@@ -48,15 +54,18 @@ VERSION=-version-info 2:2:0
#

if NO_UNDEFINED
# The -no-undefined flag is CRUCIAL for this to build fine on Cygwin. If we
# find a case in which we need to remove this flag, we should most likely
# write a configure check that detects when this flag is needed and when its
# not.
libcurl_la_LDFLAGS = -no-undefined $(VERSION)
# The -no-undefined flag is CRUCIAL for this to build fine on Cygwin.
UNDEF = -no-undefined
else
libcurl_la_LDFLAGS = $(VERSION)
UNDEF =
endif

if ARES
ARESLIB = -lares -L$(top_builddir)/ares
endif

libcurl_la_LDFLAGS = $(UNDEF) $(VERSION) $(ARESLIB)

libcurl_la_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c	\
base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c	\
hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c	\
+11 −4
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ static CURLcode bindlocal(struct connectdata *conn,
    size_t size;
    char myhost[256] = "";
    in_addr_t in;
    int rc;

    /* First check if the given name is an IP address */
    in=inet_addr(data->set.device);
@@ -217,7 +218,10 @@ static CURLcode bindlocal(struct connectdata *conn,
      /*
       * We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer
       */
      h = Curl_resolv(data, myhost, 0);
      rc = Curl_resolv(conn, myhost, 0, &h);
      if(rc == 1)
        rc = Curl_wait_for_resolv(conn, &h);

    }
    else {
      if(strlen(data->set.device)>1) {
@@ -225,11 +229,14 @@ static CURLcode bindlocal(struct connectdata *conn,
         * This was not an interface, resolve the name as a host name
         * or IP number
         */
        h = Curl_resolv(data, data->set.device, 0);
        if(h) {
        rc = Curl_resolv(conn, data->set.device, 0, &h);
        if(rc == 1)
          rc = Curl_wait_for_resolv(conn, &h);

        if(h)
          /* we know data->set.device is shorter than the myhost array */
          strcpy(myhost, data->set.device);
        }

      }
    }

+18 −5
Original line number Diff line number Diff line
@@ -1231,18 +1231,24 @@ CURLcode ftp_use_port(struct connectdata *conn)

  if(data->set.ftpport) {
    in_addr_t in;
    int rc;

    /* First check if the given name is an IP address */
    in=inet_addr(data->set.ftpport);

    if((in == CURL_INADDR_NONE) &&
       Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
      h = Curl_resolv(data, myhost, 0);
      rc = Curl_resolv(conn, myhost, 0, &h);
      if(rc == 1)
        rc = Curl_wait_for_resolv(conn, &h);
    }
    else {
      int len = strlen(data->set.ftpport);
      if(len>1)
        h = Curl_resolv(data, data->set.ftpport, 0);
      if(len>1) {
        rc = Curl_resolv(conn, data->set.ftpport, 0, &h);
        if(rc == 1)
          rc = Curl_wait_for_resolv(conn, &h);
      }
      if(h)
        strcpy(myhost, data->set.ftpport); /* buffer overflow risk */
    }
@@ -1381,6 +1387,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
  CURLcode result;
  struct Curl_dns_entry *addr=NULL;
  Curl_ipconnect *conninfo;
  int rc;

  /*
    Here's the excecutive summary on what to do:
@@ -1505,14 +1512,20 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
     * We don't want to rely on a former host lookup that might've expired
     * now, instead we remake the lookup here and now!
     */
    addr = Curl_resolv(data, conn->proxyhost, conn->port);
    rc = Curl_resolv(conn, conn->proxyhost, conn->port, &addr);
    if(rc == 1)
      rc = Curl_wait_for_resolv(conn, &addr);

    connectport =
      (unsigned short)conn->port; /* we connect to the proxy's port */    

  }
  else {
    /* normal, direct, ftp connection */
    addr = Curl_resolv(data, newhostp, newport);
    rc = Curl_resolv(conn, newhostp, newport, &addr);
    if(rc == 1)
      rc = Curl_wait_for_resolv(conn, &addr);

    if(!addr) {
      failf(data, "Can't resolve new host %s:%d", newhostp, newport);
      return CURLE_FTP_CANT_GET_HOST;
+338 −109
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@
#include "hostip.h"
#include "hash.h"
#include "share.h"
#include "url.h"

#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -81,10 +82,13 @@
static curl_hash hostname_cache;
static int host_cache_initialized;

static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
                                     char *hostname,
                                     int port,
                                       char **bufp);
                                     int *waitp);
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES)
static struct hostent* pack_hostent(char** buf, struct hostent* orig);
#endif

void Curl_global_host_cache_init(void)
{
@@ -136,14 +140,13 @@ create_hostcache_id(char *server, int port, ssize_t *entry_len)

  /* Get the length of the new entry id */
  *entry_len = *entry_len + /* Hostname length */
               1 +               /* The ':' seperator */
               _num_chars(port); /* The number of characters the port will take up */
    1 +                     /* ':' seperator */
    _num_chars(port);       /* number of characters the port will take up */
  
  /* Allocate the new entry id */
  id = malloc(*entry_len + 1);
  if (!id) {
  if (!id)
    return NULL;
  }

  /* Create the new entry */
  /* If sprintf() doesn't return the entry length, that signals failure */
@@ -192,47 +195,88 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
                                 hostcache_timestamp_remove);
}

#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
/* Called from Curl_done() to check that there's no DNS cache entry with
   a non-zero counter left. */
void Curl_scan_cache_used(void *user, void *ptr)
{
  struct Curl_dns_entry *e = ptr;
  (void)user; /* prevent compiler warning */
  if(e->inuse) {
    fprintf(stderr, "*** WARNING: locked DNS cache entry detected: %s\n",
            e->entry_id);
    /* perform a segmentation fault to draw attention */
    *(void **)0 = 0;
  }
}
#endif

/* Macro to save redundant free'ing of entry_id */
#define HOSTCACHE_RETURN(dns) \
{ \
  free(entry_id); \
  if(data->share) \
  {               \
    Curl_share_unlock(data, CURL_LOCK_DATA_DNS); \
  }               \
  return dns; \
}

#ifdef HAVE_SIGSETJMP
/* Beware this is a global and unique instance */
sigjmp_buf curl_jmpenv;
#endif

struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,

/* When calling Curl_resolv() has resulted in a response with a returned
   address, we call this function to store the information in the dns
   cache etc */

static struct Curl_dns_entry *
cache_resolv_response(struct SessionHandle *data,
                      Curl_addrinfo *addr,
                      char *hostname,
                      int port)
{
  char *entry_id;
  int entry_len;
  struct Curl_dns_entry *dns;
  time_t now;

  /* Create an entry id, based upon the hostname and port */
  entry_len = strlen(hostname);
  entry_id = create_hostcache_id(hostname, port, &entry_len);
  /* If we can't create the entry id, fail */
  if (!entry_id)
    return NULL;

  /* Create a new cache entry */
  dns = (struct Curl_dns_entry *) malloc(sizeof(struct Curl_dns_entry));
  if (!dns) {
    Curl_freeaddrinfo(addr);
    free(entry_id);
    return NULL;
  }

  dns->inuse = 0;
  dns->addr = addr;

  /* Store it in our dns cache */
  Curl_hash_add(data->hostcache, entry_id, entry_len+1,
                (const void *) dns);
  time(&now);

  dns->timestamp = now;
  dns->inuse++;         /* mark entry as in-use */

    
  /* Remove outdated and unused entries from the hostcache */
  hostcache_prune(data->hostcache, 
                  data->set.dns_cache_timeout, 
                  now);

  /* free the allocated entry_id again */
  free(entry_id);

  return dns;
}

/* Resolve a name and return a pointer in the 'entry' argument if one
   is available.

   Return codes:

   -1 = error, no pointer
   0 = OK, pointer provided
   1 = waiting for response, no pointer
*/
int Curl_resolv(struct connectdata *conn,
                char *hostname,
                int port,
                struct Curl_dns_entry **entry)
{
  char *entry_id = NULL;
  struct Curl_dns_entry *dns = NULL;
  ssize_t entry_len;
  time_t now;
  char *bufp;
  int wait;
  struct SessionHandle *data = conn->data;

  /* default to failure */
  int rc = -1;
  *entry = NULL;

#ifdef HAVE_SIGSETJMP
  /* this allows us to time-out from the name resolver, as the timeout
@@ -240,7 +284,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
  if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) {
    /* this is coming from a siglongjmp() */
    failf(data, "name lookup timed out");
    return NULL;
    return -1;
  }
#endif

@@ -249,7 +293,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
  entry_id = create_hostcache_id(hostname, port, &entry_len);
  /* If we can't create the entry id, fail */
  if (!entry_id)
    return NULL;
    return -1;

  if(data->share)
    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
@@ -257,39 +301,34 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
  /* See if its already in our dns cache */
  dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);

  /* free the allocated entry_id again */
  free(entry_id);

  if (!dns) {
    Curl_addrinfo *addr = my_getaddrinfo(data, hostname, port, &bufp);
    /* The entry was not in the cache. Resolve it to IP address */
      
    /* If my_getaddrinfo() returns NULL, 'wait' might be set to a non-zero
       value indicating that we need to wait for the response to the resolve
       call */
    Curl_addrinfo *addr = my_getaddrinfo(conn, hostname, port, &wait);
    
    if (!addr) {
      HOSTCACHE_RETURN(NULL);
      if(wait)
        /* the response to our resolve call will come asynchronously at 
           a later time, good or bad */
        rc = 1;
    }

    /* Create a new cache entry */
    dns = (struct Curl_dns_entry *) malloc(sizeof(struct Curl_dns_entry));
    if (!dns) {
      Curl_freeaddrinfo(addr);
      HOSTCACHE_RETURN(NULL);
    else
      /* we got a response, store it in the cache */
      dns = cache_resolv_response(data, addr, hostname, port);
  }

    dns->inuse = 0;
    dns->addr = addr;
    /* Save it in our host cache */
    Curl_hash_add(data->hostcache, entry_id, entry_len+1, (const void *) dns);
  }
  time(&now);
  if(data->share)
    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);

  dns->timestamp = now;
  dns->inuse++;         /* mark entry as in-use */
#ifdef CURLDEBUG
  dns->entry_id = entry_id;
#endif
  *entry = dns;

  /* Remove outdated and unused entries from the hostcache */
  hostcache_prune(data->hostcache, 
                  data->set.dns_cache_timeout, 
                  now);

  HOSTCACHE_RETURN(dns);
  return rc;
}

void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
@@ -314,7 +353,7 @@ void Curl_freeaddrinfo(Curl_addrinfo *p)
#ifdef ENABLE_IPV6
  freeaddrinfo(p);
#else
  free(p);
  free(p); /* works fine for the ARES case too */
#endif
}

@@ -332,7 +371,203 @@ void Curl_freednsinfo(void *freethis)

/* --- resolve name or IP-number --- */

#ifdef ENABLE_IPV6
/* Allocate enough memory to hold the full name information structs and
 * everything. OSF1 is known to require at least 8872 bytes. The buffer
 * required for storing all possible aliases and IP numbers is according to
 * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
 */
#define CURL_NAMELOOKUP_SIZE 9000

#ifdef USE_ARES

CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
                               fd_set *read_fd_set,
                               fd_set *write_fd_set,
                               int *max_fdp)

{
  int max = ares_fds(conn->data->state.areschannel,
                     read_fd_set, write_fd_set);
  *max_fdp = max;

  return CURLE_OK;
}

/* called to check if the name is resolved now */
CURLcode Curl_is_resolved(struct connectdata *conn, bool *done)
{
  fd_set read_fds, write_fds;
  static const struct timeval tv={0,0};
  int count;
  struct SessionHandle *data = conn->data;
  int nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);

  count = select(nfds, &read_fds, &write_fds, NULL,
                 (struct timeval *)&tv);

  if(count)
    ares_process(data->state.areschannel, &read_fds, &write_fds);

  if(conn->async.done) {
    *done = TRUE;

    if(!conn->async.dns)
      return CURLE_COULDNT_RESOLVE_HOST;
  }
  else
    *done = FALSE;

  return CURLE_OK;
}

/* This is a function that locks and waits until the name resolve operation
   has completed.

   If 'entry' is non-NULL, make it point to the resolved dns entry

   Return CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
   CURLE_OPERATION_TIMEDOUT if a time-out occurred.
*/
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
                              struct Curl_dns_entry **entry)
{
  CURLcode rc=CURLE_OK;
  struct SessionHandle *data = conn->data;
    
  /* Wait for the name resolve query to complete. */
  while (1) {
    int nfds=0;
    fd_set read_fds, write_fds;
    struct timeval *tvp, tv;
    int count;
    
    FD_ZERO(&read_fds);
    FD_ZERO(&write_fds);
    nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
    if (nfds == 0)
      break;
    tvp = ares_timeout(data->state.areschannel,
                       NULL, /* pass in our maximum time here */
                       &tv);
    count = select(nfds, &read_fds, &write_fds, NULL, tvp);
    if (count < 0 && errno != EINVAL)
      break;

    ares_process(data->state.areschannel, &read_fds, &write_fds);
  }

  /* Operation complete, if the lookup was successful we now have the entry
     in the cache. */
    
  /* this destroys the channel and we cannot use it anymore after this */
  ares_destroy(data->state.areschannel);

  if(entry)
    *entry = conn->async.dns;

  if(!conn->async.dns) {
    /* a name was not resolved */
    if(conn->async.done)
      rc = CURLE_COULDNT_RESOLVE_HOST;
    else
      rc = CURLE_OPERATION_TIMEDOUT;

    /* close the connection, since we can't return failure here without
       cleaning up this connection properly */
    Curl_disconnect(conn);
  }
  
  return rc;
}

/* this function gets called by ares when we got the name resolved */
static void host_callback(void *arg, /* "struct connectdata *" */
                          int status,
                          struct hostent *hostent)
{
  struct connectdata *conn = (struct connectdata *)arg;
  struct Curl_dns_entry *dns = NULL;

  conn->async.done = TRUE;
  conn->async.status = status;

  if(ARES_SUCCESS == status) {
    /* we got a resolved name in 'hostent' */
    char *bufp = (char *)malloc(CURL_NAMELOOKUP_SIZE);
    if(bufp) {

      /* pack_hostent() copies to and shrinks the target buffer */
      struct hostent *he = pack_hostent(&bufp, hostent);

      dns = cache_resolv_response(conn->data, he,
                                  conn->async.hostname, conn->async.port);
    }
  }

  conn->async.dns = dns;

  /* The input hostent struct will be freed by ares when we return from this
     function */
}

/*
 * Return name information about the given hostname and port number. If
 * successful, the 'hostent' is returned and the forth argument will point to
 * memory we need to free after use. That meory *MUST* be freed with
 * Curl_freeaddrinfo(), nothing else.
 */
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
                                     char *hostname,
                                     int port,
                                     int *waitp)
{
  int rc;
  char *bufp;
  struct SessionHandle *data = conn->data;

  rc = ares_init(&data->state.areschannel);

  *waitp = FALSE;
  
  if(!rc) {
    /* only if success */

    bufp = strdup(hostname);

    if(bufp) {
      Curl_safefree(conn->async.hostname);
      conn->async.hostname = bufp;
      conn->async.port = port;
      conn->async.done = FALSE; /* not done */
      conn->async.status = 0;   /* clear */
      conn->async.dns = NULL;   /* clear */
      
      ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
                         host_callback, conn);

      *waitp = TRUE; /* please wait for the response */      
    }
    else
      ares_destroy(data->state.areschannel);
  }

  return NULL; /* no struct yet */
  
}
#else
/* For builds without ARES, Curl_resolv() can never return wait==TRUE,
   so this function will never be called. If it still gets called, we
   return failure at once. */
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
                              struct Curl_dns_entry **entry)
{
  (void)conn;
  *entry=NULL;
  return CURLE_COULDNT_RESOLVE_HOST;
}
#endif

#if defined(ENABLE_IPV6) && !defined(USE_ARES)

#ifdef CURLDEBUG
/* These two are strictly for memory tracing and are using the same
@@ -377,15 +612,16 @@ void curl_freeaddrinfo(struct addrinfo *freethis,
 * memory we need to free after use. That meory *MUST* be freed with
 * Curl_freeaddrinfo(), nothing else.
 */
static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
                                     char *hostname,
                                     int port,
                                     char **bufp)
                                     int *waitp)
{
  struct addrinfo hints, *res;
  int error;
  char sbuf[NI_MAXSERV];
  int s, pf = PF_UNSPEC;
  struct SessionHandle *data = conn->data;

  /* see if we have an IPv6 stack */
  s = socket(PF_INET6, SOCK_DGRAM, 0);
@@ -410,20 +646,18 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
    infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);    
    return NULL;
  }
  *bufp=(char *)res; /* make it point to the result struct */
  *waitp=0; /* don't wait, we have the response now */

  return res;
}
#else /* following code is IPv4-only */

#ifndef HAVE_GETHOSTBYNAME_R
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES)
static void hostcache_fixoffset(struct hostent *h, int offset);
/**
/*
 * Performs a "deep" copy of a hostent into a buffer (returns a pointer to the
 * copy). Make absolutely sure the destination buffer is big enough!
 *
 * Keith McGuigan 
 * 10/3/2001 */
 */
static struct hostent* pack_hostent(char** buf, struct hostent* orig)
{
  char *bufptr;
@@ -512,6 +746,25 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
}
#endif

static void hostcache_fixoffset(struct hostent *h, int offset)
{
  int i=0;
  h->h_name=(char *)((long)h->h_name+offset);
  h->h_aliases=(char **)((long)h->h_aliases+offset);
  while(h->h_aliases[i]) {
    h->h_aliases[i]=(char *)((long)h->h_aliases[i]+offset);
    i++;
  }
  h->h_addr_list=(char **)((long)h->h_addr_list+offset);
  i=0;
  while(h->h_addr_list[i]) {
    h->h_addr_list[i]=(char *)((long)h->h_addr_list[i]+offset);
    i++;
  }
}

#ifndef USE_ARES

static char *MakeIP(unsigned long num, char *addr, int addr_len)
{
#if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R)
@@ -533,43 +786,24 @@ static char *MakeIP(unsigned long num, char *addr, int addr_len)
  return (addr);
}

static void hostcache_fixoffset(struct hostent *h, int offset)
{
  int i=0;
  h->h_name=(char *)((long)h->h_name+offset);
  h->h_aliases=(char **)((long)h->h_aliases+offset);
  while(h->h_aliases[i]) {
    h->h_aliases[i]=(char *)((long)h->h_aliases[i]+offset);
    i++;
  }
  h->h_addr_list=(char **)((long)h->h_addr_list+offset);
  i=0;
  while(h->h_addr_list[i]) {
    h->h_addr_list[i]=(char *)((long)h->h_addr_list[i]+offset);
    i++;
  }
}

/* The original code to this function was once stolen from the Dancer source
   code, written by Bjorn Reese, it has since been patched and modified
   considerably. */
static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
                                     char *hostname,
                                     int port,
                                     char **bufp)
                                     int *waitp)
{
  struct hostent *h = NULL;
  in_addr_t in;
  int ret; /* this variable is unused on several platforms but used on some */
  struct SessionHandle *data = conn->data;

#define CURL_NAMELOOKUP_SIZE 9000
  /* Allocate enough memory to hold the full name information structs and
   * everything. OSF1 is known to require at least 8872 bytes. The buffer
   * required for storing all possible aliases and IP numbers is according to
   * Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */
  port=0; /* unused in IPv4 code */
  (void)port; /* unused in IPv4 code */
  ret = 0; /* to prevent the compiler warning */

  *waitp = 0; /* don't wait, we act synchronously */

  in=inet_addr(hostname);
  if (in != CURL_INADDR_NONE) {
    struct in_addr *addrentry;
@@ -581,7 +815,6 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
    } *buf = (struct namebuf *)malloc(sizeof(struct namebuf));
    if(!buf)
      return NULL; /* major failure */
    *bufp = (char *)buf;

    h = &buf->hostentry;
    h->h_addr_list = &buf->h_addr_list[0];
@@ -602,7 +835,6 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
    int *buf = (int *)malloc(CURL_NAMELOOKUP_SIZE);
    if(!buf)
      return NULL; /* major failure */
    *bufp=(char *)buf;

     /* Workaround for gethostbyname_r bug in qnx nto. It is also _required_
        for some of these functions. */
@@ -638,7 +870,6 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
      offset=(long)h-(long)buf;
      hostcache_fixoffset(h, offset);
      buf=(int *)h;
      *bufp=(char *)buf;
    }
    else
#endif
@@ -687,7 +918,6 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
      offset=(long)h-(long)buf;
      hostcache_fixoffset(h, offset);
      buf=(int *)h;
      *bufp=(char *)buf;
    }
    else
#endif
@@ -730,13 +960,11 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
      infof(data, "gethostbyname_r(2) failed for %s\n", hostname);
      h = NULL; /* set return code to NULL */
      free(buf);
      *bufp=NULL;
    }
#else
  else {
    if ((h = gethostbyname(hostname)) == NULL ) {
      infof(data, "gethostbyname(2) failed for %s\n", hostname);
      *bufp=NULL;
    }
    else 
    {
@@ -745,7 +973,6 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
         static one we got a pointer to might get removed when we don't
         want/expect that */
      h = pack_hostent(&buf, h);
      *bufp=(char *)buf;
    }
#endif
  }
@@ -753,3 +980,5 @@ static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
}

#endif /* end of IPv4-specific code */

#endif /* end of !USE_ARES */
+12 −6
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
struct addrinfo;
struct hostent;
struct SessionHandle;
struct connectdata;

void Curl_global_host_cache_init(void);
void Curl_global_host_cache_dtor(void);
@@ -41,9 +42,6 @@ struct Curl_dns_entry {
  time_t timestamp;
  long inuse;      /* use-counter, make very sure you decrease this
                      when you're done using the address you received */
#ifdef CURLDEBUG
  char *entry_id;
#endif
};

/*
@@ -54,10 +52,18 @@ struct Curl_dns_entry {
 * use, or we'll leak memory!
 */

struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
int Curl_resolv(struct connectdata *conn,
                char *hostname,
                                   int port);
                int port,
                struct Curl_dns_entry **dnsentry);

CURLcode Curl_is_resolved(struct connectdata *conn, bool *done);
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
                              struct Curl_dns_entry **dnsentry);
CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
                               fd_set *read_fd_set,
                               fd_set *write_fd_set,
                               int *max_fdp);
/* unlock a previously resolved dns entry */
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns);

Loading