#endif
free(s->server_string);
+ free(s->server_string_full);
free(s->server_name);
return mfree(s);
}
if (s->verified_feature_level != level) {
log_debug("Verified we get a response at feature level %s from DNS server %s.",
dns_server_feature_level_to_string(level),
- dns_server_string(s));
+ strna(dns_server_string_full(s)));
s->verified_feature_level = level;
}
dns_server_reset_counters(s);
}
- log_debug("Downgrading transaction feature level fixed an RCODE error, downgrading server %s too.", dns_server_string(s));
+ log_debug("Downgrading transaction feature level fixed an RCODE error, downgrading server %s too.", strna(dns_server_string_full(s)));
}
static bool dns_server_grace_period_expired(DnsServer *s) {
log_info("Grace period over, resuming full feature set (%s) for DNS server %s.",
dns_server_feature_level_to_string(s->possible_feature_level),
- dns_server_string(s));
+ strna(dns_server_string_full(s)));
dns_server_flush_cache(s);
log_full(log_level, "Using degraded feature set %s instead of %s for DNS server %s.",
dns_server_feature_level_to_string(s->possible_feature_level),
- dns_server_feature_level_to_string(p), dns_server_string(s));
+ dns_server_feature_level_to_string(p), strna(dns_server_string_full(s)));
}
}
if (!server->server_string)
(void) in_addr_ifindex_to_string(server->family, &server->address, dns_server_ifindex(server), &server->server_string);
- return strna(server->server_string);
+ return server->server_string;
+}
+
+const char *dns_server_string_full(DnsServer *server) {
+ assert(server);
+
+ if (!server->server_string_full)
+ (void) in_addr_port_ifindex_name_to_string(
+ server->family,
+ &server->address,
+ server->port,
+ dns_server_ifindex(server),
+ server->server_name,
+ &server->server_string_full);
+
+ return server->server_string_full;
}
bool dns_server_dnssec_supported(DnsServer *server) {
log_struct(LOG_NOTICE,
"MESSAGE_ID=" SD_MESSAGE_DNSSEC_DOWNGRADE_STR,
- LOG_MESSAGE("Server %s does not support DNSSEC, downgrading to non-DNSSEC mode.", dns_server_string(server)),
- "DNS_SERVER=%s", dns_server_string(server),
+ LOG_MESSAGE("Server %s does not support DNSSEC, downgrading to non-DNSSEC mode.", strna(dns_server_string_full(server))),
+ "DNS_SERVER=%s", strna(dns_server_string_full(server)),
"DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(server->possible_feature_level));
server->warned_downgrade = true;
if (s)
log_debug("Switching to %s DNS server %s.",
dns_server_type_to_string(s->type),
- dns_server_string(s));
+ strna(dns_server_string_full(s)));
dns_server_unref(m->current_dns_server);
m->current_dns_server = dns_server_ref(s);
f = stdout;
fputs("[Server ", f);
- fputs(dns_server_string(s), f);
+ fputs(strna(dns_server_string_full(s)), f);
fputs(" type=", f);
fputs(dns_server_type_to_string(s->type), f);
char *server_name;
char *server_string;
+ char *server_string_full;
/* The long-lived stream towards this server. */
DnsStream *stream;
int dns_server_adjust_opt(DnsServer *server, DnsPacket *packet, DnsServerFeatureLevel level);
const char *dns_server_string(DnsServer *server);
+const char *dns_server_string_full(DnsServer *server);
int dns_server_ifindex(const DnsServer *s);
uint16_t dns_server_port(const DnsServer *s);
"DNS_TRANSACTION=%" PRIu16, t->id,
"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=%s", strna(dns_server_string_full(t->server)),
"DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level));
}
t->n_picked_servers ++;
- log_debug("Using DNS server %s for transaction %u.", dns_server_string(t->server), t->id);
+ log_debug("Using DNS server %s for transaction %u.", strna(dns_server_string_full(t->server)), t->id);
return 1;
}
#include "resolved-link.h"
#include "resolved-llmnr.h"
#include "resolved-mdns.h"
+#include "socket-netlink.h"
#include "string-util.h"
#include "strv.h"
#include "tmpfile-util.h"
return 0;
}
-static int link_update_dns_server_one(Link *l, const char *name) {
+static int link_update_dns_server_one(Link *l, const char *str) {
+ _cleanup_free_ char *name = NULL;
+ int family, ifindex, r;
union in_addr_union a;
DnsServer *s;
- int family, r;
+ uint16_t port;
assert(l);
- assert(name);
+ assert(str);
- r = in_addr_from_string_auto(name, &family, &a);
+ r = in_addr_port_ifindex_name_from_string_auto(str, &family, &a, &port, &ifindex, &name);
if (r < 0)
return r;
- s = dns_server_find(l->dns_servers, family, &a, 0, 0, NULL);
+ if (ifindex != 0 && ifindex != l->ifindex)
+ return -EINVAL;
+
+ /* By default, the port number is determined with the transaction feature level.
+ * See dns_transaction_port() and dns_server_port(). */
+ if (IN_SET(port, 53, 853))
+ port = 0;
+
+ s = dns_server_find(l->dns_servers, family, &a, port, 0, name);
if (s) {
dns_server_move_back_and_unmark(s);
return 0;
}
- return dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a, 0, 0, NULL);
+ return dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a, port, 0, name);
}
static int link_update_dns_servers(Link *l) {
return s;
if (s)
- log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s), l->ifname);
+ log_debug("Switching to DNS server %s for interface %s.", strna(dns_server_string_full(s)), l->ifname);
dns_server_unref(l->current_dns_server);
l->current_dns_server = dns_server_ref(s);
if (server != l->dns_servers)
fputc(' ', f);
- v = dns_server_string(server);
+ v = dns_server_string_full(server);
if (!v) {
r = -ENOMEM;
goto fail;