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;
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)
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;
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;
dns_zone_item_probe_stop(i);
i->state = DNS_ZONE_ITEM_ESTABLISHED;
-
} else
dns_zone_item_conflict(i);
}