changeset 21697:0d071dadb856

lib-http: client: Fixed i_unreached() failure occurring when a host's list of IPs changes while a connection is still pending. In that case, the IP of the pending connection may no longer be associated with that host. If the IP was not found anymore, the i_unreached() error occurred.
author Stephan Bosch <stephan.bosch@dovecot.fi>
date Thu, 23 Feb 2017 19:38:31 +0100
parents b421793ac7cf
children afe2bff4d292
files src/lib-http/http-client-private.h src/lib-http/http-client-queue.c
diffstat 2 files changed, 12 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-http/http-client-private.h	Thu Feb 23 11:29:17 2017 +0200
+++ b/src/lib-http/http-client-private.h	Thu Feb 23 19:38:31 2017 +0100
@@ -516,17 +516,19 @@
  * Host
  */
 
-static inline unsigned int
+static inline bool
 http_client_host_get_ip_idx(struct http_client_host *host,
-			    const struct ip_addr *ip)
+			    const struct ip_addr *ip, unsigned int *idx_r)
 {
 	unsigned int i;
 
 	for (i = 0; i < host->ips_count; i++) {
-		if (net_ip_compare(&host->ips[i], ip))
-			return i;
+		if (net_ip_compare(&host->ips[i], ip)) {
+			*idx_r = i;
+			return TRUE;
+		}
 	}
-	i_unreached();
+	return FALSE;
 }
 
 struct http_client_host *
--- a/src/lib-http/http-client-queue.c	Thu Feb 23 11:29:17 2017 +0200
+++ b/src/lib-http/http-client-queue.c	Thu Feb 23 19:38:31 2017 +0100
@@ -430,8 +430,11 @@
 	if (queue->host->dns_lookup == NULL &&
 		queue->addr.type != HTTP_CLIENT_PEER_ADDR_UNIX) {
 		/* we achieved at least one connection the the addr->ip */
-		queue->ips_connect_start_idx =
-			http_client_host_get_ip_idx(queue->host, &addr->a.tcp.ip);
+		if (!http_client_host_get_ip_idx(queue->host,
+			&addr->a.tcp.ip, &queue->ips_connect_start_idx)) {
+			/* list of IPs changed during connect */
+			queue->ips_connect_start_idx = 0;
+		}
 	}
 
 	/* reset attempt counter */