+static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+ _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+ DnsTransaction *t = userdata;
+ int r;
+
+ assert(t);
+ assert(t->scope);
+
+ r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
+ if (r <= 0)
+ return r;
+
+ if (dns_packet_validate_reply(p) > 0 &&
+ DNS_PACKET_ID(p) == t->id)
+ dns_transaction_process_reply(t, p);
+ else
+ log_debug("Invalid DNS packet.");
+
+ return 0;
+}
+
+static int dns_transaction_emit(DnsTransaction *t) {
+ int r;
+
+ assert(t);
+
+ if (t->scope->protocol == DNS_PROTOCOL_DNS && !t->server) {
+ DnsServer *server = NULL;
+ _cleanup_close_ int fd = -1;
+
+ fd = dns_scope_udp_dns_socket(t->scope, &server);
+ if (fd < 0)
+ return fd;
+
+ 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_udp_fd = fd;
+ fd = -1;
+ t->server = dns_server_ref(server);
+ }
+
+ r = dns_scope_emit(t->scope, t->dns_udp_fd, t->sent);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+