Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Solves a number of issues around the IPv6 support of the server,

specially related with internal connections (the proxy server
connecting to an internal server, the uWSGI/FastCGI/SCGI handler
connecting to a app server, etc).

Thanks a million to Stefan de Konink for his code and help!!

git-svn-id: svn://cherokee-project.com/cherokee/trunk@6869 5dc97367-97f1-0310-9951-d761b3857238
  • Loading branch information...
commit 85a296d7b4027da72576f40613ef68ac0f46a284 1 parent b974f1f
@alobbs alobbs authored
View
1  cherokee/Makefile.am
@@ -1399,6 +1399,7 @@ module.h \
module.c \
cryptor.h \
cryptor.c \
+socket_lowlevel.h \
socket.h \
socket.c \
fdpoll.h \
View
2  cherokee/bind.c
@@ -234,7 +234,7 @@ init_socket (cherokee_bind_t *listener, int family)
/* Create the socket, and set its properties
*/
- ret = cherokee_socket_set_client (&listener->socket, family);
+ ret = cherokee_socket_create_fd (&listener->socket, family);
if ((ret != ret_ok) || (SOCKET_FD(&listener->socket) < 0)) {
return ret_error;
}
View
2  cherokee/downloader.c
@@ -216,7 +216,7 @@ connect_to (cherokee_downloader_t *downloader,
/* Create the socket
*/
- ret = cherokee_socket_set_client (sock, AF_INET);
+ ret = cherokee_socket_create_fd (sock, AF_INET);
if (unlikely(ret != ret_ok)) return ret_error;
/* Set the port
View
5 cherokee/main_admin.c
@@ -89,20 +89,21 @@ find_empty_port (int starting, int *port)
cherokee_buffer_add_str (&bind_, "127.0.0.1");
cherokee_socket_init (&s);
- cherokee_socket_set_client (&s, AF_INET);
+ cherokee_socket_create_fd (&s, AF_INET);
while (true) {
ret = cherokee_socket_bind (&s, p, &bind_);
if (ret == ret_ok)
break;
+ cherokee_socket_close (&s);
+
p += 1;
if (p > 0XFFFF) {
goto error;
}
}
- cherokee_socket_close (&s);
cherokee_socket_mrproper (&s);
cherokee_buffer_mrproper (&bind_);
View
38 cherokee/proxy_hosts.c
@@ -437,37 +437,41 @@ cherokee_proxy_util_init_socket (cherokee_socket_t *socket,
{
ret_t ret;
cherokee_resolv_cache_t *resolv;
+ const struct addrinfo *addr_info = NULL;
- TRACE (ENTRIES, "Initializing proxy socket: %s\n",
- cherokee_string_is_ipv6 (&src->host) ? "IPv6": "IPv4");
+ TRACE (ENTRIES, "Initializing proxy %s\n", "socket");
- /* Ensure that no fd leak happens */
- cherokee_socket_close (socket);
-
- /* Create socket & set Family */
- if (cherokee_string_is_ipv6 (&src->host)) {
- ret = cherokee_socket_set_client (socket, AF_INET6);
- } else {
- ret = cherokee_socket_set_client (socket, AF_INET);
+ /* Resolve the hostname of the target server */
+ ret = cherokee_resolv_cache_get_default (&resolv);
+ if (unlikely (ret != ret_ok)) {
+ return ret_error;
}
- if (unlikely(ret != ret_ok))
+ ret = cherokee_resolv_cache_get_addrinfo (resolv, &src->host, &addr_info);
+ if ((ret != ret_ok) || (addr_info == NULL)) {
return ret_error;
+ }
- /* TCP port */
- SOCKET_SIN_PORT(socket) = htons (src->port);
+ /* Ensure that no fd leak happens */
+ cherokee_socket_close (socket);
- /* IP host */
- ret = cherokee_resolv_cache_get_default (&resolv);
+ /* Create the socket descriptor */
+ ret = cherokee_socket_create_fd (socket, addr_info->ai_family);
if (unlikely (ret != ret_ok)) {
return ret_error;
}
- ret = cherokee_resolv_cache_get_host (resolv, &src->host, socket);
- if (ret != ret_ok) {
+ /* Update the new socket */
+ SOCKET_SIN_PORT(socket) = htons (src->port);
+
+ ret = cherokee_socket_update_from_addrinfo (socket, addr_info);
+ if (unlikely (ret != ret_ok)) {
return ret_error;
}
+ TRACE (ENTRIES, "Proxy socket Initialized: %s, target: %s\n",
+ SOCKET_AF(socket) == AF_INET6 ? "IPv6": "IPv4", src->host.buf);
+
/* Set a few properties */
cherokee_fd_set_closexec (socket->socket);
cherokee_fd_set_nonblocking (socket->socket, true);
View
59 cherokee/resolv_cache.c
@@ -32,17 +32,19 @@
#endif
#include "resolv_cache.h"
+#include "socket_lowlevel.h"
#include "util.h"
#include "avl.h"
#include "socket.h"
#include "bogotime.h"
+
#define ENTRIES "resolve"
typedef struct {
- struct in_addr addr;
- cherokee_buffer_t ip_str;
+ struct addrinfo *addr;
+ cherokee_buffer_t ip_str;
} cherokee_resolv_cache_entry_t;
struct cherokee_resolv_cache {
@@ -60,8 +62,8 @@ entry_new (cherokee_resolv_cache_entry_t **entry)
{
CHEROKEE_NEW_STRUCT(n, resolv_cache_entry);
+ n->addr = NULL;
cherokee_buffer_init (&n->ip_str);
- memset (&n->addr, 0, sizeof(n->addr));
*entry = n;
return ret_ok;
@@ -73,6 +75,10 @@ entry_free (void *entry)
{
cherokee_resolv_cache_entry_t *e = entry;
+ if (e->addr) {
+ freeaddrinfo (e->addr);
+ }
+
cherokee_buffer_mrproper (&e->ip_str);
free(entry);
}
@@ -83,7 +89,7 @@ entry_fill_up (cherokee_resolv_cache_entry_t *entry,
cherokee_buffer_t *domain)
{
ret_t ret;
- char *tmp;
+ char tmp[46]; // Max IPv6 length is 45
time_t eagain_at = 0;
while (true) {
@@ -108,8 +114,14 @@ entry_fill_up (cherokee_resolv_cache_entry_t *entry,
}
}
- tmp = inet_ntoa (entry->addr);
- if (tmp == NULL) {
+ if (unlikely (entry->addr == NULL)) {
+ return ret_error;
+ }
+
+ /* Render the text representation
+ */
+ ret = cherokee_ntop (entry->addr->ai_family, entry->addr->ai_addr, tmp, sizeof(tmp));
+ if (ret != ret_ok) {
return ret_error;
}
@@ -234,6 +246,7 @@ cherokee_resolv_cache_get_ipstr (cherokee_resolv_cache_t *resolv,
if (ret != ret_ok) {
return ret;
}
+ TRACE (ENTRIES, "Resolve '%s': added succesfuly as '%s'.\n", domain->buf, entry->ip_str.buf);
} else {
TRACE (ENTRIES, "Resolve '%s': hit.\n", domain->buf);
}
@@ -253,8 +266,34 @@ cherokee_resolv_cache_get_host (cherokee_resolv_cache_t *resolv,
cherokee_buffer_t *domain,
void *sock_)
{
+ ret_t ret;
+ const struct addrinfo *addr = NULL;
+ cherokee_socket_t *sock = sock_;
+
+ /* Get addrinfo
+ */
+ ret = cherokee_resolv_cache_get_addrinfo (resolv, domain, &addr);
+ if (ret != ret_ok) {
+ return ret;
+ }
+
+ /* Copy it to the socket object
+ */
+ ret = cherokee_socket_update_from_addrinfo (sock, addr);
+ if (ret != ret_ok) {
+ return ret;
+ }
+
+ return ret_ok;
+}
+
+
+ret_t
+cherokee_resolv_cache_get_addrinfo (cherokee_resolv_cache_t *resolv,
+ cherokee_buffer_t *domain,
+ const struct addrinfo **addr_info)
+{
ret_t ret;
- cherokee_socket_t *sock = sock_;
cherokee_resolv_cache_entry_t *entry = NULL;
/* Look for the name in the cache
@@ -270,14 +309,14 @@ cherokee_resolv_cache_get_host (cherokee_resolv_cache_t *resolv,
*/
ret = table_add_new_entry (resolv, domain, &entry);
if (ret != ret_ok) {
+ TRACE (ENTRIES, "Resolve '%s': error ret=%d.\n", domain->buf, ret);
return ret;
}
+ TRACE (ENTRIES, "Resolve '%s': added succesfuly as '%s'.\n", domain->buf, entry->ip_str.buf);
} else {
TRACE (ENTRIES, "Resolve '%s': hit.\n", domain->buf);
}
- /* Copy the address
- */
- memcpy (&SOCKET_SIN_ADDR(sock), &entry->addr, sizeof(entry->addr));
+ *addr_info = entry->addr;
return ret_ok;
}
View
5 cherokee/resolv_cache.h
@@ -44,8 +44,9 @@ ret_t cherokee_resolv_cache_init (cherokee_resolv_cache_t *resolv);
ret_t cherokee_resolv_cache_mrproper (cherokee_resolv_cache_t *resolv);
ret_t cherokee_resolv_cache_clean (cherokee_resolv_cache_t *resolv);
-ret_t cherokee_resolv_cache_get_ipstr (cherokee_resolv_cache_t *resolv, cherokee_buffer_t *domain, const char **ip);
-ret_t cherokee_resolv_cache_get_host (cherokee_resolv_cache_t *resolv, cherokee_buffer_t *domain, void *sock);
+ret_t cherokee_resolv_cache_get_ipstr (cherokee_resolv_cache_t *resolv, cherokee_buffer_t *domain, const char **ip);
+ret_t cherokee_resolv_cache_get_host (cherokee_resolv_cache_t *resolv, cherokee_buffer_t *domain, void *sock);
+ret_t cherokee_resolv_cache_get_addrinfo (cherokee_resolv_cache_t *resolv, cherokee_buffer_t *domain, const struct addrinfo **addr_info);
CHEROKEE_END_DECLS
View
55 cherokee/socket.c
@@ -93,6 +93,7 @@ extern int32_t sendfile (int out_fd, int in_fd, int32_t *offset, uint32_t count)
#include "buffer.h"
#include "server-protected.h"
#include "virtual_server.h"
+#include "resolv_cache.h"
/* Max. sendfile block size (bytes), limiting size of data sent by
@@ -365,6 +366,32 @@ cherokee_socket_set_sockaddr (cherokee_socket_t *socket, int fd, cherokee_sockad
ret_t
+cherokee_socket_update_from_addrinfo (cherokee_socket_t *socket,
+ const struct addrinfo *addr)
+{
+ if (unlikely (addr == NULL))
+ return ret_error;
+
+ SOCKET_AF(socket) = addr->ai_family;
+ socket->client_addr_len = addr->ai_addrlen;
+
+ switch (addr->ai_family) {
+ case AF_INET:
+ memcpy (&SOCKET_SIN_ADDR(socket), &((struct sockaddr_in *) addr->ai_addr)->sin_addr, sizeof(struct in_addr));
+ break;
+ case AF_INET6:
+ memcpy (&SOCKET_SIN6_ADDR(socket), &((struct sockaddr_in6 *) addr->ai_addr)->sin6_addr, sizeof(struct in6_addr));
+ break;
+ default:
+ SHOULDNT_HAPPEN;
+ return ret_error;
+ }
+
+ return ret_ok;
+}
+
+
+ret_t
cherokee_socket_accept_fd (cherokee_socket_t *server_socket,
int *new_fd,
cherokee_sockaddr_t *sa)
@@ -420,17 +447,17 @@ cherokee_socket_accept_fd (cherokee_socket_t *server_socket,
ret_t
-cherokee_socket_set_client (cherokee_socket_t *sock, unsigned short int type)
+cherokee_socket_create_fd (cherokee_socket_t *sock, unsigned short int family)
{
/* Create the socket
*/
do {
- sock->socket = socket (type, SOCK_STREAM, 0);
+ sock->socket = socket (family, SOCK_STREAM, 0);
} while ((sock->socket == -1) && (errno == EINTR));
if (sock->socket < 0) {
#ifdef HAVE_IPV6
- if ((type == AF_INET6) &&
+ if ((family == AF_INET6) &&
(errno == EAFNOSUPPORT))
{
LOG_WARNING (CHEROKEE_ERROR_SOCKET_NO_IPV6);
@@ -444,7 +471,7 @@ cherokee_socket_set_client (cherokee_socket_t *sock, unsigned short int type)
/* Set the family length
*/
- switch (type) {
+ switch (family) {
case AF_INET:
sock->client_addr_len = sizeof (struct sockaddr_in);
memset (&sock->client_addr, 0, sock->client_addr_len);
@@ -467,7 +494,7 @@ cherokee_socket_set_client (cherokee_socket_t *sock, unsigned short int type)
/* Set the family
*/
- SOCKET_AF(sock) = type;
+ SOCKET_AF(sock) = family;
return ret_ok;
}
@@ -1310,6 +1337,11 @@ ret_t
cherokee_socket_gethostbyname (cherokee_socket_t *socket, cherokee_buffer_t *hostname)
{
#ifndef _WIN32
+ ret_t ret;
+ cherokee_resolv_cache_t *resolv = NULL;
+
+ /* Unix sockets
+ */
if (SOCKET_AF(socket) == AF_UNIX) {
memset ((char*) SOCKET_SUN_PATH(socket), 0,
sizeof (SOCKET_ADDR_UNIX(socket)));
@@ -1329,8 +1361,19 @@ cherokee_socket_gethostbyname (cherokee_socket_t *socket, cherokee_buffer_t *hos
return ret_ok;
}
- return cherokee_gethostbyname (hostname->buf, &SOCKET_SIN_ADDR(socket));
+ /* TCP sockets
+ */
+ ret = cherokee_resolv_cache_get_default (&resolv);
+ if (ret != ret_ok) {
+ return ret_error;
+ }
+
+ ret = cherokee_resolv_cache_get_host (resolv, hostname, socket);
+ if (ret != ret_ok) {
+ return ret_error;
+ }
+ return ret_ok;
#else
SHOULDNT_HAPPEN;
return ret_no_sys;
View
56 cherokee/socket.h
@@ -27,60 +27,12 @@
#include "common-internal.h"
-#include <sys/types.h>
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-
-#include <sys/types.h>
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-# include <sys/un.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-
+#include "socket_lowlevel.h"
#include "buffer.h"
#include "virtual_server.h"
#include "fdpoll.h"
#include "cryptor.h"
-#ifdef INET6_ADDRSTRLEN
-# define CHE_INET_ADDRSTRLEN INET6_ADDRSTRLEN
-#else
-# ifdef INET_ADDRSTRLEN
-# define CHE_INET_ADDRSTRLEN INET_ADDRSTRLEN
-# else
-# define CHE_INET_ADDRSTRLEN 16
-# endif
-#endif
-
-#ifndef AF_LOCAL
-# define AF_LOCAL AF_UNIX
-#endif
-
-#ifndef SUN_LEN
-#define SUN_LEN(sa) \
- (strlen((sa)->sun_path) + \
- (size_t)(((struct sockaddr_un*)0)->sun_path))
-#endif
-
-#ifndef SUN_ABSTRACT_LEN
-#define SUN_ABSTRACT_LEN(sa) \
- (strlen((sa)->sun_path+1) + 2 + \
- (size_t)(((struct sockaddr_un*)0)->sun_path))
-#endif
-
/* Socket status
*/
@@ -173,7 +125,7 @@ int cherokee_socket_pending_read (cherokee_socket_t *socket);
ret_t cherokee_socket_flush (cherokee_socket_t *socket);
ret_t cherokee_socket_test_read (cherokee_socket_t *socket);
-ret_t cherokee_socket_set_client (cherokee_socket_t *socket, unsigned short int type);
+ret_t cherokee_socket_create_fd (cherokee_socket_t *socket, unsigned short int family);
ret_t cherokee_socket_bind (cherokee_socket_t *socket, int port, cherokee_buffer_t *listen_to);
ret_t cherokee_socket_listen (cherokee_socket_t *socket, int backlog);
@@ -188,6 +140,7 @@ ret_t cherokee_socket_gethostbyname (cherokee_socket_t *socket, cherokee_buf
ret_t cherokee_socket_set_status (cherokee_socket_t *socket, cherokee_socket_status_t status);
ret_t cherokee_socket_set_cork (cherokee_socket_t *socket, cherokee_boolean_t enable);
+
/* Low level functions
*/
ret_t cherokee_socket_read (cherokee_socket_t *socket, char *buf, int buf_size, size_t *pcnt_read);
@@ -196,6 +149,7 @@ ret_t cherokee_socket_writev (cherokee_socket_t *socket, const struct iovec *vec
/* Extra
*/
-ret_t cherokee_socket_set_sockaddr (cherokee_socket_t *socket, int fd, cherokee_sockaddr_t *sa);
+ret_t cherokee_socket_set_sockaddr (cherokee_socket_t *socket, int fd, cherokee_sockaddr_t *sa);
+ret_t cherokee_socket_update_from_addrinfo (cherokee_socket_t *socket, const struct addrinfo *addr_info);
#endif /* CHEROKEE_SOCKET_H */
View
90 cherokee/socket_lowlevel.h
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ * Alvaro Lopez Ortega <alvaro@alobbs.com>
+ *
+ * Copyright (C) 2001-2011 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef CHEROKEE_SOCKET_LOWLEVEL_H
+#define CHEROKEE_SOCKET_LOWLEVEL_H
+
+#include "common-internal.h"
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#include <sys/types.h>
+#include <netdb.h>
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+# include <sys/un.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+
+
+#ifdef INET6_ADDRSTRLEN
+# define CHE_INET_ADDRSTRLEN INET6_ADDRSTRLEN
+#else
+# ifdef INET_ADDRSTRLEN
+# define CHE_INET_ADDRSTRLEN INET_ADDRSTRLEN
+# else
+# define CHE_INET_ADDRSTRLEN 16
+# endif
+#endif
+
+#ifndef AF_LOCAL
+# define AF_LOCAL AF_UNIX
+#endif
+
+#ifndef SUN_LEN
+#define SUN_LEN(sa) \
+ (strlen((sa)->sun_path) + \
+ (size_t)(((struct sockaddr_un*)0)->sun_path))
+#endif
+
+#ifndef SUN_ABSTRACT_LEN
+#define SUN_ABSTRACT_LEN(sa) \
+ (strlen((sa)->sun_path+1) + 2 + \
+ (size_t)(((struct sockaddr_un*)0)->sun_path))
+#endif
+
+
+typedef struct {
+ union {
+ struct in_addr addr_ipv4;
+ struct in6_addr addr_ipv6;
+ } addr;
+ unsigned short family;
+} cherokee_in_addr_t;
+
+
+#endif /* CHEROKEE_SOCKET_LOWLEVEL_H */
View
57 cherokee/source.c
@@ -80,60 +80,57 @@ cherokee_source_connect (cherokee_source_t *src, cherokee_socket_t *sock)
return cherokee_socket_connect (sock);
}
- /* Get required objects
- */
- ret = cherokee_resolv_cache_get_default (&resolv);
- if (unlikely (ret!=ret_ok)) {
- return ret;
- }
-
- /* UNIX socket
+ /* Create the new socket and set the target IP info
*/
if (! cherokee_buffer_is_empty (&src->unix_socket)) {
- ret = cherokee_socket_set_client (sock, AF_UNIX);
+
+ /* Create the socket descriptor
+ */
+ ret = cherokee_socket_create_fd (sock, AF_UNIX);
if (unlikely (ret != ret_ok)) {
return ret;
}
- /* Copy the unix socket path */
ret = cherokee_socket_gethostbyname (sock, &src->unix_socket);
if (unlikely (ret != ret_ok)) {
return ret;
}
+ } else {
+ const struct addrinfo *addr_info = NULL;
- /* Set non-blocking */
- ret = cherokee_fd_set_nonblocking (sock->socket, true);
- if (unlikely (ret != ret_ok)) {
- LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOURCE_NONBLOCK, sock->socket);
+ /* Query the resolv cache
+ */
+ ret = cherokee_resolv_cache_get_default (&resolv);
+ if (unlikely (ret!=ret_ok)) {
+ return ret;
}
- /* INET socket
- */
- } else {
- if (cherokee_string_is_ipv6 (&src->host)) {
- ret = cherokee_socket_set_client (sock, AF_INET6);
- } else {
- ret = cherokee_socket_set_client (sock, AF_INET);
- }
- if (unlikely (ret != ret_ok)) {
- return ret;
+ ret = cherokee_resolv_cache_get_addrinfo (resolv, &src->host, &addr_info);
+ if ((ret != ret_ok) || (addr_info == NULL)) {
+ return ret_error;
}
- /* Query the host */
- ret = cherokee_resolv_cache_get_host (resolv, &src->host, sock);
+ /* Create the socket descriptor */
+ ret = cherokee_socket_create_fd (sock, addr_info->ai_family);
if (unlikely (ret != ret_ok)) {
- return ret;
+ return ret_error;
}
+ /* Update the new socket */
SOCKET_ADDR_IPv4(sock)->sin_port = htons(src->port);
- /* Set non-blocking */
- ret = cherokee_fd_set_nonblocking (sock->socket, true);
+ ret = cherokee_socket_update_from_addrinfo (sock, addr_info);
if (unlikely (ret != ret_ok)) {
- LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOURCE_NONBLOCK, sock->socket);
+ return ret_error;
}
}
+ /* Set non-blocking */
+ ret = cherokee_fd_set_nonblocking (sock->socket, true);
+ if (unlikely (ret != ret_ok)) {
+ LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOURCE_NONBLOCK, sock->socket);
+ }
+
/* Set close-on-exec and reuse-address */
cherokee_fd_set_closexec (sock->socket);
cherokee_fd_set_reuseaddr (sock->socket);
View
103 cherokee/util.c
@@ -305,10 +305,10 @@ strncasestrn (const char *s, size_t slen, const char *find, size_t findlen)
char sc;
if (unlikely (find == NULL) || (findlen == 0))
- return s;
+ return (char *)s;
if (unlikely (*find == '\0'))
- return s;
+ return (char *)s;
c = *find;
find++;
@@ -756,104 +756,27 @@ cherokee_eval_formated_time (cherokee_buffer_t *buf)
}
-
-/* gethostbyname_r () emulation
- */
-#if defined(HAVE_PTHREAD) && !defined(HAVE_GETHOSTBYNAME_R)
-static pthread_mutex_t __global_gethostbyname_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
ret_t
-cherokee_gethostbyname (const char *hostname, void *_addr)
+cherokee_gethostbyname (const char *hostname, struct addrinfo **addr)
{
- struct in_addr *addr = _addr;
-
-#if !defined(HAVE_PTHREAD) || (defined(HAVE_PTHREAD) && !defined(HAVE_GETHOSTBYNAME_R))
+ int n;
+ struct addrinfo hints;
- struct hostent *host;
-
- CHEROKEE_MUTEX_LOCK (&__global_gethostbyname_mutex);
-
- /* Resolv the host name
- */
- do {
- host = gethostbyname (hostname);
- } while ((host == NULL) && (errno == EINTR));
-
- if (host == NULL) {
- if (h_errno == TRY_AGAIN) {
- CHEROKEE_MUTEX_UNLOCK (&__global_gethostbyname_mutex);
- return ret_eagain;
- }
-
- CHEROKEE_MUTEX_UNLOCK (&__global_gethostbyname_mutex);
- return ret_error;
- }
-
- /* Copy the address
- */
- memcpy (addr, host->h_addr, host->h_length);
- CHEROKEE_MUTEX_UNLOCK (&__global_gethostbyname_mutex);
- return ret_ok;
-
-#elif defined(HAVE_PTHREAD) && defined(HAVE_GETHOSTBYNAME_R)
-
-/* Maximum size that should use gethostbyname_r() function.
- * It will return ERANGE, if more space is needed.
- */
-# define GETHOSTBYNAME_R_BUF_LEN 512
-
- int r;
- struct hostent hs;
- int h_errnop = 0;
- struct hostent *hp = NULL;
- char tmp[GETHOSTBYNAME_R_BUF_LEN];
-
-# if defined(SOLARIS) || defined(IRIX)
- /* Solaris 10:
- * struct hostent *gethostbyname_r
- * (const char *, struct hostent *, char *, int, int *h_errnop);
+ /* What we are trying to get
*/
- hp = gethostbyname_r (hostname, &hs, tmp,
- GETHOSTBYNAME_R_BUF_LEN - 1, &h_errnop);
+ memset (&hints, 0, sizeof(struct addrinfo));
- if (hp == NULL) {
- if (h_errnop == TRY_AGAIN) {
- return ret_eagain;
- }
- return ret_error;
- }
-# else
- /* Linux glibc2:
- * int gethostbyname_r (const char *name,
- * struct hostent *ret, char *buf, size_t buflen,
- * struct hostent **result, int *h_errnop);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ /* Resolve address
*/
- r = gethostbyname_r (hostname,
- &hs, tmp, GETHOSTBYNAME_R_BUF_LEN - 1,
- &hp, &h_errnop);
- if (r != 0) {
- if (h_errnop == TRY_AGAIN) {
- return ret_eagain;
- }
+ n = getaddrinfo (hostname, NULL, &hints, addr);
+ if (n < 0) {
return ret_error;
}
-# endif
- /* Copy the address
- */
- if (hp == NULL) {
- return ret_not_found;
- }
- memcpy (addr, hp->h_addr, hp->h_length);
return ret_ok;
-
-#else
- /* Bad case !
- */
- SHOULDNT_HAPPEN;
- return ret_error;
-#endif
}
View
7 cherokee/util.h
@@ -54,6 +54,10 @@
# include <sys/uio.h>
#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
#include <time.h>
#include <dirent.h>
#include <errno.h>
@@ -157,7 +161,8 @@ int cherokee_open (const char *path, int oflag, int mode);
int cherokee_unlink (const char *path);
int cherokee_pipe (int fildes[2]);
-ret_t cherokee_gethostbyname (const char *hostname, void *addr);
+ret_t cherokee_gethostbyname (const char *hostname, struct addrinfo **addr);
+
ret_t cherokee_gethostname (cherokee_buffer_t *buf);
ret_t cherokee_syslog (int priority, cherokee_buffer_t *buf);
Please sign in to comment.
Something went wrong with that request. Please try again.