This file is part of systemd.
Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "sd-messages.h"
"DNS_QUESTION=%s", key_str,
"DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
"DNS_SERVER=%s", dns_server_string(t->server),
- "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level),
- NULL);
+ "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level));
}
/* Note that this call might invalidate the query. Callers
dns_server_unref(t->server);
t->server = dns_server_ref(server);
+ t->n_picked_servers ++;
+
log_debug("Using DNS server %s for transaction %u.", dns_server_string(t->server), t->id);
return 1;
dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
return 0;
-
default:
log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt->state));
goto fail;
if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
t->scope->dnssec_mode == DNSSEC_YES) {
- /* We are not in automatic downgrade mode, and the
- * server is bad, refuse operation. */
+
+ /* We are not in automatic downgrade mode, and the server is bad. Let's try a different server, maybe
+ * that works. */
+
+ if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
+ /* We tried fewer servers on this transaction than we know, let's try another one then */
+ dns_transaction_retry(t, true);
+ return;
+ }
+
+ /* OK, let's give up, apparently all servers we tried didn't work. */
dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
return;
}
/* Request failed, immediately try again with reduced features */
if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_UDP) {
+
/* This was already at UDP feature level? If so, it doesn't make sense to downgrade
- * this transaction anymore, hence let's process the response, and accept the
+ * this transaction anymore, but let's see if it might make sense to send the request
+ * to a different DNS server instead. If not let's process the response, and accept the
* rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
* packet loss, but is not going to give us better rcodes should we actually have
* managed to get them already at UDP level. */
+ if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
+ /* We tried fewer servers on this transaction than we know, let's try another one then */
+ dns_transaction_retry(t, true);
+ return;
+ }
+
+ /* Give up, accept the rcode */
log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
break;
}
assert(t);
assert(t->scope);
-
switch (t->scope->protocol) {
case DNS_PROTOCOL_DNS:
/* Before trying the cache, let's make sure we figured out a
* server to use. Should this cause a change of server this
* might flush the cache. */
- dns_scope_get_dns_server(t->scope);
+ (void) dns_scope_get_dns_server(t->scope);
/* Let's then prune all outdated entries */
dns_cache_prune(&t->scope->cache);
}
DNS_PACKET_HEADER(p)->nscount = htobe16(nscount);
- t->sent = p;
- p = NULL;
+ t->sent = TAKE_PTR(p);
return 0;
}
DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
DNS_PACKET_HEADER(p)->id = t->id;
- t->sent = p;
- p = NULL;
+ t->sent = TAKE_PTR(p);
return 0;
}
}
dns_answer_unref(t->answer);
- t->answer = validated;
- validated = NULL;
+ t->answer = TAKE_PTR(validated);
/* At this point the answer only contains validated
* RRsets. Now, let's see if it actually answers the question