Re: cvs: php4 /main network.c
| From: | Andi Gutmans | Date: | Tue, 05 Sep 2000 17:23:00 +0000 |
| Subject: | Re: cvs: php4 /main network.c | ||
| References: | 1 | Groups: | php.cvs |
| Request: | Send a blank email to php-cvs+get-1581@lists.php.net to get a copy of this message | ||
Any reason not to use emalloc()/efree() here? Are these functions used before the memory manager is initialized?
Andi
At 13:56 05/09/00 +0000, Stig Venaas wrote:
--- Andi Gutmans <andi@zend.com> http://www.zend.com/venaas Tue Sep 5 06:56:11 2000 EDTModified files:/php4/main network.cLog: hostconnect now supports IPv6 if getaddrinfo exists, and also tries to connect to all addresses of a host before giving up. It should also be thread safe when using getaddrinfo. Index: php4/main/network.c diff -u php4/main/network.c:1.3 php4/main/network.c:1.4--- php4/main/network.c:1.3 Mon Sep 4 05:58:08 2000+++ php4/main/network.c Tue Sep 5 06:56:11 2000 @@ -15,7 +15,7 @@| Authors: Stig Venaas <venaas@uninett.no> | +----------------------------------------------------------------------+*/ -/* $Id: network.c,v 1.3 2000/09/04 12:58:08 sas Exp $ */ +/* $Id: network.c,v 1.4 2000/09/05 13:56:11 venaas Exp $ */ #include "php.h" @@ -55,25 +55,94 @@ # define SOCK_CONN_ERR -1 #endif -/* Copied lookup_hostname, will be replaced */ - -/* - * Converts a host name to an IP address. - */ -static int php_network_lookup_hostname(const char *addr, struct in_addr *in) +static void php_network_freeaddresses(struct sockaddr **sal) {- struct hostent *host_info; + struct sockaddr **sap;- if (!inet_aton(addr, in)) { - /* XXX NOT THREAD SAFE */ - host_info = gethostbyname(addr); - if (host_info == 0) { - /* Error: unknown host */ + if (sal == NULL) + return; + for (sap = sal; *sap != NULL; sap++) + free(*sap); + free(sal);+} + +static int php_network_getaddresses(const char *host, struct sockaddr ***sal) +{+ struct sockaddr **sap;++ if (host != NULL) {+#ifdef HAVE_GETADDRINFO+ struct addrinfo hints, *res, *sai; + int n;++ memset( &hints, '\0', sizeof(hints) ); + hints.ai_family = AF_UNSPEC; + if (getaddrinfo(host, NULL, &hints, &res)) return -1; - } - *in = *((struct in_addr *) host_info->h_addr); + sai = res; + for (n=2; (sai = sai->ai_next) != NULL; n++); + *sal = malloc(n * sizeof(*sal)); + if (*sal == NULL) + return -1;++ sai = res; + sap = *sal; + do { + switch (sai->ai_family) {+# ifdef AF_INET6+ case AF_INET6: { + *sap = malloc(sizeof(struct sockaddr_in6)); + if (*sap == NULL) { + freeaddrinfo(res); + goto errexit; + } + *(struct sockaddr_in6 *)*sap = + *((struct sockaddr_in6 *)sai->ai_addr); + } break;+# endif+ case AF_INET: { + *sap = malloc(sizeof(struct sockaddr_in)); + if (*sap == NULL) { + freeaddrinfo(res); + goto errexit; + } + *(struct sockaddr_in *)*sap = + *((struct sockaddr_in *)sai->ai_addr); + } break; + } + sap++; + } while ((sai = sai->ai_next) != NULL); + freeaddrinfo(res);+#else+ struct hostent *host_info; + struct in_addr in;++ if (!inet_aton(host, &in)) { + /* XXX NOT THREAD SAFE */ + host_info = gethostbyname(host); + if (host_info == NULL) + return -1; + in = *((struct in_addr *) host_info->h_addr); + }++ *sal = malloc(2 * sizeof(*sal)); + if (*sal == NULL) + return -1; + sap = *sal; + *sap = malloc(sizeof(struct sockaddr_in)); + if (*sap == NULL) + goto errexit;++ (*sap)->sa_family = AF_INET; + ((struct sockaddr_in *)*sap)->sin_addr = in; + sap++;+#endif+ *sap = NULL; + return 0; + errexit: + php_network_freeaddresses(*sal); } - return 0; + return -1;} /* @@ -84,19 +153,49 @@ int hostconnect(char *host, int port, int socktype, int timeout) {int s; - struct sockaddr_in sa; + struct sockaddr **sal, **psal;- if (php_network_lookup_hostname(host, &sa.sin_addr)) - return -1; - s = socket(PF_INET, socktype, 0); - if (s == SOCK_ERR) + if (php_network_getaddresses(host, &sal)) return -1; - sa.sin_family = AF_INET; - sa.sin_port = htons(port); - if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) == SOCK_CONN_ERR) { - close (s); - return -1;++ psal = sal; + while (*sal != NULL) { + s = socket((*sal)->sa_family, socktype, 0); + if (s != SOCK_ERR) { + switch ((*sal)->sa_family) {+#if defined( HAVE_GETADDRINFO ) && defined( AF_INET6 )+ case AF_INET6: { + struct sockaddr_in6 *sa = + (struct sockaddr_in6 *)*sal;++ sa->sin6_family = (*sal)->sa_family; + sa->sin6_port = htons(port); + if (connect(s, (struct sockaddr *) sa, + sizeof(*sa)) != SOCK_CONN_ERR) + goto ok; + } break;+#endif+ case AF_INET: { + struct sockaddr_in *sa = + (struct sockaddr_in *)*sal;++ sa->sin_family = (*sal)->sa_family; + sa->sin_port = htons(port); + if (connect(s, (struct sockaddr *) sa, + sizeof(*sa)) != SOCK_CONN_ERR) + goto ok;++ } break; + } + close (s); + } + sal++; } + php_network_freeaddresses(psal); + return -1;+ + ok:+ php_network_freeaddresses(psal); return s;} -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, e-mail: php-cvs-unsubscribe@lists.php.net For additional commands, e-mail: php-cvs-help@lists.php.net To contact the list administrators, e-mail: php-list-admin@lists.php.net