Merge pull request #16757 from poettering/nss-resolve-varlink

resolved: use varlink for communication between nss-resolve and resolved
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2020-08-26 22:07:34 +02:00
committed by GitHub
14 changed files with 1035 additions and 390 deletions

View File

@@ -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

View File

@@ -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('''

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 */

File diff suppressed because it is too large Load Diff

View 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);

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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;

View File

@@ -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);