dovecot-2.2: lib-http: Always try to connect to host's all IPs w...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jul 10 01:45:51 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/dee7822501b0
changeset: 16577:dee7822501b0
user: Timo Sirainen <tss at iki.fi>
date: Wed Jul 10 01:44:40 2013 +0300
description:
lib-http: Always try to connect to host's all IPs when connections fail.
Previously this was done only when the new connections started from the
first IP.
diffstat:
src/lib-http/http-client-host.c | 44 +++++++++++++++++++++++++++++++------
src/lib-http/http-client-private.h | 4 +++
2 files changed, 41 insertions(+), 7 deletions(-)
diffs (121 lines):
diff -r 1fbac590b9d4 -r dee7822501b0 src/lib-http/http-client-host.c
--- a/src/lib-http/http-client-host.c Fri Jun 28 19:48:37 2013 +0300
+++ b/src/lib-http/http-client-host.c Wed Jul 10 01:44:40 2013 +0300
@@ -114,6 +114,20 @@
}
}
+static bool
+http_client_hport_is_last_connect_ip(struct http_client_host_port *hport)
+{
+ i_assert(hport->ips_connect_idx < hport->host->ips_count);
+ i_assert(hport->ips_connect_start_idx < hport->host->ips_count);
+
+ /* we'll always go through all the IPs. we don't necessarily start
+ connecting from the first IP, so we'll need to treat the IPs as
+ a ring buffer where we automatically wrap back to the first IP
+ when necessary. */
+ return (hport->ips_connect_idx + 1) % hport->host->ips_count ==
+ hport->ips_connect_start_idx;
+}
+
static void
http_client_host_port_soft_connect_timeout(struct http_client_host_port *hport)
{
@@ -122,7 +136,7 @@
if (hport->to_connect != NULL)
timeout_remove(&hport->to_connect);
- if (hport->ips_connect_idx + 1 >= host->ips_count)
+ if (http_client_hport_is_last_connect_ip(hport))
return;
/* if our our previous connection attempt takes longer than the
@@ -135,7 +149,7 @@
hport->https_name == NULL ? "" :
t_strdup_printf(" (SSL=%s)", hport->https_name));
- hport->ips_connect_idx++;
+ hport->ips_connect_idx = (hport->ips_connect_idx + 1) % host->ips_count;
http_client_host_port_connection_setup(hport);
}
@@ -161,7 +175,7 @@
/* start soft connect time-out (but only if we have another IP left) */
msecs = host->client->set.soft_connect_timeout_msecs;
- if (host->ips_count - hport->ips_connect_idx > 1 && msecs > 0 &&
+ if (!http_client_hport_is_last_connect_ip(hport) && msecs > 0 &&
hport->to_connect == NULL) {
hport->to_connect =
timeout_add(msecs, http_client_host_port_soft_connect_timeout, hport);
@@ -200,11 +214,26 @@
}
}
+static unsigned int
+http_client_host_get_ip_idx(struct http_client_host *host,
+ const struct ip_addr *ip)
+{
+ unsigned int i;
+
+ for (i = 0; i < host->ips_count; i++) {
+ if (net_ip_compare(&host->ips[i], ip))
+ return i;
+ }
+ i_unreached();
+}
+
static void
http_client_host_port_connection_success(struct http_client_host_port *hport,
const struct http_client_peer_addr *addr)
{
/* we achieved at least one connection the the addr->ip */
+ hport->ips_connect_start_idx =
+ http_client_host_get_ip_idx(hport->host, &addr->ip);
/* stop soft connect time-out */
if (hport->to_connect != NULL)
@@ -237,15 +266,16 @@
if (hport->to_connect != NULL)
timeout_remove(&hport->to_connect);
- i_assert(hport->ips_connect_idx < host->ips_count);
- if (++hport->ips_connect_idx == host->ips_count) {
+ if (http_client_hport_is_last_connect_ip(hport)) {
/* all IPs failed, but retry all of them again on the
next request. */
- hport->ips_connect_idx = 0;
+ hport->ips_connect_idx = hport->ips_connect_start_idx =
+ (hport->ips_connect_idx + 1) % host->ips_count;
http_client_host_port_error(hport,
HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, reason);
return FALSE;
}
+ hport->ips_connect_idx = (hport->ips_connect_idx + 1) % host->ips_count;
http_client_host_port_connection_setup(hport);
return TRUE;
@@ -329,7 +359,7 @@
/* make connections to requested ports */
array_foreach_modifiable(&host->ports, hport) {
unsigned int count = array_count(&hport->request_queue);
- hport->ips_connect_idx = 0;
+ hport->ips_connect_idx = hport->ips_connect_start_idx = 0;
if (count > 0)
http_client_host_port_connection_setup(hport);
requests += count;
diff -r 1fbac590b9d4 -r dee7822501b0 src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h Fri Jun 28 19:48:37 2013 +0300
+++ b/src/lib-http/http-client-private.h Wed Jul 10 01:44:40 2013 +0300
@@ -78,6 +78,10 @@
/* current index in host->ips */
unsigned int ips_connect_idx;
+ /* the first IP that started the current round of connection attempts.
+ initially 0, and later set to the (ip_idx+1) of the last successful
+ connected IP */
+ unsigned int ips_connect_start_idx;
/* number of connections trying to connect for this host+port */
unsigned int pending_connection_count;
More information about the dovecot-cvs
mailing list