]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-dns: The dns_lookup() call caused a crash upon a connect error, because dns_clien...
authorStephan Bosch <stephan@rename-it.nl>
Fri, 10 Oct 2014 21:43:38 +0000 (00:43 +0300)
committerStephan Bosch <stephan@rename-it.nl>
Fri, 10 Oct 2014 21:43:38 +0000 (00:43 +0300)
Solved by dropping the list of lookups from the client object before the
lookups are destroyed.

src/lib-dns/dns-lookup.c

index d34c81925afc47a475c21dd33f79dc27e8d778c3..80ac57090cd2a26e29993d74a0d6a77a15f6e2a9 100644 (file)
@@ -56,18 +56,9 @@ static void dns_lookup_free(struct dns_lookup **_lookup);
 
 static void dns_client_disconnect(struct dns_client *client, const char *error)
 {
-       struct dns_lookup *lookup;
+       struct dns_lookup *lookup, *next;
        struct dns_lookup_result result;
 
-       memset(&result, 0, sizeof(result));
-       result.ret = EAI_FAIL;
-       result.error = error;
-
-       while (client->head != NULL) {
-               lookup = client->head;
-               lookup->callback(&result, lookup->context);
-               dns_lookup_free(&lookup);
-       }
        if (client->to_idle != NULL)
                timeout_remove(&client->to_idle);
        if (client->io != NULL)
@@ -79,6 +70,19 @@ static void dns_client_disconnect(struct dns_client *client, const char *error)
                        i_error("close(%s) failed: %m", client->path);
                client->fd = -1;
        }
+
+       memset(&result, 0, sizeof(result));
+       result.ret = EAI_FAIL;
+       result.error = error;
+
+       lookup = client->head;
+       client->head = NULL;
+       while (lookup != NULL) {
+               next = lookup->next;
+               lookup->callback(&result, lookup->context);
+               dns_lookup_free(&lookup);
+               lookup = next;
+       }
 }
 
 static int dns_lookup_input_line(struct dns_lookup *lookup, const char *line)
@@ -242,7 +246,7 @@ static void dns_lookup_free(struct dns_lookup **_lookup)
        i_free(lookup->ips);
        if (client->deinit_client_at_free)
                dns_client_deinit(&client);
-       else if (client->head == NULL) {
+       else if (client->head == NULL && client->fd != -1) {
                client->to_idle = timeout_add(client->idle_timeout_msecs,
                                              dns_client_idle_timeout, client);
        }