/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "alloc-util.h"
#include "env-util.h"
#include "hostname-util.h"
#include "local-addresses.h"
#include "missing_network.h"
#include "resolved-dns-synthesize.h"

int dns_synthesize_family(uint64_t flags) {

        /* Picks an address family depending on set flags. This is
         * purely for synthesized answers, where the family we return
         * for the reply should match what was requested in the
         * question, even though we are synthesizing the answer
         * here. */

        if (!(flags & SD_RESOLVED_DNS)) {
                if (flags & (SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_MDNS_IPV4))
                        return AF_INET;
                if (flags & (SD_RESOLVED_LLMNR_IPV6|SD_RESOLVED_MDNS_IPV6))
                        return AF_INET6;
        }

        return AF_UNSPEC;
}

DnsProtocol dns_synthesize_protocol(uint64_t flags) {

        /* Similar as dns_synthesize_family() but does this for the
         * protocol. If resolving via DNS was requested, we claim it
         * was DNS. Similar, if nothing specific was
         * requested. However, if only resolving via LLMNR was
         * requested we return that. */

        if (flags & SD_RESOLVED_DNS)
                return DNS_PROTOCOL_DNS;
        if (flags & SD_RESOLVED_LLMNR)
                return DNS_PROTOCOL_LLMNR;
        if (flags & SD_RESOLVED_MDNS)
                return DNS_PROTOCOL_MDNS;

        return DNS_PROTOCOL_DNS;
}

static int synthesize_localhost_rr(Manager *m, const DnsResourceKey *key, DnsAnswer **answer) {
        int r;

        assert(m);
        assert(key);
        assert(answer);

        r = dns_answer_reserve(answer, 2);
        if (r < 0)
                return r;

        if (IN_SET(key->type, DNS_TYPE_A, DNS_TYPE_ANY)) {
                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;

                rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, dns_resource_key_name(key));
                if (!rr)
                        return -ENOMEM;

                rr->a.in_addr.s_addr = htobe32(INADDR_LOOPBACK);

                r = dns_answer_add(*answer, rr, LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED, NULL);
                if (r < 0)
                        return r;
        }

        if (IN_SET(key->type, DNS_TYPE_AAAA, DNS_TYPE_ANY) && socket_ipv6_is_enabled()) {
                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;

                rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_AAAA, dns_resource_key_name(key));
                if (!rr)
                        return -ENOMEM;

                rr->aaaa.in6_addr = in6addr_loopback;

                r = dns_answer_add(*answer, rr, LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED, NULL);
                if (r < 0)
                        return r;
        }

        return 0;
}

static int answer_add_ptr(DnsAnswer **answer, const char *from, const char *to, int ifindex, DnsAnswerFlags flags) {
        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;

        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_PTR, from);
        if (!rr)
                return -ENOMEM;

        rr->ptr.name = strdup(to);
        if (!rr->ptr.name)
                return -ENOMEM;

        return dns_answer_add(*answer, rr, ifindex, flags, NULL);
}

static int synthesize_localhost_ptr(Manager *m, const DnsResourceKey *key, DnsAnswer **answer) {
        int r;

        assert(m);
        assert(key);
        assert(answer);

        if (IN_SET(key->type, DNS_TYPE_PTR, DNS_TYPE_ANY)) {
                r = dns_answer_reserve(answer, 1);
                if (r < 0)
                        return r;

                r = answer_add_ptr(answer, dns_resource_key_name(key), "localhost", LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED);
                if (r < 0)
                        return r;
        }

        return 0;
}

static int answer_add_addresses_rr(
                DnsAnswer **answer,
                const char *name,
                struct local_address *addresses,
                unsigned n_addresses) {

        unsigned j;
        int r;

        assert(answer);
        assert(name);

        r = dns_answer_reserve(answer, n_addresses);
        if (r < 0)
                return r;

        for (j = 0; j < n_addresses; j++) {
                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;

                r = dns_resource_record_new_address(&rr, addresses[j].family, &addresses[j].address, name);
                if (r < 0)
                        return r;

                r = dns_answer_add(*answer, rr, addresses[j].ifindex, DNS_ANSWER_AUTHENTICATED, NULL);
                if (r < 0)
                        return r;
        }

        return 0;
}

static int answer_add_addresses_ptr(
                DnsAnswer **answer,
                const char *name,
                struct local_address *addresses,
                unsigned n_addresses,
                int af, const union in_addr_union *match) {

        bool added = false;
        unsigned j;
        int r;

        assert(answer);
        assert(name);

        for (j = 0; j < n_addresses; j++) {
                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;

                if (af != AF_UNSPEC) {

                        if (addresses[j].family != af)
                                continue;

                        if (match && !in_addr_equal(af, match, &addresses[j].address))
                                continue;
                }

                r = dns_answer_reserve(answer, 1);
                if (r < 0)
                        return r;

                r = dns_resource_record_new_reverse(&rr, addresses[j].family, &addresses[j].address, name);
                if (r < 0)
                        return r;

                r = dns_answer_add(*answer, rr, addresses[j].ifindex, DNS_ANSWER_AUTHENTICATED, NULL);
                if (r < 0)
                        return r;

                added = true;
        }

        return added;
}

static int synthesize_system_hostname_rr(Manager *m, const DnsResourceKey *key, int ifindex, DnsAnswer **answer) {
        _cleanup_free_ struct local_address *addresses = NULL;
        int n = 0, af;

        assert(m);
        assert(key);
        assert(answer);

        af = dns_type_to_af(key->type);
        if (af >= 0) {
                n = local_addresses(m->rtnl, ifindex, af, &addresses);
                if (n < 0)
                        return n;

                if (n == 0) {
                        struct local_address buffer[2];

                        /* If we have no local addresses then use ::1 and 127.0.0.2 as local ones. */

                        if (IN_SET(af, AF_INET, AF_UNSPEC))
                                buffer[n++] = (struct local_address) {
                                        .family = AF_INET,
                                        .ifindex = LOOPBACK_IFINDEX,
                                        .address.in.s_addr = htobe32(INADDR_LOCALADDRESS),
                                };

                        if (IN_SET(af, AF_INET6, AF_UNSPEC) && socket_ipv6_is_enabled())
                                buffer[n++] = (struct local_address) {
                                        .family = AF_INET6,
                                        .ifindex = LOOPBACK_IFINDEX,
                                        .address.in6 = in6addr_loopback,
                                };

                        return answer_add_addresses_rr(answer,
                                                       dns_resource_key_name(key),
                                                       buffer, n);
                }
        }

        return answer_add_addresses_rr(answer, dns_resource_key_name(key), addresses, n);
}

static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_addr_union *address, int ifindex, DnsAnswer **answer) {
        _cleanup_free_ struct local_address *addresses = NULL;
        bool added = false;
        int n, r;

        assert(m);
        assert(address);
        assert(answer);

        if (af == AF_INET && address->in.s_addr == htobe32(INADDR_LOCALADDRESS)) {

                /* Always map the IPv4 address 127.0.0.2 to the local hostname, in addition to "localhost": */

                r = dns_answer_reserve(answer, 4);
                if (r < 0)
                        return r;

                r = answer_add_ptr(answer, "2.0.0.127.in-addr.arpa", m->full_hostname, LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED);
                if (r < 0)
                        return r;

                r = answer_add_ptr(answer, "2.0.0.127.in-addr.arpa", m->llmnr_hostname, LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED);
                if (r < 0)
                        return r;

                r = answer_add_ptr(answer, "2.0.0.127.in-addr.arpa", m->mdns_hostname, LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED);
                if (r < 0)
                        return r;

                r = answer_add_ptr(answer, "2.0.0.127.in-addr.arpa", "localhost", LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED);
                if (r < 0)
                        return r;

                return 1;
        }

        n = local_addresses(m->rtnl, ifindex, af, &addresses);
        if (n <= 0)
                return n;

        r = answer_add_addresses_ptr(answer, m->full_hostname, addresses, n, af, address);
        if (r < 0)
                return r;
        if (r > 0)
                added = true;

        r = answer_add_addresses_ptr(answer, m->llmnr_hostname, addresses, n, af, address);
        if (r < 0)
                return r;
        if (r > 0)
                added = true;

        r = answer_add_addresses_ptr(answer, m->mdns_hostname, addresses, n, af, address);
        if (r < 0)
                return r;
        if (r > 0)
                added = true;

        return added;
}

static int synthesize_gateway_rr(
                Manager *m,
                const DnsResourceKey *key,
                int ifindex,
                int (*lookup)(sd_netlink *context, int ifindex, int af, struct local_address **ret), /* either local_gateways() or local_outbound() */
                DnsAnswer **answer) {
        _cleanup_free_ struct local_address *addresses = NULL;
        int n = 0, af, r;

        assert(m);
        assert(key);
        assert(lookup);
        assert(answer);

        af = dns_type_to_af(key->type);
        if (af >= 0) {
                n = lookup(m->rtnl, ifindex, af, &addresses);
                if (n < 0) /* < 0 means: error */
                        return n;

                if (n == 0) { /* == 0 means we have no gateway */
                        /* See if there's a gateway on the other protocol */
                        if (af == AF_INET)
                                n = lookup(m->rtnl, ifindex, AF_INET6, NULL);
                        else {
                                assert(af == AF_INET6);
                                n = lookup(m->rtnl, ifindex, AF_INET, NULL);
                        }
                        if (n <= 0) /* error (if < 0) or really no gateway at all (if == 0) */
                                return n;

                        /* We have a gateway on the other protocol. Let's return > 0 without adding any RR to
                         * the answer, i.e. synthesize NODATA (and not NXDOMAIN!) */
                        return 1;
                }
        }

        r = answer_add_addresses_rr(answer, dns_resource_key_name(key), addresses, n);
        if (r < 0)
                return r;

        return 1; /* > 0 means: we have some gateway */
}

static int synthesize_dns_stub_rr(
                Manager *m,
                const DnsResourceKey *key,
                in_addr_t addr,
                DnsAnswer **answer) {

        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
        int r;

        assert(m);
        assert(key);
        assert(answer);

        if (!IN_SET(key->type, DNS_TYPE_A, DNS_TYPE_ANY))
                return 1; /* we still consider ourselves the owner of this name */

        r = dns_answer_reserve(answer, 1);
        if (r < 0)
                return r;

        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, dns_resource_key_name(key));
        if (!rr)
                return -ENOMEM;

        rr->a.in_addr.s_addr = htobe32(addr);

        r = dns_answer_add(*answer, rr, LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED, NULL);
        if (r < 0)
                return r;

        return 1;
}

static int synthesize_dns_stub_ptr(
                Manager *m,
                int af,
                const union in_addr_union *address,
                DnsAnswer **answer) {

        int r;

        assert(m);
        assert(address);
        assert(answer);

        if (af != AF_INET)
                return 0;

        if (address->in.s_addr == htobe32(INADDR_DNS_STUB)) {

                r = dns_answer_reserve(answer, 1);
                if (r < 0)
                        return r;

                r = answer_add_ptr(answer, "53.0.0.127.in-addr.arpa", "_localdnsstub", LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED);
                if (r < 0)
                        return r;

                return 1;
        }

        if (address->in.s_addr == htobe32(INADDR_DNS_PROXY_STUB)) {

                r = dns_answer_reserve(answer, 1);
                if (r < 0)
                        return r;

                r = answer_add_ptr(answer, "54.0.0.127.in-addr.arpa", "_localdnsproxy", LOOPBACK_IFINDEX, DNS_ANSWER_AUTHENTICATED);
                if (r < 0)
                        return r;

                return 1;
        }

        return 0;
}

static int synthesize_gateway_ptr(
                Manager *m,
                int af,
                const union in_addr_union *address,
                int ifindex,
                DnsAnswer **answer) {

        _cleanup_free_ struct local_address *addresses = NULL;
        int n;

        assert(m);
        assert(address);
        assert(answer);

        n = local_gateways(m->rtnl, ifindex, af, &addresses);
        if (n <= 0)
                return n;

        return answer_add_addresses_ptr(answer, "_gateway", addresses, n, af, address);
}

int dns_synthesize_answer(
                Manager *m,
                DnsQuestion *q,
                int ifindex,
                DnsAnswer **ret) {

        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
        DnsResourceKey *key;
        bool found = false, nxdomain = false;
        int r;

        assert(m);
        assert(q);

        DNS_QUESTION_FOREACH(key, q) {
                union in_addr_union address;
                const char *name;
                int af;

                if (!IN_SET(key->class, DNS_CLASS_IN, DNS_CLASS_ANY))
                        continue;

                name = dns_resource_key_name(key);

                if (dns_name_is_root(name)) {
                        /* Do nothing. */

                } else if (dns_name_dont_resolve(name)) {
                        /* Synthesize NXDOMAIN for some of the domains in RFC6303 + RFC6761 */
                        nxdomain = true;
                        continue;

                } else if (is_localhost(name)) {

                        r = synthesize_localhost_rr(m, key, &answer);
                        if (r < 0)
                                return log_error_errno(r, "Failed to synthesize localhost RRs: %m");

                } else if (manager_is_own_hostname(m, name)) {

                        if (getenv_bool("SYSTEMD_RESOLVED_SYNTHESIZE_HOSTNAME") == 0)
                                continue;
                        r = synthesize_system_hostname_rr(m, key, ifindex, &answer);
                        if (r < 0)
                                return log_error_errno(r, "Failed to synthesize system hostname RRs: %m");

                } else if (is_gateway_hostname(name)) {

                        r = synthesize_gateway_rr(m, key, ifindex, local_gateways, &answer);
                        if (r < 0)
                                return log_error_errno(r, "Failed to synthesize gateway RRs: %m");
                        if (r == 0) { /* if we have no gateway return NXDOMAIN */
                                nxdomain = true;
                                continue;
                        }

                } else if (is_outbound_hostname(name)) {

                        r = synthesize_gateway_rr(m, key, ifindex, local_outbounds, &answer);
                        if (r < 0)
                                return log_error_errno(r, "Failed to synthesize outbound RRs: %m");
                        if (r == 0) { /* if we have no gateway return NXDOMAIN */
                                nxdomain = true;
                                continue;
                        }

                } else if (is_dns_stub_hostname(name)) {

                        r = synthesize_dns_stub_rr(m, key, INADDR_DNS_STUB, &answer);
                        if (r < 0)
                                return log_error_errno(r, "Failed to synthesize local DNS stub RRs: %m");

                } else if (is_dns_proxy_stub_hostname(name)) {

                        r = synthesize_dns_stub_rr(m, key, INADDR_DNS_PROXY_STUB, &answer);
                        if (r < 0)
                                return log_error_errno(r, "Failed to synthesize local DNS stub RRs: %m");

                } else if ((dns_name_endswith(name, "127.in-addr.arpa") > 0 &&
                            dns_name_equal(name, "2.0.0.127.in-addr.arpa") == 0 &&
                            dns_name_equal(name, "53.0.0.127.in-addr.arpa") == 0 &&
                            dns_name_equal(name, "54.0.0.127.in-addr.arpa") == 0) ||
                           dns_name_equal(name, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0) {

                        r = synthesize_localhost_ptr(m, key, &answer);
                        if (r < 0)
                                return log_error_errno(r, "Failed to synthesize localhost PTR RRs: %m");

                } else if (dns_name_address(name, &af, &address) > 0) {
                        int v, w, u;

                        if (getenv_bool("SYSTEMD_RESOLVED_SYNTHESIZE_HOSTNAME") == 0)
                                continue;

                        v = synthesize_system_hostname_ptr(m, af, &address, ifindex, &answer);
                        if (v < 0)
                                return log_error_errno(v, "Failed to synthesize system hostname PTR RR: %m");

                        w = synthesize_gateway_ptr(m, af, &address, ifindex, &answer);
                        if (w < 0)
                                return log_error_errno(w, "Failed to synthesize gateway hostname PTR RR: %m");

                        u = synthesize_dns_stub_ptr(m, af, &address, &answer);
                        if (u < 0)
                                return log_error_errno(u, "Failed to synthesize local stub hostname PTR PR: %m");

                        if (v == 0 && w == 0 && u == 0) /* This IP address is neither a local one, nor a gateway, nor a stub address */
                                continue;

                        /* Note that we never synthesize reverse PTR for _outbound, since those are local
                         * addresses and thus mapped to the local hostname anyway, hence they already have a
                         * mapping. */

                } else
                        continue;

                found = true;
        }

        if (found) {

                if (ret)
                        *ret = TAKE_PTR(answer);

                return 1;
        } else if (nxdomain)
                return -ENXIO;

        return 0;
}
