Loading lib/Makefile.inc +2 −2 Original line number Diff line number Diff line Loading @@ -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 \ Loading @@ -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 lib/curl_addrinfo.c 0 → 100644 +332 −0 Original line number Diff line number Diff line /*************************************************************************** * _ _ ____ _ * 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; } lib/curl_addrinfo.h 0 → 100644 +81 −0 Original line number Diff line number Diff line #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 */ lib/hostasyn.c +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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. Loading lib/hostip.c +4 −146 Original line number Diff line number Diff line Loading @@ -693,9 +693,11 @@ static void freednsentry(void *freethis) { struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis; if(p) { Curl_freeaddrinfo(p->addr); free(p); } } /* * Curl_mk_dnscache() creates a new DNS cache and returns the handle for it. Loading Loading @@ -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; Loading Loading @@ -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 */ Loading
lib/Makefile.inc +2 −2 Original line number Diff line number Diff line Loading @@ -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 \ Loading @@ -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
lib/curl_addrinfo.c 0 → 100644 +332 −0 Original line number Diff line number Diff line /*************************************************************************** * _ _ ____ _ * 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; }
lib/curl_addrinfo.h 0 → 100644 +81 −0 Original line number Diff line number Diff line #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 */
lib/hostasyn.c +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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. Loading
lib/hostip.c +4 −146 Original line number Diff line number Diff line Loading @@ -693,9 +693,11 @@ static void freednsentry(void *freethis) { struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis; if(p) { Curl_freeaddrinfo(p->addr); free(p); } } /* * Curl_mk_dnscache() creates a new DNS cache and returns the handle for it. Loading Loading @@ -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; Loading Loading @@ -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 */