diff options
-rw-r--r-- | src/resolve/resolve-tool.c | 31 | ||||
-rw-r--r-- | src/resolve/resolved-bus.c | 11 | ||||
-rw-r--r-- | src/resolve/resolved-dns-answer.c | 4 | ||||
-rw-r--r-- | src/resolve/resolved-dns-answer.h | 2 | ||||
-rw-r--r-- | src/resolve/resolved-dns-scope.c | 11 | ||||
-rw-r--r-- | src/resolve/resolved-dns-scope.h | 2 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 17 | ||||
-rw-r--r-- | src/resolve/resolved-dns-zone.c | 13 | ||||
-rw-r--r-- | src/resolve/resolved-dns-zone.h | 2 |
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); |