summaryrefslogtreecommitdiff
path: root/src/resolve
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve')
-rw-r--r--src/resolve/resolve-tool.c31
-rw-r--r--src/resolve/resolved-bus.c11
-rw-r--r--src/resolve/resolved-dns-answer.c4
-rw-r--r--src/resolve/resolved-dns-answer.h2
-rw-r--r--src/resolve/resolved-dns-scope.c11
-rw-r--r--src/resolve/resolved-dns-scope.h2
-rw-r--r--src/resolve/resolved-dns-transaction.c17
-rw-r--r--src/resolve/resolved-dns-zone.c13
-rw-r--r--src/resolve/resolved-dns-zone.h2
9 files changed, 41 insertions, 52 deletions
diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c
index bc6dcf04a4..2cb2e42b23 100644
--- a/src/resolve/resolve-tool.c
+++ b/src/resolve/resolve-tool.c
@@ -199,7 +199,7 @@ static int resolve_host(sd_bus *bus, const char *name) {
if (ifindex > 0 && !if_indextoname(ifindex, ifname))
log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex);
- r = in_addr_to_string(family, a, &pretty);
+ r = in_addr_ifindex_to_string(family, a, ifindex, &pretty);
if (r < 0)
return log_error_errno(r, "Failed to print address for %s: %m", name);
@@ -253,7 +253,7 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a
if (ifindex <= 0)
ifindex = arg_ifindex;
- r = in_addr_to_string(family, address, &pretty);
+ r = in_addr_ifindex_to_string(family, address, ifindex, &pretty);
if (r < 0)
return log_oom();
@@ -345,31 +345,6 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a
return 0;
}
-static int parse_address(const char *s, int *family, union in_addr_union *address, int *ifindex) {
- const char *percent, *a;
- int ifi = 0;
- int r;
-
- percent = strchr(s, '%');
- if (percent) {
- if (parse_ifindex(percent+1, &ifi) < 0) {
- ifi = if_nametoindex(percent+1);
- if (ifi <= 0)
- return -EINVAL;
- }
-
- a = strndupa(s, percent - s);
- } else
- a = s;
-
- r = in_addr_from_string_auto(a, family, address);
- if (r < 0)
- return r;
-
- *ifindex = ifi;
- return 0;
-}
-
static int output_rr_packet(const void *d, size_t l, int ifindex) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
@@ -1392,7 +1367,7 @@ int main(int argc, char **argv) {
if (startswith(argv[optind], "dns:"))
k = resolve_rfc4501(bus, argv[optind]);
else {
- k = parse_address(argv[optind], &family, &a, &ifindex);
+ k = in_addr_ifindex_from_string_auto(argv[optind], &family, &a, &ifindex);
if (k >= 0)
k = resolve_address(bus, family, &a, ifindex);
else
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 6d86cbf123..f08c6c0637 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -245,17 +245,22 @@ static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *canonical = NULL;
union in_addr_union parsed;
- int r, ff;
+ int r, ff, parsed_ifindex = 0;
/* Check if the hostname is actually already an IP address formatted as string. In that case just parse it,
* let's not attempt to look it up. */
- r = in_addr_from_string_auto(hostname, &ff, &parsed);
+ r = in_addr_ifindex_from_string_auto(hostname, &ff, &parsed, &parsed_ifindex);
if (r < 0) /* not an address */
return 0;
if (family != AF_UNSPEC && ff != family)
return sd_bus_reply_method_errorf(m, BUS_ERROR_NO_SUCH_RR, "The specified address is not of the requested family.");
+ if (ifindex > 0 && parsed_ifindex > 0 && parsed_ifindex != ifindex)
+ return sd_bus_reply_method_errorf(m, BUS_ERROR_NO_SUCH_RR, "The specified address interface index does not match requested interface.");
+
+ if (parsed_ifindex > 0)
+ ifindex = parsed_ifindex;
r = sd_bus_message_new_method_return(m, &reply);
if (r < 0)
@@ -288,7 +293,7 @@ static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname
/* When an IP address is specified we just return it as canonical name, in order to avoid a DNS
* look-up. However, we reformat it to make sure it's in a truly canonical form (i.e. on IPv6 the inner
* omissions are always done the same way). */
- r = in_addr_to_string(ff, &parsed, &canonical);
+ r = in_addr_ifindex_to_string(ff, &parsed, ifindex, &canonical);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
index 0dadf8b1dd..13dcba8421 100644
--- a/src/resolve/resolved-dns-answer.c
+++ b/src/resolve/resolved-dns-answer.c
@@ -185,7 +185,7 @@ int dns_answer_add_extend(DnsAnswer **a, DnsResourceRecord *rr, int ifindex, Dns
return dns_answer_add(*a, rr, ifindex, flags);
}
-int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl) {
+int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl, int ifindex) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *soa = NULL;
soa = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_SOA, name);
@@ -208,7 +208,7 @@ int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl) {
soa->soa.expire = 1;
soa->soa.minimum = ttl;
- return dns_answer_add(a, soa, 0, DNS_ANSWER_AUTHENTICATED);
+ return dns_answer_add(a, soa, ifindex, DNS_ANSWER_AUTHENTICATED);
}
int dns_answer_match_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags *ret_flags) {
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
index 0679c610f5..b2b86d1772 100644
--- a/src/resolve/resolved-dns-answer.h
+++ b/src/resolve/resolved-dns-answer.h
@@ -56,7 +56,7 @@ DnsAnswer *dns_answer_unref(DnsAnswer *a);
int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags);
int dns_answer_add_extend(DnsAnswer **a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags);
-int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl);
+int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl, int ifindex);
int dns_answer_match_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags *combined_flags);
int dns_answer_contains_rr(DnsAnswer *a, DnsResourceRecord *rr, DnsAnswerFlags *combined_flags);
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index 6a69d7b7c2..9d484d0a48 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -721,7 +721,7 @@ void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
assert(p->question->n_keys == 1);
key = p->question->keys[0];
- r = dns_zone_lookup(&s->zone, key, &answer, &soa, &tentative);
+ r = dns_zone_lookup(&s->zone, key, 0, &answer, &soa, &tentative);
if (r < 0) {
log_debug_errno(r, "Failed to lookup key: %m");
return;
@@ -1029,3 +1029,12 @@ bool dns_scope_network_good(DnsScope *s) {
return manager_routable(s->manager, AF_UNSPEC);
}
+
+int dns_scope_ifindex(DnsScope *s) {
+ assert(s);
+
+ if (s->link)
+ return s->link->ifindex;
+
+ return 0;
+}
diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h
index 291e5817d0..538bc61f81 100644
--- a/src/resolve/resolved-dns-scope.h
+++ b/src/resolve/resolved-dns-scope.h
@@ -107,3 +107,5 @@ DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s);
bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name);
bool dns_scope_network_good(DnsScope *s);
+
+int dns_scope_ifindex(DnsScope *s);
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index a4a67623e7..ed18df35cb 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -557,8 +557,7 @@ static int dns_transaction_open_tcp(DnsTransaction *t) {
/* The interface index is difficult to determine if we are
* connecting to the local host, hence fill this in right away
* instead of determining it from the socket */
- if (t->scope->link)
- t->stream->ifindex = t->scope->link->ifindex;
+ t->stream->ifindex = dns_scope_ifindex(t->scope);
dns_transaction_reset_answer(t);
@@ -798,12 +797,9 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
switch (t->scope->protocol) {
case DNS_PROTOCOL_LLMNR:
- assert(t->scope->link);
+ /* For LLMNR we will not accept any packets from other interfaces */
- /* For LLMNR we will not accept any packets from other
- * interfaces */
-
- if (p->ifindex != t->scope->link->ifindex)
+ if (p->ifindex != dns_scope_ifindex(t->scope))
return;
if (p->family != t->scope->family)
@@ -820,10 +816,9 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
break;
case DNS_PROTOCOL_MDNS:
- assert(t->scope->link);
-
/* For mDNS we will not accept any packets from other interfaces */
- if (p->ifindex != t->scope->link->ifindex)
+
+ if (p->ifindex != dns_scope_ifindex(t->scope))
return;
if (p->family != t->scope->family)
@@ -1246,7 +1241,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
* for probing or verifying a zone item. */
if (set_isempty(t->notify_zone_items)) {
- r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
+ r = dns_zone_lookup(&t->scope->zone, t->key, dns_scope_ifindex(t->scope), &t->answer, NULL, NULL);
if (r < 0)
return r;
if (r > 0) {
diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c
index 850eed8cb8..746a979f47 100644
--- a/src/resolve/resolved-dns-zone.c
+++ b/src/resolve/resolved-dns-zone.c
@@ -287,13 +287,16 @@ int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe) {
return 0;
}
-int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, DnsAnswer **ret_soa, bool *ret_tentative) {
+int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **ret_answer, DnsAnswer **ret_soa, bool *ret_tentative) {
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
unsigned n_answer = 0;
DnsZoneItem *j, *first;
bool tentative = true, need_soa = false;
int r;
+ /* Note that we don't actually need the ifindex for anything. However when it is passed we'll initialize the
+ * ifindex field in the answer with it */
+
assert(z);
assert(key);
assert(ret_answer);
@@ -389,7 +392,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
if (k < 0)
return k;
if (k > 0) {
- r = dns_answer_add(answer, j->rr, 0, DNS_ANSWER_AUTHENTICATED);
+ r = dns_answer_add(answer, j->rr, ifindex, DNS_ANSWER_AUTHENTICATED);
if (r < 0)
return r;
@@ -398,7 +401,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
}
if (found && !added) {
- r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL);
+ r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL, ifindex);
if (r < 0)
return r;
}
@@ -415,7 +418,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
if (j->state != DNS_ZONE_ITEM_PROBING)
tentative = false;
- r = dns_answer_add(answer, j->rr, 0, DNS_ANSWER_AUTHENTICATED);
+ r = dns_answer_add(answer, j->rr, ifindex, DNS_ANSWER_AUTHENTICATED);
if (r < 0)
return r;
}
@@ -435,7 +438,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
}
if (add_soa) {
- r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL);
+ r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL, ifindex);
if (r < 0)
return r;
}
diff --git a/src/resolve/resolved-dns-zone.h b/src/resolve/resolved-dns-zone.h
index 408833c359..a41df37e6b 100644
--- a/src/resolve/resolved-dns-zone.h
+++ b/src/resolve/resolved-dns-zone.h
@@ -65,7 +65,7 @@ void dns_zone_flush(DnsZone *z);
int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe);
void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr);
-int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
+int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
void dns_zone_item_conflict(DnsZoneItem *i);
void dns_zone_item_notify(DnsZoneItem *i);