summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve/resolved-dns-transaction.c')
-rw-r--r--src/resolve/resolved-dns-transaction.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 81156dfa45..8092bb514d 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -35,24 +35,25 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) {
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);
- sd_event_source_unref(t->dns_event_source);
- safe_close(t->dns_fd);
+ sd_event_source_unref(t->dns_udp_event_source);
+ safe_close(t->dns_udp_fd);
dns_server_unref(t->server);
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);
@@ -89,14 +90,18 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key)
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->dns_udp_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 ||
@@ -108,7 +113,12 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key)
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)
@@ -176,9 +186,6 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
assert(t);
assert(!IN_SET(state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
- if (!IN_SET(t->state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING))
- return;
-
/* Note that this call might invalidate the query. Callers
* should hence not attempt to access the query or transaction
* after calling this function. */
@@ -253,10 +260,12 @@ static int dns_transaction_open_tcp(DnsTransaction *t) {
if (t->stream)
return 0;
- if (t->scope->protocol == DNS_PROTOCOL_DNS)
+ switch (t->scope->protocol) {
+ case DNS_PROTOCOL_DNS:
fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53, &server);
- else if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
+ break;
+ case DNS_PROTOCOL_LLMNR:
/* When we already received a reply to this (but it was truncated), send to its sender address */
if (t->received)
fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port, NULL);
@@ -274,12 +283,16 @@ static int dns_transaction_open_tcp(DnsTransaction *t) {
if (r == 0)
return -EINVAL;
if (family != t->scope->family)
- return -EAFNOSUPPORT;
+ return -ESRCH;
fd = dns_scope_tcp_socket(t->scope, family, &address, LLMNR_PORT, NULL);
}
- } else
+
+ break;
+
+ default:
return -EAFNOSUPPORT;
+ }
if (fd < 0)
return fd;
@@ -315,8 +328,8 @@ static void dns_transaction_next_dns_server(DnsTransaction *t) {
assert(t);
t->server = dns_server_unref(t->server);
- t->dns_event_source = sd_event_source_unref(t->dns_event_source);
- t->dns_fd = safe_close(t->dns_fd);
+ t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
+ t->dns_udp_fd = safe_close(t->dns_udp_fd);
dns_scope_next_dns_server(t->scope);
}
@@ -335,7 +348,8 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
* should hence not attempt to access the query or transaction
* after calling this function. */
- if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
+ switch (t->scope->protocol) {
+ case DNS_PROTOCOL_LLMNR:
assert(t->scope->link);
/* For LLMNR we will not accept any packets from other
@@ -354,6 +368,14 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
dns_transaction_tentative(t, p);
return;
}
+
+ break;
+
+ case DNS_PROTOCOL_DNS:
+ break;
+
+ default:
+ assert_not_reached("Invalid DNS protocol.");
}
if (t->received != p) {
@@ -390,7 +412,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
break;
default:
- assert_not_reached("Invalid DNS protocol.");
+ break;
}
if (DNS_PACKET_TC(p)) {
@@ -478,16 +500,16 @@ static int dns_transaction_emit(DnsTransaction *t) {
if (fd < 0)
return fd;
- r = sd_event_add_io(t->scope->manager->event, &t->dns_event_source, fd, EPOLLIN, on_dns_packet, t);
+ r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
if (r < 0)
return r;
- t->dns_fd = fd;
+ t->dns_udp_fd = fd;
fd = -1;
t->server = dns_server_ref(server);
}
- r = dns_scope_emit(t->scope, t->dns_fd, t->sent);
+ r = dns_scope_emit(t->scope, t->dns_udp_fd, t->sent);
if (r < 0)
return r;