* Host
*/
-static inline bool
-http_client_host_get_ip_idx(struct http_client_host *host,
- const struct ip_addr *ip, unsigned int *idx_r)
+static inline unsigned int
+http_client_host_get_ips_count(struct http_client_host *host)
{
- unsigned int i;
+ return host->ips_count;
+}
- for (i = 0; i < host->ips_count; i++) {
- if (net_ip_compare(&host->ips[i], ip)) {
- *idx_r = i;
- return TRUE;
- }
- }
- return FALSE;
+static inline const struct ip_addr *
+http_client_host_get_ip(struct http_client_host *host,
+ unsigned int idx)
+{
+ i_assert(idx < host->ips_count);
+ return &host->ips[idx];
+}
+
+static inline bool
+http_client_host_ready(struct http_client_host *host)
+{
+ return host->dns_lookup == NULL;
}
struct http_client_host *
void http_client_host_switch_ioloop(struct http_client_host *host);
void http_client_host_check_idle(struct http_client_host *host);
int http_client_host_refresh(struct http_client_host *host);
+bool http_client_host_get_ip_idx(struct http_client_host *host,
+ const struct ip_addr *ip, unsigned int *idx_r);
/*
* Client
const struct http_client_settings *set =
&queue->client->set;
struct http_client_host *host = queue->host;
+ unsigned int ips_count = http_client_host_get_ips_count(host);
i_assert(queue->addr.type != HTTP_CLIENT_PEER_ADDR_UNIX);
- i_assert(queue->ips_connect_idx < host->ips_count);
- i_assert(queue->ips_connect_start_idx < host->ips_count);
+ i_assert(queue->ips_connect_idx < ips_count);
+ i_assert(queue->ips_connect_start_idx < ips_count);
/* if a maximum connect attempts > 1 is set, enforce it directly */
if (set->max_connect_attempts > 1 &&
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 (queue->ips_connect_idx + 1) % host->ips_count ==
+ return (queue->ips_connect_idx + 1) % ips_count ==
queue->ips_connect_start_idx;
}
http_client_queue_recover_from_lookup(struct http_client_queue *queue)
{
struct http_client_host *host = queue->host;
- struct http_client_peer_addr new_addr = queue->addr;
- unsigned int i;
+ unsigned int ip_idx;
i_assert(queue->addr.type != HTTP_CLIENT_PEER_ADDR_UNIX);
return;
}
- /* try to find current peer amongst new IPs */
- for (i = 0; i < host->ips_count; i++) {
- new_addr.a.tcp.ip = host->ips[i];
- if (http_client_peer_addr_cmp
- (&new_addr, &queue->cur_peer->addr) == 0)
- break;
- }
-
- if (i < host->ips_count) {
+ if (http_client_host_get_ip_idx(host,
+ &queue->cur_peer->addr.a.tcp.ip, &ip_idx)) {
/* continue with current peer */
- queue->ips_connect_idx = queue->ips_connect_start_idx = i;
+ queue->ips_connect_idx = queue->ips_connect_start_idx = ip_idx;
} else {
/* reset connect attempts */
queue->ips_connect_idx = queue->ips_connect_start_idx = 0;
{
struct http_client_host *host = queue->host;
const struct http_client_peer_addr *addr = &queue->addr;
+ unsigned int ips_count = http_client_host_get_ips_count(host);
const char *https_name;
i_assert(queue->addr.type != HTTP_CLIENT_PEER_ADDR_UNIX);
t_strdup_printf(" (SSL=%s)", https_name)));
/* next IP */
- queue->ips_connect_idx = (queue->ips_connect_idx + 1) % host->ips_count;
+ queue->ips_connect_idx = (queue->ips_connect_idx + 1) % ips_count;
/* setup connection to new peer (can start new soft timeout) */
http_client_queue_connection_setup(queue);
/* update our peer address */
if (queue->addr.type != HTTP_CLIENT_PEER_ADDR_UNIX) {
- i_assert(queue->ips_connect_idx < host->ips_count);
- queue->addr.a.tcp.ip = host->ips[queue->ips_connect_idx];
+ const struct ip_addr *ip = http_client_host_get_ip(host,
+ queue->ips_connect_idx);
+ queue->addr.a.tcp.ip = *ip;
ssl = http_client_peer_addr_get_https_name(addr);
ssl = (ssl == NULL ? "" : t_strdup_printf(" (SSL=%s)", ssl));
}
http_client_queue_connection_success(struct http_client_queue *queue,
const struct http_client_peer_addr *addr)
{
- if (queue->host->dns_lookup == NULL &&
+ struct http_client_host *host = queue->host;
+
+ if (http_client_host_ready(host) &&
queue->addr.type != HTTP_CLIENT_PEER_ADDR_UNIX) {
/* we achieved at least one connection the the addr->ip */
- if (!http_client_host_get_ip_idx(queue->host,
+ if (!http_client_host_get_ip_idx(host,
&addr->a.tcp.ip, &queue->ips_connect_start_idx)) {
/* list of IPs changed during connect */
queue->ips_connect_start_idx = 0;
&queue->client->set;
const char *https_name = http_client_peer_addr_get_https_name(addr);
struct http_client_host *host = queue->host;
+ unsigned int ips_count = http_client_host_get_ips_count(host);
struct http_client_peer *failed_peer;
struct http_client_peer *const *peer_idx;
/* all IPs failed, but retry all of them again if we have more
connect attempts left or on the next request. */
queue->ips_connect_idx = queue->ips_connect_start_idx =
- (queue->ips_connect_idx + 1) % host->ips_count;
+ (queue->ips_connect_idx + 1) % ips_count;
if (set->max_connect_attempts == 0 ||
queue->connect_attempts >= set->max_connect_attempts) {
return;
}
} else {
- queue->ips_connect_idx = (queue->ips_connect_idx + 1) % host->ips_count;
+ queue->ips_connect_idx = (queue->ips_connect_idx + 1) % ips_count;
}
if (http_client_queue_connection_attempt(queue) != failed_peer)