resolved-dns-question.c revision 45ec7efb6c2560c80dfa752bc9d3733749dc52cb
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering/***
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering This file is part of systemd.
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering Copyright 2014 Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering systemd is free software; you can redistribute it and/or modify it
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering under the terms of the GNU Lesser General Public License as published by
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering (at your option) any later version.
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering systemd is distributed in the hope that it will be useful, but
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering Lesser General Public License for more details.
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering You should have received a copy of the GNU Lesser General Public License
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering***/
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering#include "alloc-util.h"
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering#include "dns-domain.h"
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering#include "resolved-dns-question.h"
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart PoetteringDnsQuestion *dns_question_new(unsigned n) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering DnsQuestion *q;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(n > 0);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering q = malloc0(offsetof(DnsQuestion, keys) + sizeof(DnsResourceKey*) * n);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return NULL;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering q->n_ref = 1;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering q->n_allocated = n;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return q;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart PoetteringDnsQuestion *dns_question_ref(DnsQuestion *q) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return NULL;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(q->n_ref > 0);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering q->n_ref++;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return q;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart PoetteringDnsQuestion *dns_question_unref(DnsQuestion *q) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return NULL;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(q->n_ref > 0);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (q->n_ref == 1) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned i;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (i = 0; i < q->n_keys; i++)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering dns_resource_key_unref(q->keys[i]);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering free(q);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering } else
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering q->n_ref--;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return NULL;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringint dns_question_add(DnsQuestion *q, DnsResourceKey *key) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned i;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering int r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(key);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return -ENOSPC;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (i = 0; i < q->n_keys; i++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = dns_resource_key_equal(q->keys[i], key);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r < 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r > 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (q->n_keys >= q->n_allocated)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return -ENOSPC;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering q->keys[q->n_keys++] = dns_resource_key_ref(key);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringint dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned i;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering int r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(rr);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (i = 0; i < q->n_keys; i++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = dns_resource_key_match_rr(q->keys[i], rr);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r != 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringint dns_question_matches_cname(DnsQuestion *q, DnsResourceRecord *rr) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned i;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering int r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(rr);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (i = 0; i < q->n_keys; i++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = dns_resource_key_match_cname(q->keys[i], rr);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r != 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
c90feab4ff8bc23d88d4f9c67d9652ba189cb51bMichal Schmidt return 0;
c90feab4ff8bc23d88d4f9c67d9652ba189cb51bMichal Schmidt}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringint dns_question_is_valid(DnsQuestion *q) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering const char *name;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned i;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering int r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (q->n_keys <= 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
c90feab4ff8bc23d88d4f9c67d9652ba189cb51bMichal Schmidt
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (q->n_keys > 65535)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
c90feab4ff8bc23d88d4f9c67d9652ba189cb51bMichal Schmidt
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering name = DNS_RESOURCE_KEY_NAME(q->keys[0]);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!name)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering /* Check that all keys in this question bear the same name */
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (i = 1; i < q->n_keys; i++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(q->keys[i]);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r <= 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 1;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringint dns_question_is_superset(DnsQuestion *q, DnsQuestion *other) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned j;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering int r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering /* Checks if all keys in "other" are also contained in "q" */
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!other)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 1;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (j = 0; j < other->n_keys; j++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering DnsResourceKey *b = other->keys[j];
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering bool found = false;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned i;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (i = 0; i < q->n_keys; i++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering DnsResourceKey *a = q->keys[i];
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r < 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r == 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering continue;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (a->class != b->class && a->class != DNS_CLASS_ANY)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering continue;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (a->type != b->type && a->type != DNS_TYPE_ANY)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering continue;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering found = true;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering break;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!found)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 1;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringint dns_question_contains(DnsQuestion *a, DnsResourceKey *k) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned j;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering int r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(k);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!a)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (j = 0; j < a->n_keys; j++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = dns_resource_key_equal(a->keys[j], k);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r != 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringint dns_question_is_equal(DnsQuestion *a, DnsQuestion *b) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned j;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering int r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!a)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return !b || b->n_keys == 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!b)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return a->n_keys == 0;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering /* Checks if all keys in a are also contained b, and vice versa */
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (j = 0; j < a->n_keys; j++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = dns_question_contains(b, a->keys[j]);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r <= 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering for (j = 0; j < b->n_keys; j++) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = dns_question_contains(a, b->keys[j]);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (r <= 0)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering }
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return 1;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering}
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringint dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname, DnsQuestion **ret) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *n = NULL;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering bool same = true;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering unsigned i;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering int r;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(cname);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert(ret);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!q) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering n = dns_question_new(0);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (!n)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return -ENOMEM;
*ret = n;
n = 0;
return 0;
}
for (i = 0; i < q->n_keys; i++) {
r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), cname->cname.name);
if (r < 0)
return r;
if (r == 0) {
same = false;
break;
}
}
if (same) {
/* Shortcut, the names are already right */
*ret = dns_question_ref(q);
return 0;
}
n = dns_question_new(q->n_keys);
if (!n)
return -ENOMEM;
/* Create a new question, and patch in the new name */
for (i = 0; i < q->n_keys; i++) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *k = NULL;
k = dns_resource_key_new_redirect(q->keys[i], cname);
if (!k)
return -ENOMEM;
r = dns_question_add(n, k);
if (r < 0)
return r;
}
*ret = n;
n = NULL;
return 1;
}
const char *dns_question_name(DnsQuestion *q) {
assert(q);
if (q->n_keys < 1)
return NULL;
return DNS_RESOURCE_KEY_NAME(q->keys[0]);
}
int dns_question_new_address(DnsQuestion **ret, int family, const char *name) {
_cleanup_(dns_question_unrefp) DnsQuestion *q = NULL;
int r;
assert(ret);
assert(name);
if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
return -EAFNOSUPPORT;
q = dns_question_new(family == AF_UNSPEC ? 2 : 1);
if (!q)
return -ENOMEM;
if (family != AF_INET6) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, name);
if (!key)
return -ENOMEM;
r = dns_question_add(q, key);
if (r < 0)
return r;
}
if (family != AF_INET) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, name);
if (!key)
return -ENOMEM;
r = dns_question_add(q, key);
if (r < 0)
return r;
}
*ret = q;
q = NULL;
return 0;
}
int dns_question_new_reverse(DnsQuestion **ret, int family, const union in_addr_union *a) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
_cleanup_(dns_question_unrefp) DnsQuestion *q = NULL;
_cleanup_free_ char *reverse = NULL;
int r;
assert(ret);
assert(a);
if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
return -EAFNOSUPPORT;
r = dns_name_reverse(family, a, &reverse);
if (r < 0)
return r;
q = dns_question_new(1);
if (!q)
return -ENOMEM;
key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, reverse);
if (!key)
return -ENOMEM;
reverse = NULL;
r = dns_question_add(q, key);
if (r < 0)
return r;
*ret = q;
q = NULL;
return 0;
}
int dns_question_new_service(DnsQuestion **ret, const char *name, bool with_txt) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
_cleanup_(dns_question_unrefp) DnsQuestion *q = NULL;
int r;
assert(ret);
assert(name);
q = dns_question_new(1 + with_txt);
if (!q)
return -ENOMEM;
key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SRV, name);
if (!key)
return -ENOMEM;
r = dns_question_add(q, key);
if (r < 0)
return r;
if (with_txt) {
dns_resource_key_unref(key);
key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_TXT, name);
if (!key)
return -ENOMEM;
r = dns_question_add(q, key);
if (r < 0)
return r;
}
*ret = q;
q = NULL;
return 0;
}