chiark / gitweb /
resolved: properly check return value of dns_resource_record_equal()
[elogind.git] / src / resolve / resolved-dns-zone.c
index b577fd6cc6892c215b5dfaed80e158e1b1f5d797..ed477591062187210d0a02c3e17b83f427f17d86 100644 (file)
@@ -104,7 +104,7 @@ static DnsZoneItem* dns_zone_get(DnsZone *z, DnsResourceRecord *rr) {
         assert(rr);
 
         LIST_FOREACH(by_key, i, hashmap_get(z->by_key, rr->key))
-                if (dns_resource_record_equal(i->rr, rr))
+                if (dns_resource_record_equal(i->rr, rr) > 0)
                         return i;
 
         return NULL;
@@ -187,7 +187,7 @@ static int dns_zone_item_probe_start(DnsZoneItem *i)  {
         if (r < 0)
                 return r;
 
-        t = dns_scope_find_transaction(i->scope, question);
+        t = dns_scope_find_transaction(i->scope, question, false);
         if (!t) {
                 r = dns_transaction_new(&t, i->scope, question);
                 if (r < 0)
@@ -260,14 +260,34 @@ int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe) {
                 return r;
 
         if (probe) {
-                r = dns_zone_item_probe_start(i);
-                if (r < 0) {
-                        dns_zone_item_remove_and_free(z, i);
-                        i = NULL;
-                        return r;
+                DnsZoneItem *first, *j;
+                bool established = false;
+
+                /* Check if there's already an RR with the same name
+                 * established. If so, it has been probed already, and
+                 * we don't ned to probe again. */
+
+                LIST_FIND_HEAD(by_name, i, first);
+                LIST_FOREACH(by_name, j, first) {
+                        if (i == j)
+                                continue;
+
+                        if (j->state == DNS_ZONE_ITEM_ESTABLISHED)
+                                established = true;
                 }
 
-                i->state = DNS_ZONE_ITEM_PROBING;
+                if (established)
+                        i->state = DNS_ZONE_ITEM_ESTABLISHED;
+                else {
+                        i->state = DNS_ZONE_ITEM_PROBING;
+
+                        r = dns_zone_item_probe_start(i);
+                        if (r < 0) {
+                                dns_zone_item_remove_and_free(z, i);
+                                i = NULL;
+                                return r;
+                        }
+                }
         } else
                 i->state = DNS_ZONE_ITEM_ESTABLISHED;
 
@@ -476,6 +496,8 @@ void dns_zone_item_conflict(DnsZoneItem *i) {
         dns_resource_record_to_string(i->rr, &pretty);
         log_info("Detected conflict on %s", strna(pretty));
 
+        dns_zone_item_probe_stop(i);
+
         /* Withdraw the conflict item */
         i->state = DNS_ZONE_ITEM_WITHDRAWN;
 
@@ -502,7 +524,6 @@ void dns_zone_item_ready(DnsZoneItem *i) {
 
                 dns_zone_item_probe_stop(i);
                 i->state = DNS_ZONE_ITEM_ESTABLISHED;
-
         } else
                 dns_zone_item_conflict(i);
 }