diff options
author | Sara Golemon <pollita@php.net> | 2006-09-11 19:18:10 +0000 |
---|---|---|
committer | Sara Golemon <pollita@php.net> | 2006-09-11 19:18:10 +0000 |
commit | b4812733a0e3f08cf3501a281e6935c743a1aad9 (patch) | |
tree | 62a4d3b82af204102fbe19ca849c124e35fab442 | |
parent | 6024885e40594bc9b9972affb8aebfc04b2a6014 (diff) | |
download | php-git-b4812733a0e3f08cf3501a281e6935c743a1aad9.tar.gz |
MFH: Bug #38687 - sockaddr local storage insufficient for all sock families
-rw-r--r-- | main/network.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/main/network.c b/main/network.c index 15fa5aad97..9921d76acf 100644 --- a/main/network.c +++ b/main/network.c @@ -787,37 +787,46 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short /* make a connection attempt */ if (bindto) { - struct sockaddr local_address; + struct sockaddr *local_address = NULL; + int local_address_len = 0; if (sa->sa_family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in*)&local_address; + struct sockaddr_in *in4 = emalloc(sizeof(struct sockaddr_in)); + + local_address = (struct sockaddr*)in4; + local_address_len = sizeof(struct sockaddr_in); in4->sin_family = sa->sa_family; in4->sin_port = htons(bindport); if (!inet_aton(bindto, &in4->sin_addr)) { - goto bad_ip; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid IP Address: %s", bindto); + goto skip_bind; } memset(&(in4->sin_zero), 0, sizeof(in4->sin_zero)); } #if HAVE_IPV6 && HAVE_INET_PTON else { /* IPV6 */ - struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&local_address; + struct sockaddr_in6 *in6 = emalloc(sizeof(struct sockaddr_in6)); + + local_address = (struct sockaddr*)in6; + local_address_len = sizeof(struct sockaddr_in6); in6->sin6_family = sa->sa_family; in6->sin6_port = htons(bindport); if (inet_pton(AF_INET6, bindto, &in6->sin6_addr) < 1) { - goto bad_ip; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid IP Address: %s", bindto); + goto skip_bind; } } #endif - if (bind(sock, &local_address, sizeof(struct sockaddr))) { + if (!local_address || bind(sock, local_address, local_address_len)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to bind to '%s:%d', system said: %s", bindto, bindport, strerror(errno)); } - goto bind_done; -bad_ip: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid IP Address: %s", bindto); +skip_bind: + if (local_address) { + efree(local_address); + } } -bind_done: /* free error string recieved during previous iteration (if any) */ if (error_string && *error_string) { efree(*error_string); |