bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "lib.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "net.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "str.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "hash.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "array.h"
aacf2a69acc59e9382578d6f4e030788abc79706Timo Sirainen#include "llist.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "ioloop.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "istream.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "ostream.h"
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch#include "time-util.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "dns-lookup.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "http-response-parser.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "http-client-private.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch#define HTTP_CLIENT_HOST_MINIMUM_IDLE_TIMEOUT_MSECS 100
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_lookup_done(struct http_client_host *host);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_lookup_failure(struct http_client_host *host,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch const char *error);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic bool
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_is_idle(struct http_client_host *host);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen/*
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch * Host (shared)
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen */
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_shared_idle_timeout(struct http_client_host_shared *hshared)
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch{
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Idle host timed out");
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_free(&hshared);
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch}
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_shared_check_idle(
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared)
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host *host;
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch int timeout = 0;
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->to_idle != NULL)
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch return;
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = hshared->hosts_list;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch while (host != NULL) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (!http_client_host_is_idle(host))
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch return;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = host->shared_next;
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch }
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (!hshared->unix_local && !hshared->explicit_ip &&
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips_timeout.tv_sec > 0) {
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch timeout = timeval_diff_msecs
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch (&hshared->ips_timeout, &ioloop_timeval);
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch }
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch if (timeout <= HTTP_CLIENT_HOST_MINIMUM_IDLE_TIMEOUT_MSECS)
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch timeout = HTTP_CLIENT_HOST_MINIMUM_IDLE_TIMEOUT_MSECS;
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch
a68aaff537e2e30d782bb8b9d8782e1a10a17d1aStephan Bosch hshared->to_idle = timeout_add_to(hshared->cctx->ioloop, timeout,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_idle_timeout, hshared);
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Host is idle (timeout = %u msecs)", timeout);
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch}
fbe111ce65bb5af03314adbfa8bcde3f08c08641Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_shared_lookup_failure(struct http_client_host_shared *hshared,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch const char *error)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host *host;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
18d2775f815cdeed9bc1a2da078e682f5d354cf9Timo Sirainen error = t_strdup_printf("Failed to lookup host %s: %s",
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->name, error);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = hshared->hosts_list;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch while (host != NULL) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_lookup_failure(host, error);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = host->shared_next;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_check_idle(hshared);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_shared_dns_callback(const struct dns_lookup_result *result,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch struct http_client_context *cctx = hshared->cctx;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host *host;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->dns_lookup = NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (result->ret != 0) {
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch /* lookup failed */
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_lookup_failure(hshared, result->error);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch "DNS lookup successful; got %d IPs", result->ips_count);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_assert(result->ips_count > 0);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips = i_realloc_type(hshared->ips, struct ip_addr,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips_count, result->ips_count);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips_count = result->ips_count;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch memcpy(hshared->ips, result->ips, sizeof(*hshared->ips) * hshared->ips_count);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips_timeout = ioloop_timeval;
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch i_assert(cctx->dns_ttl_msecs > 0);
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch timeval_add_msecs(&hshared->ips_timeout, cctx->dns_ttl_msecs);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch /* notify all sessions */
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = hshared->hosts_list;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch while (host != NULL) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_lookup_done(host);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = host->shared_next;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic void http_client_host_shared_lookup
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch(struct http_client_host_shared *hshared)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch struct http_client_context *cctx = hshared->cctx;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct dns_lookup_settings dns_set;
c936df07cf490f090f2f336f40ca386cc953b055Stephan Bosch struct ip_addr *ips;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch i_assert(!hshared->explicit_ip);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch i_assert(hshared->dns_lookup == NULL);
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch if (cctx->dns_client != NULL) {
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Performing asynchronous DNS lookup");
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch (void)dns_client_lookup(cctx->dns_client, hshared->name,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_dns_callback, hshared, &hshared->dns_lookup);
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch } else if (cctx->dns_client_socket_path != NULL) {
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch i_assert(cctx->dns_lookup_timeout_msecs > 0);
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Performing asynchronous DNS lookup");
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&dns_set);
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch dns_set.dns_client_socket_path = cctx->dns_client_socket_path;
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch dns_set.timeout_msecs = cctx->dns_lookup_timeout_msecs;
a68aaff537e2e30d782bb8b9d8782e1a10a17d1aStephan Bosch dns_set.ioloop = cctx->ioloop;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch (void)dns_lookup(hshared->name, &dns_set,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_dns_callback, hshared, &hshared->dns_lookup);
7944646fad6aa1e7c649c3d33e454c516b0220b6Timo Sirainen } else {
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch unsigned int ips_count;
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch ret = net_gethostbyname(hshared->name, &ips, &ips_count);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (ret != 0) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_lookup_failure(hshared, net_gethosterror(ret));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch "DNS lookup successful; got %d IPs", ips_count);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch i_free(hshared->ips);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips_count = ips_count;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips = i_new(struct ip_addr, ips_count);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch memcpy(hshared->ips, ips, ips_count * sizeof(*ips));
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch }
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->ips_count > 0) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips_timeout = ioloop_timeval;
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch i_assert(cctx->dns_ttl_msecs > 0);
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch timeval_add_msecs(&hshared->ips_timeout, cctx->dns_ttl_msecs);
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch }
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch}
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic int
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_shared_refresh(struct http_client_host_shared *hshared)
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->unix_local)
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch return 0;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->explicit_ip)
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch return 0;
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->dns_lookup != NULL)
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch return -1;
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->ips_count > 0 &&
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch timeval_cmp(&hshared->ips_timeout, &ioloop_timeval) > 0)
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch return 0;
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->to_idle != NULL)
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch return 0;
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "IPs have expired; need to refresh DNS lookup");
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_lookup(hshared);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->dns_lookup != NULL)
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch return -1;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch return (hshared->ips_count > 0 ? 1 : -1);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic struct http_client_host_shared *http_client_host_shared_create
a79ae29fa95877ab857b1b25268c75327717ae8dTimo Sirainen(struct http_client_context *cctx, const char *name)
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch // FIXME: limit the maximum number of inactive cached hosts
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared = i_new(struct http_client_host_shared, 1);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->cctx = cctx;
a79ae29fa95877ab857b1b25268c75327717ae8dTimo Sirainen hshared->name = i_strdup(name);
2d1ad5742dd723b39c51bcf64c62a600237de8aeTimo Sirainen hshared->event = event_create(cctx->event);
2d1ad5742dd723b39c51bcf64c62a600237de8aeTimo Sirainen event_set_append_log_prefix(hshared->event,
2d1ad5742dd723b39c51bcf64c62a600237de8aeTimo Sirainen t_strdup_printf("host %s: ", name));
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch DLLIST_PREPEND(&cctx->hosts_list, hshared);
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch return hshared;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch}
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic struct http_client_host_shared *
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_shared_get
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch(struct http_client_context *cctx,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch const struct http_url *host_url)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch if (host_url == NULL) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared = cctx->unix_host;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared == NULL) {
a79ae29fa95877ab857b1b25268c75327717ae8dTimo Sirainen hshared = http_client_host_shared_create(cctx, "[unix]");
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->name = i_strdup("[unix]");
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->unix_local = TRUE;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch cctx->unix_host = hshared;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Unix host created");
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch }
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch } else {
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch const char *hostname = host_url->host.name;
c936df07cf490f090f2f336f40ca386cc953b055Stephan Bosch struct ip_addr ip = host_url->host.ip;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared = hash_table_lookup(cctx->hosts, hostname);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared == NULL) {
a79ae29fa95877ab857b1b25268c75327717ae8dTimo Sirainen hshared = http_client_host_shared_create(cctx, hostname);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hostname = hshared->name;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hash_table_insert(cctx->hosts, hostname, hshared);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (ip.family != 0 || net_addr2ip(hshared->name, &ip) == 0) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips_count = 1;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips = i_new(struct ip_addr, hshared->ips_count);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->ips[0] = ip;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->explicit_ip = TRUE;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch }
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Host created");
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch return hshared;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschvoid http_client_host_shared_free(struct http_client_host_shared **_hshared)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared = *_hshared;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_context *cctx = hshared->cctx;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host *host;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch const char *hostname = hshared->name;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Host destroy");
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
d90a924480a061683786e459a2e1c1d0b6e4f1e4Josef 'Jeff' Sipek timeout_remove(&hshared->to_idle);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch DLLIST_REMOVE(&cctx->hosts_list, hshared);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared == cctx->unix_host)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch cctx->unix_host = NULL;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch else
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hash_table_remove(cctx->hosts, hostname);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->dns_lookup != NULL)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch dns_lookup_abort(&hshared->dns_lookup);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch /* drop client sessions */
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch while (hshared->hosts_list != NULL) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = hshared->hosts_list;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_free(&host);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch }
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
2d1ad5742dd723b39c51bcf64c62a600237de8aeTimo Sirainen event_unref(&hshared->event);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch i_free(hshared->ips);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch i_free(hshared->name);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch i_free(hshared);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch *_hshared = NULL;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_shared_request_submitted(
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch /* cancel host idle timeout */
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch timeout_remove(&hshared->to_idle);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschvoid http_client_host_shared_switch_ioloop(
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch struct http_client_context *cctx = hshared->cctx;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
ee90a96c4f47ff9c1e56451201386ca8a0b48124Stephan Bosch if (hshared->dns_lookup != NULL && cctx->dns_client == NULL)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch dns_lookup_switch_ioloop(hshared->dns_lookup);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (hshared->to_idle != NULL)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared->to_idle = io_loop_move_timeout(&hshared->to_idle);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch/*
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch * Host
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch */
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstruct http_client_host *
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_get(struct http_client *client,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch const struct http_url *host_url)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host *host;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch hshared = http_client_host_shared_get(client->cctx, host_url);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = hshared->hosts_list;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch while (host != NULL) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (host->client == client)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch break;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = host->shared_next;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch }
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (host == NULL) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host = i_new(struct http_client_host, 1);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host->client = client;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host->shared = hshared;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch i_array_init(&host->queues, 4);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch DLLIST_PREPEND_FULL(&hshared->hosts_list,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host, shared_prev, shared_next);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch DLLIST_PREPEND_FULL(&client->hosts_list,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host, client_prev, client_next);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Host session created");
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch }
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return host;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschvoid http_client_host_free(
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host **_host)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client_host *host = *_host;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client *client = host->client;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared = host->shared;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_queue *const *queue_idx;
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch ARRAY_TYPE(http_client_queue) queues;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
36409af77b42dc1c18c0691970b2eb07785fbba4Timo Sirainen e_debug(hshared->event, "Host session destroy");
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch DLLIST_REMOVE_FULL(&hshared->hosts_list,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host, shared_prev, shared_next);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch DLLIST_REMOVE_FULL(&client->hosts_list,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch host, client_prev, client_next);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* drop request queues */
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch t_array_init(&queues, array_count(&host->queues));
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch array_copy(&queues.arr, 0,
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch &host->queues.arr, 0, array_count(&host->queues));
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch array_clear(&host->queues);
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch array_foreach(&queues, queue_idx) {
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch http_client_queue_free(*queue_idx);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch array_free(&host->queues);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_free(host);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_check_idle(hshared);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch *_host = NULL;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_lookup_done(
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host *host)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client *client = host->client;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_queue *const *queue_idx;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch unsigned int requests = 0;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch /* notify all queues */
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch array_foreach_modifiable(&host->queues, queue_idx) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch requests += http_client_queue_host_lookup_done(*queue_idx);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch }
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
3c8a163545079984e827aa50349cbc4fe570875fStephan Bosch if (requests == 0 && client->waiting)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch io_loop_stop(client->ioloop);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic void
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_lookup_failure(struct http_client_host *host,
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch const char *error)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_queue *const *queue_idx;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch array_foreach_modifiable(&host->queues, queue_idx)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_queue_host_lookup_failure(*queue_idx, error);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
2300bdf148ee501082947c2ec79d12c175489897Stephan Boschvoid http_client_host_submit_request(struct http_client_host *host,
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch struct http_client_request *req)
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client *client = req->client;
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch struct http_client_queue *queue;
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch struct http_client_peer_addr addr;
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch const char *error;
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch req->host = host;
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch http_client_request_get_peer_addr(req, &addr);
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch if (http_client_peer_addr_is_https(&addr) &&
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch client->ssl_ctx == NULL) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (http_client_init_ssl_ctx(client, &error) < 0) {
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch http_client_request_error(&req,
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, error);
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch return;
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch }
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch }
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch /* add request to queue */
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch queue = http_client_queue_get(host, &addr);
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch http_client_queue_submit_request(queue, req);
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_request_submitted(host->shared);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch /* queue will trigger host lookup once the request is activated
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch (may be delayed) */
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschstatic bool
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschhttp_client_host_is_idle(struct http_client_host *host)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_queue *const *queue_idx;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch unsigned int requests = 0;
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch array_foreach(&host->queues, queue_idx) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch requests += http_client_queue_requests_active(*queue_idx);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch }
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch return (requests > 0);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschvoid http_client_host_check_idle(struct http_client_host *host)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch http_client_host_shared_check_idle(host->shared);
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Boschint http_client_host_refresh(struct http_client_host *host)
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch return http_client_host_shared_refresh(host->shared);
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch}
2300bdf148ee501082947c2ec79d12c175489897Stephan Bosch
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Boschbool http_client_host_get_ip_idx(struct http_client_host *host,
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch const struct ip_addr *ip, unsigned int *idx_r)
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch{
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch struct http_client_host_shared *hshared = host->shared;
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch unsigned int i;
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch for (i = 0; i < hshared->ips_count; i++) {
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch if (net_ip_compare(&hshared->ips[i], ip)) {
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch *idx_r = i;
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch return TRUE;
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch }
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch }
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch return FALSE;
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch}
23fe024e1dfc8eb5eaefc4e57a16b4257568f510Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid http_client_host_switch_ioloop(struct http_client_host *host)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_queue *const *queue_idx;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch array_foreach(&host->queues, queue_idx)
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch http_client_queue_switch_ioloop(*queue_idx);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
e48102389fb49deadfc685600dc2e56177fd0d7cStephan Bosch