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

#include <fcntl.h>
#include <netinet/in.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "af-list.h"
#include "alloc-util.h"
#include "bus-polkit.h"
#include "dirent-util.h"
#include "dns-domain.h"
#include "fd-util.h"
#include "fileio.h"
#include "hostname-util.h"
#include "idn-util.h"
#include "io-util.h"
#include "missing_network.h"
#include "missing_socket.h"
#include "netlink-util.h"
#include "ordered-set.h"
#include "parse-util.h"
#include "random-util.h"
#include "resolved-bus.h"
#include "resolved-conf.h"
#include "resolved-dns-stub.h"
#include "resolved-dnssd.h"
#include "resolved-etc-hosts.h"
#include "resolved-llmnr.h"
#include "resolved-manager.h"
#include "resolved-mdns.h"
#include "resolved-resolv-conf.h"
#include "resolved-util.h"
#include "resolved-varlink.h"
#include "socket-util.h"
#include "string-table.h"
#include "string-util.h"
#include "utf8.h"

#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)

static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
        Manager *m = userdata;
        uint16_t type;
        Link *l;
        int ifindex, r;

        assert(rtnl);
        assert(m);
        assert(mm);

        r = sd_netlink_message_get_type(mm, &type);
        if (r < 0)
                goto fail;

        r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
        if (r < 0)
                goto fail;

        l = hashmap_get(m->links, INT_TO_PTR(ifindex));

        switch (type) {

        case RTM_NEWLINK:{
                bool is_new = !l;

                if (!l) {
                        r = link_new(m, &l, ifindex);
                        if (r < 0)
                                goto fail;
                }

                r = link_process_rtnl(l, mm);
                if (r < 0)
                        goto fail;

                r = link_update(l);
                if (r < 0)
                        goto fail;

                if (is_new)
                        log_debug("Found new link %i/%s", ifindex, l->ifname);

                break;
        }

        case RTM_DELLINK:
                if (l) {
                        log_debug("Removing link %i/%s", l->ifindex, l->ifname);
                        link_remove_user(l);
                        link_free(l);
                }

                break;
        }

        return 0;

fail:
        log_warning_errno(r, "Failed to process RTNL link message: %m");
        return 0;
}

static int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
        Manager *m = userdata;
        union in_addr_union address;
        uint16_t type;
        int r, ifindex, family;
        LinkAddress *a;
        Link *l;

        assert(rtnl);
        assert(mm);
        assert(m);

        r = sd_netlink_message_get_type(mm, &type);
        if (r < 0)
                goto fail;

        r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
        if (r < 0)
                goto fail;

        l = hashmap_get(m->links, INT_TO_PTR(ifindex));
        if (!l)
                return 0;

        r = sd_rtnl_message_addr_get_family(mm, &family);
        if (r < 0)
                goto fail;

        switch (family) {

        case AF_INET:
                r = sd_netlink_message_read_in_addr(mm, IFA_LOCAL, &address.in);
                if (r < 0) {
                        r = sd_netlink_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
                        if (r < 0)
                                goto fail;
                }

                break;

        case AF_INET6:
                r = sd_netlink_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
                if (r < 0) {
                        r = sd_netlink_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
                        if (r < 0)
                                goto fail;
                }

                break;

        default:
                return 0;
        }

        a = link_find_address(l, family, &address);

        switch (type) {

        case RTM_NEWADDR:

                if (!a) {
                        r = link_address_new(l, &a, family, &address);
                        if (r < 0)
                                return r;
                }

                r = link_address_update_rtnl(a, mm);
                if (r < 0)
                        return r;

                break;

        case RTM_DELADDR:
                link_address_free(a);
                break;
        }

        return 0;

fail:
        log_warning_errno(r, "Failed to process RTNL address message: %m");
        return 0;
}

static int manager_rtnl_listen(Manager *m) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
        sd_netlink_message *i;
        int r;

        assert(m);

        /* First, subscribe to interfaces coming and going */
        r = sd_netlink_open(&m->rtnl);
        if (r < 0)
                return r;

        r = sd_netlink_attach_event(m->rtnl, m->event, SD_EVENT_PRIORITY_IMPORTANT);
        if (r < 0)
                return r;

        r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, manager_process_link, NULL, m, "resolve-NEWLINK");
        if (r < 0)
                return r;

        r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, manager_process_link, NULL, m, "resolve-DELLINK");
        if (r < 0)
                return r;

        r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, manager_process_address, NULL, m, "resolve-NEWADDR");
        if (r < 0)
                return r;

        r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, manager_process_address, NULL, m, "resolve-DELADDR");
        if (r < 0)
                return r;

        /* Then, enumerate all links */
        r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
        if (r < 0)
                return r;

        r = sd_netlink_message_request_dump(req, true);
        if (r < 0)
                return r;

        r = sd_netlink_call(m->rtnl, req, 0, &reply);
        if (r < 0)
                return r;

        for (i = reply; i; i = sd_netlink_message_next(i)) {
                r = manager_process_link(m->rtnl, i, m);
                if (r < 0)
                        return r;
        }

        req = sd_netlink_message_unref(req);
        reply = sd_netlink_message_unref(reply);

        /* Finally, enumerate all addresses, too */
        r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
        if (r < 0)
                return r;

        r = sd_netlink_message_request_dump(req, true);
        if (r < 0)
                return r;

        r = sd_netlink_call(m->rtnl, req, 0, &reply);
        if (r < 0)
                return r;

        for (i = reply; i; i = sd_netlink_message_next(i)) {
                r = manager_process_address(m->rtnl, i, m);
                if (r < 0)
                        return r;
        }

        return r;
}

static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
        Manager *m = userdata;
        Link *l;
        int r;

        assert(m);

        sd_network_monitor_flush(m->network_monitor);

        HASHMAP_FOREACH(l, m->links) {
                r = link_update(l);
                if (r < 0)
                        log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
        }

        (void) manager_write_resolv_conf(m);
        (void) manager_send_changed(m, "DNS");

        return 0;
}

static int manager_network_monitor_listen(Manager *m) {
        int r, fd, events;

        assert(m);

        r = sd_network_monitor_new(&m->network_monitor, NULL);
        if (r < 0)
                return r;

        fd = sd_network_monitor_get_fd(m->network_monitor);
        if (fd < 0)
                return fd;

        events = sd_network_monitor_get_events(m->network_monitor);
        if (events < 0)
                return events;

        r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
        if (r < 0)
                return r;

        r = sd_event_source_set_priority(m->network_event_source, SD_EVENT_PRIORITY_IMPORTANT+5);
        if (r < 0)
                return r;

        (void) sd_event_source_set_description(m->network_event_source, "network-monitor");

        return 0;
}

static int manager_clock_change_listen(Manager *m);

static int on_clock_change(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
        Manager *m = userdata;

        assert(m);

        /* The clock has changed, let's flush all caches. Why that? That's because DNSSEC validation takes
         * the system clock into consideration, and if the clock changes the old validations might have been
         * wrong. Let's redo all validation with the new, correct time.
         *
         * (Also, this is triggered after system suspend, which is also a good reason to drop caches, since
         * we might be connected to a different network now without this being visible in a dropped link
         * carrier or so.) */

        log_info("Clock change detected. Flushing caches.");
        manager_flush_caches(m, LOG_DEBUG /* downgrade the functions own log message, since we already logged here at LOG_INFO level */);

        /* The clock change timerfd is unusable after it triggered once, create a new one. */
        return manager_clock_change_listen(m);
}

static int manager_clock_change_listen(Manager *m) {
        _cleanup_close_ int fd = -1;
        int r;

        assert(m);

        m->clock_change_event_source = sd_event_source_disable_unref(m->clock_change_event_source);

        fd = time_change_fd();
        if (fd < 0)
                return log_error_errno(fd, "Failed to allocate clock change timer fd: %m");

        r = sd_event_add_io(m->event, &m->clock_change_event_source, fd, EPOLLIN, on_clock_change, m);
        if (r < 0)
                return log_error_errno(r, "Failed to create clock change event source: %m");

        r = sd_event_source_set_io_fd_own(m->clock_change_event_source, true);
        if (r < 0)
                return log_error_errno(r, "Failed to pass ownership of clock fd to event source: %m");
        TAKE_FD(fd);

        (void) sd_event_source_set_description(m->clock_change_event_source, "clock-change");

        return 0;
}

static int determine_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
        _cleanup_free_ char *h = NULL, *n = NULL;
        int r;

        assert(full_hostname);
        assert(llmnr_hostname);
        assert(mdns_hostname);

        r = resolve_system_hostname(&h, &n);
        if (r < 0)
                return r;

        r = dns_name_concat(n, "local", 0, mdns_hostname);
        if (r < 0)
                return log_error_errno(r, "Failed to determine mDNS hostname: %m");

        *llmnr_hostname = TAKE_PTR(n);
        *full_hostname = TAKE_PTR(h);

        return 0;
}

static char* fallback_hostname(void) {

        /* Determine the fall back hostname. For exposing this system to the outside world, we cannot have it
         * to be "localhost" even if that's the default hostname. In this case, let's revert to "linux"
         * instead. */

        _cleanup_free_ char *n = get_default_hostname();
        if (!n)
                return NULL;

        if (is_localhost(n))
                return strdup("linux");

        return TAKE_PTR(n);
}

static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
        _cleanup_free_ char *h = NULL, *n = NULL, *m = NULL;
        char label[DNS_LABEL_MAX];
        const char *p;
        int r;

        assert(full_hostname);
        assert(llmnr_hostname);
        assert(mdns_hostname);

        p = h = fallback_hostname();
        if (!h)
                return log_oom();

        r = dns_label_unescape(&p, label, sizeof label, 0);
        if (r < 0)
                return log_error_errno(r, "Failed to unescape fallback hostname: %m");

        assert(r > 0); /* The fallback hostname must have at least one label */

        r = dns_label_escape_new(label, r, &n);
        if (r < 0)
                return log_error_errno(r, "Failed to escape fallback hostname: %m");

        r = dns_name_concat(n, "local", 0, &m);
        if (r < 0)
                return log_error_errno(r, "Failed to concatenate mDNS hostname: %m");

        *llmnr_hostname = TAKE_PTR(n);
        *mdns_hostname = TAKE_PTR(m);
        *full_hostname = TAKE_PTR(h);

        return 0;
}

static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
        _cleanup_free_ char *full_hostname = NULL, *llmnr_hostname = NULL, *mdns_hostname = NULL;
        Manager *m = userdata;
        bool llmnr_hostname_changed;
        int r;

        assert(m);

        r = determine_hostnames(&full_hostname, &llmnr_hostname, &mdns_hostname);
        if (r < 0) {
                log_warning_errno(r, "Failed to determine the local hostname and LLMNR/mDNS names, ignoring: %m");
                return 0; /* ignore invalid hostnames */
        }

        llmnr_hostname_changed = !streq(llmnr_hostname, m->llmnr_hostname);
        if (streq(full_hostname, m->full_hostname) &&
            !llmnr_hostname_changed &&
            streq(mdns_hostname, m->mdns_hostname))
                return 0;

        log_info("System hostname changed to '%s'.", full_hostname);

        free_and_replace(m->full_hostname, full_hostname);
        free_and_replace(m->llmnr_hostname, llmnr_hostname);
        free_and_replace(m->mdns_hostname, mdns_hostname);

        manager_refresh_rrs(m);
        (void) manager_send_changed(m, "LLMNRHostname");

        return 0;
}

static int manager_watch_hostname(Manager *m) {
        int r;

        assert(m);

        m->hostname_fd = open("/proc/sys/kernel/hostname",
                              O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
        if (m->hostname_fd < 0) {
                log_warning_errno(errno, "Failed to watch hostname: %m");
                return 0;
        }

        r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
        if (r < 0) {
                if (r == -EPERM)
                        /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
                        m->hostname_fd = safe_close(m->hostname_fd);
                else
                        return log_error_errno(r, "Failed to add hostname event source: %m");
        }

        (void) sd_event_source_set_description(m->hostname_event_source, "hostname");

        r = determine_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
        if (r < 0) {
                _cleanup_free_ char *d = NULL;

                d = fallback_hostname();
                if (!d)
                        return log_oom();

                log_info("Defaulting to hostname '%s'.", d);

                r = make_fallback_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
                if (r < 0)
                        return r;
        } else
                log_info("Using system hostname '%s'.", m->full_hostname);

        return 0;
}

static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
        _cleanup_free_ char *buffer = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        Manager *m = userdata;
        DnsServer *server;
        size_t size = 0;
        DnsScope *scope;
        Link *l;

        assert(s);
        assert(si);
        assert(m);

        f = open_memstream_unlocked(&buffer, &size);
        if (!f)
                return log_oom();

        LIST_FOREACH(scopes, scope, m->dns_scopes)
                dns_scope_dump(scope, f);

        LIST_FOREACH(servers, server, m->dns_servers)
                dns_server_dump(server, f);
        LIST_FOREACH(servers, server, m->fallback_dns_servers)
                dns_server_dump(server, f);
        HASHMAP_FOREACH(l, m->links)
                LIST_FOREACH(servers, server, l->dns_servers)
                        dns_server_dump(server, f);

        if (fflush_and_check(f) < 0)
                return log_oom();

        log_dump(LOG_INFO, buffer);
        return 0;
}

static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
        Manager *m = userdata;

        assert(s);
        assert(si);
        assert(m);

        manager_flush_caches(m, LOG_INFO);

        return 0;
}

static int manager_sigrtmin1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
        Manager *m = userdata;

        assert(s);
        assert(si);
        assert(m);

        manager_reset_server_features(m);
        return 0;
}

int manager_new(Manager **ret) {
        _cleanup_(manager_freep) Manager *m = NULL;
        int r;

        assert(ret);

        m = new(Manager, 1);
        if (!m)
                return -ENOMEM;

        *m = (Manager) {
                .llmnr_ipv4_udp_fd = -1,
                .llmnr_ipv6_udp_fd = -1,
                .llmnr_ipv4_tcp_fd = -1,
                .llmnr_ipv6_tcp_fd = -1,
                .mdns_ipv4_fd = -1,
                .mdns_ipv6_fd = -1,
                .hostname_fd = -1,

                .llmnr_support = DEFAULT_LLMNR_MODE,
                .mdns_support = DEFAULT_MDNS_MODE,
                .dnssec_mode = DEFAULT_DNSSEC_MODE,
                .dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE,
                .enable_cache = DNS_CACHE_MODE_YES,
                .dns_stub_listener_mode = DNS_STUB_LISTENER_YES,
                .read_resolv_conf = true,
                .need_builtin_fallbacks = true,
                .etc_hosts_last = USEC_INFINITY,
                .read_etc_hosts = true,
        };

        r = dns_trust_anchor_load(&m->trust_anchor);
        if (r < 0)
                return r;

        r = manager_parse_config_file(m);
        if (r < 0)
                log_warning_errno(r, "Failed to parse configuration file: %m");

#if ENABLE_DNS_OVER_TLS
        r = dnstls_manager_init(m);
        if (r < 0)
                return r;
#endif

        r = sd_event_default(&m->event);
        if (r < 0)
                return r;

        (void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL,  NULL);
        (void) sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);

        (void) sd_event_set_watchdog(m->event, true);

        r = manager_watch_hostname(m);
        if (r < 0)
                return r;

        r = dnssd_load(m);
        if (r < 0)
                log_warning_errno(r, "Failed to load DNS-SD configuration files: %m");

        r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
        if (r < 0)
                return r;

        r = manager_network_monitor_listen(m);
        if (r < 0)
                return r;

        r = manager_rtnl_listen(m);
        if (r < 0)
                return r;

        r = manager_clock_change_listen(m);
        if (r < 0)
                return r;

        r = manager_connect_bus(m);
        if (r < 0)
                return r;

        (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
        (void) sd_event_add_signal(m->event, &m->sigusr2_event_source, SIGUSR2, manager_sigusr2, m);
        (void) sd_event_add_signal(m->event, &m->sigrtmin1_event_source, SIGRTMIN+1, manager_sigrtmin1, m);

        manager_cleanup_saved_user(m);

        *ret = TAKE_PTR(m);

        return 0;
}

int manager_start(Manager *m) {
        int r;

        assert(m);

        r = manager_dns_stub_start(m);
        if (r < 0)
                return r;

        r = manager_varlink_init(m);
        if (r < 0)
                return r;

        return 0;
}

Manager *manager_free(Manager *m) {
        Link *l;
        DnssdService *s;

        if (!m)
                return NULL;

        dns_server_unlink_all(m->dns_servers);
        dns_server_unlink_all(m->fallback_dns_servers);
        dns_search_domain_unlink_all(m->search_domains);

        while ((l = hashmap_first(m->links)))
               link_free(l);

        while (m->dns_queries)
                dns_query_free(m->dns_queries);

        m->stub_queries_by_packet = hashmap_free(m->stub_queries_by_packet);

        dns_scope_free(m->unicast_scope);

        /* At this point only orphaned streams should remain. All others should have been freed already by their
         * owners */
        while (m->dns_streams)
                dns_stream_unref(m->dns_streams);

#if ENABLE_DNS_OVER_TLS
        dnstls_manager_free(m);
#endif

        hashmap_free(m->links);
        hashmap_free(m->dns_transactions);

        sd_event_source_unref(m->network_event_source);
        sd_network_monitor_unref(m->network_monitor);

        sd_netlink_unref(m->rtnl);
        sd_event_source_unref(m->rtnl_event_source);
        sd_event_source_unref(m->clock_change_event_source);

        manager_llmnr_stop(m);
        manager_mdns_stop(m);
        manager_dns_stub_stop(m);
        manager_varlink_done(m);

        manager_socket_graveyard_clear(m);

        ordered_set_free(m->dns_extra_stub_listeners);

        bus_verify_polkit_async_registry_free(m->polkit_registry);

        sd_bus_flush_close_unref(m->bus);

        sd_event_source_unref(m->sigusr1_event_source);
        sd_event_source_unref(m->sigusr2_event_source);
        sd_event_source_unref(m->sigrtmin1_event_source);

        dns_resource_key_unref(m->llmnr_host_ipv4_key);
        dns_resource_key_unref(m->llmnr_host_ipv6_key);
        dns_resource_key_unref(m->mdns_host_ipv4_key);
        dns_resource_key_unref(m->mdns_host_ipv6_key);

        sd_event_source_unref(m->hostname_event_source);
        safe_close(m->hostname_fd);

        sd_event_unref(m->event);

        free(m->full_hostname);
        free(m->llmnr_hostname);
        free(m->mdns_hostname);

        while ((s = hashmap_first(m->dnssd_services)))
               dnssd_service_free(s);
        hashmap_free(m->dnssd_services);

        dns_trust_anchor_flush(&m->trust_anchor);
        manager_etc_hosts_flush(m);

        return mfree(m);
}

int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
        CMSG_BUFFER_TYPE(CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
                         + CMSG_SPACE(int) /* ttl/hoplimit */
                         + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */) control;
        union sockaddr_union sa;
        struct iovec iov;
        struct msghdr mh = {
                .msg_name = &sa.sa,
                .msg_namelen = sizeof(sa),
                .msg_iov = &iov,
                .msg_iovlen = 1,
                .msg_control = &control,
                .msg_controllen = sizeof(control),
        };
        struct cmsghdr *cmsg;
        ssize_t ms, l;
        int r;

        assert(m);
        assert(fd >= 0);
        assert(ret);

        ms = next_datagram_size_fd(fd);
        if (ms < 0)
                return ms;

        r = dns_packet_new(&p, protocol, ms, DNS_PACKET_SIZE_MAX);
        if (r < 0)
                return r;

        iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->allocated);

        l = recvmsg_safe(fd, &mh, 0);
        if (IN_SET(l, -EAGAIN, -EINTR))
                return 0;
        if (l <= 0)
                return l;

        assert(!(mh.msg_flags & MSG_TRUNC));

        p->size = (size_t) l;

        p->family = sa.sa.sa_family;
        p->ipproto = IPPROTO_UDP;
        if (p->family == AF_INET) {
                p->sender.in = sa.in.sin_addr;
                p->sender_port = be16toh(sa.in.sin_port);
        } else if (p->family == AF_INET6) {
                p->sender.in6 = sa.in6.sin6_addr;
                p->sender_port = be16toh(sa.in6.sin6_port);
                p->ifindex = sa.in6.sin6_scope_id;
        } else
                return -EAFNOSUPPORT;

        p->timestamp = now(clock_boottime_or_monotonic());

        CMSG_FOREACH(cmsg, &mh) {

                if (cmsg->cmsg_level == IPPROTO_IPV6) {
                        assert(p->family == AF_INET6);

                        switch (cmsg->cmsg_type) {

                        case IPV6_PKTINFO: {
                                struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);

                                if (p->ifindex <= 0)
                                        p->ifindex = i->ipi6_ifindex;

                                p->destination.in6 = i->ipi6_addr;
                                break;
                        }

                        case IPV6_HOPLIMIT:
                                p->ttl = *(int *) CMSG_DATA(cmsg);
                                break;

                        case IPV6_RECVFRAGSIZE:
                                p->fragsize = *(int *) CMSG_DATA(cmsg);
                                break;
                        }
                } else if (cmsg->cmsg_level == IPPROTO_IP) {
                        assert(p->family == AF_INET);

                        switch (cmsg->cmsg_type) {

                        case IP_PKTINFO: {
                                struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);

                                if (p->ifindex <= 0)
                                        p->ifindex = i->ipi_ifindex;

                                p->destination.in = i->ipi_addr;
                                break;
                        }

                        case IP_TTL:
                                p->ttl = *(int *) CMSG_DATA(cmsg);
                                break;

                        case IP_RECVFRAGSIZE:
                                p->fragsize = *(int *) CMSG_DATA(cmsg);
                                break;
                        }
                }
        }

        /* The Linux kernel sets the interface index to the loopback
         * device if the packet came from the local host since it
         * avoids the routing table in such a case. Let's unset the
         * interface index in such a case. */
        if (p->ifindex == LOOPBACK_IFINDEX)
                p->ifindex = 0;

        if (protocol != DNS_PROTOCOL_DNS) {
                /* If we don't know the interface index still, we look for the
                 * first local interface with a matching address. Yuck! */
                if (p->ifindex <= 0)
                        p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
        }

        log_debug("Received %s UDP packet of size %zu, ifindex=%i, ttl=%i, fragsize=%zu",
                  dns_protocol_to_string(protocol), p->size, p->ifindex, p->ttl, p->fragsize);

        *ret = TAKE_PTR(p);
        return 1;
}

static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
        int r;

        assert(fd >= 0);
        assert(mh);

        for (;;) {
                if (sendmsg(fd, mh, flags) >= 0)
                        return 0;

                if (errno == EINTR)
                        continue;

                if (errno != EAGAIN)
                        return -errno;

                r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
                if (r < 0)
                        return r;
                if (r == 0)
                        return -ETIMEDOUT;
        }
}

static int write_loop(int fd, void *message, size_t length) {
        int r;

        assert(fd >= 0);
        assert(message);

        for (;;) {
                if (write(fd, message, length) >= 0)
                        return 0;

                if (errno == EINTR)
                        continue;

                if (errno != EAGAIN)
                        return -errno;

                r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
                if (r < 0)
                        return r;
                if (r == 0)
                        return -ETIMEDOUT;
        }
}

int manager_write(Manager *m, int fd, DnsPacket *p) {
        int r;

        log_debug("Sending %s%s packet with id %" PRIu16 " of size %zu.",
                  DNS_PACKET_TC(p) ? "truncated (!) " : "",
                  DNS_PACKET_QR(p) ? "response" : "query",
                  DNS_PACKET_ID(p),
                  p->size);

        r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
        if (r < 0)
                return r;

        return 0;
}

static int manager_ipv4_send(
                Manager *m,
                int fd,
                int ifindex,
                const struct in_addr *destination,
                uint16_t port,
                const struct in_addr *source,
                DnsPacket *p) {

        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control = {};
        union sockaddr_union sa;
        struct iovec iov;
        struct msghdr mh = {
                .msg_iov = &iov,
                .msg_iovlen = 1,
                .msg_name = &sa.sa,
                .msg_namelen = sizeof(sa.in),
        };

        assert(m);
        assert(fd >= 0);
        assert(destination);
        assert(port > 0);
        assert(p);

        iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->size);

        sa = (union sockaddr_union) {
                .in.sin_family = AF_INET,
                .in.sin_addr = *destination,
                .in.sin_port = htobe16(port),
        };

        if (ifindex > 0) {
                struct cmsghdr *cmsg;
                struct in_pktinfo *pi;

                mh.msg_control = &control;
                mh.msg_controllen = sizeof(control);

                cmsg = CMSG_FIRSTHDR(&mh);
                cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
                cmsg->cmsg_level = IPPROTO_IP;
                cmsg->cmsg_type = IP_PKTINFO;

                pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
                pi->ipi_ifindex = ifindex;

                if (source)
                        pi->ipi_spec_dst = *source;
        }

        return sendmsg_loop(fd, &mh, 0);
}

static int manager_ipv6_send(
                Manager *m,
                int fd,
                int ifindex,
                const struct in6_addr *destination,
                uint16_t port,
                const struct in6_addr *source,
                DnsPacket *p) {

        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in6_pktinfo))) control = {};
        union sockaddr_union sa;
        struct iovec iov;
        struct msghdr mh = {
                .msg_iov = &iov,
                .msg_iovlen = 1,
                .msg_name = &sa.sa,
                .msg_namelen = sizeof(sa.in6),
        };

        assert(m);
        assert(fd >= 0);
        assert(destination);
        assert(port > 0);
        assert(p);

        iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->size);

        sa = (union sockaddr_union) {
                .in6.sin6_family = AF_INET6,
                .in6.sin6_addr = *destination,
                .in6.sin6_port = htobe16(port),
                .in6.sin6_scope_id = ifindex,
        };

        if (ifindex > 0) {
                struct cmsghdr *cmsg;
                struct in6_pktinfo *pi;

                mh.msg_control = &control;
                mh.msg_controllen = sizeof(control);

                cmsg = CMSG_FIRSTHDR(&mh);
                cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
                cmsg->cmsg_level = IPPROTO_IPV6;
                cmsg->cmsg_type = IPV6_PKTINFO;

                pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
                pi->ipi6_ifindex = ifindex;

                if (source)
                        pi->ipi6_addr = *source;
        }

        return sendmsg_loop(fd, &mh, 0);
}

int manager_send(
                Manager *m,
                int fd,
                int ifindex,
                int family,
                const union in_addr_union *destination,
                uint16_t port,
                const union in_addr_union *source,
                DnsPacket *p) {

        assert(m);
        assert(fd >= 0);
        assert(destination);
        assert(port > 0);
        assert(p);

        log_debug("Sending %s%s packet with id %" PRIu16 " on interface %i/%s of size %zu.",
                  DNS_PACKET_TC(p) ? "truncated (!) " : "",
                  DNS_PACKET_QR(p) ? "response" : "query",
                  DNS_PACKET_ID(p),
                  ifindex, af_to_name(family),
                  p->size);

        if (family == AF_INET)
                return manager_ipv4_send(m, fd, ifindex, &destination->in, port, source ? &source->in : NULL, p);
        if (family == AF_INET6)
                return manager_ipv6_send(m, fd, ifindex, &destination->in6, port, source ? &source->in6 : NULL, p);

        return -EAFNOSUPPORT;
}

uint32_t manager_find_mtu(Manager *m) {
        uint32_t mtu = 0;
        Link *l;

        /* If we don't know on which link a DNS packet would be delivered, let's find the largest MTU that
         * works on all interfaces we know of that have an IP address associated */

        HASHMAP_FOREACH(l, m->links) {
                /* Let's filter out links without IP addresses (e.g. AF_CAN links and suchlike) */
                if (!l->addresses)
                        continue;

                /* Safety check: MTU shorter than what we need for the absolutely shortest DNS request? Then
                 * let's ignore this link. */
                if (l->mtu < MIN(UDP4_PACKET_HEADER_SIZE + DNS_PACKET_HEADER_SIZE,
                                 UDP6_PACKET_HEADER_SIZE + DNS_PACKET_HEADER_SIZE))
                        continue;

                if (mtu <= 0 || l->mtu < mtu)
                        mtu = l->mtu;
        }

        if (mtu == 0) /* found nothing? then let's assume the typical Ethernet MTU for lack of anything more precise */
                return 1500;

        return mtu;
}

int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
        LinkAddress *a;

        assert(m);

        if (!IN_SET(family, AF_INET, AF_INET6))
                return 0;

        if (!in_addr)
                return 0;

        a = manager_find_link_address(m, family, in_addr);
        if (a)
                return a->link->ifindex;

        return 0;
}

void manager_refresh_rrs(Manager *m) {
        Link *l;
        DnssdService *s;

        assert(m);

        m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
        m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
        m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
        m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);

        HASHMAP_FOREACH(l, m->links)
                link_add_rrs(l, true);

        if (m->mdns_support == RESOLVE_SUPPORT_YES)
                HASHMAP_FOREACH(s, m->dnssd_services)
                        if (dnssd_update_rrs(s) < 0)
                                log_warning("Failed to refresh DNS-SD service '%s'", s->name);

        HASHMAP_FOREACH(l, m->links)
                link_add_rrs(l, false);
}

static int manager_next_random_name(const char *old, char **ret_new) {
        const char *p;
        uint64_t u, a;
        char *n;

        p = strchr(old, 0);
        assert(p);

        while (p > old) {
                if (!strchr(DIGITS, p[-1]))
                        break;

                p--;
        }

        if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
                u = 1;

        /* Add a random number to the old value. This way we can avoid
         * that two hosts pick the same hostname, win on IPv4 and lose
         * on IPv6 (or vice versa), and pick the same hostname
         * replacement hostname, ad infinitum. We still want the
         * numbers to go up monotonically, hence we just add a random
         * value 1..10 */

        random_bytes(&a, sizeof(a));
        u += 1 + a % 10;

        if (asprintf(&n, "%.*s%" PRIu64, (int) (p - old), old, u) < 0)
                return -ENOMEM;

        *ret_new = n;

        return 0;
}

int manager_next_hostname(Manager *m) {
        _cleanup_free_ char *h = NULL, *k = NULL;
        int r;

        assert(m);

        r = manager_next_random_name(m->llmnr_hostname, &h);
        if (r < 0)
                return r;

        r = dns_name_concat(h, "local", 0, &k);
        if (r < 0)
                return r;

        log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);

        free_and_replace(m->llmnr_hostname, h);
        free_and_replace(m->mdns_hostname, k);

        manager_refresh_rrs(m);
        (void) manager_send_changed(m, "LLMNRHostname");

        return 0;
}

LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
        Link *l;

        assert(m);

        if (!IN_SET(family, AF_INET, AF_INET6))
                return NULL;

        if (!in_addr)
                return NULL;

        HASHMAP_FOREACH(l, m->links) {
                LinkAddress *a;

                a = link_find_address(l, family, in_addr);
                if (a)
                        return a;
        }

        return NULL;
}

bool manager_packet_from_local_address(Manager *m, DnsPacket *p) {
        assert(m);
        assert(p);

        /* Let's see if this packet comes from an IP address we have on any local interface */

        return !!manager_find_link_address(m, p->family, &p->sender);
}

bool manager_packet_from_our_transaction(Manager *m, DnsPacket *p) {
        DnsTransaction *t;

        assert(m);
        assert(p);

        /* Let's see if we have a transaction with a query message with the exact same binary contents as the
         * one we just got. If so, it's almost definitely a packet loop of some kind. */

        t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
        if (!t)
                return false;

        return t->sent && dns_packet_equal(t->sent, p);
}

DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
        Link *l;

        assert(m);
        assert(p);

        l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
        if (!l)
                return NULL;

        switch (p->protocol) {
        case DNS_PROTOCOL_LLMNR:
                if (p->family == AF_INET)
                        return l->llmnr_ipv4_scope;
                else if (p->family == AF_INET6)
                        return l->llmnr_ipv6_scope;

                break;

        case DNS_PROTOCOL_MDNS:
                if (p->family == AF_INET)
                        return l->mdns_ipv4_scope;
                else if (p->family == AF_INET6)
                        return l->mdns_ipv6_scope;

                break;

        default:
                break;
        }

        return NULL;
}

void manager_verify_all(Manager *m) {
        DnsScope *s;

        assert(m);

        LIST_FOREACH(scopes, s, m->dns_scopes)
                dns_zone_verify_all(&s->zone);
}

int manager_is_own_hostname(Manager *m, const char *name) {
        int r;

        assert(m);
        assert(name);

        if (m->llmnr_hostname) {
                r = dns_name_equal(name, m->llmnr_hostname);
                if (r != 0)
                        return r;
        }

        if (m->mdns_hostname) {
                r = dns_name_equal(name, m->mdns_hostname);
                if (r != 0)
                        return r;
        }

        if (m->full_hostname)
                return dns_name_equal(name, m->full_hostname);

        return 0;
}

int manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
        DnsServer *s;
        Link *l;
        int r;

        assert(m);
        assert(dns);

        r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
        if (r < 0)
                return r;

        /* First add the system-wide servers and domains */
        LIST_FOREACH(servers, s, m->dns_servers) {
                r = ordered_set_put(*dns, s);
                if (r == -EEXIST)
                        continue;
                if (r < 0)
                        return r;
        }

        /* Then, add the per-link servers */
        HASHMAP_FOREACH(l, m->links) {
                LIST_FOREACH(servers, s, l->dns_servers) {
                        r = ordered_set_put(*dns, s);
                        if (r == -EEXIST)
                                continue;
                        if (r < 0)
                                return r;
                }
        }

        /* If we found nothing, add the fallback servers */
        if (ordered_set_isempty(*dns)) {
                LIST_FOREACH(servers, s, m->fallback_dns_servers) {
                        r = ordered_set_put(*dns, s);
                        if (r == -EEXIST)
                                continue;
                        if (r < 0)
                                return r;
                }
        }

        return 0;
}

/* filter_route is a tri-state:
 *   < 0: no filtering
 *   = 0 or false: return only domains which should be used for searching
 *   > 0 or true: return only domains which are for routing only
 */
int manager_compile_search_domains(Manager *m, OrderedSet **domains, int filter_route) {
        DnsSearchDomain *d;
        Link *l;
        int r;

        assert(m);
        assert(domains);

        r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
        if (r < 0)
                return r;

        LIST_FOREACH(domains, d, m->search_domains) {

                if (filter_route >= 0 &&
                    d->route_only != !!filter_route)
                        continue;

                r = ordered_set_put(*domains, d->name);
                if (r == -EEXIST)
                        continue;
                if (r < 0)
                        return r;
        }

        HASHMAP_FOREACH(l, m->links) {

                LIST_FOREACH(domains, d, l->search_domains) {

                        if (filter_route >= 0 &&
                            d->route_only != !!filter_route)
                                continue;

                        r = ordered_set_put(*domains, d->name);
                        if (r == -EEXIST)
                                continue;
                        if (r < 0)
                                return r;
                }
        }

        return 0;
}

DnssecMode manager_get_dnssec_mode(Manager *m) {
        assert(m);

        if (m->dnssec_mode != _DNSSEC_MODE_INVALID)
                return m->dnssec_mode;

        return DNSSEC_NO;
}

bool manager_dnssec_supported(Manager *m) {
        DnsServer *server;
        Link *l;

        assert(m);

        if (manager_get_dnssec_mode(m) == DNSSEC_NO)
                return false;

        server = manager_get_dns_server(m);
        if (server && !dns_server_dnssec_supported(server))
                return false;

        HASHMAP_FOREACH(l, m->links)
                if (!link_dnssec_supported(l))
                        return false;

        return true;
}

DnsOverTlsMode manager_get_dns_over_tls_mode(Manager *m) {
        assert(m);

        if (m->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
                return m->dns_over_tls_mode;

        return DNS_OVER_TLS_NO;
}

void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {

        assert(verdict >= 0);
        assert(verdict < _DNSSEC_VERDICT_MAX);

        if (DEBUG_LOGGING) {
                char s[DNS_RESOURCE_KEY_STRING_MAX];

                log_debug("Found verdict for lookup %s: %s",
                          dns_resource_key_to_string(key, s, sizeof s),
                          dnssec_verdict_to_string(verdict));
        }

        m->n_dnssec_verdict[verdict]++;
}

bool manager_routable(Manager *m) {
        Link *l;

        assert(m);

        /* Returns true if the host has at least one interface with a routable address (regardless if IPv4 or IPv6) */

        HASHMAP_FOREACH(l, m->links)
                if (link_relevant(l, AF_UNSPEC, false))
                        return true;

        return false;
}

void manager_flush_caches(Manager *m, int log_level) {
        DnsScope *scope;

        assert(m);

        LIST_FOREACH(scopes, scope, m->dns_scopes)
                dns_cache_flush(&scope->cache);

        log_full(log_level, "Flushed all caches.");
}

void manager_reset_server_features(Manager *m) {
        Link *l;

        dns_server_reset_features_all(m->dns_servers);
        dns_server_reset_features_all(m->fallback_dns_servers);

        HASHMAP_FOREACH(l, m->links)
                dns_server_reset_features_all(l->dns_servers);

        log_info("Resetting learnt feature levels on all servers.");
}

void manager_cleanup_saved_user(Manager *m) {
        _cleanup_closedir_ DIR *d = NULL;
        struct dirent *de;

        assert(m);

        /* Clean up all saved per-link files in /run/systemd/resolve/netif/ that don't have a matching interface
         * anymore. These files are created to persist settings pushed in by the user via the bus, so that resolved can
         * be restarted without losing this data. */

        d = opendir("/run/systemd/resolve/netif/");
        if (!d) {
                if (errno == ENOENT)
                        return;

                log_warning_errno(errno, "Failed to open interface directory: %m");
                return;
        }

        FOREACH_DIRENT_ALL(de, d, log_error_errno(errno, "Failed to read interface directory: %m")) {
                _cleanup_free_ char *p = NULL;
                int ifindex;
                Link *l;

                if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG))
                        continue;

                if (dot_or_dot_dot(de->d_name))
                        continue;

                ifindex = parse_ifindex(de->d_name);
                if (ifindex < 0) /* Probably some temporary file from a previous run. Delete it */
                        goto rm;

                l = hashmap_get(m->links, INT_TO_PTR(ifindex));
                if (!l) /* link vanished */
                        goto rm;

                if (l->is_managed) /* now managed by networkd, hence the bus settings are useless */
                        goto rm;

                continue;

        rm:
                p = path_join("/run/systemd/resolve/netif", de->d_name);
                if (!p) {
                        log_oom();
                        return;
                }

                (void) unlink(p);
        }
}

bool manager_next_dnssd_names(Manager *m) {
        DnssdService *s;
        bool tried = false;
        int r;

        assert(m);

        HASHMAP_FOREACH(s, m->dnssd_services) {
                _cleanup_free_ char * new_name = NULL;

                if (!s->withdrawn)
                        continue;

                r = manager_next_random_name(s->name_template, &new_name);
                if (r < 0) {
                        log_warning_errno(r, "Failed to get new name for service '%s': %m", s->name);
                        continue;
                }

                free_and_replace(s->name_template, new_name);

                s->withdrawn = false;

                tried = true;
        }

        if (tried)
                manager_refresh_rrs(m);

        return tried;
}

bool manager_server_is_stub(Manager *m, DnsServer *s) {
        DnsStubListenerExtra *l;

        assert(m);
        assert(s);

        /* Safety check: we generally already skip the main stub when parsing configuration. But let's be
         * extra careful, and check here again */
        if (s->family == AF_INET &&
            s->address.in.s_addr == htobe32(INADDR_DNS_STUB) &&
            dns_server_port(s) == 53)
                return true;

        /* Main reason to call this is to check server data against the extra listeners, and filter things
         * out. */
        ORDERED_SET_FOREACH(l, m->dns_extra_stub_listeners)
                if (s->family == l->family &&
                    in_addr_equal(s->family, &s->address, &l->address) &&
                    dns_server_port(s) == dns_stub_listener_extra_port(l))
                        return true;

        return false;
}

int socket_disable_pmtud(int fd, int af) {
        int r;

        assert(fd >= 0);

        if (af == AF_UNSPEC) {
                r = socket_get_family(fd, &af);
                if (r < 0)
                        return r;
        }

        switch (af) {

        case AF_INET: {
                /* Turn off path MTU discovery, let's rather fragment on the way than to open us up against
                 * PMTU forgery vulnerabilities.
                 *
                 * There appears to be no documentation about IP_PMTUDISC_OMIT, but it has the effect that
                 * the "Don't Fragment" bit in the IPv4 header is turned off, thus enforcing fragmentation if
                 * our datagram size exceeds the MTU of a router in the path, and turning off path MTU
                 * discovery.
                 *
                 * This helps mitigating the PMTUD vulnerability described here:
                 *
                 * https://blog.apnic.net/2019/07/12/its-time-to-consider-avoiding-ip-fragmentation-in-the-dns/
                 *
                 * Similar logic is in place in most DNS servers.
                 *
                 * There are multiple conflicting goals: we want to allow the largest datagrams possible (for
                 * efficiency reasons), but not have fragmentation (for security reasons), nor use PMTUD (for
                 * security reasons, too). Our strategy to deal with this is: use large packets, turn off
                 * PMTUD, but watch fragmentation taking place, and then size our packets to the max of the
                 * fragments seen — and if we need larger packets always go to TCP.
                 */

                r = setsockopt_int(fd, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_OMIT);
                if (r < 0)
                        return r;

                return 0;
        }

        case AF_INET6: {
                /* On IPv6 fragmentation only is done by the sender — never by routers on the path. PMTUD is
                 * mandatory. If we want to turn off PMTUD, the only way is by sending with minimal MTU only,
                 * so that we apply maximum fragmentation locally already, and thus PMTUD doesn't happen
                 * because there's nothing that could be fragmented further anymore. */

                r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_MTU, IPV6_MIN_MTU);
                if (r < 0)
                        return r;

                return 0;
        }

        default:
                return -EAFNOSUPPORT;
        }
}
