dns_scope_llmnr_membership(s, false);
- while ((t = s->transactions)) {
-
+ while ((t = hashmap_steal_first(s->transactions))) {
/* Abort the transaction, but make sure it is not
* freed while we still look at it */
dns_transaction_free(t);
}
+ hashmap_free(s->transactions);
+
while ((rr = ordered_hashmap_steal_first(s->conflict_queue)))
dns_resource_record_unref(rr);
assert(scope);
assert(key);
- /* Try to find an ongoing transaction that is a equal or a
- * superset of the specified question */
-
- LIST_FOREACH(transactions_by_scope, t, scope->transactions) {
-
- /* 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_FAILURE) &&
- !t->received)
- continue;
+ /* Try to find an ongoing transaction that is a equal to the
+ * specified question */
+ t = hashmap_get(scope->transactions, key);
+ if (!t)
+ return NULL;
- if (dns_resource_key_equal(t->key, key) > 0)
- return t;
- }
+ /* 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_FAILURE) &&
+ !t->received)
+ return NULL;
- return NULL;
+ return t;
}
static int dns_scope_make_conflict_packet(
sd_event_source_unref(t->timeout_event_source);
- dns_resource_key_unref(t->key);
dns_packet_unref(t->sent);
dns_packet_unref(t->received);
dns_answer_unref(t->cached);
dns_stream_free(t->stream);
if (t->scope) {
- LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
+ hashmap_remove(t->scope->transactions, t->key);
if (t->id != 0)
hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
}
+ dns_resource_key_unref(t->key);
+
while ((q = set_steal_first(t->queries)))
set_remove(q->transactions, t);
set_free(t->queries);
if (r < 0)
return r;
+ r = hashmap_ensure_allocated(&s->transactions, &dns_resource_key_hash_ops);
+ if (r < 0)
+ return r;
+
t = new0(DnsTransaction, 1);
if (!t)
return -ENOMEM;
t->dns_fd = -1;
-
t->key = dns_resource_key_ref(key);
+ /* Find a fresh, unused transaction id */
do
random_bytes(&t->id, sizeof(t->id));
while (t->id == 0 ||
return r;
}
- LIST_PREPEND(transactions_by_scope, s->transactions, t);
+ r = hashmap_put(s->transactions, t->key, t);
+ if (r < 0) {
+ hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
+ return r;
+ }
+
t->scope = s;
if (ret)