resolved-dns-question.c revision 34b9656f0b2890743eee6a746ef08d817abfd5e9
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering/***
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering This file is part of systemd.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering Copyright 2014 Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering systemd is free software; you can redistribute it and/or modify it
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering under the terms of the GNU Lesser General Public License as published by
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering (at your option) any later version.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering systemd is distributed in the hope that it will be useful, but
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering Lesser General Public License for more details.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering You should have received a copy of the GNU Lesser General Public License
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering***/
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek#include "resolved-dns-question.h"
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen#include "resolved-dns-domain.h"
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart PoetteringDnsQuestion *dns_question_new(unsigned n) {
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering DnsQuestion *q;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(n > 0);
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek q = malloc0(offsetof(DnsQuestion, keys) + sizeof(DnsResourceKey*) * n);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!q)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek q->n_ref = 1;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek q->n_allocated = n;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return q;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-SzmekDnsQuestion *dns_question_ref(DnsQuestion *q) {
57255510c95ca3369d241502f26d7bbd8fac30a6Lennart Poettering if (!q)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q->n_ref > 0);
a1e58e8ee1c84b633d6d6d651d5328d4dd4eba5bLennart Poettering q->n_ref++;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return q;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek}
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal SchmidtDnsQuestion *dns_question_unref(DnsQuestion *q) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!q)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return NULL;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q->n_ref > 0);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (q->n_ref == 1) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek dns_resource_key_unref(q->keys[i]);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek free(q);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek } else
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek q->n_ref--;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint dns_question_add(DnsQuestion *q, DnsResourceKey *key) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q);
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt assert(key);
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = dns_resource_key_equal(q->keys[i], key);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r > 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (q->n_keys >= q->n_allocated)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return -ENOSPC;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek q->keys[q->n_keys++] = dns_resource_key_ref(key);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(rr);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++) {
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt r = dns_resource_key_match_rr(q->keys[i], rr);
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt if (r != 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint dns_question_matches_cname(DnsQuestion *q, DnsResourceRecord *rr) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(rr);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = dns_resource_key_match_cname(q->keys[i], rr);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r != 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint dns_question_is_valid(DnsQuestion *q) {
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt const char *name;
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q);
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (q->n_keys <= 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (q->n_keys > 65535)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek name = DNS_RESOURCE_KEY_NAME(q->keys[0]);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!name)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* Check that all keys in this question bear the same name */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 1; i < q->n_keys; i++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q->keys[i]);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r <= 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 1;
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt}
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidtint dns_question_is_superset(DnsQuestion *q, DnsQuestion *other) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned j;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(other);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* Checks if all keys in "other" are also contained in "q" */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (j = 0; j < other->n_keys; j++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek DnsResourceKey *b = other->keys[j];
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek bool found = false;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek DnsResourceKey *a = q->keys[i];
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r == 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek continue;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (a->class != b->class && a->class != DNS_CLASS_ANY)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek continue;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (a->type != b->type && a->type != DNS_TYPE_ANY)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek continue;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek found = true;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek break;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!found)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 1;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **ret) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_(dns_question_unrefp) DnsQuestion *n = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek bool same = true;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(name);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(ret);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r == 0) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek same = false;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek break;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (same) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* Shortcut, the names are already right */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek *ret = dns_question_ref(q);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek n = dns_question_new(q->n_keys);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!n)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return -ENOMEM;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* Create a new question, and patch in the new name */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_(dns_resource_key_unrefp) DnsResourceKey *k = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek k = dns_resource_key_new(q->keys[i]->class, q->keys[i]->type, name);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!k)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return -ENOMEM;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = dns_question_add(n, k);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek *ret = n;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek n = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 1;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint dns_question_endswith(DnsQuestion *q, const char *suffix) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(suffix);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int k;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek k = dns_name_endswith(DNS_RESOURCE_KEY_NAME(q->keys[i]), suffix);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (k <= 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return k;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 1;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint dns_question_extract_reverse_address(DnsQuestion *q, int *family, union in_addr_union *address) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned i;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(q);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(family);
c33b329709ebe2755181980a050d02ec7c81ed87Michal Schmidt assert(address);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (i = 0; i < q->n_keys; i++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int k;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek k = dns_name_address(DNS_RESOURCE_KEY_NAME(q->keys[i]), family, address);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (k != 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return k;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek