resolved-dns-transaction.c revision 471d40d92fc8e7b452dff99a156f9e0b520ded20
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster This file is part of systemd.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Copyright 2014 Lennart Poettering
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster systemd is free software; you can redistribute it and/or modify it
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster under the terms of the GNU Lesser General Public License as published by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster the Free Software Foundation; either version 2.1 of the License, or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (at your option) any later version.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster systemd is distributed in the hope that it will be useful, but
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster WITHOUT ANY WARRANTY; without even the implied warranty of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Lesser General Public License for more details.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster You should have received a copy of the GNU Lesser General Public License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster along with systemd; If not, see <http://www.gnu.org/licenses/>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterDnsTransaction* dns_transaction_free(DnsTransaction *t) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sd_event_source_unref(t->timeout_event_source);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (t->id != 0)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterDEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (set_isempty(t->queries) && set_isempty(t->zone_items))
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterint dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsQuestion *q) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (t->id == 0 ||
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id)));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (r < 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LIST_PREPEND(transactions_by_scope, s->transactions, t);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic void dns_transaction_stop(DnsTransaction *t) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (manager_our_packet(t->scope->manager, p) != 0)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster in_addr_to_string(p->family, &p->sender, &pretty);
pretty);
t->block_gc++;
t->block_gc--;
DnsQuery *q;
DnsZoneItem *z;
Iterator i;
assert(t);
t->block_gc++;
dns_query_ready(q);
t->block_gc--;
DnsTransaction *t;
assert(s);
t = s->transaction;
if (error != 0) {
if (dns_packet_validate_reply(p) <= 0) {
t->block_gc++;
t->block_gc--;
assert(t);
if (t->stream)
if (t->received)
fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port, NULL);
return -EINVAL;
return -EAFNOSUPPORT;
if (fd < 0)
return fd;
assert(t);
assert(t);
assert(p);
if (DNS_PACKET_LLMNR_T(p)) {
dns_transaction_tentative(t, p);
if (t->received != p) {
if (DNS_PACKET_TC(p)) {
if (DNS_PACKET_TC(p)) {
r = dns_transaction_open_tcp(t);
if (r == -ESRCH) {
r = dns_transaction_go(t);
r = dns_packet_extract(p);
dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0, p->family, &p->sender);
assert(t);
if (dns_packet_validate_reply(p) > 0 &&
assert(t);
if (fd < 0)
return fd;
assert(s);
assert(t);
r = dns_transaction_go(t);
unsigned n, added = 0;
assert(t);
if (t->sent)
added++;
if (added <= 0)
return -EDOM;
t->sent = p;
p = NULL;
bool had_stream;
assert(t);
t->n_attempts++;
t->cached_rcode = 0;
t->initial_jitter = true;
r = sd_event_add_time(
&t->timeout_event_source,
t->n_attempts = 0;
r = dns_transaction_make_packet(t);
if (r == -EDOM) {
r = dns_transaction_open_tcp(t);
r = dns_transaction_emit(t);
if (r == -EMSGSIZE)
r = dns_transaction_open_tcp(t);
if (r == -ESRCH) {
return dns_transaction_go(t);
r = sd_event_add_time(
&t->timeout_event_source,