Zbigniew Jędrzejewski-Szmek 2b6823
From 61596a9aac5f0d4cef3845b04d61f2dad4aa0814 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 2b6823
From: Lennart Poettering <lennart@poettering.net>
Zbigniew Jędrzejewski-Szmek 2b6823
Date: Mon, 22 Feb 2016 20:39:45 +0100
Zbigniew Jędrzejewski-Szmek 2b6823
Subject: [PATCH] resolved: fix notification iteration logic when transactions
Zbigniew Jędrzejewski-Szmek 2b6823
 are completed
Zbigniew Jędrzejewski-Szmek 2b6823
Zbigniew Jędrzejewski-Szmek 2b6823
When a transaction is complete, and we notify its owners, make sure we deal
Zbigniew Jędrzejewski-Szmek 2b6823
correctly with the requesters removing themselves from the list of owners while
Zbigniew Jędrzejewski-Szmek 2b6823
we continue iterating.
Zbigniew Jędrzejewski-Szmek 2b6823
Zbigniew Jędrzejewski-Szmek 2b6823
This was previously already dealt with with transactions that require other
Zbigniew Jędrzejewski-Szmek 2b6823
transactions for DNSSEC purposes, fix this for other possibly transaction
Zbigniew Jędrzejewski-Szmek 2b6823
owners too now.
Zbigniew Jędrzejewski-Szmek 2b6823
Zbigniew Jędrzejewski-Szmek 2b6823
Since iterating through "Set" objects is not safe regarding removal of entries
Zbigniew Jędrzejewski-Szmek 2b6823
from it, rework the logic to use two Sets, and move each entry we notified from
Zbigniew Jędrzejewski-Szmek 2b6823
one set to the other set before we dispatch the notification. This move operation
Zbigniew Jędrzejewski-Szmek 2b6823
requires no additional memory, and enables us to ensure that we don't notify
Zbigniew Jędrzejewski-Szmek 2b6823
any object twice.
Zbigniew Jędrzejewski-Szmek 2b6823
Zbigniew Jędrzejewski-Szmek 2b6823
Fixes: #2676
Zbigniew Jędrzejewski-Szmek 2b6823
(cherry picked from commit 35aa04e9edf422beac3493afa555d29575b3046c)
Zbigniew Jędrzejewski-Szmek 2b6823
---
Zbigniew Jędrzejewski-Szmek 2b6823
 src/basic/macro.h                      |  6 ++++
Zbigniew Jędrzejewski-Szmek 2b6823
 src/basic/set.h                        |  3 ++
Zbigniew Jędrzejewski-Szmek 2b6823
 src/resolve/resolved-dns-query.c       |  5 +++
Zbigniew Jędrzejewski-Szmek 2b6823
 src/resolve/resolved-dns-transaction.c | 62 ++++++++++++++++------------------
Zbigniew Jędrzejewski-Szmek 2b6823
 src/resolve/resolved-dns-transaction.h |  6 ++--
Zbigniew Jędrzejewski-Szmek 2b6823
 src/resolve/resolved-dns-zone.c        |  5 +++
Zbigniew Jędrzejewski-Szmek 2b6823
 6 files changed, 52 insertions(+), 35 deletions(-)
Zbigniew Jędrzejewski-Szmek 2b6823
Zbigniew Jędrzejewski-Szmek 2b6823
diff --git a/src/basic/macro.h b/src/basic/macro.h
Zbigniew Jędrzejewski-Szmek 2b6823
index 2695d0edb7..ab5cc97e17 100644
Zbigniew Jędrzejewski-Szmek 2b6823
--- a/src/basic/macro.h
Zbigniew Jędrzejewski-Szmek 2b6823
+++ b/src/basic/macro.h
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -361,6 +361,12 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
Zbigniew Jędrzejewski-Szmek 2b6823
                 _found;                         \
Zbigniew Jędrzejewski-Szmek 2b6823
         })
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
+#define SWAP_TWO(x, y) do {                        \
Zbigniew Jędrzejewski-Szmek 2b6823
+                typeof(x) _t = (x);                \
Zbigniew Jędrzejewski-Szmek 2b6823
+                (x) = (y);                         \
Zbigniew Jędrzejewski-Szmek 2b6823
+                (y) = (_t);                        \
Zbigniew Jędrzejewski-Szmek 2b6823
+        } while (false)
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
 /* Define C11 thread_local attribute even on older gcc compiler
Zbigniew Jędrzejewski-Szmek 2b6823
  * version */
Zbigniew Jędrzejewski-Szmek 2b6823
 #ifndef thread_local
Zbigniew Jędrzejewski-Szmek 2b6823
diff --git a/src/basic/set.h b/src/basic/set.h
Zbigniew Jędrzejewski-Szmek 2b6823
index 2bff5062da..e0d9dd001c 100644
Zbigniew Jędrzejewski-Szmek 2b6823
--- a/src/basic/set.h
Zbigniew Jędrzejewski-Szmek 2b6823
+++ b/src/basic/set.h
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -126,6 +126,9 @@ int set_put_strdupv(Set *s, char **l);
Zbigniew Jędrzejewski-Szmek 2b6823
 #define SET_FOREACH(e, s, i) \
Zbigniew Jędrzejewski-Szmek 2b6823
         for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); )
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
+#define SET_FOREACH_MOVE(e, d, s)                                       \
Zbigniew Jędrzejewski-Szmek 2b6823
+        for (; ({ e = set_first(s); assert_se(!e || set_move_one(d, s, e) >= 0); e; }); )
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
 DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free);
Zbigniew Jędrzejewski-Szmek 2b6823
 DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
Zbigniew Jędrzejewski-Szmek 2b6823
index a378b2b7f7..2a02544eb6 100644
Zbigniew Jędrzejewski-Szmek 2b6823
--- a/src/resolve/resolved-dns-query.c
Zbigniew Jędrzejewski-Szmek 2b6823
+++ b/src/resolve/resolved-dns-query.c
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -62,6 +62,7 @@ static void dns_query_candidate_stop(DnsQueryCandidate *c) {
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         while ((t = set_steal_first(c->transactions))) {
Zbigniew Jędrzejewski-Szmek 2b6823
                 set_remove(t->notify_query_candidates, c);
Zbigniew Jędrzejewski-Szmek 2b6823
+                set_remove(t->notify_query_candidates_done, c);
Zbigniew Jędrzejewski-Szmek 2b6823
                 dns_transaction_gc(t);
Zbigniew Jędrzejewski-Szmek 2b6823
         }
Zbigniew Jędrzejewski-Szmek 2b6823
 }
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -139,6 +140,10 @@ static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResource
Zbigniew Jędrzejewski-Szmek 2b6823
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
                 goto gc;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
+        r = set_ensure_allocated(&t->notify_query_candidates_done, NULL);
Zbigniew Jędrzejewski-Szmek 2b6823
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
+                goto gc;
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
         r = set_put(t->notify_query_candidates, c);
Zbigniew Jędrzejewski-Szmek 2b6823
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
                 goto gc;
Zbigniew Jędrzejewski-Szmek 2b6823
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
Zbigniew Jędrzejewski-Szmek 2b6823
index d48fdd1281..4f5cbab702 100644
Zbigniew Jędrzejewski-Szmek 2b6823
--- a/src/resolve/resolved-dns-transaction.c
Zbigniew Jędrzejewski-Szmek 2b6823
+++ b/src/resolve/resolved-dns-transaction.c
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -52,6 +52,7 @@ static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) {
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         while ((z = set_steal_first(t->dnssec_transactions))) {
Zbigniew Jędrzejewski-Szmek 2b6823
                 set_remove(z->notify_transactions, t);
Zbigniew Jędrzejewski-Szmek 2b6823
+                set_remove(z->notify_transactions_done, t);
Zbigniew Jędrzejewski-Szmek 2b6823
                 dns_transaction_gc(z);
Zbigniew Jędrzejewski-Szmek 2b6823
         }
Zbigniew Jędrzejewski-Szmek 2b6823
 }
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -100,14 +101,26 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) {
Zbigniew Jędrzejewski-Szmek 2b6823
                 set_remove(c->transactions, t);
Zbigniew Jędrzejewski-Szmek 2b6823
         set_free(t->notify_query_candidates);
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
+        while ((c = set_steal_first(t->notify_query_candidates_done)))
Zbigniew Jędrzejewski-Szmek 2b6823
+                set_remove(c->transactions, t);
Zbigniew Jędrzejewski-Szmek 2b6823
+        set_free(t->notify_query_candidates_done);
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
         while ((i = set_steal_first(t->notify_zone_items)))
Zbigniew Jędrzejewski-Szmek 2b6823
                 i->probe_transaction = NULL;
Zbigniew Jędrzejewski-Szmek 2b6823
         set_free(t->notify_zone_items);
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
+        while ((i = set_steal_first(t->notify_zone_items_done)))
Zbigniew Jędrzejewski-Szmek 2b6823
+                i->probe_transaction = NULL;
Zbigniew Jędrzejewski-Szmek 2b6823
+        set_free(t->notify_zone_items_done);
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
         while ((z = set_steal_first(t->notify_transactions)))
Zbigniew Jędrzejewski-Szmek 2b6823
                 set_remove(z->dnssec_transactions, t);
Zbigniew Jędrzejewski-Szmek 2b6823
         set_free(t->notify_transactions);
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
+        while ((z = set_steal_first(t->notify_transactions_done)))
Zbigniew Jędrzejewski-Szmek 2b6823
+                set_remove(z->dnssec_transactions, t);
Zbigniew Jędrzejewski-Szmek 2b6823
+        set_free(t->notify_transactions_done);
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
         dns_transaction_flush_dnssec_transactions(t);
Zbigniew Jędrzejewski-Szmek 2b6823
         set_free(t->dnssec_transactions);
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -128,8 +141,11 @@ bool dns_transaction_gc(DnsTransaction *t) {
Zbigniew Jędrzejewski-Szmek 2b6823
                 return true;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         if (set_isempty(t->notify_query_candidates) &&
Zbigniew Jędrzejewski-Szmek 2b6823
+            set_isempty(t->notify_query_candidates_done) &&
Zbigniew Jędrzejewski-Szmek 2b6823
             set_isempty(t->notify_zone_items) &&
Zbigniew Jędrzejewski-Szmek 2b6823
-            set_isempty(t->notify_transactions)) {
Zbigniew Jędrzejewski-Szmek 2b6823
+            set_isempty(t->notify_zone_items_done) &&
Zbigniew Jędrzejewski-Szmek 2b6823
+            set_isempty(t->notify_transactions) &&
Zbigniew Jędrzejewski-Szmek 2b6823
+            set_isempty(t->notify_transactions_done)) {
Zbigniew Jędrzejewski-Szmek 2b6823
                 dns_transaction_free(t);
Zbigniew Jędrzejewski-Szmek 2b6823
                 return false;
Zbigniew Jędrzejewski-Szmek 2b6823
         }
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -266,6 +282,7 @@ static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
Zbigniew Jędrzejewski-Szmek 2b6823
         log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         t->block_gc++;
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
         while ((z = set_first(t->notify_zone_items))) {
Zbigniew Jędrzejewski-Szmek 2b6823
                 /* First, make sure the zone item drops the reference
Zbigniew Jędrzejewski-Szmek 2b6823
                  * to us */
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -284,7 +301,6 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
Zbigniew Jędrzejewski-Szmek 2b6823
         DnsQueryCandidate *c;
Zbigniew Jędrzejewski-Szmek 2b6823
         DnsZoneItem *z;
Zbigniew Jędrzejewski-Szmek 2b6823
         DnsTransaction *d;
Zbigniew Jędrzejewski-Szmek 2b6823
-        Iterator i;
Zbigniew Jędrzejewski-Szmek 2b6823
         const char *st;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         assert(t);
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -329,39 +345,17 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
Zbigniew Jędrzejewski-Szmek 2b6823
          * transaction isn't freed while we are still looking at it */
Zbigniew Jędrzejewski-Szmek 2b6823
         t->block_gc++;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
-        SET_FOREACH(c, t->notify_query_candidates, i)
Zbigniew Jędrzejewski-Szmek 2b6823
+        SET_FOREACH_MOVE(c, t->notify_query_candidates_done, t->notify_query_candidates)
Zbigniew Jędrzejewski-Szmek 2b6823
                 dns_query_candidate_notify(c);
Zbigniew Jędrzejewski-Szmek 2b6823
-        SET_FOREACH(z, t->notify_zone_items, i)
Zbigniew Jędrzejewski-Szmek 2b6823
-                dns_zone_item_notify(z);
Zbigniew Jędrzejewski-Szmek 2b6823
+        SWAP_TWO(t->notify_query_candidates, t->notify_query_candidates_done);
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
-        if (!set_isempty(t->notify_transactions)) {
Zbigniew Jędrzejewski-Szmek 2b6823
-                DnsTransaction **nt;
Zbigniew Jędrzejewski-Szmek 2b6823
-                unsigned j, n = 0;
Zbigniew Jędrzejewski-Szmek 2b6823
-
Zbigniew Jędrzejewski-Szmek 2b6823
-                /* We need to be careful when notifying other
Zbigniew Jędrzejewski-Szmek 2b6823
-                 * transactions, as that might destroy other
Zbigniew Jędrzejewski-Szmek 2b6823
-                 * transactions in our list. Hence, in order to be
Zbigniew Jędrzejewski-Szmek 2b6823
-                 * able to safely iterate through the list of
Zbigniew Jędrzejewski-Szmek 2b6823
-                 * transactions, take a GC lock on all of them
Zbigniew Jędrzejewski-Szmek 2b6823
-                 * first. Then, in a second loop, notify them, but
Zbigniew Jędrzejewski-Szmek 2b6823
-                 * first unlock that specific transaction. */
Zbigniew Jędrzejewski-Szmek 2b6823
-
Zbigniew Jędrzejewski-Szmek 2b6823
-                nt = newa(DnsTransaction*, set_size(t->notify_transactions));
Zbigniew Jędrzejewski-Szmek 2b6823
-                SET_FOREACH(d, t->notify_transactions, i) {
Zbigniew Jędrzejewski-Szmek 2b6823
-                        nt[n++] = d;
Zbigniew Jędrzejewski-Szmek 2b6823
-                        d->block_gc++;
Zbigniew Jędrzejewski-Szmek 2b6823
-                }
Zbigniew Jędrzejewski-Szmek 2b6823
-
Zbigniew Jędrzejewski-Szmek 2b6823
-                assert(n == set_size(t->notify_transactions));
Zbigniew Jędrzejewski-Szmek 2b6823
+        SET_FOREACH_MOVE(z, t->notify_zone_items_done, t->notify_zone_items)
Zbigniew Jędrzejewski-Szmek 2b6823
+                dns_zone_item_notify(z);
Zbigniew Jędrzejewski-Szmek 2b6823
+        SWAP_TWO(t->notify_zone_items, t->notify_zone_items_done);
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
-                for (j = 0; j < n; j++) {
Zbigniew Jędrzejewski-Szmek 2b6823
-                        if (set_contains(t->notify_transactions, nt[j]))
Zbigniew Jędrzejewski-Szmek 2b6823
-                                dns_transaction_notify(nt[j], t);
Zbigniew Jędrzejewski-Szmek 2b6823
-
Zbigniew Jędrzejewski-Szmek 2b6823
-                        nt[j]->block_gc--;
Zbigniew Jędrzejewski-Szmek 2b6823
-                        dns_transaction_gc(nt[j]);
Zbigniew Jędrzejewski-Szmek 2b6823
-                }
Zbigniew Jędrzejewski-Szmek 2b6823
-        }
Zbigniew Jędrzejewski-Szmek 2b6823
+        SET_FOREACH_MOVE(d, t->notify_transactions_done, t->notify_transactions)
Zbigniew Jędrzejewski-Szmek 2b6823
+                dns_transaction_notify(d, t);
Zbigniew Jędrzejewski-Szmek 2b6823
+        SWAP_TWO(t->notify_transactions, t->notify_transactions_done);
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         t->block_gc--;
Zbigniew Jędrzejewski-Szmek 2b6823
         dns_transaction_gc(t);
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -1619,6 +1613,10 @@ static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResource
Zbigniew Jędrzejewski-Szmek 2b6823
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
                 goto gc;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
+        r = set_ensure_allocated(&aux->notify_transactions_done, NULL);
Zbigniew Jędrzejewski-Szmek 2b6823
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
+                goto gc;
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
         r = set_put(t->dnssec_transactions, aux);
Zbigniew Jędrzejewski-Szmek 2b6823
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
                 goto gc;
Zbigniew Jędrzejewski-Szmek 2b6823
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
Zbigniew Jędrzejewski-Szmek 2b6823
index 4617194711..fd0237d166 100644
Zbigniew Jędrzejewski-Szmek 2b6823
--- a/src/resolve/resolved-dns-transaction.h
Zbigniew Jędrzejewski-Szmek 2b6823
+++ b/src/resolve/resolved-dns-transaction.h
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -119,17 +119,17 @@ struct DnsTransaction {
Zbigniew Jędrzejewski-Szmek 2b6823
         /* Query candidates this transaction is referenced by and that
Zbigniew Jędrzejewski-Szmek 2b6823
          * shall be notified about this specific transaction
Zbigniew Jędrzejewski-Szmek 2b6823
          * completing. */
Zbigniew Jędrzejewski-Szmek 2b6823
-        Set *notify_query_candidates;
Zbigniew Jędrzejewski-Szmek 2b6823
+        Set *notify_query_candidates, *notify_query_candidates_done;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         /* Zone items this transaction is referenced by and that shall
Zbigniew Jędrzejewski-Szmek 2b6823
          * be notified about completion. */
Zbigniew Jędrzejewski-Szmek 2b6823
-        Set *notify_zone_items;
Zbigniew Jędrzejewski-Szmek 2b6823
+        Set *notify_zone_items, *notify_zone_items_done;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         /* Other transactions that this transactions is referenced by
Zbigniew Jędrzejewski-Szmek 2b6823
          * and that shall be notified about completion. This is used
Zbigniew Jędrzejewski-Szmek 2b6823
          * when transactions want to validate their RRsets, but need
Zbigniew Jędrzejewski-Szmek 2b6823
          * another DNSKEY or DS RR to do so. */
Zbigniew Jędrzejewski-Szmek 2b6823
-        Set *notify_transactions;
Zbigniew Jędrzejewski-Szmek 2b6823
+        Set *notify_transactions, *notify_transactions_done;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         /* The opposite direction: the transactions this transaction
Zbigniew Jędrzejewski-Szmek 2b6823
          * created in order to request DNSKEY or DS RRs. */
Zbigniew Jędrzejewski-Szmek 2b6823
diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c
Zbigniew Jędrzejewski-Szmek 2b6823
index f52383cfd1..be535cff14 100644
Zbigniew Jędrzejewski-Szmek 2b6823
--- a/src/resolve/resolved-dns-zone.c
Zbigniew Jędrzejewski-Szmek 2b6823
+++ b/src/resolve/resolved-dns-zone.c
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -38,6 +38,7 @@ void dns_zone_item_probe_stop(DnsZoneItem *i) {
Zbigniew Jędrzejewski-Szmek 2b6823
         i->probe_transaction = NULL;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
         set_remove(t->notify_zone_items, i);
Zbigniew Jędrzejewski-Szmek 2b6823
+        set_remove(t->notify_zone_items_done, i);
Zbigniew Jędrzejewski-Szmek 2b6823
         dns_transaction_gc(t);
Zbigniew Jędrzejewski-Szmek 2b6823
 }
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
@@ -186,6 +187,10 @@ static int dns_zone_item_probe_start(DnsZoneItem *i)  {
Zbigniew Jędrzejewski-Szmek 2b6823
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
                 goto gc;
Zbigniew Jędrzejewski-Szmek 2b6823
 
Zbigniew Jędrzejewski-Szmek 2b6823
+        r = set_ensure_allocated(&t->notify_zone_items_done, NULL);
Zbigniew Jędrzejewski-Szmek 2b6823
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
+                goto gc;
Zbigniew Jędrzejewski-Szmek 2b6823
+
Zbigniew Jędrzejewski-Szmek 2b6823
         r = set_put(t->notify_zone_items, i);
Zbigniew Jędrzejewski-Szmek 2b6823
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 2b6823
                 goto gc;