Skip to content

Commit

Permalink
lib-http: client: Fix panic occurring at connection failure.
Browse files Browse the repository at this point in the history
In http_client_peer_connection_failed_pool(), all linked queues are notified
about the connection failure through http_client_queue_connection_failure().
That function can internally link and unlink peers to the queue, including the
calling one. This means that the peer->queues array can be modified while it is
iterated in the array_foreach() loop. The problem is fixed by making a local
copy of the peer->queues array.
  • Loading branch information
stephanbosch committed Dec 7, 2018
1 parent a2ac8c0 commit 90f5df3
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/lib-http/http-client-peer.c
Expand Up @@ -1270,7 +1270,8 @@ static void
http_client_peer_connection_failed_pool(struct http_client_peer *peer,
const char *reason)
{
struct http_client_queue *const *queue;
struct http_client_queue *const *queuep;
ARRAY_TYPE(http_client_queue) queues;

e_debug(peer->event,
"Failed to establish any connection within our peer pool: %s "
Expand All @@ -1279,11 +1280,17 @@ http_client_peer_connection_failed_pool(struct http_client_peer *peer,

peer->connect_failed = TRUE;

/* make a copy of the queue array; queues get linked/unlinged while the
connection failure is handled */
t_array_init(&queues, array_count(&peer->queues));
array_copy(&queues.arr, 0, &peer->queues.arr, 0,
array_count(&peer->queues));

/* failed to make any connection. a second connect will probably also
fail, so just try another IP for the hosts(s) or abort all requests
if this was the only/last option. */
array_foreach(&peer->queues, queue)
http_client_queue_connection_failure(*queue, peer, reason);
array_foreach(&queues, queuep)
http_client_queue_connection_failure(*queuep, peer, reason);
}

void http_client_peer_connection_lost(struct http_client_peer *peer,
Expand Down

0 comments on commit 90f5df3

Please sign in to comment.