mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
Merge pull request #16757 from poettering/nss-resolve-varlink
resolved: use varlink for communication between nss-resolve and resolved
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
union in_addr_union {
|
||||
struct in_addr in;
|
||||
struct in6_addr in6;
|
||||
uint8_t bytes[CONST_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))];
|
||||
};
|
||||
|
||||
struct in_addr_data {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,53 +17,55 @@ basic_dns_sources = files('''
|
||||
dns_type_h = files('dns-type.h')[0]
|
||||
|
||||
systemd_resolved_sources = files('''
|
||||
resolved.c
|
||||
resolved-manager.c
|
||||
resolved-manager.h
|
||||
resolved-dnssd.c
|
||||
resolved-dnssd.h
|
||||
resolved-dnssd-bus.c
|
||||
resolved-dnssd-bus.h
|
||||
resolved-conf.c
|
||||
resolved-conf.h
|
||||
resolved-resolv-conf.c
|
||||
resolved-resolv-conf.h
|
||||
resolved-bus.c
|
||||
resolved-bus.h
|
||||
resolved-link.h
|
||||
resolved-link.c
|
||||
resolved-conf.c
|
||||
resolved-conf.h
|
||||
resolved-def.h
|
||||
resolved-dns-cache.c
|
||||
resolved-dns-cache.h
|
||||
resolved-dns-query.c
|
||||
resolved-dns-query.h
|
||||
resolved-dns-scope.c
|
||||
resolved-dns-scope.h
|
||||
resolved-dns-search-domain.c
|
||||
resolved-dns-search-domain.h
|
||||
resolved-dns-server.c
|
||||
resolved-dns-server.h
|
||||
resolved-dns-stream.c
|
||||
resolved-dns-stream.h
|
||||
resolved-dns-stub.c
|
||||
resolved-dns-stub.h
|
||||
resolved-dns-synthesize.c
|
||||
resolved-dns-synthesize.h
|
||||
resolved-dns-transaction.c
|
||||
resolved-dns-transaction.h
|
||||
resolved-dns-trust-anchor.c
|
||||
resolved-dns-trust-anchor.h
|
||||
resolved-dns-zone.c
|
||||
resolved-dns-zone.h
|
||||
resolved-dnssd-bus.c
|
||||
resolved-dnssd-bus.h
|
||||
resolved-dnssd.c
|
||||
resolved-dnssd.h
|
||||
resolved-dnstls.h
|
||||
resolved-etc-hosts.c
|
||||
resolved-etc-hosts.h
|
||||
resolved-link-bus.c
|
||||
resolved-link-bus.h
|
||||
resolved-llmnr.h
|
||||
resolved-link.c
|
||||
resolved-link.h
|
||||
resolved-llmnr.c
|
||||
resolved-mdns.h
|
||||
resolved-llmnr.h
|
||||
resolved-manager.c
|
||||
resolved-manager.h
|
||||
resolved-mdns.c
|
||||
resolved-def.h
|
||||
resolved-dns-query.h
|
||||
resolved-dns-query.c
|
||||
resolved-dns-synthesize.h
|
||||
resolved-dns-synthesize.c
|
||||
resolved-dns-transaction.h
|
||||
resolved-dns-transaction.c
|
||||
resolved-dns-scope.h
|
||||
resolved-dns-scope.c
|
||||
resolved-dns-server.h
|
||||
resolved-dns-server.c
|
||||
resolved-dns-search-domain.h
|
||||
resolved-dns-search-domain.c
|
||||
resolved-dns-cache.h
|
||||
resolved-dns-cache.c
|
||||
resolved-dns-zone.h
|
||||
resolved-dns-zone.c
|
||||
resolved-dns-stream.h
|
||||
resolved-dns-stream.c
|
||||
resolved-dns-trust-anchor.h
|
||||
resolved-dns-trust-anchor.c
|
||||
resolved-dns-stub.h
|
||||
resolved-dns-stub.c
|
||||
resolved-etc-hosts.h
|
||||
resolved-etc-hosts.c
|
||||
resolved-dnstls.h
|
||||
resolved-mdns.h
|
||||
resolved-resolv-conf.c
|
||||
resolved-resolv-conf.h
|
||||
resolved-varlink.c
|
||||
resolved-varlink.h
|
||||
resolved.c
|
||||
'''.split())
|
||||
|
||||
resolvectl_sources = files('''
|
||||
|
||||
@@ -24,45 +24,81 @@
|
||||
|
||||
BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_resolve_support, resolve_support, ResolveSupport);
|
||||
|
||||
static int query_on_bus_track(sd_bus_track *t, void *userdata) {
|
||||
DnsQuery *q = userdata;
|
||||
|
||||
assert(t);
|
||||
assert(q);
|
||||
|
||||
if (!DNS_TRANSACTION_IS_LIVE(q->state))
|
||||
return 0;
|
||||
|
||||
log_debug("Client of active query vanished, aborting query.");
|
||||
dns_query_complete(q, DNS_TRANSACTION_ABORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dns_query_bus_track(DnsQuery *q, sd_bus_message *m) {
|
||||
int r;
|
||||
|
||||
assert(q);
|
||||
assert(m);
|
||||
|
||||
if (!q->bus_track) {
|
||||
r = sd_bus_track_new(sd_bus_message_get_bus(m), &q->bus_track, query_on_bus_track, q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_track_add_sender(q->bus_track, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reply_query_state(DnsQuery *q) {
|
||||
|
||||
assert(q);
|
||||
assert(q->bus_request);
|
||||
|
||||
switch (q->state) {
|
||||
|
||||
case DNS_TRANSACTION_NO_SERVERS:
|
||||
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
|
||||
return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
|
||||
|
||||
case DNS_TRANSACTION_TIMEOUT:
|
||||
return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
|
||||
return sd_bus_reply_method_errorf(q->bus_request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
|
||||
|
||||
case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
|
||||
return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
|
||||
return sd_bus_reply_method_errorf(q->bus_request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
|
||||
|
||||
case DNS_TRANSACTION_INVALID_REPLY:
|
||||
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
|
||||
return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
|
||||
|
||||
case DNS_TRANSACTION_ERRNO:
|
||||
return sd_bus_reply_method_errnof(q->request, q->answer_errno, "Lookup failed due to system error: %m");
|
||||
return sd_bus_reply_method_errnof(q->bus_request, q->answer_errno, "Lookup failed due to system error: %m");
|
||||
|
||||
case DNS_TRANSACTION_ABORTED:
|
||||
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
|
||||
return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_ABORTED, "Query aborted");
|
||||
|
||||
case DNS_TRANSACTION_DNSSEC_FAILED:
|
||||
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_DNSSEC_FAILED, "DNSSEC validation failed: %s",
|
||||
return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_DNSSEC_FAILED, "DNSSEC validation failed: %s",
|
||||
dnssec_result_to_string(q->answer_dnssec_result));
|
||||
|
||||
case DNS_TRANSACTION_NO_TRUST_ANCHOR:
|
||||
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_TRUST_ANCHOR, "No suitable trust anchor known");
|
||||
return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_TRUST_ANCHOR, "No suitable trust anchor known");
|
||||
|
||||
case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED:
|
||||
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_RR_TYPE_UNSUPPORTED, "Server does not support requested resource record type");
|
||||
return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_RR_TYPE_UNSUPPORTED, "Server does not support requested resource record type");
|
||||
|
||||
case DNS_TRANSACTION_NETWORK_DOWN:
|
||||
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NETWORK_DOWN, "Network is down");
|
||||
return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NETWORK_DOWN, "Network is down");
|
||||
|
||||
case DNS_TRANSACTION_NOT_FOUND:
|
||||
/* We return this as NXDOMAIN. This is only generated when a host doesn't implement LLMNR/TCP, and we
|
||||
* thus quickly know that we cannot resolve an in-addr.arpa or ip6.arpa address. */
|
||||
return sd_bus_reply_method_errorf(q->request, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", dns_query_string(q));
|
||||
return sd_bus_reply_method_errorf(q->bus_request, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", dns_query_string(q));
|
||||
|
||||
case DNS_TRANSACTION_RCODE_FAILURE: {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
@@ -83,7 +119,7 @@ static int reply_query_state(DnsQuery *q) {
|
||||
sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", dns_query_string(q), rc);
|
||||
}
|
||||
|
||||
return sd_bus_reply_method_error(q->request, &error);
|
||||
return sd_bus_reply_method_error(q->bus_request, &error);
|
||||
}
|
||||
|
||||
case DNS_TRANSACTION_NULL:
|
||||
@@ -139,6 +175,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
|
||||
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_free_ char *normalized = NULL;
|
||||
DnsQuestion *question;
|
||||
DnsResourceRecord *rr;
|
||||
unsigned added = 0;
|
||||
int ifindex, r;
|
||||
@@ -152,7 +189,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
|
||||
|
||||
r = dns_query_process_cname(q);
|
||||
if (r == -ELOOP) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
if (r < 0)
|
||||
@@ -160,7 +197,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
|
||||
if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
|
||||
return;
|
||||
|
||||
r = sd_bus_message_new_method_return(q->request, &reply);
|
||||
r = sd_bus_message_new_method_return(q->bus_request, &reply);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
@@ -168,10 +205,9 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
|
||||
DnsQuestion *question;
|
||||
question = dns_query_question_for_protocol(q, q->answer_protocol);
|
||||
|
||||
question = dns_query_question_for_protocol(q, q->answer_protocol);
|
||||
DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
|
||||
|
||||
r = dns_question_matches_rr(question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
|
||||
if (r < 0)
|
||||
@@ -190,7 +226,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
|
||||
}
|
||||
|
||||
if (added <= 0) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -198,14 +234,14 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
/* The key names are not necessarily normalized, make sure that they are when we return them to our bus
|
||||
* clients. */
|
||||
/* The key names are not necessarily normalized, make sure that they are when we return them to our
|
||||
* bus clients. */
|
||||
assert(canonical);
|
||||
r = dns_name_normalize(dns_resource_key_name(canonical->key), 0, &normalized);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
/* Return the precise spelling and uppercasing and CNAME target reported by the server */
|
||||
assert(canonical);
|
||||
r = sd_bus_message_append(
|
||||
reply, "st",
|
||||
normalized,
|
||||
@@ -218,15 +254,29 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
|
||||
finish:
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to send hostname reply: %m");
|
||||
sd_bus_reply_method_errno(q->request, r, NULL);
|
||||
sd_bus_reply_method_errno(q->bus_request, r, NULL);
|
||||
}
|
||||
|
||||
dns_query_free(q);
|
||||
}
|
||||
|
||||
static int check_ifindex_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus_error *error) {
|
||||
static int validate_and_mangle_ifindex_and_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus_error *error) {
|
||||
assert(flags);
|
||||
|
||||
/* Checks that the client supplied interface index and flags parameter actually are valid and make
|
||||
* sense in our method call context. Specifically:
|
||||
*
|
||||
* 1. Checks that the interface index is either 0 (meaning *all* interfaces) or positive
|
||||
*
|
||||
* 2. Only the protocols flags and the NO_CNAME flag are set, at most. Plus additional flags specific
|
||||
* to our method, passed in the "ok" parameter.
|
||||
*
|
||||
* 3. If zero protocol flags are specified it is automatically turned into *all* protocols. This way
|
||||
* clients can simply pass 0 as flags and all will work as it should. They can also use this so
|
||||
* that clients don't have to know all the protocols resolved implements, but can just specify 0
|
||||
* to mean "all supported protocols".
|
||||
*/
|
||||
|
||||
if (ifindex < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
|
||||
|
||||
@@ -324,7 +374,7 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata,
|
||||
if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
|
||||
|
||||
r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error);
|
||||
r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -350,10 +400,9 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
q->request = sd_bus_message_ref(message);
|
||||
q->bus_request = sd_bus_message_ref(message);
|
||||
q->request_family = family;
|
||||
q->complete = bus_method_resolve_hostname_complete;
|
||||
q->suppress_unroutable_family = family == AF_UNSPEC;
|
||||
|
||||
r = dns_query_bus_track(q, message);
|
||||
if (r < 0)
|
||||
@@ -386,7 +435,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
|
||||
|
||||
r = dns_query_process_cname(q);
|
||||
if (r == -ELOOP) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
if (r < 0)
|
||||
@@ -394,7 +443,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
|
||||
if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
|
||||
return;
|
||||
|
||||
r = sd_bus_message_new_method_return(q->request, &reply);
|
||||
r = sd_bus_message_new_method_return(q->bus_request, &reply);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
@@ -428,7 +477,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
|
||||
_cleanup_free_ char *ip = NULL;
|
||||
|
||||
(void) in_addr_to_string(q->request_family, &q->request_address, &ip);
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR,
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR,
|
||||
"Address '%s' does not have any RR of requested type", strnull(ip));
|
||||
goto finish;
|
||||
}
|
||||
@@ -446,7 +495,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
|
||||
finish:
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to send address reply: %m");
|
||||
sd_bus_reply_method_errno(q->request, r, NULL);
|
||||
sd_bus_reply_method_errno(q->bus_request, r, NULL);
|
||||
}
|
||||
|
||||
dns_query_free(q);
|
||||
@@ -478,7 +527,7 @@ static int bus_method_resolve_address(sd_bus_message *message, void *userdata, s
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = check_ifindex_flags(ifindex, &flags, 0, error);
|
||||
r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, 0, error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -490,7 +539,7 @@ static int bus_method_resolve_address(sd_bus_message *message, void *userdata, s
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
q->request = sd_bus_message_ref(message);
|
||||
q->bus_request = sd_bus_message_ref(message);
|
||||
q->request_family = family;
|
||||
q->request_address = a;
|
||||
q->complete = bus_method_resolve_address_complete;
|
||||
@@ -555,7 +604,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) {
|
||||
|
||||
r = dns_query_process_cname(q);
|
||||
if (r == -ELOOP) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
if (r < 0)
|
||||
@@ -563,7 +612,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) {
|
||||
if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
|
||||
return;
|
||||
|
||||
r = sd_bus_message_new_method_return(q->request, &reply);
|
||||
r = sd_bus_message_new_method_return(q->bus_request, &reply);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
@@ -588,7 +637,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) {
|
||||
}
|
||||
|
||||
if (added <= 0) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -605,7 +654,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) {
|
||||
finish:
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to send record reply: %m");
|
||||
sd_bus_reply_method_errno(q->request, r, NULL);
|
||||
sd_bus_reply_method_errno(q->bus_request, r, NULL);
|
||||
}
|
||||
|
||||
dns_query_free(q);
|
||||
@@ -643,7 +692,7 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
|
||||
if (dns_type_is_obsolete(type))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type);
|
||||
|
||||
r = check_ifindex_flags(ifindex, &flags, 0, error);
|
||||
r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, 0, error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -667,7 +716,7 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
|
||||
* blob */
|
||||
q->clamp_ttl = true;
|
||||
|
||||
q->request = sd_bus_message_ref(message);
|
||||
q->bus_request = sd_bus_message_ref(message);
|
||||
q->complete = bus_method_resolve_record_complete;
|
||||
|
||||
r = dns_query_bus_track(q, message);
|
||||
@@ -891,7 +940,7 @@ static void resolve_service_all_complete(DnsQuery *q) {
|
||||
assert(bad->auxiliary_result != 0);
|
||||
|
||||
if (bad->auxiliary_result == -ELOOP) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(bad));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(bad));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -904,7 +953,7 @@ static void resolve_service_all_complete(DnsQuery *q) {
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_bus_message_new_method_return(q->request, &reply);
|
||||
r = sd_bus_message_new_method_return(q->bus_request, &reply);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
@@ -913,6 +962,7 @@ static void resolve_service_all_complete(DnsQuery *q) {
|
||||
goto finish;
|
||||
|
||||
question = dns_query_question_for_protocol(q, q->answer_protocol);
|
||||
|
||||
DNS_ANSWER_FOREACH(rr, q->answer) {
|
||||
r = dns_question_matches_rr(question, rr, NULL);
|
||||
if (r < 0)
|
||||
@@ -933,7 +983,7 @@ static void resolve_service_all_complete(DnsQuery *q) {
|
||||
}
|
||||
|
||||
if (added <= 0) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -979,7 +1029,7 @@ static void resolve_service_all_complete(DnsQuery *q) {
|
||||
finish:
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to send service reply: %m");
|
||||
sd_bus_reply_method_errno(q->request, r, NULL);
|
||||
sd_bus_reply_method_errno(q->bus_request, r, NULL);
|
||||
}
|
||||
|
||||
dns_query_free(q);
|
||||
@@ -1071,7 +1121,7 @@ static void bus_method_resolve_service_complete(DnsQuery *q) {
|
||||
|
||||
r = dns_query_process_cname(q);
|
||||
if (r == -ELOOP) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
if (r < 0)
|
||||
@@ -1115,12 +1165,12 @@ static void bus_method_resolve_service_complete(DnsQuery *q) {
|
||||
* domain. Report this as a recognizable
|
||||
* error. See RFC 2782, Section "Usage
|
||||
* Rules". */
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_SERVICE, "'%s' does not provide the requested service", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_SERVICE, "'%s' does not provide the requested service", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (found <= 0) {
|
||||
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
|
||||
r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -1131,7 +1181,7 @@ static void bus_method_resolve_service_complete(DnsQuery *q) {
|
||||
finish:
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to send service reply: %m");
|
||||
sd_bus_reply_method_errno(q->request, r, NULL);
|
||||
sd_bus_reply_method_errno(q->bus_request, r, NULL);
|
||||
}
|
||||
|
||||
dns_query_free(q);
|
||||
@@ -1177,7 +1227,7 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
|
||||
if (name && !type)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
|
||||
|
||||
r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
|
||||
r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1193,7 +1243,7 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
q->request = sd_bus_message_ref(message);
|
||||
q->bus_request = sd_bus_message_ref(message);
|
||||
q->request_family = family;
|
||||
q->complete = bus_method_resolve_service_complete;
|
||||
|
||||
@@ -1690,7 +1740,7 @@ static int bus_method_reset_server_features(sd_bus_message *message, void *userd
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
static int on_bus_track(sd_bus_track *t, void *userdata) {
|
||||
static int dnssd_service_on_bus_track(sd_bus_track *t, void *userdata) {
|
||||
DnssdService *s = userdata;
|
||||
|
||||
assert(t);
|
||||
@@ -1863,7 +1913,7 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_track_new(sd_bus_message_get_bus(message), &bus_track, on_bus_track, service);
|
||||
r = sd_bus_track_new(sd_bus_message_get_bus(message), &bus_track, dnssd_service_on_bus_track, service);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -338,9 +338,14 @@ DnsQuery *dns_query_free(DnsQuery *q) {
|
||||
|
||||
dns_query_reset_answer(q);
|
||||
|
||||
sd_bus_message_unref(q->request);
|
||||
sd_bus_message_unref(q->bus_request);
|
||||
sd_bus_track_unref(q->bus_track);
|
||||
|
||||
if (q->varlink_request) {
|
||||
varlink_set_userdata(q->varlink_request, NULL);
|
||||
varlink_unref(q->varlink_request);
|
||||
}
|
||||
|
||||
dns_packet_unref(q->request_dns_packet);
|
||||
dns_packet_unref(q->reply_dns_packet);
|
||||
|
||||
@@ -473,14 +478,13 @@ int dns_query_make_auxiliary(DnsQuery *q, DnsQuery *auxiliary_for) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dns_query_complete(DnsQuery *q, DnsTransactionState state) {
|
||||
void dns_query_complete(DnsQuery *q, DnsTransactionState state) {
|
||||
assert(q);
|
||||
assert(!DNS_TRANSACTION_IS_LIVE(state));
|
||||
assert(DNS_TRANSACTION_IS_LIVE(q->state));
|
||||
|
||||
/* Note that this call might invalidate the query. Callers
|
||||
* should hence not attempt to access the query or transaction
|
||||
* after calling this function. */
|
||||
/* Note that this call might invalidate the query. Callers should hence not attempt to access the
|
||||
* query or transaction after calling this function. */
|
||||
|
||||
q->state = state;
|
||||
|
||||
@@ -987,36 +991,6 @@ int dns_query_process_cname(DnsQuery *q) {
|
||||
return DNS_QUERY_RESTARTED; /* We restarted the query for a new cname */
|
||||
}
|
||||
|
||||
static int on_bus_track(sd_bus_track *t, void *userdata) {
|
||||
DnsQuery *q = userdata;
|
||||
|
||||
assert(t);
|
||||
assert(q);
|
||||
|
||||
log_debug("Client of active query vanished, aborting query.");
|
||||
dns_query_complete(q, DNS_TRANSACTION_ABORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_query_bus_track(DnsQuery *q, sd_bus_message *m) {
|
||||
int r;
|
||||
|
||||
assert(q);
|
||||
assert(m);
|
||||
|
||||
if (!q->bus_track) {
|
||||
r = sd_bus_track_new(sd_bus_message_get_bus(m), &q->bus_track, on_bus_track, q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_track_add_sender(q->bus_track, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DnsQuestion* dns_query_question_for_protocol(DnsQuery *q, DnsProtocol protocol) {
|
||||
assert(q);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "set.h"
|
||||
#include "varlink.h"
|
||||
|
||||
typedef struct DnsQueryCandidate DnsQueryCandidate;
|
||||
typedef struct DnsQuery DnsQuery;
|
||||
@@ -48,10 +49,6 @@ struct DnsQuery {
|
||||
uint64_t flags;
|
||||
int ifindex;
|
||||
|
||||
/* If true, A or AAAA RR lookups will be suppressed on links with no routable address of the matching address
|
||||
* family */
|
||||
bool suppress_unroutable_family;
|
||||
|
||||
/* If true, the RR TTLs of the answer will be clamped by their current left validity in the cache */
|
||||
bool clamp_ttl;
|
||||
|
||||
@@ -72,8 +69,9 @@ struct DnsQuery {
|
||||
int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
|
||||
bool previous_redirect_unauthenticated;
|
||||
|
||||
/* Bus client information */
|
||||
sd_bus_message *request;
|
||||
/* Bus + Varlink client information */
|
||||
sd_bus_message *bus_request;
|
||||
Varlink *varlink_request;
|
||||
int request_family;
|
||||
bool request_address_valid;
|
||||
union in_addr_union request_address;
|
||||
@@ -116,7 +114,7 @@ void dns_query_ready(DnsQuery *q);
|
||||
|
||||
int dns_query_process_cname(DnsQuery *q);
|
||||
|
||||
int dns_query_bus_track(DnsQuery *q, sd_bus_message *m);
|
||||
void dns_query_complete(DnsQuery *q, DnsTransactionState state);
|
||||
|
||||
DnsQuestion* dns_query_question_for_protocol(DnsQuery *q, DnsProtocol protocol);
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "resolved-manager.h"
|
||||
#include "resolved-mdns.h"
|
||||
#include "resolved-resolv-conf.h"
|
||||
#include "resolved-varlink.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
@@ -663,6 +664,10 @@ int manager_start(Manager *m) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_varlink_init(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -706,6 +711,7 @@ Manager *manager_free(Manager *m) {
|
||||
manager_llmnr_stop(m);
|
||||
manager_mdns_stop(m);
|
||||
manager_dns_stub_stop(m);
|
||||
manager_varlink_done(m);
|
||||
|
||||
bus_verify_polkit_async_registry_free(m->polkit_registry);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "list.h"
|
||||
#include "ordered-set.h"
|
||||
#include "resolve-util.h"
|
||||
#include "varlink.h"
|
||||
|
||||
typedef struct Manager Manager;
|
||||
|
||||
@@ -140,6 +141,8 @@ struct Manager {
|
||||
sd_event_source *dns_stub_tcp_event_source;
|
||||
|
||||
Hashmap *polkit_registry;
|
||||
|
||||
VarlinkServer *varlink_server;
|
||||
};
|
||||
|
||||
/* Manager */
|
||||
|
||||
534
src/resolve/resolved-varlink.c
Normal file
534
src/resolve/resolved-varlink.c
Normal file
File diff suppressed because it is too large
Load Diff
7
src/resolve/resolved-varlink.h
Normal file
7
src/resolve/resolved-varlink.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "resolved-manager.h"
|
||||
|
||||
int manager_varlink_init(Manager *m);
|
||||
void manager_varlink_done(Manager *m);
|
||||
@@ -3624,6 +3624,36 @@ int json_buildv(JsonVariant **ret, va_list ap) {
|
||||
break;
|
||||
}
|
||||
|
||||
case _JSON_BUILD_BYTE_ARRAY: {
|
||||
const void *array;
|
||||
size_t n;
|
||||
|
||||
if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
array = va_arg(ap, const void*);
|
||||
n = va_arg(ap, size_t);
|
||||
|
||||
if (current->n_suppress == 0) {
|
||||
r = json_variant_new_array_bytes(&add, array, n);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
n_subtract = 1;
|
||||
|
||||
if (current->expect == EXPECT_TOPLEVEL)
|
||||
current->expect = EXPECT_END;
|
||||
else if (current->expect == EXPECT_OBJECT_VALUE)
|
||||
current->expect = EXPECT_OBJECT_KEY;
|
||||
else
|
||||
assert(current->expect == EXPECT_ARRAY_ELEMENT);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case _JSON_BUILD_OBJECT_BEGIN:
|
||||
|
||||
if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
|
||||
|
||||
@@ -228,6 +228,7 @@ enum {
|
||||
_JSON_BUILD_STRV,
|
||||
_JSON_BUILD_BASE64,
|
||||
_JSON_BUILD_ID128,
|
||||
_JSON_BUILD_BYTE_ARRAY,
|
||||
_JSON_BUILD_MAX,
|
||||
};
|
||||
|
||||
@@ -249,6 +250,7 @@ enum {
|
||||
#define JSON_BUILD_STRV(l) _JSON_BUILD_STRV, ({ char **_x = l; _x; })
|
||||
#define JSON_BUILD_BASE64(p, n) _JSON_BUILD_BASE64, ({ const void *_x = p; _x; }), ({ size_t _y = n; _y; })
|
||||
#define JSON_BUILD_ID128(id) _JSON_BUILD_ID128, ({ sd_id128_t _x = id; _x; })
|
||||
#define JSON_BUILD_BYTE_ARRAY(v, n) _JSON_BUILD_BYTE_ARRAY, ({ const void *_x = v; _x; }), ({ size_t _y = n; _y; })
|
||||
|
||||
int json_build(JsonVariant **ret, ...);
|
||||
int json_buildv(JsonVariant **ret, va_list ap);
|
||||
@@ -302,6 +304,12 @@ assert_cc(sizeof(uintmax_t) == sizeof(uint64_t));
|
||||
assert_cc(sizeof(intmax_t) == sizeof(int64_t));
|
||||
#define json_dispatch_int64 json_dispatch_integer
|
||||
|
||||
assert_cc(sizeof(uint32_t) == sizeof(unsigned));
|
||||
#define json_dispatch_uint json_dispatch_uint32
|
||||
|
||||
assert_cc(sizeof(int32_t) == sizeof(int));
|
||||
#define json_dispatch_int json_dispatch_int32
|
||||
|
||||
static inline int json_dispatch_level(JsonDispatchFlags flags) {
|
||||
|
||||
/* Did the user request no logging? If so, then never log higher than LOG_DEBUG. Also, if this is marked as
|
||||
|
||||
@@ -862,7 +862,7 @@ static int varlink_dispatch_method(Varlink *v) {
|
||||
|
||||
/* We got an error back from the callback. Propagate it to the client if the method call remains unanswered. */
|
||||
if (!FLAGS_SET(flags, VARLINK_METHOD_ONEWAY)) {
|
||||
r = varlink_errorb(v, VARLINK_ERROR_SYSTEM, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("errno", JSON_BUILD_INTEGER(-r))));
|
||||
r = varlink_error_errno(v, r);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -1659,6 +1659,13 @@ int varlink_error_invalid_parameter(Varlink *v, JsonVariant *parameters) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int varlink_error_errno(Varlink *v, int error) {
|
||||
return varlink_errorb(
|
||||
v,
|
||||
VARLINK_ERROR_SYSTEM,
|
||||
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("errno", JSON_BUILD_INTEGER(abs(error)))));
|
||||
}
|
||||
|
||||
int varlink_notify(Varlink *v, JsonVariant *parameters) {
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
|
||||
int r;
|
||||
|
||||
@@ -100,6 +100,7 @@ int varlink_replyb(Varlink *v, ...);
|
||||
int varlink_error(Varlink *v, const char *error_id, JsonVariant *parameters);
|
||||
int varlink_errorb(Varlink *v, const char *error_id, ...);
|
||||
int varlink_error_invalid_parameter(Varlink *v, JsonVariant *parameters);
|
||||
int varlink_error_errno(Varlink *v, int error);
|
||||
|
||||
/* Enqueue a "more" reply */
|
||||
int varlink_notify(Varlink *v, JsonVariant *parameters);
|
||||
|
||||
Reference in New Issue
Block a user