int dns_trust_anchor_lookup(DnsTrustAnchor *d, DnsResourceKey *key, DnsAnswer **ret) { DnsAnswer *a; assert(d); assert(key); assert(ret); /* We only serve DS and DNSKEY RRs. */ if (!IN_SET(key->type, DNS_TYPE_DS, DNS_TYPE_DNSKEY)) return 0; a = hashmap_get(d->by_key, key); if (!a) return 0; *ret = dns_answer_ref(a); return 1; }
static void bus_method_resolve_address_complete(DnsQuery *q) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; unsigned added = 0, i; int r; assert(q); if (q->state != DNS_TRANSACTION_SUCCESS) { r = reply_query_state(q); goto finish; } r = sd_bus_message_new_method_return(q->request, &reply); if (r < 0) goto finish; r = sd_bus_message_append(reply, "i", q->answer_ifindex); if (r < 0) goto finish; r = sd_bus_message_open_container(reply, 'a', "s"); if (r < 0) goto finish; if (q->answer) { answer = dns_answer_ref(q->answer); for (i = 0; i < answer->n_rrs; i++) { r = dns_question_matches_rr(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r == 0) continue; r = sd_bus_message_append(reply, "s", answer->rrs[i]->ptr.name); if (r < 0) goto finish; added ++; } } if (added <= 0) { _cleanup_free_ char *ip = NULL; in_addr_to_string(q->request_family, &q->request_address, &ip); r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", ip); goto finish; } r = sd_bus_message_close_container(reply); if (r < 0) goto finish; r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family)); if (r < 0) goto finish; r = sd_bus_send(q->manager->bus, reply, NULL); finish: if (r < 0) { log_error_errno(r, "Failed to send address reply: %m"); sd_bus_reply_method_errno(q->request, -r, NULL); } dns_query_free(q); }
static void bus_method_resolve_record_complete(DnsQuery *q) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; unsigned added = 0, i; int r; assert(q); if (q->state != DNS_TRANSACTION_SUCCESS) { r = reply_query_state(q); goto finish; } r = sd_bus_message_new_method_return(q->request, &reply); if (r < 0) goto finish; r = sd_bus_message_append(reply, "i", q->answer_ifindex); if (r < 0) goto finish; r = sd_bus_message_open_container(reply, 'a', "(qqay)"); if (r < 0) goto finish; if (q->answer) { answer = dns_answer_ref(q->answer); for (i = 0; i < answer->n_rrs; i++) { _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; size_t start; r = dns_question_matches_rr(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r == 0) continue; r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0); if (r < 0) goto finish; r = dns_packet_append_rr(p, answer->rrs[i], &start); if (r < 0) goto finish; r = sd_bus_message_open_container(reply, 'r', "qqay"); if (r < 0) goto finish; r = sd_bus_message_append(reply, "qq", answer->rrs[i]->key->class, answer->rrs[i]->key->type); if (r < 0) goto finish; r = sd_bus_message_append_array(reply, 'y', DNS_PACKET_DATA(p) + start, p->size - start); if (r < 0) goto finish; r = sd_bus_message_close_container(reply); if (r < 0) goto finish; added ++; } }
static void bus_method_resolve_hostname_complete(DnsQuery *q) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *canonical = NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; unsigned added = 0, i; int r; assert(q); if (q->state != DNS_TRANSACTION_SUCCESS) { r = reply_query_state(q); goto finish; } r = sd_bus_message_new_method_return(q->request, &reply); if (r < 0) goto finish; r = sd_bus_message_append(reply, "i", q->answer_ifindex); if (r < 0) goto finish; r = sd_bus_message_open_container(reply, 'a', "(iay)"); if (r < 0) goto finish; if (q->answer) { answer = dns_answer_ref(q->answer); for (i = 0; i < answer->n_rrs; i++) { r = dns_question_matches_rr(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r == 0) { /* Hmm, if this is not an address record, maybe it's a cname? If so, remember this */ r = dns_question_matches_cname(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r > 0) cname = dns_resource_record_ref(answer->rrs[i]); continue; } r = append_address(reply, answer->rrs[i]); if (r < 0) goto finish; if (!canonical) canonical = dns_resource_record_ref(answer->rrs[i]); added ++; } } if (added <= 0) { if (!cname) { r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of requested type", q->request_hostname); goto finish; } /* This has a cname? Then update the query with the * new cname. */ r = dns_query_cname_redirect(q, cname->cname.name); if (r < 0) { if (r == -ELOOP) r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname); else r = sd_bus_reply_method_errno(q->request, -r, NULL); goto finish; } /* Before we restart the query, let's see if any of * the RRs we already got already answers our query */ for (i = 0; i < answer->n_rrs; i++) { r = dns_question_matches_rr(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r == 0) continue; r = append_address(reply, answer->rrs[i]); if (r < 0) goto finish; if (!canonical) canonical = dns_resource_record_ref(answer->rrs[i]); added++; } /* If we didn't find anything, then let's restart the * query, this time with the cname */ if (added <= 0) { r = dns_query_go(q); if (r == -ESRCH) { r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found"); goto finish; } if (r < 0) { r = sd_bus_reply_method_errno(q->request, -r, NULL); goto finish; } return; } } r = sd_bus_message_close_container(reply); if (r < 0) goto finish; /* Return the precise spelling and uppercasing reported by the server */ assert(canonical); r = sd_bus_message_append(reply, "st", DNS_RESOURCE_KEY_NAME(canonical->key), SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family)); if (r < 0) goto finish; r = sd_bus_send(q->manager->bus, reply, NULL); finish: if (r < 0) { log_error_errno(r, "Failed to send hostname reply: %m"); sd_bus_reply_method_errno(q->request, -r, NULL); } dns_query_free(q); }