Newer
Older
/***************************************************************************
Daniel Stenberg
committed
* _ _ ____ _
* 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.
Daniel Stenberg
committed
*
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
* 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#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
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/***********************************************************************
* Only for builds using asynchronous name resolves
**********************************************************************/
#ifdef CURLRES_ASYNCH
/*
* addrinfo_callback() gets called by ares, gethostbyname_thread() or
* getaddrinfo_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.
*/
Daniel Stenberg
committed
static void addrinfo_callback(void *arg, /* "struct connectdata *" */
int status,
void *addr)
{
struct connectdata *conn = (struct connectdata *)arg;
struct Curl_dns_entry *dns = NULL;
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!
*/
Daniel Stenberg
committed
Curl_addrinfo *ai = Curl_addrinfo_copy(addr, conn->async.port);
if(ai) {
struct SessionHandle *data = conn->data;
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
Daniel Stenberg
committed
dns = Curl_cache_addr(data, ai,
conn->async.hostname,
conn->async.port);
Daniel Stenberg
committed
if(!dns)
/* failed to store, cleanup and return error */
Daniel Stenberg
committed
Curl_freeaddrinfo(ai);
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
}
conn->async.dns = dns;
Daniel Stenberg
committed
/* Set async.done TRUE last in this function since it may be used multi-
threaded and once this is TRUE the other thread may read fields from the
async struct */
conn->async.done = TRUE;
/* ipv4: The input hostent struct will be freed by ares when we return from
this function */
}
Daniel Stenberg
committed
void Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
int status,
struct hostent *hostent)
{
addrinfo_callback(arg, status, hostent);
}
#ifdef CURLRES_IPV6
void Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
int status,
struct addrinfo *ai)
Daniel Stenberg
committed
{
addrinfo_callback(arg, status, ai);
Daniel Stenberg
committed
}
#endif
#endif /* CURLRES_ASYNC */