From e28d0865539e07fcabe14270c700d21ef16ffdce Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Sep 2017 17:48:29 +0200 Subject: [PATCH 1/6] sd-bus: when showing brief message info show error name in debug out put too When debug logging is enabled we show brief information about every bus message we send or receieve. Pretty much all information is shown, except for the error name if a message is an error (interestingly we do print the error text however). Fix that, and add the error name as well. --- src/libsystemd/sd-bus/sd-bus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 16d997c85e..5ce1cdeb0f 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -56,7 +56,7 @@ #define log_debug_bus_message(m) \ do { \ sd_bus_message *_mm = (m); \ - log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s", \ + log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error-name=%s error-message=%s", \ bus_message_type_to_string(_mm->header->type), \ strna(sd_bus_message_get_sender(_mm)), \ strna(sd_bus_message_get_destination(_mm)), \ @@ -65,6 +65,7 @@ strna(sd_bus_message_get_member(_mm)), \ BUS_MESSAGE_COOKIE(_mm), \ _mm->reply_cookie, \ + strna(_mm->error.name), \ strna(_mm->error.message)); \ } while (false) @@ -1465,7 +1466,7 @@ static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call return r; if (*idx >= BUS_MESSAGE_SIZE(m)) - log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s", + log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error-name=%s error-message=%s", bus_message_type_to_string(m->header->type), strna(sd_bus_message_get_sender(m)), strna(sd_bus_message_get_destination(m)), @@ -1474,6 +1475,7 @@ static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call strna(sd_bus_message_get_member(m)), BUS_MESSAGE_COOKIE(m), m->reply_cookie, + strna(m->error.name), strna(m->error.message)); return r; From 532f808fd15ec2cd91777ab3ad9afce2670ebac5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Sep 2017 17:57:34 +0200 Subject: [PATCH 2/6] sd-bus: drop match cookie concept THe match cookie was used by kdbus to identify matches we install uniquely. But given that kdbus is gone, the cookie serves no process anymore, let's kill it. --- src/libsystemd/sd-bus/bus-control.c | 6 ++---- src/libsystemd/sd-bus/bus-control.h | 7 ++----- src/libsystemd/sd-bus/bus-internal.h | 3 --- src/libsystemd/sd-bus/bus-slot.c | 2 +- src/libsystemd/sd-bus/sd-bus.c | 3 +-- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 1a87d3a0ee..3c770a6e2e 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -650,8 +650,7 @@ int bus_add_match_internal( sd_bus *bus, const char *match, struct bus_match_component *components, - unsigned n_components, - uint64_t cookie) { + unsigned n_components) { assert(bus); @@ -686,8 +685,7 @@ static int bus_remove_match_internal_dbus1( int bus_remove_match_internal( sd_bus *bus, - const char *match, - uint64_t cookie) { + const char *match) { assert(bus); diff --git a/src/libsystemd/sd-bus/bus-control.h b/src/libsystemd/sd-bus/bus-control.h index 91efc68d57..01c71874db 100644 --- a/src/libsystemd/sd-bus/bus-control.h +++ b/src/libsystemd/sd-bus/bus-control.h @@ -23,8 +23,5 @@ #include "bus-match.h" -int bus_add_match_internal(sd_bus *bus, const char *match, struct bus_match_component *components, unsigned n_components, uint64_t cookie); -int bus_remove_match_internal(sd_bus *bus, const char *match, uint64_t cookie); - -int bus_add_match_internal_kernel(sd_bus *bus, struct bus_match_component *components, unsigned n_components, uint64_t cookie); -int bus_remove_match_internal_kernel(sd_bus *bus, uint64_t cookie); +int bus_add_match_internal(sd_bus *bus, const char *match, struct bus_match_component *components, unsigned n_components); +int bus_remove_match_internal(sd_bus *bus, const char *match); diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 9a3bc9dd98..5afd9f0936 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -53,7 +53,6 @@ struct filter_callback { struct match_callback { sd_bus_message_handler_t callback; - uint64_t cookie; unsigned last_iteration; char *match_string; @@ -287,8 +286,6 @@ struct sd_bus { uint64_t hello_flags; uint64_t attach_flags; - uint64_t match_cookie; - sd_event_source *input_io_event_source; sd_event_source *output_io_event_source; sd_event_source *time_event_source; diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c index 33590c31ac..725265b331 100644 --- a/src/libsystemd/sd-bus/bus-slot.c +++ b/src/libsystemd/sd-bus/bus-slot.c @@ -93,7 +93,7 @@ void bus_slot_disconnect(sd_bus_slot *slot) { case BUS_MATCH_CALLBACK: if (slot->match_added) - bus_remove_match_internal(slot->bus, slot->match_callback.match_string, slot->match_callback.cookie); + bus_remove_match_internal(slot->bus, slot->match_callback.match_string); slot->bus->match_callbacks_modified = true; bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback); diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 5ce1cdeb0f..621fabb015 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -2858,7 +2858,6 @@ _public_ int sd_bus_add_match( } s->match_callback.callback = callback; - s->match_callback.cookie = ++bus->match_cookie; if (bus->bus_client) { enum bus_match_scope scope; @@ -2878,7 +2877,7 @@ _public_ int sd_bus_add_match( goto finish; } - r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components, s->match_callback.cookie); + r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components); if (r < 0) goto finish; From 21a13ab0543e593637cf2a301076666c7ff82a18 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Sep 2017 17:58:11 +0200 Subject: [PATCH 3/6] sd-bus: drop bloom fields These fields are unused since kdbus support has been removed. --- src/libsystemd/sd-bus/bus-internal.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 5afd9f0936..3af383e18b 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -305,9 +305,6 @@ struct sd_bus { char *description; - size_t bloom_size; - unsigned bloom_n_hash; - sd_bus_track *track_queue; LIST_HEAD(sd_bus_slot, slots); From acf06088d3c64a54c760bd35d5e1b414488d5e77 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Sep 2017 18:01:04 +0200 Subject: [PATCH 4/6] resolved: when there is no gateway, make sure _gateway results in NXDOMAIN Let's ensure that "no gateway" translates to "no domain", instead of an empty reply. This is in line with what nss-myhostname does in the same case, hence let's unify behaviour here of nss-myhostname and resolved. --- src/resolve/resolved-dns-query.c | 11 +++++++++ src/resolve/resolved-dns-synthesize.c | 34 ++++++++++++++++++--------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 2b091e6c45..c2b29bc452 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -623,7 +623,18 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { q->question_utf8, q->ifindex, &answer); + if (r == -ENXIO) { + /* If we get ENXIO this tells us to generate NXDOMAIN unconditionally. */ + dns_query_reset_answer(q); + q->answer_rcode = DNS_RCODE_NXDOMAIN; + q->answer_protocol = dns_synthesize_protocol(q->flags); + q->answer_family = dns_synthesize_family(q->flags); + q->answer_authenticated = true; + *state = DNS_TRANSACTION_RCODE_FAILURE; + + return 0; + } if (r <= 0) return r; diff --git a/src/resolve/resolved-dns-synthesize.c b/src/resolve/resolved-dns-synthesize.c index c454f64049..38e99cd9c7 100644 --- a/src/resolve/resolved-dns-synthesize.c +++ b/src/resolve/resolved-dns-synthesize.c @@ -306,7 +306,7 @@ static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_add static int synthesize_gateway_rr(Manager *m, const DnsResourceKey *key, int ifindex, DnsAnswer **answer) { _cleanup_free_ struct local_address *addresses = NULL; - int n = 0, af; + int n = 0, af, r; assert(m); assert(key); @@ -315,11 +315,15 @@ static int synthesize_gateway_rr(Manager *m, const DnsResourceKey *key, int ifin af = dns_type_to_af(key->type); if (af >= 0) { n = local_gateways(m->rtnl, ifindex, af, &addresses); - if (n < 0) - return n; + if (n <= 0) + return n; /* < 0 means: error; == 0 means we have no gateway */ } - return answer_add_addresses_rr(answer, dns_resource_key_name(key), addresses, n); + r = answer_add_addresses_rr(answer, dns_resource_key_name(key), addresses, n); + if (r < 0) + return r; + + return 1; /* > 0 means: we have some gateway */ } static int synthesize_gateway_ptr(Manager *m, int af, const union in_addr_union *address, int ifindex, DnsAnswer **answer) { @@ -345,7 +349,7 @@ int dns_synthesize_answer( _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; DnsResourceKey *key; - bool found = false; + bool found = false, nxdomain = false; int r; assert(m); @@ -379,6 +383,10 @@ int dns_synthesize_answer( r = synthesize_gateway_rr(m, key, ifindex, &answer); if (r < 0) return log_error_errno(r, "Failed to synthesize gateway RRs: %m"); + if (r == 0) { /* if we have no gateway return NXDOMAIN */ + nxdomain = true; + continue; + } } else if ((dns_name_endswith(name, "127.in-addr.arpa") > 0 && dns_name_equal(name, "2.0.0.127.in-addr.arpa") == 0) || dns_name_equal(name, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0) { @@ -402,12 +410,16 @@ int dns_synthesize_answer( found = true; } - r = found; + if (found) { - if (ret) { - *ret = answer; - answer = NULL; - } + if (ret) { + *ret = answer; + answer = NULL; + } - return r; + return 1; + } else if (nxdomain) + return -ENXIO; + + return 0; } From 2855b6c39c8149709e1d0e714df47020138947f9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Sep 2017 18:02:31 +0200 Subject: [PATCH 5/6] resolved: make sure a non-existing PTR record never gets mangled into NODATA Previously, if a PTR query is seen for a non-existing record, we'd generate an empty response (but not NXDOMAIN or so). Fix that. If we have no data about an IP address, then let's say so, so that the original error is returned, instead of anything synthesized. Fixes: #6543 --- src/resolve/resolved-dns-synthesize.c | 35 ++++++++++++++++++++------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/resolve/resolved-dns-synthesize.c b/src/resolve/resolved-dns-synthesize.c index 38e99cd9c7..ca8f5da804 100644 --- a/src/resolve/resolved-dns-synthesize.c +++ b/src/resolve/resolved-dns-synthesize.c @@ -186,6 +186,7 @@ static int answer_add_addresses_ptr( unsigned n_addresses, int af, const union in_addr_union *match) { + bool added = false; unsigned j; int r; @@ -215,9 +216,11 @@ static int answer_add_addresses_ptr( r = dns_answer_add(*answer, rr, addresses[j].ifindex, DNS_ANSWER_AUTHENTICATED); if (r < 0) return r; + + added = true; } - return 0; + return added; } static int synthesize_system_hostname_rr(Manager *m, const DnsResourceKey *key, int ifindex, DnsAnswer **answer) { @@ -263,6 +266,7 @@ static int synthesize_system_hostname_rr(Manager *m, const DnsResourceKey *key, static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_addr_union *address, int ifindex, DnsAnswer **answer) { _cleanup_free_ struct local_address *addresses = NULL; + bool added = false; int n, r; assert(m); @@ -290,18 +294,26 @@ static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_add if (r < 0) return r; - return 0; + return 1; } n = local_addresses(m->rtnl, ifindex, af, &addresses); - if (n < 0) + if (n <= 0) return n; r = answer_add_addresses_ptr(answer, m->llmnr_hostname, addresses, n, af, address); if (r < 0) return r; + if (r > 0) + added = true; - return answer_add_addresses_ptr(answer, m->mdns_hostname, addresses, n, af, address); + r = answer_add_addresses_ptr(answer, m->mdns_hostname, addresses, n, af, address); + if (r < 0) + return r; + if (r > 0) + added = true; + + return added; } static int synthesize_gateway_rr(Manager *m, const DnsResourceKey *key, int ifindex, DnsAnswer **answer) { @@ -335,7 +347,7 @@ static int synthesize_gateway_ptr(Manager *m, int af, const union in_addr_union assert(answer); n = local_gateways(m->rtnl, ifindex, af, &addresses); - if (n < 0) + if (n <= 0) return n; return answer_add_addresses_ptr(answer, "_gateway", addresses, n, af, address); @@ -396,14 +408,19 @@ int dns_synthesize_answer( return log_error_errno(r, "Failed to synthesize localhost PTR RRs: %m"); } else if (dns_name_address(name, &af, &address) > 0) { + int v, w; - r = synthesize_system_hostname_ptr(m, af, &address, ifindex, &answer); - if (r < 0) + v = synthesize_system_hostname_ptr(m, af, &address, ifindex, &answer); + if (v < 0) return log_error_errno(r, "Failed to synthesize system hostname PTR RR: %m"); - r = synthesize_gateway_ptr(m, af, &address, ifindex, &answer); - if (r < 0) + w = synthesize_gateway_ptr(m, af, &address, ifindex, &answer); + if (w < 0) return log_error_errno(r, "Failed to synthesize gateway hostname PTR RR: %m"); + + if (v == 0 && w == 0) /* This IP address is neither a local one nor a gateway */ + continue; + } else continue; From a4f3375d727efb801cf1da5422c03f6c004d6aca Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Sep 2017 18:05:51 +0200 Subject: [PATCH 6/6] resolved: synthesize records for the full local hostname, too This was forgotten, let's add it too, so that the llmnr, mdns and full hostname RRs are all synthesized if needed. --- src/resolve/resolved-dns-synthesize.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/resolve/resolved-dns-synthesize.c b/src/resolve/resolved-dns-synthesize.c index ca8f5da804..513ac22466 100644 --- a/src/resolve/resolved-dns-synthesize.c +++ b/src/resolve/resolved-dns-synthesize.c @@ -275,10 +275,13 @@ static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_add if (af == AF_INET && address->in.s_addr == htobe32(0x7F000002)) { - /* Always map the IPv4 address 127.0.0.2 to the local - * hostname, in addition to "localhost": */ + /* Always map the IPv4 address 127.0.0.2 to the local hostname, in addition to "localhost": */ - r = dns_answer_reserve(answer, 3); + r = dns_answer_reserve(answer, 4); + if (r < 0) + return r; + + r = answer_add_ptr(answer, "2.0.0.127.in-addr.arpa", m->full_hostname, dns_synthesize_ifindex(ifindex), DNS_ANSWER_AUTHENTICATED); if (r < 0) return r; @@ -301,6 +304,12 @@ static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_add if (n <= 0) return n; + r = answer_add_addresses_ptr(answer, m->full_hostname, addresses, n, af, address); + if (r < 0) + return r; + if (r > 0) + added = true; + r = answer_add_addresses_ptr(answer, m->llmnr_hostname, addresses, n, af, address); if (r < 0) return r;