mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 15:48:49 -05:00
Use our Curl_addrinfo definition even when an addrinfo struct is available.
Use a wrapper function to call system's getaddrinfo().
This commit is contained in:
parent
197ad60d21
commit
0ce97f77e0
@ -9,7 +9,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
http_negotiate.c http_ntlm.c inet_pton.c strtoofft.c strerror.c \
|
||||
hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \
|
||||
inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \
|
||||
strdup.c socks.c ssh.c nss.c qssl.c rawstr.c
|
||||
strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c
|
||||
|
||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||
@ -20,4 +20,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
strtoofft.h strerror.h inet_ntop.h curlx.h memory.h setup.h \
|
||||
transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h \
|
||||
tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \
|
||||
curl_base64.h rawstr.h
|
||||
curl_base64.h rawstr.h curl_addrinfo.h
|
||||
|
332
lib/curl_addrinfo.c
Normal file
332
lib/curl_addrinfo.c
Normal file
@ -0,0 +1,332 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2008, 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 <curl/curl.h>
|
||||
|
||||
#ifdef NEED_MALLOC_H
|
||||
# include <malloc.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 VMS
|
||||
# include <in.h>
|
||||
# include <inet.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(NETWARE) && defined(__NOVELL_LIBC__)
|
||||
# undef in_addr_t
|
||||
# define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Curl_freeaddrinfo()
|
||||
*
|
||||
* This is used to free a linked list of Curl_addrinfo structs along
|
||||
* with all its associated allocated storage. This function should be
|
||||
* called once for each successful call to Curl_getaddrinfo_ex() or to
|
||||
* any function call which actually allocates a Curl_addrinfo struct.
|
||||
*/
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(Curl_addrinfo *cahead)
|
||||
{
|
||||
Curl_addrinfo *ca, *canext;
|
||||
|
||||
for(ca = cahead; ca != NULL; ca = canext) {
|
||||
|
||||
if(ca->ai_addr)
|
||||
free(ca->ai_addr);
|
||||
|
||||
if(ca->ai_canonname)
|
||||
free(ca->ai_canonname);
|
||||
|
||||
canext = ca->ai_next;
|
||||
|
||||
free(ca);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
/*
|
||||
* Curl_getaddrinfo_ex()
|
||||
*
|
||||
* This is a warapper function around system's getaddrinfo(), with
|
||||
* the only difference that instead of returning a linked list of
|
||||
* addrinfo structs this one returns a linked list of Curl_addrinfo
|
||||
* ones. The memory allocated by this function *MUST* be free'd with
|
||||
* Curl_freeaddrinfo(). For each successful call to this function
|
||||
* there must be an associated call later to Curl_freeaddrinfo().
|
||||
*
|
||||
* There should be no single call to system's getaddrinfo() in the
|
||||
* whole library, any such call should be 'routed' through this one.
|
||||
*/
|
||||
|
||||
int
|
||||
Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
Curl_addrinfo **result)
|
||||
{
|
||||
const struct addrinfo *ainext;
|
||||
const struct addrinfo *ai;
|
||||
struct addrinfo *aihead;
|
||||
Curl_addrinfo *cafirst = NULL;
|
||||
Curl_addrinfo *calast = NULL;
|
||||
Curl_addrinfo *ca;
|
||||
int error;
|
||||
|
||||
*result = NULL; /* assume failure */
|
||||
|
||||
error = getaddrinfo(nodename, servname, hints, &aihead);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
for(ai = aihead; ai != NULL; ai = ainext) {
|
||||
|
||||
if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy each structure member individually, member ordering, */
|
||||
/* size, or padding might be different for each structure. */
|
||||
|
||||
ca->ai_flags = ai->ai_flags;
|
||||
ca->ai_family = ai->ai_family;
|
||||
ca->ai_socktype = ai->ai_socktype;
|
||||
ca->ai_protocol = ai->ai_protocol;
|
||||
ca->ai_addrlen = 0;
|
||||
ca->ai_addr = NULL;
|
||||
ca->ai_canonname = NULL;
|
||||
ca->ai_next = NULL;
|
||||
|
||||
if((ai->ai_addrlen > 0) && (ai->ai_addr != NULL)) {
|
||||
ca->ai_addrlen = ai->ai_addrlen;
|
||||
if((ca->ai_addr = malloc(ca->ai_addrlen)) == NULL) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca);
|
||||
break;
|
||||
}
|
||||
memcpy(ca->ai_addr, ai->ai_addr, ca->ai_addrlen);
|
||||
}
|
||||
|
||||
if(ai->ai_canonname != NULL) {
|
||||
if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
|
||||
error = EAI_MEMORY;
|
||||
if(ca->ai_addr)
|
||||
free(ca->ai_addr);
|
||||
free(ca);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the return list is empty, this becomes the first element */
|
||||
if(!cafirst)
|
||||
cafirst = ca;
|
||||
|
||||
/* add this element last in the return list */
|
||||
if(calast)
|
||||
calast->ai_next = ca;
|
||||
calast = ca;
|
||||
|
||||
/* fetch next element fom the addrinfo list */
|
||||
ainext = ai->ai_next;
|
||||
}
|
||||
|
||||
/* destroy the addrinfo list */
|
||||
if(aihead)
|
||||
freeaddrinfo(aihead);
|
||||
|
||||
/* if we failed, also destroy the Curl_addrinfo list */
|
||||
if(error) {
|
||||
Curl_freeaddrinfo(cafirst);
|
||||
cafirst = NULL;
|
||||
}
|
||||
|
||||
*result = cafirst;
|
||||
|
||||
return error; /* This is not a CURLcode */
|
||||
}
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
|
||||
/*
|
||||
* Curl_he2ai()
|
||||
*
|
||||
* This function returns a pointer to the first element of a newly allocated
|
||||
* Curl_addrinfo struct linked list filled with the data of a given hostent.
|
||||
* Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6
|
||||
* stack, but usable also for IPv4, all hosts and environments.
|
||||
*
|
||||
* The memory allocated by this function *MUST* be free'd later on calling
|
||||
* Curl_freeaddrinfo(). For each successful call to this function there
|
||||
* must be an associated call later to Curl_freeaddrinfo().
|
||||
*
|
||||
* Curl_addrinfo defined in "lib/curl_addrinfo.h"
|
||||
*
|
||||
* struct Curl_addrinfo {
|
||||
* int ai_flags;
|
||||
* int ai_family;
|
||||
* int ai_socktype;
|
||||
* int ai_protocol;
|
||||
* socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo *
|
||||
* char *ai_canonname;
|
||||
* struct sockaddr *ai_addr;
|
||||
* struct Curl_addrinfo *ai_next;
|
||||
* };
|
||||
* typedef struct Curl_addrinfo Curl_addrinfo;
|
||||
*
|
||||
* hostent defined in <netdb.h>
|
||||
*
|
||||
* struct hostent {
|
||||
* char *h_name;
|
||||
* char **h_aliases;
|
||||
* int h_addrtype;
|
||||
* int h_length;
|
||||
* char **h_addr_list;
|
||||
* };
|
||||
*
|
||||
* for backward compatibility:
|
||||
*
|
||||
* #define h_addr h_addr_list[0]
|
||||
*/
|
||||
|
||||
Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
Curl_addrinfo *prevai = NULL;
|
||||
Curl_addrinfo *firstai = NULL;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *addr6;
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
int i;
|
||||
char *curr;
|
||||
|
||||
if(!he)
|
||||
/* no input == no output! */
|
||||
return NULL;
|
||||
|
||||
for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
|
||||
|
||||
int ss_size;
|
||||
#ifdef ENABLE_IPV6
|
||||
if (he->h_addrtype == AF_INET6)
|
||||
ss_size = sizeof (struct sockaddr_in6);
|
||||
else
|
||||
#endif
|
||||
ss_size = sizeof (struct sockaddr_in);
|
||||
|
||||
if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
if((ai->ai_canonname = strdup(he->h_name)) == NULL) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
if((ai->ai_addr = calloc(1, ss_size)) == NULL) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!firstai)
|
||||
/* store the pointer we want to return from this function */
|
||||
firstai = ai;
|
||||
|
||||
if(prevai)
|
||||
/* make the previous entry point to this */
|
||||
prevai->ai_next = ai;
|
||||
|
||||
ai->ai_family = he->h_addrtype;
|
||||
|
||||
/* we return all names as STREAM, so when using this address for TFTP
|
||||
the type must be ignored and conn->socktype be used instead! */
|
||||
ai->ai_socktype = SOCK_STREAM;
|
||||
|
||||
ai->ai_addrlen = ss_size;
|
||||
|
||||
/* leave the rest of the struct filled with zero */
|
||||
|
||||
switch (ai->ai_family) {
|
||||
case AF_INET:
|
||||
addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
|
||||
|
||||
memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
|
||||
addr->sin_family = (unsigned short)(he->h_addrtype);
|
||||
addr->sin_port = htons((unsigned short)port);
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
addr6 = (struct sockaddr_in6 *)ai->ai_addr; /* storage area for this info */
|
||||
|
||||
memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
|
||||
addr6->sin6_family = (unsigned short)(he->h_addrtype);
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
prevai = ai;
|
||||
}
|
||||
|
||||
if(result != CURLE_OK) {
|
||||
/* Use parenthesis to prevent memdebug from replacing this */
|
||||
Curl_freeaddrinfo(firstai);
|
||||
firstai = NULL;
|
||||
}
|
||||
|
||||
return firstai;
|
||||
}
|
||||
|
81
lib/curl_addrinfo.h
Normal file
81
lib/curl_addrinfo.h
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef HEADER_CURL_ADDRINFO_H
|
||||
#define HEADER_CURL_ADDRINFO_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2008, 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"
|
||||
|
||||
#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 VMS
|
||||
# include <in.h>
|
||||
# include <inet.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Curl_addrinfo is our internal struct definition that we use to allow
|
||||
* consistent internal handling of this data. We use this even when the
|
||||
* system provides an addrinfo structure definition. And we use this for
|
||||
* all sorts of IPv4 and IPV6 builds.
|
||||
*/
|
||||
|
||||
struct Curl_addrinfo {
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */
|
||||
char *ai_canonname;
|
||||
struct sockaddr *ai_addr;
|
||||
struct Curl_addrinfo *ai_next;
|
||||
};
|
||||
typedef struct Curl_addrinfo Curl_addrinfo;
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(Curl_addrinfo *cahead);
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
int
|
||||
Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
Curl_addrinfo **result);
|
||||
#endif
|
||||
|
||||
Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port);
|
||||
|
||||
#endif /* HEADER_CURL_ADDRINFO_H */
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2008, 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
|
||||
@ -160,7 +160,7 @@ CURLcode Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
|
||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||
int timeouts,
|
||||
#endif
|
||||
struct addrinfo *ai)
|
||||
Curl_addrinfo *ai)
|
||||
{
|
||||
/* NOTE: for CURLRES_ARES, the 'ai' argument is really a
|
||||
* 'struct hostent' pointer.
|
||||
|
150
lib/hostip.c
150
lib/hostip.c
@ -693,8 +693,10 @@ static void freednsentry(void *freethis)
|
||||
{
|
||||
struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
|
||||
|
||||
Curl_freeaddrinfo(p->addr);
|
||||
free(p);
|
||||
if(p) {
|
||||
Curl_freeaddrinfo(p->addr);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -729,25 +731,6 @@ Curl_addrinfo *Curl_addrinfo_copy(const void *org, int port)
|
||||
**********************************************************************/
|
||||
|
||||
#if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
|
||||
/*
|
||||
* This is a function for freeing name information in a protocol independent
|
||||
* way.
|
||||
*/
|
||||
void Curl_freeaddrinfo(Curl_addrinfo *ai)
|
||||
{
|
||||
Curl_addrinfo *next;
|
||||
|
||||
/* walk over the list and free all entries */
|
||||
while(ai) {
|
||||
next = ai->ai_next;
|
||||
if(ai->ai_addr)
|
||||
free(ai->ai_addr);
|
||||
if(ai->ai_canonname)
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
ai = next;
|
||||
}
|
||||
}
|
||||
|
||||
struct namebuf4 {
|
||||
struct hostent hostentry;
|
||||
@ -825,129 +808,4 @@ Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port)
|
||||
return ai;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_he2ai() translates from a hostent struct to a Curl_addrinfo struct.
|
||||
* The Curl_addrinfo is meant to work like the addrinfo struct does for IPv6
|
||||
* stacks, but for all hosts and environments.
|
||||
*
|
||||
* Curl_addrinfo defined in "lib/hostip.h"
|
||||
*
|
||||
* struct Curl_addrinfo {
|
||||
* int ai_flags;
|
||||
* int ai_family;
|
||||
* int ai_socktype;
|
||||
* int ai_protocol;
|
||||
* socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo *
|
||||
* char *ai_canonname;
|
||||
* struct sockaddr *ai_addr;
|
||||
* struct Curl_addrinfo *ai_next;
|
||||
* };
|
||||
*
|
||||
* hostent defined in <netdb.h>
|
||||
*
|
||||
* struct hostent {
|
||||
* char *h_name;
|
||||
* char **h_aliases;
|
||||
* int h_addrtype;
|
||||
* int h_length;
|
||||
* char **h_addr_list;
|
||||
* };
|
||||
*
|
||||
* for backward compatibility:
|
||||
*
|
||||
* #define h_addr h_addr_list[0]
|
||||
*/
|
||||
|
||||
Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
Curl_addrinfo *prevai = NULL;
|
||||
Curl_addrinfo *firstai = NULL;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef CURLRES_IPV6
|
||||
struct sockaddr_in6 *addr6;
|
||||
#endif /* CURLRES_IPV6 */
|
||||
CURLcode result = CURLE_OK;
|
||||
int i;
|
||||
char *curr;
|
||||
|
||||
if(!he)
|
||||
/* no input == no output! */
|
||||
return NULL;
|
||||
|
||||
for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
|
||||
|
||||
int ss_size;
|
||||
#ifdef CURLRES_IPV6
|
||||
if (he->h_addrtype == AF_INET6)
|
||||
ss_size = sizeof (struct sockaddr_in6);
|
||||
else
|
||||
#endif /* CURLRES_IPV6 */
|
||||
ss_size = sizeof (struct sockaddr_in);
|
||||
|
||||
if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
if((ai->ai_canonname = strdup(he->h_name)) == NULL) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
if((ai->ai_addr = calloc(1, ss_size)) == NULL) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!firstai)
|
||||
/* store the pointer we want to return from this function */
|
||||
firstai = ai;
|
||||
|
||||
if(prevai)
|
||||
/* make the previous entry point to this */
|
||||
prevai->ai_next = ai;
|
||||
|
||||
ai->ai_family = he->h_addrtype;
|
||||
|
||||
/* we return all names as STREAM, so when using this address for TFTP
|
||||
the type must be ignored and conn->socktype be used instead! */
|
||||
ai->ai_socktype = SOCK_STREAM;
|
||||
|
||||
ai->ai_addrlen = ss_size;
|
||||
|
||||
/* leave the rest of the struct filled with zero */
|
||||
|
||||
switch (ai->ai_family) {
|
||||
case AF_INET:
|
||||
addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
|
||||
|
||||
memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
|
||||
addr->sin_family = (unsigned short)(he->h_addrtype);
|
||||
addr->sin_port = htons((unsigned short)port);
|
||||
break;
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
case AF_INET6:
|
||||
addr6 = (struct sockaddr_in6 *)ai->ai_addr; /* storage area for this info */
|
||||
|
||||
memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
|
||||
addr6->sin6_family = (unsigned short)(he->h_addrtype);
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif /* CURLRES_IPV6 */
|
||||
}
|
||||
|
||||
prevai = ai;
|
||||
}
|
||||
|
||||
if(result != CURLE_OK) {
|
||||
Curl_freeaddrinfo(firstai);
|
||||
firstai = NULL;
|
||||
}
|
||||
|
||||
return firstai;
|
||||
}
|
||||
|
||||
#endif /* CURLRES_IPV4 || CURLRES_ARES */
|
||||
|
34
lib/hostip.h
34
lib/hostip.h
@ -25,6 +25,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
#include "hash.h"
|
||||
#include "curl_addrinfo.h"
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
#include <setjmp.h>
|
||||
@ -103,29 +104,9 @@
|
||||
#define ares_destroy(x) do {} while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_addrinfo MUST be used for all name resolved info.
|
||||
*/
|
||||
#ifdef CURLRES_IPV6
|
||||
typedef struct addrinfo Curl_addrinfo;
|
||||
#ifdef CURLRES_ARES
|
||||
#if defined(CURLRES_IPV6) && defined(CURLRES_ARES)
|
||||
Curl_addrinfo *Curl_ip2addr6(struct in6_addr *in,
|
||||
const char *hostname, int port);
|
||||
#endif
|
||||
#else
|
||||
/* OK, so some ipv4-only include tree probably have the addrinfo struct, but
|
||||
to work even on those that don't, we provide our own look-alike! */
|
||||
struct Curl_addrinfo {
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */
|
||||
char *ai_canonname;
|
||||
struct sockaddr *ai_addr;
|
||||
struct Curl_addrinfo *ai_next;
|
||||
};
|
||||
typedef struct Curl_addrinfo Curl_addrinfo;
|
||||
const char *hostname, int port);
|
||||
#endif
|
||||
|
||||
struct addrinfo;
|
||||
@ -207,9 +188,6 @@ void Curl_resolv_unlock(struct SessionHandle *data,
|
||||
/* for debugging purposes only: */
|
||||
void Curl_scan_cache_used(void *user, void *ptr);
|
||||
|
||||
/* free name info */
|
||||
void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
|
||||
|
||||
/* make a new dns cache and return the handle */
|
||||
struct curl_hash *Curl_mk_dnscache(void);
|
||||
|
||||
@ -251,17 +229,13 @@ CURLcode Curl_addrinfo6_callback(void *arg,
|
||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||
int timeouts,
|
||||
#endif
|
||||
struct addrinfo *ai);
|
||||
Curl_addrinfo *ai);
|
||||
|
||||
|
||||
/* [ipv4/ares only] Creates a Curl_addrinfo struct from a numerical-only IP
|
||||
address */
|
||||
Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port);
|
||||
|
||||
/* [ipv4/ares only] Curl_he2ai() converts a struct hostent to a Curl_addrinfo chain
|
||||
and returns it */
|
||||
Curl_addrinfo *Curl_he2ai(const struct hostent *, int port);
|
||||
|
||||
/* Clone a Curl_addrinfo struct, works protocol independently */
|
||||
Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port);
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2008, 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
|
||||
@ -77,18 +77,8 @@
|
||||
* Only for ipv6-enabled builds
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_IPV6
|
||||
#ifndef CURLRES_ARES
|
||||
/*
|
||||
* This is a wrapper function for freeing name information in a protocol
|
||||
* independent way. This takes care of using the appropriate underlaying
|
||||
* function.
|
||||
*/
|
||||
void Curl_freeaddrinfo(Curl_addrinfo *p)
|
||||
{
|
||||
if(p)
|
||||
freeaddrinfo(p);
|
||||
}
|
||||
|
||||
#ifndef CURLRES_ARES
|
||||
#ifdef CURLRES_ASYNCH
|
||||
/*
|
||||
* Curl_addrinfo_copy() is used by the asynch callback to copy a given
|
||||
@ -189,7 +179,7 @@ bool Curl_ipvalid(struct SessionHandle *data)
|
||||
#if !defined(USE_THREADING_GETADDRINFO) && !defined(CURLRES_ARES)
|
||||
|
||||
#ifdef DEBUG_ADDRINFO
|
||||
static void dump_addrinfo(struct connectdata *conn, const struct addrinfo *ai)
|
||||
static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
|
||||
{
|
||||
printf("dump_addrinfo:\n");
|
||||
for ( ; ai; ai = ai->ai_next) {
|
||||
@ -221,7 +211,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
struct addrinfo hints;
|
||||
Curl_addrinfo *res;
|
||||
int error;
|
||||
char sbuf[NI_MAXSERV];
|
||||
char *sbufptr = NULL;
|
||||
@ -283,7 +274,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
sbufptr=sbuf;
|
||||
}
|
||||
error = getaddrinfo(hostname, sbufptr, &hints, &res);
|
||||
error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res);
|
||||
if(error) {
|
||||
infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
|
||||
return NULL;
|
||||
|
@ -288,7 +288,7 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata*) arg;
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
struct addrinfo *res;
|
||||
Curl_addrinfo *res;
|
||||
char service [NI_MAXSERV];
|
||||
int rc;
|
||||
struct addrinfo hints = td->hints;
|
||||
@ -313,7 +313,7 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
|
||||
need */
|
||||
SetEvent(td->event_thread_started);
|
||||
|
||||
rc = getaddrinfo(tsd.hostname, service, &hints, &res);
|
||||
rc = Curl_getaddrinfo_ex(tsd.hostname, service, &hints, &res);
|
||||
|
||||
/* is parent thread waiting for us and are we able to access conn members? */
|
||||
if(acquire_thread_sync(&tsd)) {
|
||||
@ -703,7 +703,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
struct addrinfo hints;
|
||||
Curl_addrinfo *res;
|
||||
int error;
|
||||
char sbuf[NI_MAXSERV];
|
||||
int pf;
|
||||
@ -762,7 +763,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
infof(data, "init_resolve_thread() failed for %s; %s\n",
|
||||
hostname, Curl_strerror(conn, ERRNO));
|
||||
|
||||
error = getaddrinfo(hostname, sbuf, &hints, &res);
|
||||
error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
|
||||
if(error) {
|
||||
infof(data, "getaddrinfo() failed for %s:%d; %s\n",
|
||||
hostname, port, Curl_strerror(conn, SOCKERRNO));
|
||||
|
@ -315,7 +315,8 @@ static void sh_freeentry(void *freethis)
|
||||
{
|
||||
struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
|
||||
|
||||
free(p);
|
||||
if(p)
|
||||
free(p);
|
||||
}
|
||||
|
||||
static size_t fd_key_compare(void*k1, size_t k1_len, void*k2, size_t k2_len)
|
||||
|
@ -10,11 +10,17 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#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>
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#define ENABLE_CURLX_PRINTF
|
||||
@ -64,13 +70,6 @@ static Curl_addrinfo *fake_ai(void)
|
||||
ai->ai_family = AF_INET;
|
||||
ai->ai_addrlen = ss_size;
|
||||
|
||||
#if defined(ENABLE_IPV6) && defined(CURLDEBUG)
|
||||
/* For tracing purposes log a fake call to getaddrinfo */
|
||||
if(logfile)
|
||||
fprintf(logfile, "ADDR %s:%d getaddrinfo() = %p\n",
|
||||
__FILE__, __LINE__, (void *)ai);
|
||||
#endif
|
||||
|
||||
return ai;
|
||||
}
|
||||
#endif /* LIB559 */
|
||||
|
Loading…
Reference in New Issue
Block a user