diff options
Diffstat (limited to 'src/resolve/resolved-dns-scope.c')
-rw-r--r-- | src/resolve/resolved-dns-scope.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 6573edd630..cee93a2c04 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -925,26 +925,50 @@ void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) { } } -DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsResourceKey *key, bool cache_ok) { - DnsTransaction *t; +DnsTransaction *dns_scope_find_transaction( + DnsScope *scope, + DnsResourceKey *key, + uint64_t query_flags) { + + DnsTransaction *first, *t; assert(scope); assert(key); - /* Try to find an ongoing transaction that is a equal to the - * specified question */ - t = hashmap_get(scope->transactions_by_key, key); - if (!t) - return NULL; + /* Iterate through the list of transactions with a matching key */ + first = hashmap_get(scope->transactions_by_key, key); + LIST_FOREACH(transactions_by_key, t, first) { + + /* These four flags must match exactly: we cannot use a validated response for a + * non-validating client, and we cannot use a non-validated response for a validating + * client. Similar, if the sources don't match things aren't usable either. */ + if (((query_flags ^ t->query_flags) & + (SD_RESOLVED_NO_VALIDATE| + SD_RESOLVED_NO_ZONE| + SD_RESOLVED_NO_TRUST_ANCHOR| + SD_RESOLVED_NO_NETWORK)) != 0) + continue; - /* Refuse reusing transactions that completed based on cached - * data instead of a real packet, if that's requested. */ - if (!cache_ok && - IN_SET(t->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_RCODE_FAILURE) && - t->answer_source != DNS_TRANSACTION_NETWORK) - return NULL; + /* We can reuse a primary query if a regular one is requested, but not vice versa */ + if ((query_flags & SD_RESOLVED_REQUIRE_PRIMARY) && + !(t->query_flags & SD_RESOLVED_REQUIRE_PRIMARY)) + continue; + + /* Don't reuse a transaction that allowed caching when we got told not to use it */ + if ((query_flags & SD_RESOLVED_NO_CACHE) && + !(t->query_flags & SD_RESOLVED_NO_CACHE)) + continue; + + /* If we are are asked to clamp ttls an the existing transaction doesn't do it, we can't + * reuse */ + if ((query_flags & SD_RESOLVED_CLAMP_TTL) && + !(t->query_flags & SD_RESOLVED_CLAMP_TTL)) + continue; + + return t; + } - return t; + return NULL; } static int dns_scope_make_conflict_packet( |