From a0ef686c542bee30be0b20cd4d3243bec6b4f059 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 6 Nov 2008 17:19:56 +0000 Subject: Merged existing IPv4 and IPv6 Curl_ip2addr functions into a single one which now also takes a protocol address family argument. --- CHANGES | 4 ++ lib/connect.c | 1 - lib/curl_addrinfo.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++-- lib/curl_addrinfo.h | 2 + lib/ftp.c | 63 ++++++++++++++++---------------- lib/hostares.c | 84 +++--------------------------------------- lib/hostip.c | 85 ------------------------------------------- lib/hostip.h | 9 ----- lib/hostip4.c | 8 ++-- lib/hostthre.c | 8 ++-- 10 files changed, 150 insertions(+), 217 deletions(-) diff --git a/CHANGES b/CHANGES index aef2668d8..b42510f96 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,10 @@ Changelog +Yang Tse (6 Nov 2008) +- Merged existing IPv4 and IPv6 Curl_ip2addr functions into a single one + which now also takes a protocol address family argument. + Version 7.19.1 (5 November 2008) Daniel Stenberg (4 Nov 2008) diff --git a/lib/connect.c b/lib/connect.c index b602731fe..65e9be4f4 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -91,7 +91,6 @@ #include "multiif.h" #include "sockaddr.h" /* required for Curl_sockaddr_storage */ #include "inet_ntop.h" -#include "inet_pton.h" #include "sslgen.h" /* for Curl_ssl_check_cxn() */ /* The last #include file should be: */ diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c index 8c538b821..826eae8ce 100644 --- a/lib/curl_addrinfo.c +++ b/lib/curl_addrinfo.c @@ -190,7 +190,8 @@ Curl_getaddrinfo_ex(const char *nodename, *result = cafirst; - return error; /* This is not a CURLcode */ + /* This is not a CURLcode */ + return error; } #endif /* HAVE_GETADDRINFO */ @@ -254,6 +255,8 @@ Curl_he2ai(const struct hostent *he, int port) /* no input == no output! */ return NULL; + DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL)); + for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) { int ss_size; @@ -300,7 +303,7 @@ Curl_he2ai(const struct hostent *he, int port) switch (ai->ai_family) { case AF_INET: - addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */ + addr = (void *)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); @@ -309,7 +312,7 @@ Curl_he2ai(const struct hostent *he, int port) #ifdef ENABLE_IPV6 case AF_INET6: - addr6 = (struct sockaddr_in6 *)ai->ai_addr; /* storage area for this info */ + addr6 = (void *)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); @@ -330,6 +333,100 @@ Curl_he2ai(const struct hostent *he, int port) } +struct namebuff { + struct hostent hostentry; + union { + struct in_addr ina4; +#ifdef ENABLE_IPV6 + struct in6_addr ina6; +#endif + } addrentry; + char *h_addr_list[2]; +}; + + +/* + * Curl_ip2addr() + * + * This function takes an internet address, in binary form, as input parameter + * along with its address family and the string version of the address, and it + * returns a Curl_addrinfo chain filled in correctly with information for the + * given address/host + */ + +Curl_addrinfo * +Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) +{ + Curl_addrinfo *ai; + +#if defined(VMS) && \ + defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) +#pragma pointer_size save +#pragma pointer_size short +#pragma message disable PTRMISMATCH +#endif + + struct hostent *h; + struct namebuff *buf; + char *addrentry; + char *hoststr; + int addrsize; + + DEBUGASSERT(inaddr && hostname); + + buf = malloc(sizeof(struct namebuff)); + if(!buf) + return NULL; + + hoststr = strdup(hostname); + if(!hoststr) { + free(buf); + return NULL; + } + + switch(af) { + case AF_INET: + addrsize = sizeof(struct in_addr); + addrentry = (void *)&buf->addrentry.ina4; + memcpy(addrentry, inaddr, sizeof(struct in_addr)); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + addrsize = sizeof(struct in6_addr); + addrentry = (void *)&buf->addrentry.ina6; + memcpy(addrentry, inaddr, sizeof(struct in6_addr)); + break; +#endif + default: + free(hoststr); + free(buf); + return NULL; + } + + h = &buf->hostentry; + h->h_name = hoststr; + h->h_aliases = NULL; + h->h_addrtype = (short)af; + h->h_length = (short)addrsize; + h->h_addr_list = &buf->h_addr_list[0]; + h->h_addr_list[0] = addrentry; + h->h_addr_list[1] = NULL; /* terminate list of entries */ + +#if defined(VMS) && \ + defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) +#pragma pointer_size restore +#pragma message enable PTRMISMATCH +#endif + + ai = Curl_he2ai(h, port); + + free(hoststr); + free(buf); + + return ai; +} + + #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) /* * curl_dofreeaddrinfo() diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h index f6456f965..50480fa09 100644 --- a/lib/curl_addrinfo.h +++ b/lib/curl_addrinfo.h @@ -78,6 +78,8 @@ Curl_getaddrinfo_ex(const char *nodename, Curl_addrinfo * Curl_he2ai(const struct hostent *he, int port); +Curl_addrinfo * +Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port); #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) void diff --git a/lib/ftp.c b/lib/ftp.c index e629cc0b0..547ad77d9 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -85,6 +85,7 @@ #include "connect.h" #include "strerror.h" #include "inet_ntop.h" +#include "inet_pton.h" #include "select.h" #include "parsedate.h" /* for the week day and month names */ #include "sockaddr.h" /* required for Curl_sockaddr_storage */ @@ -1105,41 +1106,39 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, (void)fcmd; /* not used in the IPv4 code */ if(ftpportstr) { - in_addr_t in; + struct in_addr in; - /* First check if the given name is an IP address */ - in=inet_addr(ftpportstr); - - if(in != CURL_INADDR_NONE) + /* First check if the given string is an IP address */ + if(Curl_inet_pton(AF_INET, ftpportstr, &in) > 0) { /* this is an IPv4 address */ - addr = Curl_ip2addr(in, ftpportstr, 0); - else { - if(Curl_if2ip(AF_INET, ftpportstr, myhost, sizeof(myhost))) { - /* The interface to IP conversion provided a dotted address */ - in=inet_addr(myhost); - addr = Curl_ip2addr(in, myhost, 0); + addr = Curl_ip2addr(AF_INET, &in, ftpportstr, 0); + } + /* otherwise check if the given string is an interface */ + else if(Curl_if2ip(AF_INET, ftpportstr, myhost, sizeof(myhost))) { + /* The interface to IP conversion provided a dotted address */ + if(Curl_inet_pton(AF_INET, myhost, &in) > 0) + addr = Curl_ip2addr(AF_INET, &in, myhost, 0); + } + else if(strlen(ftpportstr)> 1) { + /* might be a host name! */ + struct Curl_dns_entry *h=NULL; + int rc = Curl_resolv(conn, ftpportstr, 0, &h); + if(rc == CURLRESOLV_PENDING) + /* BLOCKING */ + rc = Curl_wait_for_resolv(conn, &h); + if(h) { + addr = h->addr; + /* when we return from this function, we can forget about this entry + so we can unlock it now already */ + Curl_resolv_unlock(data, h); + + freeaddr = FALSE; /* make sure we don't free 'addr' in this function + since it points to a DNS cache entry! */ + } /* (h) */ + else { + infof(data, "Failed to resolve host name %s\n", ftpportstr); } - else if(strlen(ftpportstr)> 1) { - /* might be a host name! */ - struct Curl_dns_entry *h=NULL; - int rc = Curl_resolv(conn, ftpportstr, 0, &h); - if(rc == CURLRESOLV_PENDING) - /* BLOCKING */ - rc = Curl_wait_for_resolv(conn, &h); - if(h) { - addr = h->addr; - /* when we return from this function, we can forget about this entry - so we can unlock it now already */ - Curl_resolv_unlock(data, h); - - freeaddr = FALSE; /* make sure we don't free 'addr' in this function - since it points to a DNS cache entry! */ - } /* (h) */ - else { - infof(data, "Failed to resolve host name %s\n", ftpportstr); - } - } /* strlen */ - } /* CURL_INADDR_NONE */ + } /* strlen */ } /* ftpportstr */ if(!addr) { diff --git a/lib/hostares.c b/lib/hostares.c index f17cdf5ec..1f49b6784 100644 --- a/lib/hostares.c +++ b/lib/hostares.c @@ -289,80 +289,6 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, return rc; } -#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ - -struct namebuf6 { - struct hostent hostentry; - struct in6_addr addrentry; - char *h_addr_list[2]; -}; - -/* - * Curl_ip2addr6() takes an ipv6 internet address as input parameter - * together with a pointer to the string version of the address, and it - * returns a Curl_addrinfo chain filled in correctly with information for this - * address/host. - * - * The input parameters ARE NOT checked for validity but they are expected - * to have been checked already when this is called. - */ -Curl_addrinfo *Curl_ip2addr6(struct in6_addr *in, - const char *hostname, int port) -{ - Curl_addrinfo *ai; - -#if defined(VMS) && \ - defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) -#pragma pointer_size save -#pragma pointer_size short -#pragma message disable PTRMISMATCH -#endif - - struct hostent *h; - struct in6_addr *addrentry; - struct namebuf6 *buf; - char *hoststr; - - DEBUGASSERT(in && hostname); - - buf = malloc(sizeof(struct namebuf6)); - if(!buf) - return NULL; - - hoststr = strdup(hostname); - if(!hoststr) { - free(buf); - return NULL; - } - - addrentry = &buf->addrentry; - memcpy(addrentry, in, sizeof(struct in6_addr)); - - h = &buf->hostentry; - h->h_name = hoststr; - h->h_aliases = NULL; - h->h_addrtype = AF_INET6; - h->h_length = sizeof(struct in6_addr); - h->h_addr_list = &buf->h_addr_list[0]; - h->h_addr_list[0] = (char*)addrentry; - h->h_addr_list[1] = NULL; /* terminate list of entries */ - -#if defined(VMS) && \ - defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) -#pragma pointer_size restore -#pragma message enable PTRMISMATCH -#endif - - ai = Curl_he2ai(h, port); - - free(hoststr); - free(buf); - - return ai; -} -#endif /* CURLRES_IPV6 */ - - /* * Curl_getaddrinfo() - when using ares @@ -379,22 +305,24 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, { char *bufp; struct SessionHandle *data = conn->data; - in_addr_t in = inet_addr(hostname); + struct in_addr in; int family = PF_INET; #ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ struct in6_addr in6; #endif /* CURLRES_IPV6 */ *waitp = FALSE; - if(in != CURL_INADDR_NONE) { + /* First check if this is an IPv4 address string */ + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) { /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(in, hostname, port); + return Curl_ip2addr(AF_INET, &in, hostname, port); } #ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ + /* Otherwise, check if this is an IPv6 address string */ if (Curl_inet_pton (AF_INET6, hostname, &in6) > 0) { /* This must be an IPv6 address literal. */ - return Curl_ip2addr6(&in6, hostname, port); + return Curl_ip2addr(AF_INET6, &in6, hostname, port); } switch(data->set.ip_version) { diff --git a/lib/hostip.c b/lib/hostip.c index f2e394665..b4eb3583a 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -724,88 +724,3 @@ Curl_addrinfo *Curl_addrinfo_copy(const void *org, int port) return Curl_he2ai(orig, port); } #endif /* CURLRES_ADDRINFO_COPY */ - -/*********************************************************************** - * Only for plain-ipv4 and c-ares builds (NOTE: c-ares builds can be IPv6 - * enabled) - **********************************************************************/ - -#if defined(CURLRES_IPV4) || defined(CURLRES_ARES) - -struct namebuf4 { - struct hostent hostentry; - struct in_addr addrentry; - char *h_addr_list[2]; -}; - -/* - * Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter - * together with a pointer to the string version of the address, and it - * returns a Curl_addrinfo chain filled in correctly with information for this - * address/host. - * - * The input parameters ARE NOT checked for validity but they are expected - * to have been checked already when this is called. - */ -Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port) -{ - Curl_addrinfo *ai; - -#if defined(VMS) && \ - defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) -#pragma pointer_size save -#pragma pointer_size short -#pragma message disable PTRMISMATCH -#endif - - struct hostent *h; - struct in_addr *addrentry; - struct namebuf4 *buf; - char *hoststr; - - DEBUGASSERT(hostname); - - buf = malloc(sizeof(struct namebuf4)); - if(!buf) - return NULL; - - hoststr = strdup(hostname); - if(!hoststr) { - free(buf); - return NULL; - } - - addrentry = &buf->addrentry; -#ifdef _CRAYC - /* On UNICOS, s_addr is a bit field and for some reason assigning to it - * doesn't work. There must be a better fix than this ugly hack. - */ - memcpy(addrentry, &num, SIZEOF_in_addr); -#else - addrentry->s_addr = num; -#endif - - h = &buf->hostentry; - h->h_name = hoststr; - h->h_aliases = NULL; - h->h_addrtype = AF_INET; - h->h_length = sizeof(struct in_addr); - h->h_addr_list = &buf->h_addr_list[0]; - h->h_addr_list[0] = (char*)addrentry; - h->h_addr_list[1] = NULL; /* terminate list of entries */ - -#if defined(VMS) && \ - defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) -#pragma pointer_size restore -#pragma message enable PTRMISMATCH -#endif - - ai = Curl_he2ai(h, port); - - free(hoststr); - free(buf); - - return ai; -} - -#endif /* CURLRES_IPV4 || CURLRES_ARES */ diff --git a/lib/hostip.h b/lib/hostip.h index 2d892b85a..8b6bb76fb 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -104,11 +104,6 @@ #define ares_destroy(x) do {} while(0) #endif -#if defined(CURLRES_IPV6) && defined(CURLRES_ARES) -Curl_addrinfo *Curl_ip2addr6(struct in6_addr *in, - const char *hostname, int port); -#endif - struct addrinfo; struct hostent; struct SessionHandle; @@ -224,10 +219,6 @@ CURLcode Curl_addrinfo6_callback(void *arg, 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); - /* Clone a Curl_addrinfo struct, works protocol independently */ Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port); diff --git a/lib/hostip4.c b/lib/hostip4.c index 576c35828..f7100417e 100644 --- a/lib/hostip4.c +++ b/lib/hostip4.c @@ -118,20 +118,18 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, #endif Curl_addrinfo *ai = NULL; struct hostent *h = NULL; - in_addr_t in; + struct in_addr in; struct hostent *buf = NULL; #ifdef CURL_DISABLE_VERBOSE_STRINGS (void)conn; #endif - (void)port; /* unused in IPv4 code */ - *waitp = 0; /* don't wait, we act synchronously */ - if(1 == Curl_inet_pton(AF_INET, hostname, &in)) + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(in, hostname, port); + return Curl_ip2addr(AF_INET, &in, hostname, port); #if defined(HAVE_GETHOSTBYNAME_R) /* diff --git a/lib/hostthre.c b/lib/hostthre.c index 242c48699..3aa1ccbce 100644 --- a/lib/hostthre.c +++ b/lib/hostthre.c @@ -70,6 +70,7 @@ #include "strerror.h" #include "url.h" #include "multiif.h" +#include "inet_pton.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -665,14 +666,13 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, { struct hostent *h = NULL; struct SessionHandle *data = conn->data; - in_addr_t in; + struct in_addr in; *waitp = 0; /* don't wait, we act synchronously */ - in = inet_addr(hostname); - if(in != CURL_INADDR_NONE) + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(in, hostname, port); + return Curl_ip2addr(AF_INET, &in, hostname, port); /* fire up a new resolver thread! */ if(init_resolve_thread(conn, hostname, port, NULL)) { -- cgit v1.2.3