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

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "sd-messages.h"
       4                 :            : 
       5                 :            : #include "alloc-util.h"
       6                 :            : #include "resolved-dns-server.h"
       7                 :            : #include "resolved-dns-stub.h"
       8                 :            : #include "resolved-resolv-conf.h"
       9                 :            : #include "siphash24.h"
      10                 :            : #include "string-table.h"
      11                 :            : #include "string-util.h"
      12                 :            : 
      13                 :            : /* The amount of time to wait before retrying with a full feature set */
      14                 :            : #define DNS_SERVER_FEATURE_GRACE_PERIOD_MAX_USEC (6 * USEC_PER_HOUR)
      15                 :            : #define DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC (5 * USEC_PER_MINUTE)
      16                 :            : 
      17                 :            : /* The number of times we will attempt a certain feature set before degrading */
      18                 :            : #define DNS_SERVER_FEATURE_RETRY_ATTEMPTS 3
      19                 :            : 
      20                 :          0 : int dns_server_new(
      21                 :            :                 Manager *m,
      22                 :            :                 DnsServer **ret,
      23                 :            :                 DnsServerType type,
      24                 :            :                 Link *l,
      25                 :            :                 int family,
      26                 :            :                 const union in_addr_union *in_addr,
      27                 :            :                 int ifindex) {
      28                 :            : 
      29                 :            :         DnsServer *s;
      30                 :            : 
      31         [ #  # ]:          0 :         assert(m);
      32         [ #  # ]:          0 :         assert((type == DNS_SERVER_LINK) == !!l);
      33         [ #  # ]:          0 :         assert(in_addr);
      34                 :            : 
      35   [ #  #  #  # ]:          0 :         if (!IN_SET(family, AF_INET, AF_INET6))
      36                 :          0 :                 return -EAFNOSUPPORT;
      37                 :            : 
      38         [ #  # ]:          0 :         if (l) {
      39         [ #  # ]:          0 :                 if (l->n_dns_servers >= LINK_DNS_SERVERS_MAX)
      40                 :          0 :                         return -E2BIG;
      41                 :            :         } else {
      42         [ #  # ]:          0 :                 if (m->n_dns_servers >= MANAGER_DNS_SERVERS_MAX)
      43                 :          0 :                         return -E2BIG;
      44                 :            :         }
      45                 :            : 
      46                 :          0 :         s = new(DnsServer, 1);
      47         [ #  # ]:          0 :         if (!s)
      48                 :          0 :                 return -ENOMEM;
      49                 :            : 
      50                 :          0 :         *s = (DnsServer) {
      51                 :            :                 .n_ref = 1,
      52                 :            :                 .manager = m,
      53                 :            :                 .type = type,
      54                 :            :                 .family = family,
      55                 :          0 :                 .address = *in_addr,
      56                 :            :                 .ifindex = ifindex,
      57                 :            :         };
      58                 :            : 
      59                 :          0 :         dns_server_reset_features(s);
      60                 :            : 
      61   [ #  #  #  # ]:          0 :         switch (type) {
      62                 :            : 
      63                 :          0 :         case DNS_SERVER_LINK:
      64                 :          0 :                 s->link = l;
      65   [ #  #  #  #  :          0 :                 LIST_APPEND(servers, l->dns_servers, s);
          #  #  #  #  #  
                #  #  # ]
      66                 :          0 :                 l->n_dns_servers++;
      67                 :          0 :                 break;
      68                 :            : 
      69                 :          0 :         case DNS_SERVER_SYSTEM:
      70   [ #  #  #  #  :          0 :                 LIST_APPEND(servers, m->dns_servers, s);
          #  #  #  #  #  
                #  #  # ]
      71                 :          0 :                 m->n_dns_servers++;
      72                 :          0 :                 break;
      73                 :            : 
      74                 :          0 :         case DNS_SERVER_FALLBACK:
      75   [ #  #  #  #  :          0 :                 LIST_APPEND(servers, m->fallback_dns_servers, s);
          #  #  #  #  #  
                #  #  # ]
      76                 :          0 :                 m->n_dns_servers++;
      77                 :          0 :                 break;
      78                 :            : 
      79                 :          0 :         default:
      80                 :          0 :                 assert_not_reached("Unknown server type");
      81                 :            :         }
      82                 :            : 
      83                 :          0 :         s->linked = true;
      84                 :            : 
      85                 :            :         /* A new DNS server that isn't fallback is added and the one
      86                 :            :          * we used so far was a fallback one? Then let's try to pick
      87                 :            :          * the new one */
      88         [ #  # ]:          0 :         if (type != DNS_SERVER_FALLBACK &&
      89         [ #  # ]:          0 :             m->current_dns_server &&
      90         [ #  # ]:          0 :             m->current_dns_server->type == DNS_SERVER_FALLBACK)
      91                 :          0 :                 manager_set_dns_server(m, NULL);
      92                 :            : 
      93         [ #  # ]:          0 :         if (ret)
      94                 :          0 :                 *ret = s;
      95                 :            : 
      96                 :          0 :         return 0;
      97                 :            : }
      98                 :            : 
      99                 :          0 : static DnsServer* dns_server_free(DnsServer *s)  {
     100         [ #  # ]:          0 :         assert(s);
     101                 :            : 
     102                 :          0 :         dns_server_unref_stream(s);
     103                 :            : 
     104                 :            : #if ENABLE_DNS_OVER_TLS
     105                 :          0 :         dnstls_server_free(s);
     106                 :            : #endif
     107                 :            : 
     108                 :          0 :         free(s->server_string);
     109                 :          0 :         return mfree(s);
     110                 :            : }
     111                 :            : 
     112   [ #  #  #  #  :          0 : DEFINE_TRIVIAL_REF_UNREF_FUNC(DnsServer, dns_server, dns_server_free);
                   #  # ]
     113                 :            : 
     114                 :          0 : void dns_server_unlink(DnsServer *s) {
     115         [ #  # ]:          0 :         assert(s);
     116         [ #  # ]:          0 :         assert(s->manager);
     117                 :            : 
     118                 :            :         /* This removes the specified server from the linked list of
     119                 :            :          * servers, but any server might still stay around if it has
     120                 :            :          * refs, for example from an ongoing transaction. */
     121                 :            : 
     122         [ #  # ]:          0 :         if (!s->linked)
     123                 :          0 :                 return;
     124                 :            : 
     125   [ #  #  #  # ]:          0 :         switch (s->type) {
     126                 :            : 
     127                 :          0 :         case DNS_SERVER_LINK:
     128         [ #  # ]:          0 :                 assert(s->link);
     129         [ #  # ]:          0 :                 assert(s->link->n_dns_servers > 0);
     130   [ #  #  #  #  :          0 :                 LIST_REMOVE(servers, s->link->dns_servers, s);
             #  #  #  # ]
     131                 :          0 :                 s->link->n_dns_servers--;
     132                 :          0 :                 break;
     133                 :            : 
     134                 :          0 :         case DNS_SERVER_SYSTEM:
     135         [ #  # ]:          0 :                 assert(s->manager->n_dns_servers > 0);
     136   [ #  #  #  #  :          0 :                 LIST_REMOVE(servers, s->manager->dns_servers, s);
             #  #  #  # ]
     137                 :          0 :                 s->manager->n_dns_servers--;
     138                 :          0 :                 break;
     139                 :            : 
     140                 :          0 :         case DNS_SERVER_FALLBACK:
     141         [ #  # ]:          0 :                 assert(s->manager->n_dns_servers > 0);
     142   [ #  #  #  #  :          0 :                 LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
             #  #  #  # ]
     143                 :          0 :                 s->manager->n_dns_servers--;
     144                 :          0 :                 break;
     145                 :          0 :         default:
     146                 :          0 :                 assert_not_reached("Unknown server type");
     147                 :            :         }
     148                 :            : 
     149                 :          0 :         s->linked = false;
     150                 :            : 
     151   [ #  #  #  # ]:          0 :         if (s->link && s->link->current_dns_server == s)
     152                 :          0 :                 link_set_dns_server(s->link, NULL);
     153                 :            : 
     154         [ #  # ]:          0 :         if (s->manager->current_dns_server == s)
     155                 :          0 :                 manager_set_dns_server(s->manager, NULL);
     156                 :            : 
     157                 :            :         /* No need to keep a default stream around anymore */
     158                 :          0 :         dns_server_unref_stream(s);
     159                 :            : 
     160                 :          0 :         dns_server_unref(s);
     161                 :            : }
     162                 :            : 
     163                 :          0 : void dns_server_move_back_and_unmark(DnsServer *s) {
     164                 :            :         DnsServer *tail;
     165                 :            : 
     166         [ #  # ]:          0 :         assert(s);
     167                 :            : 
     168         [ #  # ]:          0 :         if (!s->marked)
     169                 :          0 :                 return;
     170                 :            : 
     171                 :          0 :         s->marked = false;
     172                 :            : 
     173   [ #  #  #  # ]:          0 :         if (!s->linked || !s->servers_next)
     174                 :          0 :                 return;
     175                 :            : 
     176                 :            :         /* Move us to the end of the list, so that the order is
     177                 :            :          * strictly kept, if we are not at the end anyway. */
     178                 :            : 
     179   [ #  #  #  # ]:          0 :         switch (s->type) {
     180                 :            : 
     181                 :          0 :         case DNS_SERVER_LINK:
     182         [ #  # ]:          0 :                 assert(s->link);
     183   [ #  #  #  # ]:          0 :                 LIST_FIND_TAIL(servers, s, tail);
     184   [ #  #  #  #  :          0 :                 LIST_REMOVE(servers, s->link->dns_servers, s);
             #  #  #  # ]
     185   [ #  #  #  #  :          0 :                 LIST_INSERT_AFTER(servers, s->link->dns_servers, tail, s);
             #  #  #  # ]
     186                 :          0 :                 break;
     187                 :            : 
     188                 :          0 :         case DNS_SERVER_SYSTEM:
     189   [ #  #  #  # ]:          0 :                 LIST_FIND_TAIL(servers, s, tail);
     190   [ #  #  #  #  :          0 :                 LIST_REMOVE(servers, s->manager->dns_servers, s);
             #  #  #  # ]
     191   [ #  #  #  #  :          0 :                 LIST_INSERT_AFTER(servers, s->manager->dns_servers, tail, s);
             #  #  #  # ]
     192                 :          0 :                 break;
     193                 :            : 
     194                 :          0 :         case DNS_SERVER_FALLBACK:
     195   [ #  #  #  # ]:          0 :                 LIST_FIND_TAIL(servers, s, tail);
     196   [ #  #  #  #  :          0 :                 LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
             #  #  #  # ]
     197   [ #  #  #  #  :          0 :                 LIST_INSERT_AFTER(servers, s->manager->fallback_dns_servers, tail, s);
             #  #  #  # ]
     198                 :          0 :                 break;
     199                 :            : 
     200                 :          0 :         default:
     201                 :          0 :                 assert_not_reached("Unknown server type");
     202                 :            :         }
     203                 :            : }
     204                 :            : 
     205                 :          0 : static void dns_server_verified(DnsServer *s, DnsServerFeatureLevel level) {
     206         [ #  # ]:          0 :         assert(s);
     207                 :            : 
     208         [ #  # ]:          0 :         if (s->verified_feature_level > level)
     209                 :          0 :                 return;
     210                 :            : 
     211         [ #  # ]:          0 :         if (s->verified_feature_level != level) {
     212         [ #  # ]:          0 :                 log_debug("Verified we get a response at feature level %s from DNS server %s.",
     213                 :            :                           dns_server_feature_level_to_string(level),
     214                 :            :                           dns_server_string(s));
     215                 :          0 :                 s->verified_feature_level = level;
     216                 :            :         }
     217                 :            : 
     218         [ #  # ]:          0 :         assert_se(sd_event_now(s->manager->event, clock_boottime_or_monotonic(), &s->verified_usec) >= 0);
     219                 :            : }
     220                 :            : 
     221                 :          0 : static void dns_server_reset_counters(DnsServer *s) {
     222         [ #  # ]:          0 :         assert(s);
     223                 :            : 
     224                 :          0 :         s->n_failed_udp = 0;
     225                 :          0 :         s->n_failed_tcp = 0;
     226                 :          0 :         s->n_failed_tls = 0;
     227                 :          0 :         s->packet_truncated = false;
     228                 :          0 :         s->verified_usec = 0;
     229                 :            : 
     230                 :            :         /* Note that we do not reset s->packet_bad_opt and s->packet_rrsig_missing here. We reset them only when the
     231                 :            :          * grace period ends, but not when lowering the possible feature level, as a lower level feature level should
     232                 :            :          * not make RRSIGs appear or OPT appear, but rather make them disappear. If the reappear anyway, then that's
     233                 :            :          * indication for a differently broken OPT/RRSIG implementation, and we really don't want to support that
     234                 :            :          * either.
     235                 :            :          *
     236                 :            :          * This is particularly important to deal with certain Belkin routers which break OPT for certain lookups (A),
     237                 :            :          * but pass traffic through for others (AAAA). If we detect the broken behaviour on one lookup we should not
     238                 :            :          * re-enable it for another, because we cannot validate things anyway, given that the RRSIG/OPT data will be
     239                 :            :          * incomplete. */
     240                 :          0 : }
     241                 :            : 
     242                 :          0 : void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLevel level, size_t size) {
     243         [ #  # ]:          0 :         assert(s);
     244                 :            : 
     245         [ #  # ]:          0 :         if (protocol == IPPROTO_UDP) {
     246         [ #  # ]:          0 :                 if (s->possible_feature_level == level)
     247                 :          0 :                         s->n_failed_udp = 0;
     248         [ #  # ]:          0 :         } else if (protocol == IPPROTO_TCP) {
     249   [ #  #  #  # ]:          0 :                 if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(level)) {
     250         [ #  # ]:          0 :                         if (s->possible_feature_level == level)
     251                 :          0 :                                 s->n_failed_tls = 0;
     252                 :            :                 } else {
     253         [ #  # ]:          0 :                         if (s->possible_feature_level == level)
     254                 :          0 :                                 s->n_failed_tcp = 0;
     255                 :            : 
     256                 :            :                         /* Successful TCP connections are only useful to verify the TCP feature level. */
     257                 :          0 :                         level = DNS_SERVER_FEATURE_LEVEL_TCP;
     258                 :            :                 }
     259                 :            :         }
     260                 :            : 
     261                 :            :         /* If the RRSIG data is missing, then we can only validate EDNS0 at max */
     262   [ #  #  #  # ]:          0 :         if (s->packet_rrsig_missing && level >= DNS_SERVER_FEATURE_LEVEL_DO)
     263   [ #  #  #  # ]:          0 :                 level = DNS_SERVER_FEATURE_LEVEL_IS_TLS(level) ? DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN : DNS_SERVER_FEATURE_LEVEL_EDNS0;
     264                 :            : 
     265                 :            :         /* If the OPT RR got lost, then we can only validate UDP at max */
     266   [ #  #  #  # ]:          0 :         if (s->packet_bad_opt && level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
     267                 :          0 :                 level = DNS_SERVER_FEATURE_LEVEL_EDNS0 - 1;
     268                 :            : 
     269                 :            :         /* Even if we successfully receive a reply to a request announcing support for large packets,
     270                 :            :                 that does not mean we can necessarily receive large packets. */
     271         [ #  # ]:          0 :         if (level == DNS_SERVER_FEATURE_LEVEL_LARGE)
     272                 :          0 :                 level = DNS_SERVER_FEATURE_LEVEL_LARGE - 1;
     273                 :            : 
     274                 :          0 :         dns_server_verified(s, level);
     275                 :            : 
     276                 :            :         /* Remember the size of the largest UDP packet we received from a server,
     277                 :            :            we know that we can always announce support for packets with at least
     278                 :            :            this size. */
     279   [ #  #  #  # ]:          0 :         if (protocol == IPPROTO_UDP && s->received_udp_packet_max < size)
     280                 :          0 :                 s->received_udp_packet_max = size;
     281                 :          0 : }
     282                 :            : 
     283                 :          0 : void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel level) {
     284         [ #  # ]:          0 :         assert(s);
     285         [ #  # ]:          0 :         assert(s->manager);
     286                 :            : 
     287         [ #  # ]:          0 :         if (s->possible_feature_level == level) {
     288         [ #  # ]:          0 :                 if (protocol == IPPROTO_UDP)
     289                 :          0 :                         s->n_failed_udp++;
     290         [ #  # ]:          0 :                 else if (protocol == IPPROTO_TCP) {
     291   [ #  #  #  # ]:          0 :                         if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(level))
     292                 :          0 :                                 s->n_failed_tls++;
     293                 :            :                         else
     294                 :          0 :                                 s->n_failed_tcp++;
     295                 :            :                 }
     296                 :            :         }
     297                 :          0 : }
     298                 :            : 
     299                 :          0 : void dns_server_packet_truncated(DnsServer *s, DnsServerFeatureLevel level) {
     300         [ #  # ]:          0 :         assert(s);
     301                 :            : 
     302                 :            :         /* Invoked whenever we get a packet with TC bit set. */
     303                 :            : 
     304         [ #  # ]:          0 :         if (s->possible_feature_level != level)
     305                 :          0 :                 return;
     306                 :            : 
     307                 :          0 :         s->packet_truncated = true;
     308                 :            : }
     309                 :            : 
     310                 :          0 : void dns_server_packet_rrsig_missing(DnsServer *s, DnsServerFeatureLevel level) {
     311         [ #  # ]:          0 :         assert(s);
     312                 :            : 
     313         [ #  # ]:          0 :         if (level < DNS_SERVER_FEATURE_LEVEL_DO)
     314                 :          0 :                 return;
     315                 :            : 
     316                 :            :         /* If the RRSIG RRs are missing, we have to downgrade what we previously verified */
     317         [ #  # ]:          0 :         if (s->verified_feature_level >= DNS_SERVER_FEATURE_LEVEL_DO)
     318   [ #  #  #  # ]:          0 :                 s->verified_feature_level = DNS_SERVER_FEATURE_LEVEL_IS_TLS(level) ? DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN : DNS_SERVER_FEATURE_LEVEL_EDNS0;
     319                 :            : 
     320                 :          0 :         s->packet_rrsig_missing = true;
     321                 :            : }
     322                 :            : 
     323                 :          0 : void dns_server_packet_bad_opt(DnsServer *s, DnsServerFeatureLevel level) {
     324         [ #  # ]:          0 :         assert(s);
     325                 :            : 
     326         [ #  # ]:          0 :         if (level < DNS_SERVER_FEATURE_LEVEL_EDNS0)
     327                 :          0 :                 return;
     328                 :            : 
     329                 :            :         /* If the OPT RR got lost, we have to downgrade what we previously verified */
     330         [ #  # ]:          0 :         if (s->verified_feature_level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
     331                 :          0 :                 s->verified_feature_level = DNS_SERVER_FEATURE_LEVEL_EDNS0-1;
     332                 :            : 
     333                 :          0 :         s->packet_bad_opt = true;
     334                 :            : }
     335                 :            : 
     336                 :          0 : void dns_server_packet_rcode_downgrade(DnsServer *s, DnsServerFeatureLevel level) {
     337         [ #  # ]:          0 :         assert(s);
     338                 :            : 
     339                 :            :         /* Invoked whenever we got a FORMERR, SERVFAIL or NOTIMP rcode from a server and downgrading the feature level
     340                 :            :          * for the transaction made it go away. In this case we immediately downgrade to the feature level that made
     341                 :            :          * things work. */
     342                 :            : 
     343         [ #  # ]:          0 :         if (s->verified_feature_level > level)
     344                 :          0 :                 s->verified_feature_level = level;
     345                 :            : 
     346         [ #  # ]:          0 :         if (s->possible_feature_level > level) {
     347                 :          0 :                 s->possible_feature_level = level;
     348                 :          0 :                 dns_server_reset_counters(s);
     349                 :            :         }
     350                 :            : 
     351         [ #  # ]:          0 :         log_debug("Downgrading transaction feature level fixed an RCODE error, downgrading server %s too.", dns_server_string(s));
     352                 :          0 : }
     353                 :            : 
     354                 :          0 : static bool dns_server_grace_period_expired(DnsServer *s) {
     355                 :            :         usec_t ts;
     356                 :            : 
     357         [ #  # ]:          0 :         assert(s);
     358         [ #  # ]:          0 :         assert(s->manager);
     359                 :            : 
     360         [ #  # ]:          0 :         if (s->verified_usec == 0)
     361                 :          0 :                 return false;
     362                 :            : 
     363         [ #  # ]:          0 :         assert_se(sd_event_now(s->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
     364                 :            : 
     365         [ #  # ]:          0 :         if (s->verified_usec + s->features_grace_period_usec > ts)
     366                 :          0 :                 return false;
     367                 :            : 
     368                 :          0 :         s->features_grace_period_usec = MIN(s->features_grace_period_usec * 2, DNS_SERVER_FEATURE_GRACE_PERIOD_MAX_USEC);
     369                 :            : 
     370                 :          0 :         return true;
     371                 :            : }
     372                 :            : 
     373                 :          0 : DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
     374                 :            :         DnsServerFeatureLevel best;
     375                 :            : 
     376         [ #  # ]:          0 :         assert(s);
     377                 :            : 
     378                 :            :         /* Determine the best feature level we care about. If DNSSEC mode is off there's no point in using anything
     379                 :            :          * better than EDNS0, hence don't even try. */
     380         [ #  # ]:          0 :         if (dns_server_get_dnssec_mode(s) != DNSSEC_NO)
     381                 :          0 :                 best = dns_server_get_dns_over_tls_mode(s) == DNS_OVER_TLS_NO ?
     382         [ #  # ]:          0 :                         DNS_SERVER_FEATURE_LEVEL_LARGE :
     383                 :            :                         DNS_SERVER_FEATURE_LEVEL_TLS_DO;
     384                 :            :         else
     385                 :          0 :                 best = dns_server_get_dns_over_tls_mode(s) == DNS_OVER_TLS_NO ?
     386         [ #  # ]:          0 :                         DNS_SERVER_FEATURE_LEVEL_EDNS0 :
     387                 :            :                         DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN;
     388                 :            : 
     389                 :            :         /* Clamp the feature level the highest level we care about. The DNSSEC mode might have changed since the last
     390                 :            :          * time, hence let's downgrade if we are still at a higher level. */
     391         [ #  # ]:          0 :         if (s->possible_feature_level > best)
     392                 :          0 :                 s->possible_feature_level = best;
     393                 :            : 
     394   [ #  #  #  # ]:          0 :         if (s->possible_feature_level < best && dns_server_grace_period_expired(s)) {
     395                 :            : 
     396                 :          0 :                 s->possible_feature_level = best;
     397                 :            : 
     398                 :          0 :                 dns_server_reset_counters(s);
     399                 :            : 
     400                 :          0 :                 s->packet_bad_opt = false;
     401                 :          0 :                 s->packet_rrsig_missing = false;
     402                 :            : 
     403         [ #  # ]:          0 :                 log_info("Grace period over, resuming full feature set (%s) for DNS server %s.",
     404                 :            :                          dns_server_feature_level_to_string(s->possible_feature_level),
     405                 :            :                          dns_server_string(s));
     406                 :            : 
     407                 :          0 :                 dns_server_flush_cache(s);
     408                 :            : 
     409         [ #  # ]:          0 :         } else if (s->possible_feature_level <= s->verified_feature_level)
     410                 :          0 :                 s->possible_feature_level = s->verified_feature_level;
     411                 :            :         else {
     412                 :          0 :                 DnsServerFeatureLevel p = s->possible_feature_level;
     413                 :            : 
     414         [ #  # ]:          0 :                 if (s->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
     415         [ #  # ]:          0 :                     s->possible_feature_level == DNS_SERVER_FEATURE_LEVEL_TCP) {
     416                 :            : 
     417                 :            :                         /* We are at the TCP (lowest) level, and we tried a couple of TCP connections, and it didn't
     418                 :            :                          * work. Upgrade back to UDP again. */
     419         [ #  # ]:          0 :                         log_debug("Reached maximum number of failed TCP connection attempts, trying UDP again...");
     420                 :          0 :                         s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_UDP;
     421         [ #  # ]:          0 :                 } else if (s->n_failed_tls > 0 &&
     422   [ #  #  #  #  :          0 :                            DNS_SERVER_FEATURE_LEVEL_IS_TLS(s->possible_feature_level) && dns_server_get_dns_over_tls_mode(s) != DNS_OVER_TLS_YES) {
                   #  # ]
     423                 :            : 
     424                 :            :                         /* We tried to connect using DNS-over-TLS, and it didn't work. Downgrade to plaintext UDP
     425                 :            :                          * if we don't require DNS-over-TLS */
     426                 :            : 
     427         [ #  # ]:          0 :                         log_debug("Server doesn't support DNS-over-TLS, downgrading protocol...");
     428                 :          0 :                         s->possible_feature_level--;
     429         [ #  # ]:          0 :                 } else if (s->packet_bad_opt &&
     430         [ #  # ]:          0 :                            s->possible_feature_level >= DNS_SERVER_FEATURE_LEVEL_EDNS0) {
     431                 :            : 
     432                 :            :                         /* A reply to one of our EDNS0 queries didn't carry a valid OPT RR, then downgrade to below
     433                 :            :                          * EDNS0 levels. After all, some records generate different responses with and without OPT RR
     434                 :            :                          * in the request. Example:
     435                 :            :                          * https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
     436                 :            : 
     437         [ #  # ]:          0 :                         log_debug("Server doesn't support EDNS(0) properly, downgrading feature level...");
     438                 :          0 :                         s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_UDP;
     439                 :            : 
     440         [ #  # ]:          0 :                 } else if (s->packet_rrsig_missing &&
     441         [ #  # ]:          0 :                            s->possible_feature_level >= DNS_SERVER_FEATURE_LEVEL_DO) {
     442                 :            : 
     443                 :            :                         /* RRSIG data was missing on a EDNS0 packet with DO bit set. This means the server doesn't
     444                 :            :                          * augment responses with DNSSEC RRs. If so, let's better not ask the server for it anymore,
     445                 :            :                          * after all some servers generate different replies depending if an OPT RR is in the query or
     446                 :            :                          * not. */
     447                 :            : 
     448         [ #  # ]:          0 :                         log_debug("Detected server responses lack RRSIG records, downgrading feature level...");
     449   [ #  #  #  # ]:          0 :                         s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_IS_TLS(s->possible_feature_level) ? DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN : DNS_SERVER_FEATURE_LEVEL_EDNS0;
     450                 :            : 
     451   [ #  #  #  # ]:          0 :                 } else if (s->n_failed_udp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
     452         [ #  # ]:          0 :                            s->possible_feature_level >= (dns_server_get_dnssec_mode(s) == DNSSEC_YES ? DNS_SERVER_FEATURE_LEVEL_LARGE : DNS_SERVER_FEATURE_LEVEL_UDP)) {
     453                 :            : 
     454                 :            :                         /* We lost too many UDP packets in a row, and are on a feature level of UDP or higher. If the
     455                 :            :                          * packets are lost, maybe the server cannot parse them, hence downgrading sounds like a good
     456                 :            :                          * idea. We might downgrade all the way down to TCP this way.
     457                 :            :                          *
     458                 :            :                          * If strict DNSSEC mode is used we won't downgrade below DO level however, as packet loss
     459                 :            :                          * might have many reasons, a broken DNSSEC implementation being only one reason. And if the
     460                 :            :                          * user is strict on DNSSEC, then let's assume that DNSSEC is not the fault here. */
     461                 :            : 
     462         [ #  # ]:          0 :                         log_debug("Lost too many UDP packets, downgrading feature level...");
     463                 :          0 :                         s->possible_feature_level--;
     464                 :            : 
     465   [ #  #  #  # ]:          0 :                 } else if (s->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
     466         [ #  # ]:          0 :                            s->packet_truncated &&
     467         [ #  # ]:          0 :                            s->possible_feature_level > (dns_server_get_dnssec_mode(s) == DNSSEC_YES ? DNS_SERVER_FEATURE_LEVEL_LARGE : DNS_SERVER_FEATURE_LEVEL_UDP)) {
     468                 :            : 
     469                 :            :                          /* We got too many TCP connection failures in a row, we had at least one truncated packet, and
     470                 :            :                           * are on a feature level above UDP. By downgrading things and getting rid of DNSSEC or EDNS0
     471                 :            :                           * data we hope to make the packet smaller, so that it still works via UDP given that TCP
     472                 :            :                           * appears not to be a fallback. Note that if we are already at the lowest UDP level, we don't
     473                 :            :                           * go further down, since that's TCP, and TCP failed too often after all. */
     474                 :            : 
     475         [ #  # ]:          0 :                         log_debug("Got too many failed TCP connection failures and truncated UDP packets, downgrading feature level...");
     476                 :          0 :                         s->possible_feature_level--;
     477                 :            :                 }
     478                 :            : 
     479         [ #  # ]:          0 :                 if (p != s->possible_feature_level) {
     480                 :            : 
     481                 :            :                         /* We changed the feature level, reset the counting */
     482                 :          0 :                         dns_server_reset_counters(s);
     483                 :            : 
     484         [ #  # ]:          0 :                         log_warning("Using degraded feature set (%s) for DNS server %s.",
     485                 :            :                                     dns_server_feature_level_to_string(s->possible_feature_level),
     486                 :            :                                     dns_server_string(s));
     487                 :            :                 }
     488                 :            :         }
     489                 :            : 
     490                 :          0 :         return s->possible_feature_level;
     491                 :            : }
     492                 :            : 
     493                 :          0 : int dns_server_adjust_opt(DnsServer *server, DnsPacket *packet, DnsServerFeatureLevel level) {
     494                 :            :         size_t packet_size;
     495                 :            :         bool edns_do;
     496                 :            :         int r;
     497                 :            : 
     498         [ #  # ]:          0 :         assert(server);
     499         [ #  # ]:          0 :         assert(packet);
     500         [ #  # ]:          0 :         assert(packet->protocol == DNS_PROTOCOL_DNS);
     501                 :            : 
     502                 :            :         /* Fix the OPT field in the packet to match our current feature level. */
     503                 :            : 
     504                 :          0 :         r = dns_packet_truncate_opt(packet);
     505         [ #  # ]:          0 :         if (r < 0)
     506                 :          0 :                 return r;
     507                 :            : 
     508         [ #  # ]:          0 :         if (level < DNS_SERVER_FEATURE_LEVEL_EDNS0)
     509                 :          0 :                 return 0;
     510                 :            : 
     511                 :          0 :         edns_do = level >= DNS_SERVER_FEATURE_LEVEL_DO;
     512                 :            : 
     513         [ #  # ]:          0 :         if (level >= DNS_SERVER_FEATURE_LEVEL_LARGE)
     514                 :          0 :                 packet_size = DNS_PACKET_UNICAST_SIZE_LARGE_MAX;
     515                 :            :         else
     516                 :          0 :                 packet_size = server->received_udp_packet_max;
     517                 :            : 
     518                 :          0 :         return dns_packet_append_opt(packet, packet_size, edns_do, 0, NULL);
     519                 :            : }
     520                 :            : 
     521                 :          0 : int dns_server_ifindex(const DnsServer *s) {
     522         [ #  # ]:          0 :         assert(s);
     523                 :            : 
     524                 :            :         /* The link ifindex always takes precedence */
     525         [ #  # ]:          0 :         if (s->link)
     526                 :          0 :                 return s->link->ifindex;
     527                 :            : 
     528         [ #  # ]:          0 :         if (s->ifindex > 0)
     529                 :          0 :                 return s->ifindex;
     530                 :            : 
     531                 :          0 :         return 0;
     532                 :            : }
     533                 :            : 
     534                 :          0 : const char *dns_server_string(DnsServer *server) {
     535         [ #  # ]:          0 :         assert(server);
     536                 :            : 
     537         [ #  # ]:          0 :         if (!server->server_string)
     538                 :          0 :                 (void) in_addr_ifindex_to_string(server->family, &server->address, dns_server_ifindex(server), &server->server_string);
     539                 :            : 
     540                 :          0 :         return strna(server->server_string);
     541                 :            : }
     542                 :            : 
     543                 :          0 : bool dns_server_dnssec_supported(DnsServer *server) {
     544         [ #  # ]:          0 :         assert(server);
     545                 :            : 
     546                 :            :         /* Returns whether the server supports DNSSEC according to what we know about it */
     547                 :            : 
     548         [ #  # ]:          0 :         if (server->possible_feature_level < DNS_SERVER_FEATURE_LEVEL_DO)
     549                 :          0 :                 return false;
     550                 :            : 
     551         [ #  # ]:          0 :         if (server->packet_bad_opt)
     552                 :          0 :                 return false;
     553                 :            : 
     554         [ #  # ]:          0 :         if (server->packet_rrsig_missing)
     555                 :          0 :                 return false;
     556                 :            : 
     557                 :            :         /* DNSSEC servers need to support TCP properly (see RFC5966), if they don't, we assume DNSSEC is borked too */
     558         [ #  # ]:          0 :         if (server->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS)
     559                 :          0 :                 return false;
     560                 :            : 
     561                 :          0 :         return true;
     562                 :            : }
     563                 :            : 
     564                 :          0 : void dns_server_warn_downgrade(DnsServer *server) {
     565         [ #  # ]:          0 :         assert(server);
     566                 :            : 
     567         [ #  # ]:          0 :         if (server->warned_downgrade)
     568                 :          0 :                 return;
     569                 :            : 
     570                 :          0 :         log_struct(LOG_NOTICE,
     571                 :            :                    "MESSAGE_ID=" SD_MESSAGE_DNSSEC_DOWNGRADE_STR,
     572                 :            :                    LOG_MESSAGE("Server %s does not support DNSSEC, downgrading to non-DNSSEC mode.", dns_server_string(server)),
     573                 :            :                    "DNS_SERVER=%s", dns_server_string(server),
     574                 :            :                    "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(server->possible_feature_level));
     575                 :            : 
     576                 :          0 :         server->warned_downgrade = true;
     577                 :            : }
     578                 :            : 
     579                 :          0 : static void dns_server_hash_func(const DnsServer *s, struct siphash *state) {
     580         [ #  # ]:          0 :         assert(s);
     581                 :            : 
     582                 :          0 :         siphash24_compress(&s->family, sizeof(s->family), state);
     583                 :          0 :         siphash24_compress(&s->address, FAMILY_ADDRESS_SIZE(s->family), state);
     584                 :          0 :         siphash24_compress(&s->ifindex, sizeof(s->ifindex), state);
     585                 :          0 : }
     586                 :            : 
     587                 :          0 : static int dns_server_compare_func(const DnsServer *x, const DnsServer *y) {
     588                 :            :         int r;
     589                 :            : 
     590         [ #  # ]:          0 :         r = CMP(x->family, y->family);
     591         [ #  # ]:          0 :         if (r != 0)
     592                 :          0 :                 return r;
     593                 :            : 
     594                 :          0 :         r = memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
     595         [ #  # ]:          0 :         if (r != 0)
     596                 :          0 :                 return r;
     597                 :            : 
     598         [ #  # ]:          0 :         r = CMP(x->ifindex, y->ifindex);
     599         [ #  # ]:          0 :         if (r != 0)
     600                 :          0 :                 return r;
     601                 :            : 
     602                 :          0 :         return 0;
     603                 :            : }
     604                 :            : 
     605                 :            : DEFINE_HASH_OPS(dns_server_hash_ops, DnsServer, dns_server_hash_func, dns_server_compare_func);
     606                 :            : 
     607                 :          0 : void dns_server_unlink_all(DnsServer *first) {
     608                 :            :         DnsServer *next;
     609                 :            : 
     610         [ #  # ]:          0 :         if (!first)
     611                 :          0 :                 return;
     612                 :            : 
     613                 :          0 :         next = first->servers_next;
     614                 :          0 :         dns_server_unlink(first);
     615                 :            : 
     616                 :          0 :         dns_server_unlink_all(next);
     617                 :            : }
     618                 :            : 
     619                 :          0 : void dns_server_unlink_marked(DnsServer *first) {
     620                 :            :         DnsServer *next;
     621                 :            : 
     622         [ #  # ]:          0 :         if (!first)
     623                 :          0 :                 return;
     624                 :            : 
     625                 :          0 :         next = first->servers_next;
     626                 :            : 
     627         [ #  # ]:          0 :         if (first->marked)
     628                 :          0 :                 dns_server_unlink(first);
     629                 :            : 
     630                 :          0 :         dns_server_unlink_marked(next);
     631                 :            : }
     632                 :            : 
     633                 :          0 : void dns_server_mark_all(DnsServer *first) {
     634         [ #  # ]:          0 :         if (!first)
     635                 :          0 :                 return;
     636                 :            : 
     637                 :          0 :         first->marked = true;
     638                 :          0 :         dns_server_mark_all(first->servers_next);
     639                 :            : }
     640                 :            : 
     641                 :          0 : DnsServer *dns_server_find(DnsServer *first, int family, const union in_addr_union *in_addr, int ifindex) {
     642                 :            :         DnsServer *s;
     643                 :            : 
     644         [ #  # ]:          0 :         LIST_FOREACH(servers, s, first)
     645   [ #  #  #  #  :          0 :                 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0 && s->ifindex == ifindex)
                   #  # ]
     646                 :          0 :                         return s;
     647                 :            : 
     648                 :          0 :         return NULL;
     649                 :            : }
     650                 :            : 
     651                 :          0 : DnsServer *manager_get_first_dns_server(Manager *m, DnsServerType t) {
     652         [ #  # ]:          0 :         assert(m);
     653                 :            : 
     654      [ #  #  # ]:          0 :         switch (t) {
     655                 :            : 
     656                 :          0 :         case DNS_SERVER_SYSTEM:
     657                 :          0 :                 return m->dns_servers;
     658                 :            : 
     659                 :          0 :         case DNS_SERVER_FALLBACK:
     660                 :          0 :                 return m->fallback_dns_servers;
     661                 :            : 
     662                 :          0 :         default:
     663                 :          0 :                 return NULL;
     664                 :            :         }
     665                 :            : }
     666                 :            : 
     667                 :          0 : DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
     668         [ #  # ]:          0 :         assert(m);
     669                 :            : 
     670         [ #  # ]:          0 :         if (m->current_dns_server == s)
     671                 :          0 :                 return s;
     672                 :            : 
     673         [ #  # ]:          0 :         if (s)
     674         [ #  # ]:          0 :                 log_debug("Switching to %s DNS server %s.",
     675                 :            :                           dns_server_type_to_string(s->type),
     676                 :            :                           dns_server_string(s));
     677                 :            : 
     678                 :          0 :         dns_server_unref(m->current_dns_server);
     679                 :          0 :         m->current_dns_server = dns_server_ref(s);
     680                 :            : 
     681         [ #  # ]:          0 :         if (m->unicast_scope)
     682                 :          0 :                 dns_cache_flush(&m->unicast_scope->cache);
     683                 :            : 
     684                 :          0 :         return s;
     685                 :            : }
     686                 :            : 
     687                 :          0 : DnsServer *manager_get_dns_server(Manager *m) {
     688                 :            :         Link *l;
     689         [ #  # ]:          0 :         assert(m);
     690                 :            : 
     691                 :            :         /* Try to read updates resolv.conf */
     692                 :          0 :         manager_read_resolv_conf(m);
     693                 :            : 
     694                 :            :         /* If no DNS server was chosen so far, pick the first one */
     695         [ #  # ]:          0 :         if (!m->current_dns_server)
     696                 :          0 :                 manager_set_dns_server(m, m->dns_servers);
     697                 :            : 
     698         [ #  # ]:          0 :         if (!m->current_dns_server) {
     699                 :          0 :                 bool found = false;
     700                 :            :                 Iterator i;
     701                 :            : 
     702                 :            :                 /* No DNS servers configured, let's see if there are
     703                 :            :                  * any on any links. If not, we use the fallback
     704                 :            :                  * servers */
     705                 :            : 
     706         [ #  # ]:          0 :                 HASHMAP_FOREACH(l, m->links, i)
     707         [ #  # ]:          0 :                         if (l->dns_servers) {
     708                 :          0 :                                 found = true;
     709                 :          0 :                                 break;
     710                 :            :                         }
     711                 :            : 
     712         [ #  # ]:          0 :                 if (!found)
     713                 :          0 :                         manager_set_dns_server(m, m->fallback_dns_servers);
     714                 :            :         }
     715                 :            : 
     716                 :          0 :         return m->current_dns_server;
     717                 :            : }
     718                 :            : 
     719                 :          0 : void manager_next_dns_server(Manager *m) {
     720         [ #  # ]:          0 :         assert(m);
     721                 :            : 
     722                 :            :         /* If there's currently no DNS server set, then the next
     723                 :            :          * manager_get_dns_server() will find one */
     724         [ #  # ]:          0 :         if (!m->current_dns_server)
     725                 :          0 :                 return;
     726                 :            : 
     727                 :            :         /* Change to the next one, but make sure to follow the linked
     728                 :            :          * list only if the server is still linked. */
     729   [ #  #  #  # ]:          0 :         if (m->current_dns_server->linked && m->current_dns_server->servers_next) {
     730                 :          0 :                 manager_set_dns_server(m, m->current_dns_server->servers_next);
     731                 :          0 :                 return;
     732                 :            :         }
     733                 :            : 
     734                 :            :         /* If there was no next one, then start from the beginning of
     735                 :            :          * the list */
     736         [ #  # ]:          0 :         if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
     737                 :          0 :                 manager_set_dns_server(m, m->fallback_dns_servers);
     738                 :            :         else
     739                 :          0 :                 manager_set_dns_server(m, m->dns_servers);
     740                 :            : }
     741                 :            : 
     742                 :          0 : DnssecMode dns_server_get_dnssec_mode(DnsServer *s) {
     743         [ #  # ]:          0 :         assert(s);
     744                 :            : 
     745         [ #  # ]:          0 :         if (s->link)
     746                 :          0 :                 return link_get_dnssec_mode(s->link);
     747                 :            : 
     748                 :          0 :         return manager_get_dnssec_mode(s->manager);
     749                 :            : }
     750                 :            : 
     751                 :          0 : DnsOverTlsMode dns_server_get_dns_over_tls_mode(DnsServer *s) {
     752         [ #  # ]:          0 :         assert(s);
     753                 :            : 
     754         [ #  # ]:          0 :         if (s->link)
     755                 :          0 :                 return link_get_dns_over_tls_mode(s->link);
     756                 :            : 
     757                 :          0 :         return manager_get_dns_over_tls_mode(s->manager);
     758                 :            : }
     759                 :            : 
     760                 :          0 : void dns_server_flush_cache(DnsServer *s) {
     761                 :            :         DnsServer *current;
     762                 :            :         DnsScope *scope;
     763                 :            : 
     764         [ #  # ]:          0 :         assert(s);
     765                 :            : 
     766                 :            :         /* Flush the cache of the scope this server belongs to */
     767                 :            : 
     768         [ #  # ]:          0 :         current = s->link ? s->link->current_dns_server : s->manager->current_dns_server;
     769         [ #  # ]:          0 :         if (current != s)
     770                 :          0 :                 return;
     771                 :            : 
     772         [ #  # ]:          0 :         scope = s->link ? s->link->unicast_scope : s->manager->unicast_scope;
     773         [ #  # ]:          0 :         if (!scope)
     774                 :          0 :                 return;
     775                 :            : 
     776                 :          0 :         dns_cache_flush(&scope->cache);
     777                 :            : }
     778                 :            : 
     779                 :          0 : void dns_server_reset_features(DnsServer *s) {
     780         [ #  # ]:          0 :         assert(s);
     781                 :            : 
     782                 :          0 :         s->verified_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
     783                 :          0 :         s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_BEST;
     784                 :            : 
     785                 :          0 :         s->received_udp_packet_max = DNS_PACKET_UNICAST_SIZE_MAX;
     786                 :            : 
     787                 :          0 :         s->packet_bad_opt = false;
     788                 :          0 :         s->packet_rrsig_missing = false;
     789                 :            : 
     790                 :          0 :         s->features_grace_period_usec = DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC;
     791                 :            : 
     792                 :          0 :         s->warned_downgrade = false;
     793                 :            : 
     794                 :          0 :         dns_server_reset_counters(s);
     795                 :            : 
     796                 :            :         /* Let's close the default stream, so that we reprobe with the new features */
     797                 :          0 :         dns_server_unref_stream(s);
     798                 :          0 : }
     799                 :            : 
     800                 :          0 : void dns_server_reset_features_all(DnsServer *s) {
     801                 :            :         DnsServer *i;
     802                 :            : 
     803         [ #  # ]:          0 :         LIST_FOREACH(servers, i, s)
     804                 :          0 :                 dns_server_reset_features(i);
     805                 :          0 : }
     806                 :            : 
     807                 :          0 : void dns_server_dump(DnsServer *s, FILE *f) {
     808         [ #  # ]:          0 :         assert(s);
     809                 :            : 
     810         [ #  # ]:          0 :         if (!f)
     811                 :          0 :                 f = stdout;
     812                 :            : 
     813                 :          0 :         fputs("[Server ", f);
     814                 :          0 :         fputs(dns_server_string(s), f);
     815                 :          0 :         fputs(" type=", f);
     816                 :          0 :         fputs(dns_server_type_to_string(s->type), f);
     817                 :            : 
     818         [ #  # ]:          0 :         if (s->type == DNS_SERVER_LINK) {
     819         [ #  # ]:          0 :                 assert(s->link);
     820                 :            : 
     821                 :          0 :                 fputs(" interface=", f);
     822                 :          0 :                 fputs(s->link->ifname, f);
     823                 :            :         }
     824                 :            : 
     825                 :          0 :         fputs("]\n", f);
     826                 :            : 
     827                 :          0 :         fputs("\tVerified feature level: ", f);
     828                 :          0 :         fputs(strna(dns_server_feature_level_to_string(s->verified_feature_level)), f);
     829                 :          0 :         fputc('\n', f);
     830                 :            : 
     831                 :          0 :         fputs("\tPossible feature level: ", f);
     832                 :          0 :         fputs(strna(dns_server_feature_level_to_string(s->possible_feature_level)), f);
     833                 :          0 :         fputc('\n', f);
     834                 :            : 
     835                 :          0 :         fputs("\tDNSSEC Mode: ", f);
     836                 :          0 :         fputs(strna(dnssec_mode_to_string(dns_server_get_dnssec_mode(s))), f);
     837                 :          0 :         fputc('\n', f);
     838                 :            : 
     839                 :          0 :         fputs("\tCan do DNSSEC: ", f);
     840                 :          0 :         fputs(yes_no(dns_server_dnssec_supported(s)), f);
     841                 :          0 :         fputc('\n', f);
     842                 :            : 
     843                 :          0 :         fprintf(f,
     844                 :            :                 "\tMaximum UDP packet size received: %zu\n"
     845                 :            :                 "\tFailed UDP attempts: %u\n"
     846                 :            :                 "\tFailed TCP attempts: %u\n"
     847                 :            :                 "\tSeen truncated packet: %s\n"
     848                 :            :                 "\tSeen OPT RR getting lost: %s\n"
     849                 :            :                 "\tSeen RRSIG RR missing: %s\n",
     850                 :            :                 s->received_udp_packet_max,
     851                 :            :                 s->n_failed_udp,
     852                 :            :                 s->n_failed_tcp,
     853                 :          0 :                 yes_no(s->packet_truncated),
     854                 :          0 :                 yes_no(s->packet_bad_opt),
     855                 :          0 :                 yes_no(s->packet_rrsig_missing));
     856                 :          0 : }
     857                 :            : 
     858                 :          0 : void dns_server_unref_stream(DnsServer *s) {
     859                 :            :         DnsStream *ref;
     860                 :            : 
     861         [ #  # ]:          0 :         assert(s);
     862                 :            : 
     863                 :            :         /* Detaches the default stream of this server. Some special care needs to be taken here, as that stream and
     864                 :            :          * this server reference each other. First, take the stream out of the server. It's destructor will check if it
     865                 :            :          * is registered with us, hence let's invalidate this separately, so that it is already unregistered. */
     866                 :          0 :         ref = TAKE_PTR(s->stream);
     867                 :            : 
     868                 :            :         /* And then, unref it */
     869                 :          0 :         dns_stream_unref(ref);
     870                 :          0 : }
     871                 :            : 
     872                 :          0 : DnsScope *dns_server_scope(DnsServer *s) {
     873         [ #  # ]:          0 :         assert(s);
     874         [ #  # ]:          0 :         assert((s->type == DNS_SERVER_LINK) == !!s->link);
     875                 :            : 
     876         [ #  # ]:          0 :         if (s->link)
     877                 :          0 :                 return s->link->unicast_scope;
     878                 :            : 
     879                 :          0 :         return s->manager->unicast_scope;
     880                 :            : }
     881                 :            : 
     882                 :            : static const char* const dns_server_type_table[_DNS_SERVER_TYPE_MAX] = {
     883                 :            :         [DNS_SERVER_SYSTEM] = "system",
     884                 :            :         [DNS_SERVER_FALLBACK] = "fallback",
     885                 :            :         [DNS_SERVER_LINK] = "link",
     886                 :            : };
     887   [ #  #  #  # ]:          0 : DEFINE_STRING_TABLE_LOOKUP(dns_server_type, DnsServerType);
     888                 :            : 
     889                 :            : static const char* const dns_server_feature_level_table[_DNS_SERVER_FEATURE_LEVEL_MAX] = {
     890                 :            :         [DNS_SERVER_FEATURE_LEVEL_TCP] = "TCP",
     891                 :            :         [DNS_SERVER_FEATURE_LEVEL_UDP] = "UDP",
     892                 :            :         [DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0",
     893                 :            :         [DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN] = "TLS+EDNS0",
     894                 :            :         [DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO",
     895                 :            :         [DNS_SERVER_FEATURE_LEVEL_LARGE] = "UDP+EDNS0+DO+LARGE",
     896                 :            :         [DNS_SERVER_FEATURE_LEVEL_TLS_DO] = "TLS+EDNS0+D0",
     897                 :            : };
     898   [ #  #  #  # ]:          0 : DEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel);

Generated by: LCOV version 1.14