Skip to content
Snippets Groups Projects
hostasyn.c 4.07 KiB
Newer Older
  • Learn to ignore specific revisions
  • /***************************************************************************
     *                                  _   _ ____  _     
     *  Project                     ___| | | |  _ \| |    
     *                             / __| | | | |_) | |    
     *                            | (__| |_| |  _ <| |___ 
     *                             \___|\___/|_| \_\_____|
     *
     * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
     *
     * 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.
     * 
     * 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.
     *
     * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     * KIND, either express or implied.
     *
     * $Id$
     ***************************************************************************/
    
    #include "setup.h"
    
    #include <string.h>
    #include <errno.h>
    
    #define _REENTRANT
    
    #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
    #include <malloc.h>
    #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
    #include <netinet/in.h>
    #endif
    #ifdef HAVE_NETDB_H
    #include <netdb.h>
    #endif
    #ifdef HAVE_ARPA_INET_H
    #include <arpa/inet.h>
    #endif
    #ifdef HAVE_STDLIB_H
    #include <stdlib.h>	/* required for free() prototypes */
    #endif
    #ifdef HAVE_UNISTD_H
    #include <unistd.h>     /* for the close() proto */
    #endif
    #ifdef	VMS
    #include <in.h>
    #include <inet.h>
    #include <stdlib.h>
    #endif
    #endif
    
    #ifdef HAVE_SETJMP_H
    #include <setjmp.h>
    #endif
    
    #ifdef WIN32
    #include <process.h>
    #endif
    
    #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
    #undef in_addr_t
    #define in_addr_t unsigned long
    #endif
    
    #include "urldata.h"
    #include "sendf.h"
    #include "hostip.h"
    #include "hash.h"
    #include "share.h"
    #include "strerror.h"
    #include "url.h"
    
    #define _MPRINTF_REPLACE /* use our functions only */
    #include <curl/mprintf.h>
    
    #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
    #include "inet_ntoa_r.h"
    #endif
    
    /* The last #include file should be: */
    #ifdef CURLDEBUG
    #include "memdebug.h"
    #endif
    
    /***********************************************************************
     * Only for builds using asynchronous name resolves
     **********************************************************************/
    #ifdef CURLRES_ASYNCH
    /*
     * Curl_addrinfo_callback() gets called by ares/gethostbyname_thread() when we
     * got the name resolved (or not!).
     *
     * If the status argument is CURL_ASYNC_SUCCESS, we might need to copy the
     * address field since it might be freed when this function returns. This
     * operation stores the resolved data in the DNS cache.
     *
     * NOTE: for IPv6 operations, Curl_addrinfo_copy() returns the same
     * pointer it is given as argument!
     *
     * The storage operation locks and unlocks the DNS cache.
     */
    void Curl_addrinfo_callback(void *arg, /* "struct connectdata *" */
                                int status,
                                Curl_addrinfo *hostent)
    {
      struct connectdata *conn = (struct connectdata *)arg;
      struct Curl_dns_entry *dns = NULL;
    
      conn->async.done = TRUE;
      conn->async.status = status;
    
      if(CURL_ASYNC_SUCCESS == status) {
    
        /*
         * IPv4: Curl_addrinfo_copy() copies the address and returns an allocated
         * version.
         *
         * IPv6: Curl_addrinfo_copy() returns the input pointer!
         */
        Curl_addrinfo *he = Curl_addrinfo_copy(hostent);
        if(he) {
          struct SessionHandle *data = conn->data;
    
          if(data->share)
            Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
    
          dns = Curl_cache_addr(data, he,
                                conn->async.hostname,
                                conn->async.port);
    
          if(data->share)
            Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
        }
      }
    
      conn->async.dns = dns;
    
      /* ipv4: The input hostent struct will be freed by ares when we return from
         this function */
    }
    
    #endif /* CURLRES_ASYNC */