Hi,

On Tue, 22 Mar 2011 07:36:17 +0100
Willy Tarreau <[email protected]> wrote:

> On Mon, Mar 21, 2011 at 12:52:23PM +0100, Martin Kofahl wrote:
> > With 1.4 the backend works fine, but with 1.5-dev4 haproxy connects
> > itself in stead of the backend. Can you please verify this behavior?
> 
> Sounds like the server's address was resolved as 0.0.0.0 and that
> the system is connecting to itself :-(
> 
> Could you please run that through strace and send the output. The
> only possible thing I see was that I broke something when merging
> the IPv6 work, maybe sometimes an address is not filled before a
> connect().

I can confirm this behavior.

This bug was indeed caused by the recent IPv6 change.

In backend.c, in function assign_server_address, if a server have no
address, this address is replaced by the address the client asked.

Since the IPv6 introduction, I added a function is_addr which returns
1 when an address is not empty.

A mistake in this function caused the return value of IPv4 to be
inverted. Therefore the server address was incorrectly replaced
by the address requested by the client.

In your case, you observed a loop because your server used the same
port as HAProxy.

Please find attached the small patch which fix this problem.

-- 
David du Colombier
>From b2ec7d02f23b927adbe2b440797ab9febd9d1936 Mon Sep 17 00:00:00 2001
From: David du Colombier <[email protected]>
Date: Tue, 22 Mar 2011 11:39:41 +0100
Subject: [PATCH 1/1] [BUG] standard: is_addr return value for IPv4 was inverted

---
 include/common/standard.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/common/standard.h b/include/common/standard.h
index 712d941..7cfd5e2 100644
--- a/include/common/standard.h
+++ b/include/common/standard.h
@@ -475,7 +475,7 @@ static inline int is_addr(struct sockaddr_storage *addr)
 
 	switch (addr->ss_family) {
 	case AF_INET:
-		return *(int *)&((struct sockaddr_in *)&addr)->sin_addr;
+		return *(int *)&((struct sockaddr_in *)addr)->sin_addr;
 	case AF_INET6:
 		for (i = 0; i < sizeof(struct in6_addr) / sizeof(int); i++)
 			if (((int *)&((struct sockaddr_in6 *)addr)->sin6_addr)[i] != 0)
-- 
1.7.4

Reply via email to