LCOV - code coverage report
Current view: top level - resolve - resolved-manager.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 815 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 44 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 667 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <fcntl.h>
       4                 :            : #include <netinet/in.h>
       5                 :            : #include <poll.h>
       6                 :            : #include <sys/ioctl.h>
       7                 :            : #include <sys/stat.h>
       8                 :            : #include <sys/types.h>
       9                 :            : #include <unistd.h>
      10                 :            : 
      11                 :            : #if HAVE_LIBIDN2
      12                 :            : #include <idn2.h>
      13                 :            : #endif
      14                 :            : 
      15                 :            : #include "af-list.h"
      16                 :            : #include "alloc-util.h"
      17                 :            : #include "bus-util.h"
      18                 :            : #include "dirent-util.h"
      19                 :            : #include "dns-domain.h"
      20                 :            : #include "fd-util.h"
      21                 :            : #include "fileio.h"
      22                 :            : #include "hostname-util.h"
      23                 :            : #include "io-util.h"
      24                 :            : #include "missing_network.h"
      25                 :            : #include "netlink-util.h"
      26                 :            : #include "network-internal.h"
      27                 :            : #include "ordered-set.h"
      28                 :            : #include "parse-util.h"
      29                 :            : #include "random-util.h"
      30                 :            : #include "resolved-bus.h"
      31                 :            : #include "resolved-conf.h"
      32                 :            : #include "resolved-dns-stub.h"
      33                 :            : #include "resolved-dnssd.h"
      34                 :            : #include "resolved-etc-hosts.h"
      35                 :            : #include "resolved-llmnr.h"
      36                 :            : #include "resolved-manager.h"
      37                 :            : #include "resolved-mdns.h"
      38                 :            : #include "resolved-resolv-conf.h"
      39                 :            : #include "socket-util.h"
      40                 :            : #include "string-table.h"
      41                 :            : #include "string-util.h"
      42                 :            : #include "utf8.h"
      43                 :            : 
      44                 :            : #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
      45                 :            : 
      46                 :          0 : static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
      47                 :          0 :         Manager *m = userdata;
      48                 :            :         uint16_t type;
      49                 :            :         Link *l;
      50                 :            :         int ifindex, r;
      51                 :            : 
      52         [ #  # ]:          0 :         assert(rtnl);
      53         [ #  # ]:          0 :         assert(m);
      54         [ #  # ]:          0 :         assert(mm);
      55                 :            : 
      56                 :          0 :         r = sd_netlink_message_get_type(mm, &type);
      57         [ #  # ]:          0 :         if (r < 0)
      58                 :          0 :                 goto fail;
      59                 :            : 
      60                 :          0 :         r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
      61         [ #  # ]:          0 :         if (r < 0)
      62                 :          0 :                 goto fail;
      63                 :            : 
      64                 :          0 :         l = hashmap_get(m->links, INT_TO_PTR(ifindex));
      65                 :            : 
      66      [ #  #  # ]:          0 :         switch (type) {
      67                 :            : 
      68                 :          0 :         case RTM_NEWLINK:{
      69                 :          0 :                 bool is_new = !l;
      70                 :            : 
      71         [ #  # ]:          0 :                 if (!l) {
      72                 :          0 :                         r = link_new(m, &l, ifindex);
      73         [ #  # ]:          0 :                         if (r < 0)
      74                 :          0 :                                 goto fail;
      75                 :            :                 }
      76                 :            : 
      77                 :          0 :                 r = link_process_rtnl(l, mm);
      78         [ #  # ]:          0 :                 if (r < 0)
      79                 :          0 :                         goto fail;
      80                 :            : 
      81                 :          0 :                 r = link_update(l);
      82         [ #  # ]:          0 :                 if (r < 0)
      83                 :          0 :                         goto fail;
      84                 :            : 
      85         [ #  # ]:          0 :                 if (is_new)
      86         [ #  # ]:          0 :                         log_debug("Found new link %i/%s", ifindex, l->ifname);
      87                 :            : 
      88                 :          0 :                 break;
      89                 :            :         }
      90                 :            : 
      91                 :          0 :         case RTM_DELLINK:
      92         [ #  # ]:          0 :                 if (l) {
      93         [ #  # ]:          0 :                         log_debug("Removing link %i/%s", l->ifindex, l->ifname);
      94                 :          0 :                         link_remove_user(l);
      95                 :          0 :                         link_free(l);
      96                 :            :                 }
      97                 :            : 
      98                 :          0 :                 break;
      99                 :            :         }
     100                 :            : 
     101                 :          0 :         return 0;
     102                 :            : 
     103                 :          0 : fail:
     104         [ #  # ]:          0 :         log_warning_errno(r, "Failed to process RTNL link message: %m");
     105                 :          0 :         return 0;
     106                 :            : }
     107                 :            : 
     108                 :          0 : static int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
     109                 :          0 :         Manager *m = userdata;
     110                 :            :         union in_addr_union address;
     111                 :            :         uint16_t type;
     112                 :            :         int r, ifindex, family;
     113                 :            :         LinkAddress *a;
     114                 :            :         Link *l;
     115                 :            : 
     116         [ #  # ]:          0 :         assert(rtnl);
     117         [ #  # ]:          0 :         assert(mm);
     118         [ #  # ]:          0 :         assert(m);
     119                 :            : 
     120                 :          0 :         r = sd_netlink_message_get_type(mm, &type);
     121         [ #  # ]:          0 :         if (r < 0)
     122                 :          0 :                 goto fail;
     123                 :            : 
     124                 :          0 :         r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
     125         [ #  # ]:          0 :         if (r < 0)
     126                 :          0 :                 goto fail;
     127                 :            : 
     128                 :          0 :         l = hashmap_get(m->links, INT_TO_PTR(ifindex));
     129         [ #  # ]:          0 :         if (!l)
     130                 :          0 :                 return 0;
     131                 :            : 
     132                 :          0 :         r = sd_rtnl_message_addr_get_family(mm, &family);
     133         [ #  # ]:          0 :         if (r < 0)
     134                 :          0 :                 goto fail;
     135                 :            : 
     136      [ #  #  # ]:          0 :         switch (family) {
     137                 :            : 
     138                 :          0 :         case AF_INET:
     139                 :          0 :                 r = sd_netlink_message_read_in_addr(mm, IFA_LOCAL, &address.in);
     140         [ #  # ]:          0 :                 if (r < 0) {
     141                 :          0 :                         r = sd_netlink_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
     142         [ #  # ]:          0 :                         if (r < 0)
     143                 :          0 :                                 goto fail;
     144                 :            :                 }
     145                 :            : 
     146                 :          0 :                 break;
     147                 :            : 
     148                 :          0 :         case AF_INET6:
     149                 :          0 :                 r = sd_netlink_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
     150         [ #  # ]:          0 :                 if (r < 0) {
     151                 :          0 :                         r = sd_netlink_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
     152         [ #  # ]:          0 :                         if (r < 0)
     153                 :          0 :                                 goto fail;
     154                 :            :                 }
     155                 :            : 
     156                 :          0 :                 break;
     157                 :            : 
     158                 :          0 :         default:
     159                 :          0 :                 return 0;
     160                 :            :         }
     161                 :            : 
     162                 :          0 :         a = link_find_address(l, family, &address);
     163                 :            : 
     164      [ #  #  # ]:          0 :         switch (type) {
     165                 :            : 
     166                 :          0 :         case RTM_NEWADDR:
     167                 :            : 
     168         [ #  # ]:          0 :                 if (!a) {
     169                 :          0 :                         r = link_address_new(l, &a, family, &address);
     170         [ #  # ]:          0 :                         if (r < 0)
     171                 :          0 :                                 return r;
     172                 :            :                 }
     173                 :            : 
     174                 :          0 :                 r = link_address_update_rtnl(a, mm);
     175         [ #  # ]:          0 :                 if (r < 0)
     176                 :          0 :                         return r;
     177                 :            : 
     178                 :          0 :                 break;
     179                 :            : 
     180                 :          0 :         case RTM_DELADDR:
     181                 :          0 :                 link_address_free(a);
     182                 :          0 :                 break;
     183                 :            :         }
     184                 :            : 
     185                 :          0 :         return 0;
     186                 :            : 
     187                 :          0 : fail:
     188         [ #  # ]:          0 :         log_warning_errno(r, "Failed to process RTNL address message: %m");
     189                 :          0 :         return 0;
     190                 :            : }
     191                 :            : 
     192                 :          0 : static int manager_rtnl_listen(Manager *m) {
     193                 :          0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
     194                 :            :         sd_netlink_message *i;
     195                 :            :         int r;
     196                 :            : 
     197         [ #  # ]:          0 :         assert(m);
     198                 :            : 
     199                 :            :         /* First, subscribe to interfaces coming and going */
     200                 :          0 :         r = sd_netlink_open(&m->rtnl);
     201         [ #  # ]:          0 :         if (r < 0)
     202                 :          0 :                 return r;
     203                 :            : 
     204                 :          0 :         r = sd_netlink_attach_event(m->rtnl, m->event, SD_EVENT_PRIORITY_IMPORTANT);
     205         [ #  # ]:          0 :         if (r < 0)
     206                 :          0 :                 return r;
     207                 :            : 
     208                 :          0 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, manager_process_link, NULL, m, "resolve-NEWLINK");
     209         [ #  # ]:          0 :         if (r < 0)
     210                 :          0 :                 return r;
     211                 :            : 
     212                 :          0 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, manager_process_link, NULL, m, "resolve-DELLINK");
     213         [ #  # ]:          0 :         if (r < 0)
     214                 :          0 :                 return r;
     215                 :            : 
     216                 :          0 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, manager_process_address, NULL, m, "resolve-NEWADDR");
     217         [ #  # ]:          0 :         if (r < 0)
     218                 :          0 :                 return r;
     219                 :            : 
     220                 :          0 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, manager_process_address, NULL, m, "resolve-DELADDR");
     221         [ #  # ]:          0 :         if (r < 0)
     222                 :          0 :                 return r;
     223                 :            : 
     224                 :            :         /* Then, enumerate all links */
     225                 :          0 :         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
     226         [ #  # ]:          0 :         if (r < 0)
     227                 :          0 :                 return r;
     228                 :            : 
     229                 :          0 :         r = sd_netlink_message_request_dump(req, true);
     230         [ #  # ]:          0 :         if (r < 0)
     231                 :          0 :                 return r;
     232                 :            : 
     233                 :          0 :         r = sd_netlink_call(m->rtnl, req, 0, &reply);
     234         [ #  # ]:          0 :         if (r < 0)
     235                 :          0 :                 return r;
     236                 :            : 
     237         [ #  # ]:          0 :         for (i = reply; i; i = sd_netlink_message_next(i)) {
     238                 :          0 :                 r = manager_process_link(m->rtnl, i, m);
     239         [ #  # ]:          0 :                 if (r < 0)
     240                 :          0 :                         return r;
     241                 :            :         }
     242                 :            : 
     243                 :          0 :         req = sd_netlink_message_unref(req);
     244                 :          0 :         reply = sd_netlink_message_unref(reply);
     245                 :            : 
     246                 :            :         /* Finally, enumerate all addresses, too */
     247                 :          0 :         r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
     248         [ #  # ]:          0 :         if (r < 0)
     249                 :          0 :                 return r;
     250                 :            : 
     251                 :          0 :         r = sd_netlink_message_request_dump(req, true);
     252         [ #  # ]:          0 :         if (r < 0)
     253                 :          0 :                 return r;
     254                 :            : 
     255                 :          0 :         r = sd_netlink_call(m->rtnl, req, 0, &reply);
     256         [ #  # ]:          0 :         if (r < 0)
     257                 :          0 :                 return r;
     258                 :            : 
     259         [ #  # ]:          0 :         for (i = reply; i; i = sd_netlink_message_next(i)) {
     260                 :          0 :                 r = manager_process_address(m->rtnl, i, m);
     261         [ #  # ]:          0 :                 if (r < 0)
     262                 :          0 :                         return r;
     263                 :            :         }
     264                 :            : 
     265                 :          0 :         return r;
     266                 :            : }
     267                 :            : 
     268                 :          0 : static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
     269                 :          0 :         Manager *m = userdata;
     270                 :            :         Iterator i;
     271                 :            :         Link *l;
     272                 :            :         int r;
     273                 :            : 
     274         [ #  # ]:          0 :         assert(m);
     275                 :            : 
     276                 :          0 :         sd_network_monitor_flush(m->network_monitor);
     277                 :            : 
     278         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i) {
     279                 :          0 :                 r = link_update(l);
     280         [ #  # ]:          0 :                 if (r < 0)
     281         [ #  # ]:          0 :                         log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
     282                 :            :         }
     283                 :            : 
     284                 :          0 :         (void) manager_write_resolv_conf(m);
     285                 :            : 
     286                 :          0 :         return 0;
     287                 :            : }
     288                 :            : 
     289                 :          0 : static int manager_network_monitor_listen(Manager *m) {
     290                 :            :         int r, fd, events;
     291                 :            : 
     292         [ #  # ]:          0 :         assert(m);
     293                 :            : 
     294                 :          0 :         r = sd_network_monitor_new(&m->network_monitor, NULL);
     295         [ #  # ]:          0 :         if (r < 0)
     296                 :          0 :                 return r;
     297                 :            : 
     298                 :          0 :         fd = sd_network_monitor_get_fd(m->network_monitor);
     299         [ #  # ]:          0 :         if (fd < 0)
     300                 :          0 :                 return fd;
     301                 :            : 
     302                 :          0 :         events = sd_network_monitor_get_events(m->network_monitor);
     303         [ #  # ]:          0 :         if (events < 0)
     304                 :          0 :                 return events;
     305                 :            : 
     306                 :          0 :         r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
     307         [ #  # ]:          0 :         if (r < 0)
     308                 :          0 :                 return r;
     309                 :            : 
     310                 :          0 :         r = sd_event_source_set_priority(m->network_event_source, SD_EVENT_PRIORITY_IMPORTANT+5);
     311         [ #  # ]:          0 :         if (r < 0)
     312                 :          0 :                 return r;
     313                 :            : 
     314                 :          0 :         (void) sd_event_source_set_description(m->network_event_source, "network-monitor");
     315                 :            : 
     316                 :          0 :         return 0;
     317                 :            : }
     318                 :            : 
     319                 :          0 : static int determine_hostname(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
     320                 :          0 :         _cleanup_free_ char *h = NULL, *n = NULL;
     321                 :            : #if HAVE_LIBIDN2
     322                 :          0 :         _cleanup_free_ char *utf8 = NULL;
     323                 :            : #elif HAVE_LIBIDN
     324                 :            :         int k;
     325                 :            : #endif
     326                 :            :         char label[DNS_LABEL_MAX];
     327                 :            :         const char *p, *decoded;
     328                 :            :         int r;
     329                 :            : 
     330         [ #  # ]:          0 :         assert(full_hostname);
     331         [ #  # ]:          0 :         assert(llmnr_hostname);
     332         [ #  # ]:          0 :         assert(mdns_hostname);
     333                 :            : 
     334                 :            :         /* Extract and normalize the first label of the locally configured hostname, and check it's not "localhost". */
     335                 :            : 
     336                 :          0 :         r = gethostname_strict(&h);
     337         [ #  # ]:          0 :         if (r < 0)
     338         [ #  # ]:          0 :                 return log_debug_errno(r, "Can't determine system hostname: %m");
     339                 :            : 
     340                 :          0 :         p = h;
     341                 :          0 :         r = dns_label_unescape(&p, label, sizeof label, 0);
     342         [ #  # ]:          0 :         if (r < 0)
     343         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to unescape host name: %m");
     344         [ #  # ]:          0 :         if (r == 0)
     345         [ #  # ]:          0 :                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     346                 :            :                                        "Couldn't find a single label in hostname.");
     347                 :            : 
     348                 :            : #if HAVE_LIBIDN2
     349                 :          0 :         r = idn2_to_unicode_8z8z(label, &utf8, 0);
     350         [ #  # ]:          0 :         if (r != IDN2_OK)
     351         [ #  # ]:          0 :                 return log_error("Failed to undo IDNA: %s", idn2_strerror(r));
     352         [ #  # ]:          0 :         assert(utf8_is_valid(utf8));
     353                 :            : 
     354                 :          0 :         r = strlen(utf8);
     355                 :          0 :         decoded = utf8;
     356                 :            : #elif HAVE_LIBIDN
     357                 :            :         k = dns_label_undo_idna(label, r, label, sizeof label);
     358                 :            :         if (k < 0)
     359                 :            :                 return log_error_errno(k, "Failed to undo IDNA: %m");
     360                 :            :         if (k > 0)
     361                 :            :                 r = k;
     362                 :            : 
     363                 :            :         if (!utf8_is_valid(label))
     364                 :            :                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     365                 :            :                                        "System hostname is not UTF-8 clean.");
     366                 :            :         decoded = label;
     367                 :            : #else
     368                 :            :         decoded = label; /* no decoding */
     369                 :            : #endif
     370                 :            : 
     371                 :          0 :         r = dns_label_escape_new(decoded, r, &n);
     372         [ #  # ]:          0 :         if (r < 0)
     373         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to escape host name: %m");
     374                 :            : 
     375         [ #  # ]:          0 :         if (is_localhost(n))
     376         [ #  # ]:          0 :                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
     377                 :            :                                        "System hostname is 'localhost', ignoring.");
     378                 :            : 
     379                 :          0 :         r = dns_name_concat(n, "local", 0, mdns_hostname);
     380         [ #  # ]:          0 :         if (r < 0)
     381         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to determine mDNS hostname: %m");
     382                 :            : 
     383                 :          0 :         *llmnr_hostname = TAKE_PTR(n);
     384                 :          0 :         *full_hostname = TAKE_PTR(h);
     385                 :            : 
     386                 :          0 :         return 0;
     387                 :            : }
     388                 :            : 
     389                 :          0 : static const char *fallback_hostname(void) {
     390                 :            : 
     391                 :            :         /* Determine the fall back hostname. For exposing this system to the outside world, we cannot have it to be
     392                 :            :          * "localhost" even if that's the compiled in hostname. In this case, let's revert to "linux" instead. */
     393                 :            : 
     394         [ #  # ]:          0 :         if (is_localhost(FALLBACK_HOSTNAME))
     395                 :          0 :                 return "linux";
     396                 :            : 
     397                 :          0 :         return FALLBACK_HOSTNAME;
     398                 :            : }
     399                 :            : 
     400                 :          0 : static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
     401                 :          0 :         _cleanup_free_ char *n = NULL, *m = NULL;
     402                 :            :         char label[DNS_LABEL_MAX], *h;
     403                 :            :         const char *p;
     404                 :            :         int r;
     405                 :            : 
     406         [ #  # ]:          0 :         assert(full_hostname);
     407         [ #  # ]:          0 :         assert(llmnr_hostname);
     408         [ #  # ]:          0 :         assert(mdns_hostname);
     409                 :            : 
     410                 :          0 :         p = fallback_hostname();
     411                 :          0 :         r = dns_label_unescape(&p, label, sizeof label, 0);
     412         [ #  # ]:          0 :         if (r < 0)
     413         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to unescape fallback host name: %m");
     414                 :            : 
     415         [ #  # ]:          0 :         assert(r > 0); /* The fallback hostname must have at least one label */
     416                 :            : 
     417                 :          0 :         r = dns_label_escape_new(label, r, &n);
     418         [ #  # ]:          0 :         if (r < 0)
     419         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to escape fallback hostname: %m");
     420                 :            : 
     421                 :          0 :         r = dns_name_concat(n, "local", 0, &m);
     422         [ #  # ]:          0 :         if (r < 0)
     423         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to concatenate mDNS hostname: %m");
     424                 :            : 
     425                 :          0 :         h = strdup(fallback_hostname());
     426         [ #  # ]:          0 :         if (!h)
     427                 :          0 :                 return log_oom();
     428                 :            : 
     429                 :          0 :         *llmnr_hostname = TAKE_PTR(n);
     430                 :          0 :         *mdns_hostname = TAKE_PTR(m);
     431                 :            : 
     432                 :          0 :         *full_hostname = h;
     433                 :            : 
     434                 :          0 :         return 0;
     435                 :            : }
     436                 :            : 
     437                 :          0 : static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
     438                 :          0 :         _cleanup_free_ char *full_hostname = NULL, *llmnr_hostname = NULL, *mdns_hostname = NULL;
     439                 :          0 :         Manager *m = userdata;
     440                 :            :         int r;
     441                 :            : 
     442         [ #  # ]:          0 :         assert(m);
     443                 :            : 
     444                 :          0 :         r = determine_hostname(&full_hostname, &llmnr_hostname, &mdns_hostname);
     445         [ #  # ]:          0 :         if (r < 0)
     446                 :          0 :                 return 0; /* ignore invalid hostnames */
     447                 :            : 
     448         [ #  # ]:          0 :         if (streq(full_hostname, m->full_hostname) &&
     449         [ #  # ]:          0 :             streq(llmnr_hostname, m->llmnr_hostname) &&
     450         [ #  # ]:          0 :             streq(mdns_hostname, m->mdns_hostname))
     451                 :          0 :                 return 0;
     452                 :            : 
     453         [ #  # ]:          0 :         log_info("System hostname changed to '%s'.", full_hostname);
     454                 :            : 
     455                 :          0 :         free_and_replace(m->full_hostname, full_hostname);
     456                 :          0 :         free_and_replace(m->llmnr_hostname, llmnr_hostname);
     457                 :          0 :         free_and_replace(m->mdns_hostname, mdns_hostname);
     458                 :            : 
     459                 :          0 :         manager_refresh_rrs(m);
     460                 :            : 
     461                 :          0 :         return 0;
     462                 :            : }
     463                 :            : 
     464                 :          0 : static int manager_watch_hostname(Manager *m) {
     465                 :            :         int r;
     466                 :            : 
     467         [ #  # ]:          0 :         assert(m);
     468                 :            : 
     469                 :          0 :         m->hostname_fd = open("/proc/sys/kernel/hostname",
     470                 :            :                               O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
     471         [ #  # ]:          0 :         if (m->hostname_fd < 0) {
     472         [ #  # ]:          0 :                 log_warning_errno(errno, "Failed to watch hostname: %m");
     473                 :          0 :                 return 0;
     474                 :            :         }
     475                 :            : 
     476                 :          0 :         r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
     477         [ #  # ]:          0 :         if (r < 0) {
     478         [ #  # ]:          0 :                 if (r == -EPERM)
     479                 :            :                         /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
     480                 :          0 :                         m->hostname_fd = safe_close(m->hostname_fd);
     481                 :            :                 else
     482         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to add hostname event source: %m");
     483                 :            :         }
     484                 :            : 
     485                 :          0 :         (void) sd_event_source_set_description(m->hostname_event_source, "hostname");
     486                 :            : 
     487                 :          0 :         r = determine_hostname(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
     488         [ #  # ]:          0 :         if (r < 0) {
     489         [ #  # ]:          0 :                 log_info("Defaulting to hostname '%s'.", fallback_hostname());
     490                 :            : 
     491                 :          0 :                 r = make_fallback_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
     492         [ #  # ]:          0 :                 if (r < 0)
     493                 :          0 :                         return r;
     494                 :            :         } else
     495         [ #  # ]:          0 :                 log_info("Using system hostname '%s'.", m->full_hostname);
     496                 :            : 
     497                 :          0 :         return 0;
     498                 :            : }
     499                 :            : 
     500                 :          0 : static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
     501                 :          0 :         _cleanup_free_ char *buffer = NULL;
     502                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
     503                 :          0 :         Manager *m = userdata;
     504                 :            :         DnsServer *server;
     505                 :          0 :         size_t size = 0;
     506                 :            :         DnsScope *scope;
     507                 :            :         Iterator i;
     508                 :            :         Link *l;
     509                 :            : 
     510         [ #  # ]:          0 :         assert(s);
     511         [ #  # ]:          0 :         assert(si);
     512         [ #  # ]:          0 :         assert(m);
     513                 :            : 
     514                 :          0 :         f = open_memstream_unlocked(&buffer, &size);
     515         [ #  # ]:          0 :         if (!f)
     516                 :          0 :                 return log_oom();
     517                 :            : 
     518         [ #  # ]:          0 :         LIST_FOREACH(scopes, scope, m->dns_scopes)
     519                 :          0 :                 dns_scope_dump(scope, f);
     520                 :            : 
     521         [ #  # ]:          0 :         LIST_FOREACH(servers, server, m->dns_servers)
     522                 :          0 :                 dns_server_dump(server, f);
     523         [ #  # ]:          0 :         LIST_FOREACH(servers, server, m->fallback_dns_servers)
     524                 :          0 :                 dns_server_dump(server, f);
     525         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i)
     526         [ #  # ]:          0 :                 LIST_FOREACH(servers, server, l->dns_servers)
     527                 :          0 :                         dns_server_dump(server, f);
     528                 :            : 
     529         [ #  # ]:          0 :         if (fflush_and_check(f) < 0)
     530                 :          0 :                 return log_oom();
     531                 :            : 
     532                 :          0 :         log_dump(LOG_INFO, buffer);
     533                 :          0 :         return 0;
     534                 :            : }
     535                 :            : 
     536                 :          0 : static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
     537                 :          0 :         Manager *m = userdata;
     538                 :            : 
     539         [ #  # ]:          0 :         assert(s);
     540         [ #  # ]:          0 :         assert(si);
     541         [ #  # ]:          0 :         assert(m);
     542                 :            : 
     543                 :          0 :         manager_flush_caches(m);
     544                 :            : 
     545                 :          0 :         return 0;
     546                 :            : }
     547                 :            : 
     548                 :          0 : static int manager_sigrtmin1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
     549                 :          0 :         Manager *m = userdata;
     550                 :            : 
     551         [ #  # ]:          0 :         assert(s);
     552         [ #  # ]:          0 :         assert(si);
     553         [ #  # ]:          0 :         assert(m);
     554                 :            : 
     555                 :          0 :         manager_reset_server_features(m);
     556                 :          0 :         return 0;
     557                 :            : }
     558                 :            : 
     559                 :          0 : int manager_new(Manager **ret) {
     560                 :          0 :         _cleanup_(manager_freep) Manager *m = NULL;
     561                 :            :         int r;
     562                 :            : 
     563         [ #  # ]:          0 :         assert(ret);
     564                 :            : 
     565                 :          0 :         m = new(Manager, 1);
     566         [ #  # ]:          0 :         if (!m)
     567                 :          0 :                 return -ENOMEM;
     568                 :            : 
     569                 :          0 :         *m = (Manager) {
     570                 :            :                 .llmnr_ipv4_udp_fd = -1,
     571                 :            :                 .llmnr_ipv6_udp_fd = -1,
     572                 :            :                 .llmnr_ipv4_tcp_fd = -1,
     573                 :            :                 .llmnr_ipv6_tcp_fd = -1,
     574                 :            :                 .mdns_ipv4_fd = -1,
     575                 :            :                 .mdns_ipv6_fd = -1,
     576                 :            :                 .dns_stub_udp_fd = -1,
     577                 :            :                 .dns_stub_tcp_fd = -1,
     578                 :            :                 .hostname_fd = -1,
     579                 :            : 
     580                 :            :                 .llmnr_support = RESOLVE_SUPPORT_YES,
     581                 :            :                 .mdns_support = RESOLVE_SUPPORT_YES,
     582                 :            :                 .dnssec_mode = DEFAULT_DNSSEC_MODE,
     583                 :            :                 .dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE,
     584                 :            :                 .enable_cache = DNS_CACHE_MODE_YES,
     585                 :            :                 .dns_stub_listener_mode = DNS_STUB_LISTENER_YES,
     586                 :            :                 .read_resolv_conf = true,
     587                 :            :                 .need_builtin_fallbacks = true,
     588                 :            :                 .etc_hosts_last = USEC_INFINITY,
     589                 :            :                 .etc_hosts_mtime = USEC_INFINITY,
     590                 :            :                 .read_etc_hosts = true,
     591                 :            :         };
     592                 :            : 
     593                 :          0 :         r = dns_trust_anchor_load(&m->trust_anchor);
     594         [ #  # ]:          0 :         if (r < 0)
     595                 :          0 :                 return r;
     596                 :            : 
     597                 :          0 :         r = manager_parse_config_file(m);
     598         [ #  # ]:          0 :         if (r < 0)
     599         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to parse configuration file: %m");
     600                 :            : 
     601                 :            : #if ENABLE_DNS_OVER_TLS
     602                 :          0 :         r = dnstls_manager_init(m);
     603         [ #  # ]:          0 :         if (r < 0)
     604                 :          0 :                 return r;
     605                 :            : #endif
     606                 :            : 
     607                 :          0 :         r = sd_event_default(&m->event);
     608         [ #  # ]:          0 :         if (r < 0)
     609                 :          0 :                 return r;
     610                 :            : 
     611                 :          0 :         (void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL,  NULL);
     612                 :          0 :         (void) sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
     613                 :            : 
     614                 :          0 :         (void) sd_event_set_watchdog(m->event, true);
     615                 :            : 
     616                 :          0 :         r = manager_watch_hostname(m);
     617         [ #  # ]:          0 :         if (r < 0)
     618                 :          0 :                 return r;
     619                 :            : 
     620                 :          0 :         r = dnssd_load(m);
     621         [ #  # ]:          0 :         if (r < 0)
     622         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to load DNS-SD configuration files: %m");
     623                 :            : 
     624                 :          0 :         r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
     625         [ #  # ]:          0 :         if (r < 0)
     626                 :          0 :                 return r;
     627                 :            : 
     628                 :          0 :         r = manager_network_monitor_listen(m);
     629         [ #  # ]:          0 :         if (r < 0)
     630                 :          0 :                 return r;
     631                 :            : 
     632                 :          0 :         r = manager_rtnl_listen(m);
     633         [ #  # ]:          0 :         if (r < 0)
     634                 :          0 :                 return r;
     635                 :            : 
     636                 :          0 :         r = manager_connect_bus(m);
     637         [ #  # ]:          0 :         if (r < 0)
     638                 :          0 :                 return r;
     639                 :            : 
     640                 :          0 :         (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
     641                 :          0 :         (void) sd_event_add_signal(m->event, &m->sigusr2_event_source, SIGUSR2, manager_sigusr2, m);
     642                 :          0 :         (void) sd_event_add_signal(m->event, &m->sigrtmin1_event_source, SIGRTMIN+1, manager_sigrtmin1, m);
     643                 :            : 
     644                 :          0 :         manager_cleanup_saved_user(m);
     645                 :            : 
     646                 :          0 :         *ret = TAKE_PTR(m);
     647                 :            : 
     648                 :          0 :         return 0;
     649                 :            : }
     650                 :            : 
     651                 :          0 : int manager_start(Manager *m) {
     652                 :            :         int r;
     653                 :            : 
     654         [ #  # ]:          0 :         assert(m);
     655                 :            : 
     656                 :          0 :         r = manager_dns_stub_start(m);
     657         [ #  # ]:          0 :         if (r < 0)
     658                 :          0 :                 return r;
     659                 :            : 
     660                 :          0 :         return 0;
     661                 :            : }
     662                 :            : 
     663                 :          0 : Manager *manager_free(Manager *m) {
     664                 :            :         Link *l;
     665                 :            :         DnssdService *s;
     666                 :            : 
     667         [ #  # ]:          0 :         if (!m)
     668                 :          0 :                 return NULL;
     669                 :            : 
     670                 :          0 :         dns_server_unlink_all(m->dns_servers);
     671                 :          0 :         dns_server_unlink_all(m->fallback_dns_servers);
     672                 :          0 :         dns_search_domain_unlink_all(m->search_domains);
     673                 :            : 
     674         [ #  # ]:          0 :         while ((l = hashmap_first(m->links)))
     675                 :          0 :                link_free(l);
     676                 :            : 
     677         [ #  # ]:          0 :         while (m->dns_queries)
     678                 :          0 :                 dns_query_free(m->dns_queries);
     679                 :            : 
     680                 :          0 :         dns_scope_free(m->unicast_scope);
     681                 :            : 
     682                 :            :         /* At this point only orphaned streams should remain. All others should have been freed already by their
     683                 :            :          * owners */
     684         [ #  # ]:          0 :         while (m->dns_streams)
     685                 :          0 :                 dns_stream_unref(m->dns_streams);
     686                 :            : 
     687                 :            : #if ENABLE_DNS_OVER_TLS
     688                 :          0 :         dnstls_manager_free(m);
     689                 :            : #endif
     690                 :            : 
     691                 :          0 :         hashmap_free(m->links);
     692                 :          0 :         hashmap_free(m->dns_transactions);
     693                 :            : 
     694                 :          0 :         sd_event_source_unref(m->network_event_source);
     695                 :          0 :         sd_network_monitor_unref(m->network_monitor);
     696                 :            : 
     697                 :          0 :         sd_netlink_unref(m->rtnl);
     698                 :          0 :         sd_event_source_unref(m->rtnl_event_source);
     699                 :            : 
     700                 :          0 :         manager_llmnr_stop(m);
     701                 :          0 :         manager_mdns_stop(m);
     702                 :          0 :         manager_dns_stub_stop(m);
     703                 :            : 
     704                 :          0 :         bus_verify_polkit_async_registry_free(m->polkit_registry);
     705                 :            : 
     706                 :          0 :         sd_bus_flush_close_unref(m->bus);
     707                 :            : 
     708                 :          0 :         sd_event_source_unref(m->sigusr1_event_source);
     709                 :          0 :         sd_event_source_unref(m->sigusr2_event_source);
     710                 :          0 :         sd_event_source_unref(m->sigrtmin1_event_source);
     711                 :            : 
     712                 :          0 :         sd_event_unref(m->event);
     713                 :            : 
     714                 :          0 :         dns_resource_key_unref(m->llmnr_host_ipv4_key);
     715                 :          0 :         dns_resource_key_unref(m->llmnr_host_ipv6_key);
     716                 :          0 :         dns_resource_key_unref(m->mdns_host_ipv4_key);
     717                 :          0 :         dns_resource_key_unref(m->mdns_host_ipv6_key);
     718                 :            : 
     719                 :          0 :         sd_event_source_unref(m->hostname_event_source);
     720                 :          0 :         safe_close(m->hostname_fd);
     721                 :            : 
     722                 :          0 :         free(m->full_hostname);
     723                 :          0 :         free(m->llmnr_hostname);
     724                 :          0 :         free(m->mdns_hostname);
     725                 :            : 
     726         [ #  # ]:          0 :         while ((s = hashmap_first(m->dnssd_services)))
     727                 :          0 :                dnssd_service_free(s);
     728                 :          0 :         hashmap_free(m->dnssd_services);
     729                 :            : 
     730                 :          0 :         dns_trust_anchor_flush(&m->trust_anchor);
     731                 :          0 :         manager_etc_hosts_flush(m);
     732                 :            : 
     733                 :          0 :         return mfree(m);
     734                 :            : }
     735                 :            : 
     736                 :          0 : int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
     737                 :          0 :         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
     738                 :            :         union {
     739                 :            :                 struct cmsghdr header; /* For alignment */
     740                 :            :                 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
     741                 :            :                                + CMSG_SPACE(int) /* ttl/hoplimit */
     742                 :            :                                + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
     743                 :            :         } control;
     744                 :            :         union sockaddr_union sa;
     745                 :            :         struct iovec iov;
     746                 :          0 :         struct msghdr mh = {
     747                 :            :                 .msg_name = &sa.sa,
     748                 :            :                 .msg_namelen = sizeof(sa),
     749                 :            :                 .msg_iov = &iov,
     750                 :            :                 .msg_iovlen = 1,
     751                 :            :                 .msg_control = &control,
     752                 :            :                 .msg_controllen = sizeof(control),
     753                 :            :         };
     754                 :            :         struct cmsghdr *cmsg;
     755                 :            :         ssize_t ms, l;
     756                 :            :         int r;
     757                 :            : 
     758         [ #  # ]:          0 :         assert(m);
     759         [ #  # ]:          0 :         assert(fd >= 0);
     760         [ #  # ]:          0 :         assert(ret);
     761                 :            : 
     762                 :          0 :         ms = next_datagram_size_fd(fd);
     763         [ #  # ]:          0 :         if (ms < 0)
     764                 :          0 :                 return ms;
     765                 :            : 
     766                 :          0 :         r = dns_packet_new(&p, protocol, ms, DNS_PACKET_SIZE_MAX);
     767         [ #  # ]:          0 :         if (r < 0)
     768                 :          0 :                 return r;
     769                 :            : 
     770                 :          0 :         iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->allocated);
     771                 :            : 
     772                 :          0 :         l = recvmsg(fd, &mh, 0);
     773         [ #  # ]:          0 :         if (l < 0) {
     774   [ #  #  #  # ]:          0 :                 if (IN_SET(errno, EAGAIN, EINTR))
     775                 :          0 :                         return 0;
     776                 :            : 
     777                 :          0 :                 return -errno;
     778                 :            :         }
     779         [ #  # ]:          0 :         if (l == 0)
     780                 :          0 :                 return 0;
     781                 :            : 
     782         [ #  # ]:          0 :         assert(!(mh.msg_flags & MSG_CTRUNC));
     783         [ #  # ]:          0 :         assert(!(mh.msg_flags & MSG_TRUNC));
     784                 :            : 
     785                 :          0 :         p->size = (size_t) l;
     786                 :            : 
     787                 :          0 :         p->family = sa.sa.sa_family;
     788                 :          0 :         p->ipproto = IPPROTO_UDP;
     789         [ #  # ]:          0 :         if (p->family == AF_INET) {
     790                 :          0 :                 p->sender.in = sa.in.sin_addr;
     791                 :          0 :                 p->sender_port = be16toh(sa.in.sin_port);
     792         [ #  # ]:          0 :         } else if (p->family == AF_INET6) {
     793                 :          0 :                 p->sender.in6 = sa.in6.sin6_addr;
     794                 :          0 :                 p->sender_port = be16toh(sa.in6.sin6_port);
     795                 :          0 :                 p->ifindex = sa.in6.sin6_scope_id;
     796                 :            :         } else
     797                 :          0 :                 return -EAFNOSUPPORT;
     798                 :            : 
     799   [ #  #  #  # ]:          0 :         CMSG_FOREACH(cmsg, &mh) {
     800                 :            : 
     801         [ #  # ]:          0 :                 if (cmsg->cmsg_level == IPPROTO_IPV6) {
     802         [ #  # ]:          0 :                         assert(p->family == AF_INET6);
     803                 :            : 
     804      [ #  #  # ]:          0 :                         switch (cmsg->cmsg_type) {
     805                 :            : 
     806                 :          0 :                         case IPV6_PKTINFO: {
     807                 :          0 :                                 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
     808                 :            : 
     809         [ #  # ]:          0 :                                 if (p->ifindex <= 0)
     810                 :          0 :                                         p->ifindex = i->ipi6_ifindex;
     811                 :            : 
     812                 :          0 :                                 p->destination.in6 = i->ipi6_addr;
     813                 :          0 :                                 break;
     814                 :            :                         }
     815                 :            : 
     816                 :          0 :                         case IPV6_HOPLIMIT:
     817                 :          0 :                                 p->ttl = *(int *) CMSG_DATA(cmsg);
     818                 :          0 :                                 break;
     819                 :            : 
     820                 :            :                         }
     821         [ #  # ]:          0 :                 } else if (cmsg->cmsg_level == IPPROTO_IP) {
     822         [ #  # ]:          0 :                         assert(p->family == AF_INET);
     823                 :            : 
     824      [ #  #  # ]:          0 :                         switch (cmsg->cmsg_type) {
     825                 :            : 
     826                 :          0 :                         case IP_PKTINFO: {
     827                 :          0 :                                 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
     828                 :            : 
     829         [ #  # ]:          0 :                                 if (p->ifindex <= 0)
     830                 :          0 :                                         p->ifindex = i->ipi_ifindex;
     831                 :            : 
     832                 :          0 :                                 p->destination.in = i->ipi_addr;
     833                 :          0 :                                 break;
     834                 :            :                         }
     835                 :            : 
     836                 :          0 :                         case IP_TTL:
     837                 :          0 :                                 p->ttl = *(int *) CMSG_DATA(cmsg);
     838                 :          0 :                                 break;
     839                 :            :                         }
     840                 :          0 :                 }
     841                 :            :         }
     842                 :            : 
     843                 :            :         /* The Linux kernel sets the interface index to the loopback
     844                 :            :          * device if the packet came from the local host since it
     845                 :            :          * avoids the routing table in such a case. Let's unset the
     846                 :            :          * interface index in such a case. */
     847         [ #  # ]:          0 :         if (p->ifindex == LOOPBACK_IFINDEX)
     848                 :          0 :                 p->ifindex = 0;
     849                 :            : 
     850         [ #  # ]:          0 :         if (protocol != DNS_PROTOCOL_DNS) {
     851                 :            :                 /* If we don't know the interface index still, we look for the
     852                 :            :                  * first local interface with a matching address. Yuck! */
     853         [ #  # ]:          0 :                 if (p->ifindex <= 0)
     854                 :          0 :                         p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
     855                 :            :         }
     856                 :            : 
     857                 :          0 :         *ret = TAKE_PTR(p);
     858                 :            : 
     859                 :          0 :         return 1;
     860                 :            : }
     861                 :            : 
     862                 :          0 : static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
     863                 :            :         int r;
     864                 :            : 
     865         [ #  # ]:          0 :         assert(fd >= 0);
     866         [ #  # ]:          0 :         assert(mh);
     867                 :            : 
     868                 :            :         for (;;) {
     869         [ #  # ]:          0 :                 if (sendmsg(fd, mh, flags) >= 0)
     870                 :          0 :                         return 0;
     871                 :            : 
     872         [ #  # ]:          0 :                 if (errno == EINTR)
     873                 :          0 :                         continue;
     874                 :            : 
     875         [ #  # ]:          0 :                 if (errno != EAGAIN)
     876                 :          0 :                         return -errno;
     877                 :            : 
     878                 :          0 :                 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
     879         [ #  # ]:          0 :                 if (r < 0)
     880                 :          0 :                         return r;
     881         [ #  # ]:          0 :                 if (r == 0)
     882                 :          0 :                         return -ETIMEDOUT;
     883                 :            :         }
     884                 :            : }
     885                 :            : 
     886                 :          0 : static int write_loop(int fd, void *message, size_t length) {
     887                 :            :         int r;
     888                 :            : 
     889         [ #  # ]:          0 :         assert(fd >= 0);
     890         [ #  # ]:          0 :         assert(message);
     891                 :            : 
     892                 :            :         for (;;) {
     893         [ #  # ]:          0 :                 if (write(fd, message, length) >= 0)
     894                 :          0 :                         return 0;
     895                 :            : 
     896         [ #  # ]:          0 :                 if (errno == EINTR)
     897                 :          0 :                         continue;
     898                 :            : 
     899         [ #  # ]:          0 :                 if (errno != EAGAIN)
     900                 :          0 :                         return -errno;
     901                 :            : 
     902                 :          0 :                 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
     903         [ #  # ]:          0 :                 if (r < 0)
     904                 :          0 :                         return r;
     905         [ #  # ]:          0 :                 if (r == 0)
     906                 :          0 :                         return -ETIMEDOUT;
     907                 :            :         }
     908                 :            : }
     909                 :            : 
     910                 :          0 : int manager_write(Manager *m, int fd, DnsPacket *p) {
     911                 :            :         int r;
     912                 :            : 
     913   [ #  #  #  # ]:          0 :         log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
     914                 :            : 
     915                 :          0 :         r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
     916         [ #  # ]:          0 :         if (r < 0)
     917                 :          0 :                 return r;
     918                 :            : 
     919                 :          0 :         return 0;
     920                 :            : }
     921                 :            : 
     922                 :          0 : static int manager_ipv4_send(
     923                 :            :                 Manager *m,
     924                 :            :                 int fd,
     925                 :            :                 int ifindex,
     926                 :            :                 const struct in_addr *destination,
     927                 :            :                 uint16_t port,
     928                 :            :                 const struct in_addr *source,
     929                 :            :                 DnsPacket *p) {
     930                 :            :         union {
     931                 :            :                 struct cmsghdr header; /* For alignment */
     932                 :            :                 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
     933                 :          0 :         } control = {};
     934                 :            :         union sockaddr_union sa;
     935                 :            :         struct iovec iov;
     936                 :          0 :         struct msghdr mh = {
     937                 :            :                 .msg_iov = &iov,
     938                 :            :                 .msg_iovlen = 1,
     939                 :            :                 .msg_name = &sa.sa,
     940                 :            :                 .msg_namelen = sizeof(sa.in),
     941                 :            :         };
     942                 :            : 
     943         [ #  # ]:          0 :         assert(m);
     944         [ #  # ]:          0 :         assert(fd >= 0);
     945         [ #  # ]:          0 :         assert(destination);
     946         [ #  # ]:          0 :         assert(port > 0);
     947         [ #  # ]:          0 :         assert(p);
     948                 :            : 
     949                 :          0 :         iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->size);
     950                 :            : 
     951                 :          0 :         sa = (union sockaddr_union) {
     952                 :            :                 .in.sin_family = AF_INET,
     953                 :          0 :                 .in.sin_addr = *destination,
     954                 :          0 :                 .in.sin_port = htobe16(port),
     955                 :            :         };
     956                 :            : 
     957         [ #  # ]:          0 :         if (ifindex > 0) {
     958                 :            :                 struct cmsghdr *cmsg;
     959                 :            :                 struct in_pktinfo *pi;
     960                 :            : 
     961                 :          0 :                 mh.msg_control = &control;
     962                 :          0 :                 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
     963                 :            : 
     964         [ #  # ]:          0 :                 cmsg = CMSG_FIRSTHDR(&mh);
     965                 :          0 :                 cmsg->cmsg_len = mh.msg_controllen;
     966                 :          0 :                 cmsg->cmsg_level = IPPROTO_IP;
     967                 :          0 :                 cmsg->cmsg_type = IP_PKTINFO;
     968                 :            : 
     969                 :          0 :                 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
     970                 :          0 :                 pi->ipi_ifindex = ifindex;
     971                 :            : 
     972         [ #  # ]:          0 :                 if (source)
     973                 :          0 :                         pi->ipi_spec_dst = *source;
     974                 :            :         }
     975                 :            : 
     976                 :          0 :         return sendmsg_loop(fd, &mh, 0);
     977                 :            : }
     978                 :            : 
     979                 :          0 : static int manager_ipv6_send(
     980                 :            :                 Manager *m,
     981                 :            :                 int fd,
     982                 :            :                 int ifindex,
     983                 :            :                 const struct in6_addr *destination,
     984                 :            :                 uint16_t port,
     985                 :            :                 const struct in6_addr *source,
     986                 :            :                 DnsPacket *p) {
     987                 :            : 
     988                 :            :         union {
     989                 :            :                 struct cmsghdr header; /* For alignment */
     990                 :            :                 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
     991                 :          0 :         } control = {};
     992                 :            :         union sockaddr_union sa;
     993                 :            :         struct iovec iov;
     994                 :          0 :         struct msghdr mh = {
     995                 :            :                 .msg_iov = &iov,
     996                 :            :                 .msg_iovlen = 1,
     997                 :            :                 .msg_name = &sa.sa,
     998                 :            :                 .msg_namelen = sizeof(sa.in6),
     999                 :            :         };
    1000                 :            : 
    1001         [ #  # ]:          0 :         assert(m);
    1002         [ #  # ]:          0 :         assert(fd >= 0);
    1003         [ #  # ]:          0 :         assert(destination);
    1004         [ #  # ]:          0 :         assert(port > 0);
    1005         [ #  # ]:          0 :         assert(p);
    1006                 :            : 
    1007                 :          0 :         iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->size);
    1008                 :            : 
    1009                 :          0 :         sa = (union sockaddr_union) {
    1010                 :            :                 .in6.sin6_family = AF_INET6,
    1011                 :          0 :                 .in6.sin6_addr = *destination,
    1012                 :          0 :                 .in6.sin6_port = htobe16(port),
    1013                 :            :                 .in6.sin6_scope_id = ifindex,
    1014                 :            :         };
    1015                 :            : 
    1016         [ #  # ]:          0 :         if (ifindex > 0) {
    1017                 :            :                 struct cmsghdr *cmsg;
    1018                 :            :                 struct in6_pktinfo *pi;
    1019                 :            : 
    1020                 :          0 :                 mh.msg_control = &control;
    1021                 :          0 :                 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
    1022                 :            : 
    1023         [ #  # ]:          0 :                 cmsg = CMSG_FIRSTHDR(&mh);
    1024                 :          0 :                 cmsg->cmsg_len = mh.msg_controllen;
    1025                 :          0 :                 cmsg->cmsg_level = IPPROTO_IPV6;
    1026                 :          0 :                 cmsg->cmsg_type = IPV6_PKTINFO;
    1027                 :            : 
    1028                 :          0 :                 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
    1029                 :          0 :                 pi->ipi6_ifindex = ifindex;
    1030                 :            : 
    1031         [ #  # ]:          0 :                 if (source)
    1032                 :          0 :                         pi->ipi6_addr = *source;
    1033                 :            :         }
    1034                 :            : 
    1035                 :          0 :         return sendmsg_loop(fd, &mh, 0);
    1036                 :            : }
    1037                 :            : 
    1038                 :          0 : int manager_send(
    1039                 :            :                 Manager *m,
    1040                 :            :                 int fd,
    1041                 :            :                 int ifindex,
    1042                 :            :                 int family,
    1043                 :            :                 const union in_addr_union *destination,
    1044                 :            :                 uint16_t port,
    1045                 :            :                 const union in_addr_union *source,
    1046                 :            :                 DnsPacket *p) {
    1047                 :            : 
    1048         [ #  # ]:          0 :         assert(m);
    1049         [ #  # ]:          0 :         assert(fd >= 0);
    1050         [ #  # ]:          0 :         assert(destination);
    1051         [ #  # ]:          0 :         assert(port > 0);
    1052         [ #  # ]:          0 :         assert(p);
    1053                 :            : 
    1054   [ #  #  #  # ]:          0 :         log_debug("Sending %s packet with id %" PRIu16 " on interface %i/%s.", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
    1055                 :            : 
    1056         [ #  # ]:          0 :         if (family == AF_INET)
    1057         [ #  # ]:          0 :                 return manager_ipv4_send(m, fd, ifindex, &destination->in, port, source ? &source->in : NULL, p);
    1058         [ #  # ]:          0 :         if (family == AF_INET6)
    1059         [ #  # ]:          0 :                 return manager_ipv6_send(m, fd, ifindex, &destination->in6, port, source ? &source->in6 : NULL, p);
    1060                 :            : 
    1061                 :          0 :         return -EAFNOSUPPORT;
    1062                 :            : }
    1063                 :            : 
    1064                 :          0 : uint32_t manager_find_mtu(Manager *m) {
    1065                 :          0 :         uint32_t mtu = 0;
    1066                 :            :         Link *l;
    1067                 :            :         Iterator i;
    1068                 :            : 
    1069                 :            :         /* If we don't know on which link a DNS packet would be
    1070                 :            :          * delivered, let's find the largest MTU that works on all
    1071                 :            :          * interfaces we know of */
    1072                 :            : 
    1073         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i) {
    1074         [ #  # ]:          0 :                 if (l->mtu <= 0)
    1075                 :          0 :                         continue;
    1076                 :            : 
    1077   [ #  #  #  # ]:          0 :                 if (mtu <= 0 || l->mtu < mtu)
    1078                 :          0 :                         mtu = l->mtu;
    1079                 :            :         }
    1080                 :            : 
    1081                 :          0 :         return mtu;
    1082                 :            : }
    1083                 :            : 
    1084                 :          0 : int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
    1085                 :            :         LinkAddress *a;
    1086                 :            : 
    1087         [ #  # ]:          0 :         assert(m);
    1088                 :            : 
    1089                 :          0 :         a = manager_find_link_address(m, family, in_addr);
    1090         [ #  # ]:          0 :         if (a)
    1091                 :          0 :                 return a->link->ifindex;
    1092                 :            : 
    1093                 :          0 :         return 0;
    1094                 :            : }
    1095                 :            : 
    1096                 :          0 : void manager_refresh_rrs(Manager *m) {
    1097                 :            :         Iterator i;
    1098                 :            :         Link *l;
    1099                 :            :         DnssdService *s;
    1100                 :            : 
    1101         [ #  # ]:          0 :         assert(m);
    1102                 :            : 
    1103                 :          0 :         m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
    1104                 :          0 :         m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
    1105                 :          0 :         m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
    1106                 :          0 :         m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
    1107                 :            : 
    1108         [ #  # ]:          0 :         if (m->mdns_support == RESOLVE_SUPPORT_YES)
    1109         [ #  # ]:          0 :                 HASHMAP_FOREACH(s, m->dnssd_services, i)
    1110         [ #  # ]:          0 :                         if (dnssd_update_rrs(s) < 0)
    1111         [ #  # ]:          0 :                                 log_warning("Failed to refresh DNS-SD service '%s'", s->name);
    1112                 :            : 
    1113         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i) {
    1114                 :          0 :                 link_add_rrs(l, true);
    1115                 :          0 :                 link_add_rrs(l, false);
    1116                 :            :         }
    1117                 :          0 : }
    1118                 :            : 
    1119                 :          0 : static int manager_next_random_name(const char *old, char **ret_new) {
    1120                 :            :         const char *p;
    1121                 :            :         uint64_t u, a;
    1122                 :            :         char *n;
    1123                 :            : 
    1124                 :          0 :         p = strchr(old, 0);
    1125         [ #  # ]:          0 :         assert(p);
    1126                 :            : 
    1127         [ #  # ]:          0 :         while (p > old) {
    1128         [ #  # ]:          0 :                 if (!strchr(DIGITS, p[-1]))
    1129                 :          0 :                         break;
    1130                 :            : 
    1131                 :          0 :                 p--;
    1132                 :            :         }
    1133                 :            : 
    1134   [ #  #  #  #  :          0 :         if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
                   #  # ]
    1135                 :          0 :                 u = 1;
    1136                 :            : 
    1137                 :            :         /* Add a random number to the old value. This way we can avoid
    1138                 :            :          * that two hosts pick the same hostname, win on IPv4 and lose
    1139                 :            :          * on IPv6 (or vice versa), and pick the same hostname
    1140                 :            :          * replacement hostname, ad infinitum. We still want the
    1141                 :            :          * numbers to go up monotonically, hence we just add a random
    1142                 :            :          * value 1..10 */
    1143                 :            : 
    1144                 :          0 :         random_bytes(&a, sizeof(a));
    1145                 :          0 :         u += 1 + a % 10;
    1146                 :            : 
    1147         [ #  # ]:          0 :         if (asprintf(&n, "%.*s%" PRIu64, (int) (p - old), old, u) < 0)
    1148                 :          0 :                 return -ENOMEM;
    1149                 :            : 
    1150                 :          0 :         *ret_new = n;
    1151                 :            : 
    1152                 :          0 :         return 0;
    1153                 :            : }
    1154                 :            : 
    1155                 :          0 : int manager_next_hostname(Manager *m) {
    1156                 :          0 :         _cleanup_free_ char *h = NULL, *k = NULL;
    1157                 :            :         int r;
    1158                 :            : 
    1159         [ #  # ]:          0 :         assert(m);
    1160                 :            : 
    1161                 :          0 :         r = manager_next_random_name(m->llmnr_hostname, &h);
    1162         [ #  # ]:          0 :         if (r < 0)
    1163                 :          0 :                 return r;
    1164                 :            : 
    1165                 :          0 :         r = dns_name_concat(h, "local", 0, &k);
    1166         [ #  # ]:          0 :         if (r < 0)
    1167                 :          0 :                 return r;
    1168                 :            : 
    1169         [ #  # ]:          0 :         log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
    1170                 :            : 
    1171                 :          0 :         free_and_replace(m->llmnr_hostname, h);
    1172                 :          0 :         free_and_replace(m->mdns_hostname, k);
    1173                 :            : 
    1174                 :          0 :         manager_refresh_rrs(m);
    1175                 :            : 
    1176                 :          0 :         return 0;
    1177                 :            : }
    1178                 :            : 
    1179                 :          0 : LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
    1180                 :            :         Iterator i;
    1181                 :            :         Link *l;
    1182                 :            : 
    1183         [ #  # ]:          0 :         assert(m);
    1184                 :            : 
    1185         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i) {
    1186                 :            :                 LinkAddress *a;
    1187                 :            : 
    1188                 :          0 :                 a = link_find_address(l, family, in_addr);
    1189         [ #  # ]:          0 :                 if (a)
    1190                 :          0 :                         return a;
    1191                 :            :         }
    1192                 :            : 
    1193                 :          0 :         return NULL;
    1194                 :            : }
    1195                 :            : 
    1196                 :          0 : bool manager_our_packet(Manager *m, DnsPacket *p) {
    1197         [ #  # ]:          0 :         assert(m);
    1198         [ #  # ]:          0 :         assert(p);
    1199                 :            : 
    1200                 :          0 :         return !!manager_find_link_address(m, p->family, &p->sender);
    1201                 :            : }
    1202                 :            : 
    1203                 :          0 : DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
    1204                 :            :         Link *l;
    1205                 :            : 
    1206         [ #  # ]:          0 :         assert(m);
    1207         [ #  # ]:          0 :         assert(p);
    1208                 :            : 
    1209                 :          0 :         l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
    1210         [ #  # ]:          0 :         if (!l)
    1211                 :          0 :                 return NULL;
    1212                 :            : 
    1213      [ #  #  # ]:          0 :         switch (p->protocol) {
    1214                 :          0 :         case DNS_PROTOCOL_LLMNR:
    1215         [ #  # ]:          0 :                 if (p->family == AF_INET)
    1216                 :          0 :                         return l->llmnr_ipv4_scope;
    1217         [ #  # ]:          0 :                 else if (p->family == AF_INET6)
    1218                 :          0 :                         return l->llmnr_ipv6_scope;
    1219                 :            : 
    1220                 :          0 :                 break;
    1221                 :            : 
    1222                 :          0 :         case DNS_PROTOCOL_MDNS:
    1223         [ #  # ]:          0 :                 if (p->family == AF_INET)
    1224                 :          0 :                         return l->mdns_ipv4_scope;
    1225         [ #  # ]:          0 :                 else if (p->family == AF_INET6)
    1226                 :          0 :                         return l->mdns_ipv6_scope;
    1227                 :            : 
    1228                 :          0 :                 break;
    1229                 :            : 
    1230                 :          0 :         default:
    1231                 :          0 :                 break;
    1232                 :            :         }
    1233                 :            : 
    1234                 :          0 :         return NULL;
    1235                 :            : }
    1236                 :            : 
    1237                 :          0 : void manager_verify_all(Manager *m) {
    1238                 :            :         DnsScope *s;
    1239                 :            : 
    1240         [ #  # ]:          0 :         assert(m);
    1241                 :            : 
    1242         [ #  # ]:          0 :         LIST_FOREACH(scopes, s, m->dns_scopes)
    1243                 :          0 :                 dns_zone_verify_all(&s->zone);
    1244                 :          0 : }
    1245                 :            : 
    1246                 :          0 : int manager_is_own_hostname(Manager *m, const char *name) {
    1247                 :            :         int r;
    1248                 :            : 
    1249         [ #  # ]:          0 :         assert(m);
    1250         [ #  # ]:          0 :         assert(name);
    1251                 :            : 
    1252         [ #  # ]:          0 :         if (m->llmnr_hostname) {
    1253                 :          0 :                 r = dns_name_equal(name, m->llmnr_hostname);
    1254         [ #  # ]:          0 :                 if (r != 0)
    1255                 :          0 :                         return r;
    1256                 :            :         }
    1257                 :            : 
    1258         [ #  # ]:          0 :         if (m->mdns_hostname) {
    1259                 :          0 :                 r = dns_name_equal(name, m->mdns_hostname);
    1260         [ #  # ]:          0 :                 if (r != 0)
    1261                 :          0 :                         return r;
    1262                 :            :         }
    1263                 :            : 
    1264         [ #  # ]:          0 :         if (m->full_hostname)
    1265                 :          0 :                 return dns_name_equal(name, m->full_hostname);
    1266                 :            : 
    1267                 :          0 :         return 0;
    1268                 :            : }
    1269                 :            : 
    1270                 :          0 : int manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
    1271                 :            :         DnsServer *s;
    1272                 :            :         Iterator i;
    1273                 :            :         Link *l;
    1274                 :            :         int r;
    1275                 :            : 
    1276         [ #  # ]:          0 :         assert(m);
    1277         [ #  # ]:          0 :         assert(dns);
    1278                 :            : 
    1279                 :          0 :         r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
    1280         [ #  # ]:          0 :         if (r < 0)
    1281                 :          0 :                 return r;
    1282                 :            : 
    1283                 :            :         /* First add the system-wide servers and domains */
    1284         [ #  # ]:          0 :         LIST_FOREACH(servers, s, m->dns_servers) {
    1285                 :          0 :                 r = ordered_set_put(*dns, s);
    1286         [ #  # ]:          0 :                 if (r == -EEXIST)
    1287                 :          0 :                         continue;
    1288         [ #  # ]:          0 :                 if (r < 0)
    1289                 :          0 :                         return r;
    1290                 :            :         }
    1291                 :            : 
    1292                 :            :         /* Then, add the per-link servers */
    1293         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i) {
    1294         [ #  # ]:          0 :                 LIST_FOREACH(servers, s, l->dns_servers) {
    1295                 :          0 :                         r = ordered_set_put(*dns, s);
    1296         [ #  # ]:          0 :                         if (r == -EEXIST)
    1297                 :          0 :                                 continue;
    1298         [ #  # ]:          0 :                         if (r < 0)
    1299                 :          0 :                                 return r;
    1300                 :            :                 }
    1301                 :            :         }
    1302                 :            : 
    1303                 :            :         /* If we found nothing, add the fallback servers */
    1304         [ #  # ]:          0 :         if (ordered_set_isempty(*dns)) {
    1305         [ #  # ]:          0 :                 LIST_FOREACH(servers, s, m->fallback_dns_servers) {
    1306                 :          0 :                         r = ordered_set_put(*dns, s);
    1307         [ #  # ]:          0 :                         if (r == -EEXIST)
    1308                 :          0 :                                 continue;
    1309         [ #  # ]:          0 :                         if (r < 0)
    1310                 :          0 :                                 return r;
    1311                 :            :                 }
    1312                 :            :         }
    1313                 :            : 
    1314                 :          0 :         return 0;
    1315                 :            : }
    1316                 :            : 
    1317                 :            : /* filter_route is a tri-state:
    1318                 :            :  *   < 0: no filtering
    1319                 :            :  *   = 0 or false: return only domains which should be used for searching
    1320                 :            :  *   > 0 or true: return only domains which are for routing only
    1321                 :            :  */
    1322                 :          0 : int manager_compile_search_domains(Manager *m, OrderedSet **domains, int filter_route) {
    1323                 :            :         DnsSearchDomain *d;
    1324                 :            :         Iterator i;
    1325                 :            :         Link *l;
    1326                 :            :         int r;
    1327                 :            : 
    1328         [ #  # ]:          0 :         assert(m);
    1329         [ #  # ]:          0 :         assert(domains);
    1330                 :            : 
    1331                 :          0 :         r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
    1332         [ #  # ]:          0 :         if (r < 0)
    1333                 :          0 :                 return r;
    1334                 :            : 
    1335         [ #  # ]:          0 :         LIST_FOREACH(domains, d, m->search_domains) {
    1336                 :            : 
    1337         [ #  # ]:          0 :                 if (filter_route >= 0 &&
    1338         [ #  # ]:          0 :                     d->route_only != !!filter_route)
    1339                 :          0 :                         continue;
    1340                 :            : 
    1341                 :          0 :                 r = ordered_set_put(*domains, d->name);
    1342         [ #  # ]:          0 :                 if (r == -EEXIST)
    1343                 :          0 :                         continue;
    1344         [ #  # ]:          0 :                 if (r < 0)
    1345                 :          0 :                         return r;
    1346                 :            :         }
    1347                 :            : 
    1348         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i) {
    1349                 :            : 
    1350         [ #  # ]:          0 :                 LIST_FOREACH(domains, d, l->search_domains) {
    1351                 :            : 
    1352         [ #  # ]:          0 :                         if (filter_route >= 0 &&
    1353         [ #  # ]:          0 :                             d->route_only != !!filter_route)
    1354                 :          0 :                                 continue;
    1355                 :            : 
    1356                 :          0 :                         r = ordered_set_put(*domains, d->name);
    1357         [ #  # ]:          0 :                         if (r == -EEXIST)
    1358                 :          0 :                                 continue;
    1359         [ #  # ]:          0 :                         if (r < 0)
    1360                 :          0 :                                 return r;
    1361                 :            :                 }
    1362                 :            :         }
    1363                 :            : 
    1364                 :          0 :         return 0;
    1365                 :            : }
    1366                 :            : 
    1367                 :          0 : DnssecMode manager_get_dnssec_mode(Manager *m) {
    1368         [ #  # ]:          0 :         assert(m);
    1369                 :            : 
    1370         [ #  # ]:          0 :         if (m->dnssec_mode != _DNSSEC_MODE_INVALID)
    1371                 :          0 :                 return m->dnssec_mode;
    1372                 :            : 
    1373                 :          0 :         return DNSSEC_NO;
    1374                 :            : }
    1375                 :            : 
    1376                 :          0 : bool manager_dnssec_supported(Manager *m) {
    1377                 :            :         DnsServer *server;
    1378                 :            :         Iterator i;
    1379                 :            :         Link *l;
    1380                 :            : 
    1381         [ #  # ]:          0 :         assert(m);
    1382                 :            : 
    1383         [ #  # ]:          0 :         if (manager_get_dnssec_mode(m) == DNSSEC_NO)
    1384                 :          0 :                 return false;
    1385                 :            : 
    1386                 :          0 :         server = manager_get_dns_server(m);
    1387   [ #  #  #  # ]:          0 :         if (server && !dns_server_dnssec_supported(server))
    1388                 :          0 :                 return false;
    1389                 :            : 
    1390         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i)
    1391         [ #  # ]:          0 :                 if (!link_dnssec_supported(l))
    1392                 :          0 :                         return false;
    1393                 :            : 
    1394                 :          0 :         return true;
    1395                 :            : }
    1396                 :            : 
    1397                 :          0 : DnsOverTlsMode manager_get_dns_over_tls_mode(Manager *m) {
    1398         [ #  # ]:          0 :         assert(m);
    1399                 :            : 
    1400         [ #  # ]:          0 :         if (m->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
    1401                 :          0 :                 return m->dns_over_tls_mode;
    1402                 :            : 
    1403                 :          0 :         return DNS_OVER_TLS_NO;
    1404                 :            : }
    1405                 :            : 
    1406                 :          0 : void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {
    1407                 :            : 
    1408         [ #  # ]:          0 :         assert(verdict >= 0);
    1409         [ #  # ]:          0 :         assert(verdict < _DNSSEC_VERDICT_MAX);
    1410                 :            : 
    1411         [ #  # ]:          0 :         if (DEBUG_LOGGING) {
    1412                 :            :                 char s[DNS_RESOURCE_KEY_STRING_MAX];
    1413                 :            : 
    1414         [ #  # ]:          0 :                 log_debug("Found verdict for lookup %s: %s",
    1415                 :            :                           dns_resource_key_to_string(key, s, sizeof s),
    1416                 :            :                           dnssec_verdict_to_string(verdict));
    1417                 :            :         }
    1418                 :            : 
    1419                 :          0 :         m->n_dnssec_verdict[verdict]++;
    1420                 :          0 : }
    1421                 :            : 
    1422                 :          0 : bool manager_routable(Manager *m, int family) {
    1423                 :            :         Iterator i;
    1424                 :            :         Link *l;
    1425                 :            : 
    1426         [ #  # ]:          0 :         assert(m);
    1427                 :            : 
    1428                 :            :         /* Returns true if the host has at least one interface with a routable address of the specified type */
    1429                 :            : 
    1430         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i)
    1431         [ #  # ]:          0 :                 if (link_relevant(l, family, false))
    1432                 :          0 :                         return true;
    1433                 :            : 
    1434                 :          0 :         return false;
    1435                 :            : }
    1436                 :            : 
    1437                 :          0 : void manager_flush_caches(Manager *m) {
    1438                 :            :         DnsScope *scope;
    1439                 :            : 
    1440         [ #  # ]:          0 :         assert(m);
    1441                 :            : 
    1442         [ #  # ]:          0 :         LIST_FOREACH(scopes, scope, m->dns_scopes)
    1443                 :          0 :                 dns_cache_flush(&scope->cache);
    1444                 :            : 
    1445         [ #  # ]:          0 :         log_info("Flushed all caches.");
    1446                 :          0 : }
    1447                 :            : 
    1448                 :          0 : void manager_reset_server_features(Manager *m) {
    1449                 :            :         Iterator i;
    1450                 :            :         Link *l;
    1451                 :            : 
    1452                 :          0 :         dns_server_reset_features_all(m->dns_servers);
    1453                 :          0 :         dns_server_reset_features_all(m->fallback_dns_servers);
    1454                 :            : 
    1455         [ #  # ]:          0 :         HASHMAP_FOREACH(l, m->links, i)
    1456                 :          0 :                 dns_server_reset_features_all(l->dns_servers);
    1457                 :            : 
    1458         [ #  # ]:          0 :         log_info("Resetting learnt feature levels on all servers.");
    1459                 :          0 : }
    1460                 :            : 
    1461                 :          0 : void manager_cleanup_saved_user(Manager *m) {
    1462         [ #  # ]:          0 :         _cleanup_closedir_ DIR *d = NULL;
    1463                 :            :         struct dirent *de;
    1464                 :            :         int r;
    1465                 :            : 
    1466         [ #  # ]:          0 :         assert(m);
    1467                 :            : 
    1468                 :            :         /* Clean up all saved per-link files in /run/systemd/resolve/netif/ that don't have a matching interface
    1469                 :            :          * anymore. These files are created to persist settings pushed in by the user via the bus, so that resolved can
    1470                 :            :          * be restarted without losing this data. */
    1471                 :            : 
    1472                 :          0 :         d = opendir("/run/systemd/resolve/netif/");
    1473         [ #  # ]:          0 :         if (!d) {
    1474         [ #  # ]:          0 :                 if (errno == ENOENT)
    1475                 :          0 :                         return;
    1476                 :            : 
    1477         [ #  # ]:          0 :                 log_warning_errno(errno, "Failed to open interface directory: %m");
    1478                 :          0 :                 return;
    1479                 :            :         }
    1480                 :            : 
    1481   [ #  #  #  #  :          0 :         FOREACH_DIRENT_ALL(de, d, log_error_errno(errno, "Failed to read interface directory: %m")) {
                   #  # ]
    1482      [ #  #  # ]:          0 :                 _cleanup_free_ char *p = NULL;
    1483                 :            :                 int ifindex;
    1484                 :            :                 Link *l;
    1485                 :            : 
    1486   [ #  #  #  # ]:          0 :                 if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG))
    1487                 :          0 :                         continue;
    1488                 :            : 
    1489         [ #  # ]:          0 :                 if (dot_or_dot_dot(de->d_name))
    1490                 :          0 :                         continue;
    1491                 :            : 
    1492                 :          0 :                 r = parse_ifindex(de->d_name, &ifindex);
    1493         [ #  # ]:          0 :                 if (r < 0) /* Probably some temporary file from a previous run. Delete it */
    1494                 :          0 :                         goto rm;
    1495                 :            : 
    1496                 :          0 :                 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
    1497         [ #  # ]:          0 :                 if (!l) /* link vanished */
    1498                 :          0 :                         goto rm;
    1499                 :            : 
    1500         [ #  # ]:          0 :                 if (l->is_managed) /* now managed by networkd, hence the bus settings are useless */
    1501                 :          0 :                         goto rm;
    1502                 :            : 
    1503                 :          0 :                 continue;
    1504                 :            : 
    1505                 :          0 :         rm:
    1506                 :          0 :                 p = path_join("/run/systemd/resolve/netif", de->d_name);
    1507         [ #  # ]:          0 :                 if (!p) {
    1508                 :          0 :                         log_oom();
    1509                 :          0 :                         return;
    1510                 :            :                 }
    1511                 :            : 
    1512                 :          0 :                 (void) unlink(p);
    1513                 :            :         }
    1514                 :            : }
    1515                 :            : 
    1516                 :          0 : bool manager_next_dnssd_names(Manager *m) {
    1517                 :            :         Iterator i;
    1518                 :            :         DnssdService *s;
    1519                 :          0 :         bool tried = false;
    1520                 :            :         int r;
    1521                 :            : 
    1522         [ #  # ]:          0 :         assert(m);
    1523                 :            : 
    1524         [ #  # ]:          0 :         HASHMAP_FOREACH(s, m->dnssd_services, i) {
    1525         [ #  # ]:          0 :                 _cleanup_free_ char * new_name = NULL;
    1526                 :            : 
    1527         [ #  # ]:          0 :                 if (!s->withdrawn)
    1528                 :          0 :                         continue;
    1529                 :            : 
    1530                 :          0 :                 r = manager_next_random_name(s->name_template, &new_name);
    1531         [ #  # ]:          0 :                 if (r < 0) {
    1532         [ #  # ]:          0 :                         log_warning_errno(r, "Failed to get new name for service '%s': %m", s->name);
    1533                 :          0 :                         continue;
    1534                 :            :                 }
    1535                 :            : 
    1536                 :          0 :                 free_and_replace(s->name_template, new_name);
    1537                 :            : 
    1538                 :          0 :                 s->withdrawn = false;
    1539                 :            : 
    1540                 :          0 :                 tried = true;
    1541                 :            :         }
    1542                 :            : 
    1543         [ #  # ]:          0 :         if (tried)
    1544                 :          0 :                 manager_refresh_rrs(m);
    1545                 :            : 
    1546                 :          0 :         return tried;
    1547                 :            : }

Generated by: LCOV version 1.14