Mailing List Archive

[6869] cherokee/trunk/cherokee: Solves a number of issues around the IPv6 support of the server,
Revision: 6869
http://svn.cherokee-project.com/changeset/6869
Author: alo
Date: 2011-09-26 23:21:08 +0200 (Mon, 26 Sep 2011)
Log Message:
-----------
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!!

Modified Paths:
--------------
cherokee/trunk/cherokee/Makefile.am
cherokee/trunk/cherokee/bind.c
cherokee/trunk/cherokee/downloader.c
cherokee/trunk/cherokee/main_admin.c
cherokee/trunk/cherokee/proxy_hosts.c
cherokee/trunk/cherokee/resolv_cache.c
cherokee/trunk/cherokee/resolv_cache.h
cherokee/trunk/cherokee/socket.c
cherokee/trunk/cherokee/socket.h
cherokee/trunk/cherokee/source.c
cherokee/trunk/cherokee/util.c
cherokee/trunk/cherokee/util.h

Added Paths:
-----------
cherokee/trunk/cherokee/socket_lowlevel.h

Modified: cherokee/trunk/cherokee/Makefile.am
===================================================================
--- cherokee/trunk/cherokee/Makefile.am 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/Makefile.am 2011-09-26 21:21:08 UTC (rev 6869)
@@ -1399,6 +1399,7 @@
module.c \
cryptor.h \
cryptor.c \
+socket_lowlevel.h \
socket.h \
socket.c \
fdpoll.h \

Modified: cherokee/trunk/cherokee/bind.c
===================================================================
--- cherokee/trunk/cherokee/bind.c 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/bind.c 2011-09-26 21:21:08 UTC (rev 6869)
@@ -234,7 +234,7 @@

/* 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;
}

Modified: cherokee/trunk/cherokee/downloader.c
===================================================================
--- cherokee/trunk/cherokee/downloader.c 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/downloader.c 2011-09-26 21:21:08 UTC (rev 6869)
@@ -216,7 +216,7 @@

/* 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

Modified: cherokee/trunk/cherokee/main_admin.c
===================================================================
--- cherokee/trunk/cherokee/main_admin.c 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/main_admin.c 2011-09-26 21:21:08 UTC (rev 6869)
@@ -89,20 +89,21 @@
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_);


Modified: cherokee/trunk/cherokee/proxy_hosts.c
===================================================================
--- cherokee/trunk/cherokee/proxy_hosts.c 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/proxy_hosts.c 2011-09-26 21:21:08 UTC (rev 6869)
@@ -437,37 +437,41 @@
{
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);

Modified: cherokee/trunk/cherokee/resolv_cache.c
===================================================================
--- cherokee/trunk/cherokee/resolv_cache.c 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/resolv_cache.c 2011-09-26 21:21:08 UTC (rev 6869)
@@ -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 @@
{
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 @@
{
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 @@
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,11 +114,17 @@
}
}

- 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;
+ }
+
cherokee_buffer_add (&entry->ip_str, tmp, strlen(tmp));
return ret_ok;
}
@@ -234,6 +246,7 @@
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_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 @@
*/
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;
}

Modified: cherokee/trunk/cherokee/resolv_cache.h
===================================================================
--- cherokee/trunk/cherokee/resolv_cache.h 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/resolv_cache.h 2011-09-26 21:21:08 UTC (rev 6869)
@@ -44,8 +44,9 @@
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


Modified: cherokee/trunk/cherokee/socket.c
===================================================================
--- cherokee/trunk/cherokee/socket.c 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/socket.c 2011-09-26 21:21:08 UTC (rev 6869)
@@ -93,6 +93,7 @@
#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 @@


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 @@


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 @@

/* 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 @@

/* Set the family
*/
- SOCKET_AF(sock) = type;
+ SOCKET_AF(sock) = family;
return ret_ok;
}

@@ -1310,6 +1337,11 @@
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 @@
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;

Modified: cherokee/trunk/cherokee/socket.h
===================================================================
--- cherokee/trunk/cherokee/socket.h 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/socket.h 2011-09-26 21:21:08 UTC (rev 6869)
@@ -27,61 +27,13 @@

#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
*/
typedef enum {
@@ -173,7 +125,7 @@
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_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 @@

/* 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 */

Added: cherokee/trunk/cherokee/socket_lowlevel.h
===================================================================
--- cherokee/trunk/cherokee/socket_lowlevel.h (rev 0)
+++ cherokee/trunk/cherokee/socket_lowlevel.h 2011-09-26 21:21:08 UTC (rev 6869)
@@ -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 */

Modified: cherokee/trunk/cherokee/source.c
===================================================================
--- cherokee/trunk/cherokee/source.c 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/source.c 2011-09-26 21:21:08 UTC (rev 6869)
@@ -80,60 +80,57 @@
return cherokee_socket_connect (sock);
}

- /* Get required objects
+ /* Create the new socket and set the target IP info
*/
- ret = cherokee_resolv_cache_get_default (&resolv);
- if (unlikely (ret!=ret_ok)) {
- return ret;
- }
-
- /* UNIX socket
- */
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);
+ ret = cherokee_resolv_cache_get_addrinfo (resolv, &src->host, &addr_info);
+ if ((ret != ret_ok) || (addr_info == NULL)) {
+ return ret_error;
}
- if (unlikely (ret != ret_ok)) {
- return ret;
- }

- /* 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);

Modified: cherokee/trunk/cherokee/util.c
===================================================================
--- cherokee/trunk/cherokee/util.c 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/util.c 2011-09-26 21:21:08 UTC (rev 6869)
@@ -305,10 +305,10 @@
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 @@
}


-
-/* 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;
+ int n;
+ struct addrinfo hints;

-#if !defined(HAVE_PTHREAD) || (defined(HAVE_PTHREAD) && !defined(HAVE_GETHOSTBYNAME_R))
+ /* What we are trying to get
+ */
+ memset (&hints, 0, sizeof(struct addrinfo));

- struct hostent *host;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;

- 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);
+ /* Resolve address
*/
- hp = gethostbyname_r (hostname, &hs, tmp,
- GETHOSTBYNAME_R_BUF_LEN - 1, &h_errnop);
-
- if (hp == NULL) {
- if (h_errnop == TRY_AGAIN) {
- return ret_eagain;
- }
+ n = getaddrinfo (hostname, NULL, &hints, addr);
+ if (n < 0) {
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);
- */
- 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;
- }
- 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
}



Modified: cherokee/trunk/cherokee/util.h
===================================================================
--- cherokee/trunk/cherokee/util.h 2011-09-24 19:25:35 UTC (rev 6868)
+++ cherokee/trunk/cherokee/util.h 2011-09-26 21:21:08 UTC (rev 6869)
@@ -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_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);