return n;
}
-void dns_scope_next_dns_server(DnsScope *s) {
+void dns_scope_next_dns_server(DnsScope *s, DnsServer *if_current) {
assert(s);
if (s->protocol != DNS_PROTOCOL_DNS)
return;
+ /* Changes to the next DNS server in the list. If 'if_current' is passed will do so only if the
+ * current DNS server still matches it. */
+
if (s->link)
- link_next_dns_server(s->link);
+ link_next_dns_server(s->link, if_current);
else
- manager_next_dns_server(s->manager);
+ manager_next_dns_server(s->manager, if_current);
}
void dns_scope_packet_received(DnsScope *s, usec_t rtt) {
DnsServer *dns_scope_get_dns_server(DnsScope *s);
unsigned dns_scope_get_n_dns_servers(DnsScope *s);
-void dns_scope_next_dns_server(DnsScope *s);
+void dns_scope_next_dns_server(DnsScope *s, DnsServer *if_current);
int dns_scope_llmnr_membership(DnsScope *s, bool b);
int dns_scope_mdns_membership(DnsScope *s, bool b);
return m->current_dns_server;
}
-void manager_next_dns_server(Manager *m) {
+void manager_next_dns_server(Manager *m, DnsServer *if_current) {
assert(m);
- /* If there's currently no DNS server set, then the next
- * manager_get_dns_server() will find one */
+ /* If the DNS server is already a different one than the one specified in 'if_current' don't do anything */
+ if (if_current && m->current_dns_server != if_current)
+ return;
+
+ /* If there's currently no DNS server set, then the next manager_get_dns_server() will find one */
if (!m->current_dns_server)
return;
- /* Change to the next one, but make sure to follow the linked
- * list only if the server is still linked. */
+ /* Change to the next one, but make sure to follow the linked list only if the server is still
+ * linked. */
if (m->current_dns_server->linked && m->current_dns_server->servers_next) {
manager_set_dns_server(m, m->current_dns_server->servers_next);
return;
}
- /* If there was no next one, then start from the beginning of
- * the list */
+ /* If there was no next one, then start from the beginning of the list */
if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
manager_set_dns_server(m, m->fallback_dns_servers);
else
DnsServer *manager_set_dns_server(Manager *m, DnsServer *s);
DnsServer *manager_get_dns_server(Manager *m);
-void manager_next_dns_server(Manager *m);
+void manager_next_dns_server(Manager *m, DnsServer *if_current);
DnssecMode dns_server_get_dnssec_mode(DnsServer *s);
DnsOverTlsMode dns_server_get_dns_over_tls_mode(DnsServer *s);
/* Before we try again, switch to a new server. */
if (next_server)
- dns_scope_next_dns_server(t->scope);
+ dns_scope_next_dns_server(t->scope, t->server);
r = dns_transaction_go(t);
if (r < 0)
/* One of our own stub listeners */
log_debug_errno(r, "Detected that specified DNS server is our own extra listener, switching DNS servers.");
- dns_scope_next_dns_server(t->scope);
+ dns_scope_next_dns_server(t->scope, t->server);
if (dns_scope_get_dns_server(t->scope) == t->server) {
log_debug_errno(r, "Still pointing to extra listener after switching DNS servers, refusing operation.");
return r;
/* Couldn't send? Try immediately again, with a new server */
- dns_scope_next_dns_server(t->scope);
+ dns_scope_next_dns_server(t->scope, t->server);
return dns_transaction_go(t);
}
return l->current_dns_server;
}
-void link_next_dns_server(Link *l) {
+void link_next_dns_server(Link *l, DnsServer *if_current) {
assert(l);
+ /* If the current server of the transaction is specified, and we already are at a different one,
+ * don't do anything */
+ if (if_current && l->current_dns_server != if_current)
+ return;
+
+ /* If currently have no DNS server, then don't do anything, we'll pick it lazily the next time a DNS
+ * server is needed. */
if (!l->current_dns_server)
return;
- /* Change to the next one, but make sure to follow the linked
- * list only if this server is actually still linked. */
+ /* Change to the next one, but make sure to follow the linked list only if this server is actually
+ * still linked. */
if (l->current_dns_server->linked && l->current_dns_server->servers_next) {
link_set_dns_server(l, l->current_dns_server->servers_next);
return;
}
+ /* Pick the first one again, after we reached the end */
link_set_dns_server(l, l->dns_servers);
}
DnsServer* link_set_dns_server(Link *l, DnsServer *s);
DnsServer* link_get_dns_server(Link *l);
-void link_next_dns_server(Link *l);
+void link_next_dns_server(Link *l, DnsServer *if_current);
DnssecMode link_get_dnssec_mode(Link *l);
bool link_dnssec_supported(Link *l);