dovecot-2.2: lib-http: client: Fixed bug that caused queues to b...

dovecot at dovecot.org dovecot at dovecot.org
Tue Sep 22 18:18:25 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/1b1dbfaf7daa
changeset: 19187:1b1dbfaf7daa
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Tue Sep 22 21:16:34 2015 +0300
description:
lib-http: client: Fixed bug that caused queues to be duplicated over time when host has multiple IPs.
The peer address comparison did not account for the fact that the initial
queue address has no IP assigned.

diffstat:

 src/lib-http/http-client-peer.c    |  16 ++++++++++++++--
 src/lib-http/http-client-request.c |   9 +++++++++
 2 files changed, 23 insertions(+), 2 deletions(-)

diffs (79 lines):

diff -r b4a1e4d085e2 -r 1b1dbfaf7daa src/lib-http/http-client-peer.c
--- a/src/lib-http/http-client-peer.c	Tue Sep 22 21:15:45 2015 +0300
+++ b/src/lib-http/http-client-peer.c	Tue Sep 22 21:16:34 2015 +0300
@@ -53,7 +53,8 @@
 		/* fall through */
 	case HTTP_CLIENT_PEER_ADDR_RAW:
 	case HTTP_CLIENT_PEER_ADDR_HTTP:
-		hash += net_ip_hash(&peer->a.tcp.ip);
+		if (peer->a.tcp.ip.family != 0)
+			hash += net_ip_hash(&peer->a.tcp.ip);
 		hash += peer->a.tcp.port;
 		break;
 	case HTTP_CLIENT_PEER_ADDR_UNIX:
@@ -77,7 +78,13 @@
 	case HTTP_CLIENT_PEER_ADDR_HTTP:
 	case HTTP_CLIENT_PEER_ADDR_HTTPS:
 	case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
-		if ((ret=net_ip_cmp(&peer1->a.tcp.ip, &peer2->a.tcp.ip)) != 0)
+		/* Queues are created with peer addresses that have an uninitialized
+		   IP value, because that is assigned later when the host lookup completes.
+		   In all other other contexts, the IP is always initialized, so we do not
+		   compare IPs when one of them is unassigned. */
+		if (peer1->a.tcp.ip.family != 0 &&
+			peer2->a.tcp.ip.family != 0 &&
+			(ret=net_ip_cmp(&peer1->a.tcp.ip, &peer2->a.tcp.ip)) != 0)
 			return ret;
 		if (peer1->a.tcp.port != peer2->a.tcp.port)
 			return (peer1->a.tcp.port > peer2->a.tcp.port ? 1 : -1);
@@ -461,8 +468,13 @@
 	peer->addr = *addr;
 
 	switch (addr->type) {
+	case HTTP_CLIENT_PEER_ADDR_RAW:
+	case HTTP_CLIENT_PEER_ADDR_HTTP:
+		i_assert(peer->addr.a.tcp.ip.family != 0);
+		break;
 	case HTTP_CLIENT_PEER_ADDR_HTTPS:
 	case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
+		i_assert(peer->addr.a.tcp.ip.family != 0);
 		i_assert(client->ssl_ctx != NULL);
 		peer->addr_name = i_strdup(addr->a.tcp.https_name);
 		peer->addr.a.tcp.https_name = peer->addr_name;
diff -r b4a1e4d085e2 -r 1b1dbfaf7daa src/lib-http/http-client-request.c
--- a/src/lib-http/http-client-request.c	Tue Sep 22 21:15:45 2015 +0300
+++ b/src/lib-http/http-client-request.c	Tue Sep 22 21:16:34 2015 +0300
@@ -535,12 +535,17 @@
 	const char *host_socket = req->host_socket;
 	const struct http_url *host_url = req->host_url;
 	
+	/* the IP address may be unassigned in the returned peer address, since
+	   that is only available at this stage when the target URL has an
+	   explicit IP address. */
 	memset(addr, 0, sizeof(*addr));
 	if (host_socket != NULL) {
 		addr->type = HTTP_CLIENT_PEER_ADDR_UNIX;
 		addr->a.un.path = host_socket;		
 	} else if (req->connect_direct) {
 		addr->type = HTTP_CLIENT_PEER_ADDR_RAW;
+		if (host_url->have_host_ip)
+			addr->a.tcp.ip = host_url->host_ip;
 		addr->a.tcp.port =
 			(host_url->have_port ? host_url->port : HTTPS_DEFAULT_PORT);
 	} else if (host_url->have_ssl) {
@@ -548,11 +553,15 @@
 			addr->type = HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL;
 		else
 			addr->type = HTTP_CLIENT_PEER_ADDR_HTTPS;
+		if (host_url->have_host_ip)
+			addr->a.tcp.ip = host_url->host_ip;
 		addr->a.tcp.https_name = host_url->host_name;
  		addr->a.tcp.port =
 			(host_url->have_port ? host_url->port : HTTPS_DEFAULT_PORT);
 	} else {
 		addr->type = HTTP_CLIENT_PEER_ADDR_HTTP;
+		if (host_url->have_host_ip)
+			addr->a.tcp.ip = host_url->host_ip;
 		addr->a.tcp.port =
 			(host_url->have_port ? host_url->port : HTTP_DEFAULT_PORT);
 	}


More information about the dovecot-cvs mailing list