Skip to content
hostip.c 29.9 KiB
Newer Older
/***************************************************************************
Daniel Stenberg's avatar
Daniel Stenberg committed
 *                                  _   _ ____  _     
 *  Project                     ___| | | |  _ \| |    
 *                             / __| | | | |_) | |    
 *                            | (__| |_| |  _ <| |___ 
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al.
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 * 
Daniel Stenberg's avatar
Daniel Stenberg committed
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
Daniel Stenberg's avatar
Daniel Stenberg committed
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
Daniel Stenberg's avatar
Daniel Stenberg committed
 * $Id$
 ***************************************************************************/
Daniel Stenberg's avatar
Daniel Stenberg committed

Daniel Stenberg's avatar
Daniel Stenberg committed
#include <string.h>
#include <errno.h>
Daniel Stenberg's avatar
Daniel Stenberg committed

#define _REENTRANT

Daniel Stenberg's avatar
Daniel Stenberg committed
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <malloc.h>
Daniel Stenberg's avatar
Daniel Stenberg committed
#else
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
Daniel Stenberg's avatar
Daniel Stenberg committed
#include <netinet/in.h>
#endif
#ifdef HAVE_NETDB_H
Daniel Stenberg's avatar
Daniel Stenberg committed
#include <netdb.h>
#endif
Daniel Stenberg's avatar
Daniel Stenberg committed
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>	/* required for free() prototypes */
#endif
#ifdef	VMS
Daniel Stenberg's avatar
Daniel Stenberg committed
#include <in.h>
#include <inet.h>
#include <stdlib.h>
#endif
Daniel Stenberg's avatar
Daniel Stenberg committed
#endif

Daniel Stenberg's avatar
Daniel Stenberg committed
#include "urldata.h"
#include "sendf.h"
#include "hostip.h"
#include "share.h"
Daniel Stenberg's avatar
Daniel Stenberg committed

#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>

#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
Daniel Stenberg's avatar
Daniel Stenberg committed
#include "inet_ntoa_r.h"
#endif

/* The last #include file should be: */
#include "memdebug.h"
#endif

static curl_hash hostname_cache;
static int host_cache_initialized;
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
                                     char *hostname,
                                     int port,
                                     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)
  if (!host_cache_initialized) {
    Curl_hash_init(&hostname_cache, 7, Curl_freednsinfo);
curl_hash *Curl_global_host_cache_get(void)
void Curl_global_host_cache_dtor(void)
{
  if (host_cache_initialized) {
    host_cache_initialized = 0;
/* count the number of characters that an integer takes up */
static int _num_chars(int i)
{
  int chars = 0;

  /* While the number divided by 10 is greater than one, 
   * re-divide the number by 10, and increment the number of 
   * characters by 1.
   *
   * this relies on the fact that for every multiple of 10, 
   * a new digit is added onto every number
   */
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 +                     /* ':' seperator */
    _num_chars(port);       /* number of characters the port will take up */
  
  /* Allocate the new entry id */
  id = malloc(*entry_len + 1);
  /* Create the new entry */
  /* If sprintf() doesn't return the entry length, that signals failure */
  if (sprintf(id, "%s:%d", server, port) != *entry_len) {
    /* Free the allocated id, set length to zero and return NULL */
    *entry_len = 0;
  int cache_timeout;
  int now;
};

static int
hostcache_timestamp_remove(void *datap, void *hc)
  struct hostcache_prune_data *data = 
    (struct hostcache_prune_data *) datap;
  struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
  if ((data->now - c->timestamp < data->cache_timeout) ||
      c->inuse) {
    /* please don't remove */
hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)

  user.cache_timeout = cache_timeout;
  user.now = now;
  
  Curl_hash_clean_with_criterium(hostcache, 
#ifdef HAVE_SIGSETJMP
/* Beware this is a global and unique instance */
sigjmp_buf curl_jmpenv;
Loading
Loading full blame…