static int reply_query_state(DnsQuery *q) {
+ assert(q);
+ assert(q->bus_request);
+
switch (q->state) {
case DNS_TRANSACTION_NO_SERVERS:
_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;
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)
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,
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");
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;
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;
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;
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)
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;