X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fresolve%2Fresolved-dns-zone.c;h=ed477591062187210d0a02c3e17b83f427f17d86;hb=3ef77d0476046a660c1b4704140797c447e6ce3a;hp=b577fd6cc6892c215b5dfaed80e158e1b1f5d797;hpb=ec2c5e4398f9d65e5dfe61530f2556224733d1e6;p=elogind.git diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c index b577fd6cc..ed4775910 100644 --- a/src/resolve/resolved-dns-zone.c +++ b/src/resolve/resolved-dns-zone.c @@ -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); }