Permalink
Browse files

Improves how sources handle multi-IP hosts, specially with multiple

families. There were certain systems where Cherokee had problems to
sources pointing to "localhost" if it was configured with both IPv4
and IPv6.  --  Thanks to Antonio Perez (skarcha) for the patch!!!

git-svn-id: svn://cherokee-project.com/cherokee/trunk@6888 5dc97367-97f1-0310-9951-d761b3857238
  • Loading branch information...
1 parent 4182717 commit 611f7b0a8bdc8954dcf02d34e6d06a3c6abf0aa5 @alobbs alobbs committed Oct 7, 2011
Showing with 58 additions and 9 deletions.
  1. +57 −9 cherokee/source.c
  2. +1 −0 cherokee/source.h
View
@@ -46,9 +46,10 @@ cherokee_source_init (cherokee_source_t *src)
cherokee_buffer_init (&src->unix_socket);
cherokee_buffer_init (&src->host);
- src->type = source_host;
- src->port = -1;
- src->free = NULL;
+ src->type = source_host;
+ src->port = -1;
+ src->free = NULL;
+ src->addr_current = NULL;
return ret_ok;
}
@@ -57,8 +58,9 @@ cherokee_source_init (cherokee_source_t *src)
ret_t
cherokee_source_mrproper (cherokee_source_t *src)
{
- if (src->free)
+ if (src->free) {
src->free (src);
+ }
cherokee_buffer_mrproper (&src->original);
cherokee_buffer_mrproper (&src->unix_socket);
@@ -96,6 +98,8 @@ cherokee_source_connect (cherokee_source_t *src, cherokee_socket_t *sock)
return ret;
}
} else {
+ cherokee_boolean_t tested_all;
+ const struct addrinfo *addr;
const struct addrinfo *addr_info = NULL;
/* Query the resolv cache
@@ -110,13 +114,57 @@ cherokee_source_connect (cherokee_source_t *src, cherokee_socket_t *sock)
return ret_error;
}
- /* Create the socket descriptor */
- ret = cherokee_socket_create_fd (sock, addr_info->ai_family);
- if (unlikely (ret != ret_ok)) {
- return ret_error;
+ /* Current address
+ */
+ if (src->addr_current) {
+ tested_all = false;
+ addr = src->addr_current;
+ } else {
+ tested_all = true;
+ addr = addr_info;
}
- /* Update the new socket */
+ /* Create the fd for the address family
+ *
+ * Iterates through the different addresses of the
+ * host and stores a pointer to the first one with
+ * a supported family.
+ */
+ while (addr != NULL) {
+ ret = cherokee_socket_create_fd (sock, addr->ai_family);
+
+#ifdef TRACE_ENABLED
+ if (cherokee_trace_is_tracing()) {
+ ret_t ret2;
+ char ip[46];
+
+ ret2 = cherokee_ntop (addr->ai_family, addr->ai_addr, ip, sizeof(ip));
+ if (ret2 == ret_ok) {
+ TRACE (ENTRIES, "Connecting to %s, ret=%d\n", ip, ret);
+ }
+ }
+#endif
+
+ if (ret == ret_ok) {
+ src->addr_current = addr;
+ break;
+ }
+
+ addr = addr->ai_next;
+ if (addr == NULL) {
+ if (tested_all) {
+ return ret_error;
+ }
+
+ tested_all = true;
+ src->addr_current = NULL;
+ addr = addr_info;
+ continue;
+ }
+ }
+
+ /* Update the new socket with the address info
+ */
SOCKET_ADDR_IPv4(sock)->sin_port = htons(src->port);
ret = cherokee_socket_update_from_addrinfo (sock, addr_info, 0);
View
@@ -48,6 +48,7 @@ typedef struct {
cherokee_buffer_t unix_socket;
cherokee_buffer_t host;
cint_t port;
+ const struct addrinfo *addr_current;
cherokee_func_free_t free;
} cherokee_source_t;

0 comments on commit 611f7b0

Please sign in to comment.