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

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "sd-messages.h"
       4                 :            : 
       5                 :            : #include "af-list.h"
       6                 :            : #include "alloc-util.h"
       7                 :            : #include "dns-domain.h"
       8                 :            : #include "errno-list.h"
       9                 :            : #include "errno-util.h"
      10                 :            : #include "fd-util.h"
      11                 :            : #include "random-util.h"
      12                 :            : #include "resolved-dns-cache.h"
      13                 :            : #include "resolved-dns-transaction.h"
      14                 :            : #include "resolved-dnstls.h"
      15                 :            : #include "resolved-llmnr.h"
      16                 :            : #include "string-table.h"
      17                 :            : 
      18                 :            : #define TRANSACTIONS_MAX 4096
      19                 :            : #define TRANSACTION_TCP_TIMEOUT_USEC (10U*USEC_PER_SEC)
      20                 :            : 
      21                 :            : /* After how much time to repeat classic DNS requests */
      22                 :            : #define DNS_TIMEOUT_USEC (SD_RESOLVED_QUERY_TIMEOUT_USEC / DNS_TRANSACTION_ATTEMPTS_MAX)
      23                 :            : 
      24                 :          0 : static void dns_transaction_reset_answer(DnsTransaction *t) {
      25         [ #  # ]:          0 :         assert(t);
      26                 :            : 
      27                 :          0 :         t->received = dns_packet_unref(t->received);
      28                 :          0 :         t->answer = dns_answer_unref(t->answer);
      29                 :          0 :         t->answer_rcode = 0;
      30                 :          0 :         t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
      31                 :          0 :         t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
      32                 :          0 :         t->answer_authenticated = false;
      33                 :          0 :         t->answer_nsec_ttl = (uint32_t) -1;
      34                 :          0 :         t->answer_errno = 0;
      35                 :          0 : }
      36                 :            : 
      37                 :          0 : static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) {
      38                 :            :         DnsTransaction *z;
      39                 :            : 
      40         [ #  # ]:          0 :         assert(t);
      41                 :            : 
      42         [ #  # ]:          0 :         while ((z = set_steal_first(t->dnssec_transactions))) {
      43                 :          0 :                 set_remove(z->notify_transactions, t);
      44                 :          0 :                 set_remove(z->notify_transactions_done, t);
      45                 :          0 :                 dns_transaction_gc(z);
      46                 :            :         }
      47                 :          0 : }
      48                 :            : 
      49                 :          0 : static void dns_transaction_close_connection(DnsTransaction *t) {
      50         [ #  # ]:          0 :         assert(t);
      51                 :            : 
      52         [ #  # ]:          0 :         if (t->stream) {
      53                 :            :                 /* Let's detach the stream from our transaction, in case something else keeps a reference to it. */
      54   [ #  #  #  #  :          0 :                 LIST_REMOVE(transactions_by_stream, t->stream->transactions, t);
             #  #  #  # ]
      55                 :            : 
      56                 :            :                 /* Remove packet in case it's still in the queue */
      57                 :          0 :                 dns_packet_unref(ordered_set_remove(t->stream->write_queue, t->sent));
      58                 :            : 
      59                 :          0 :                 t->stream = dns_stream_unref(t->stream);
      60                 :            :         }
      61                 :            : 
      62                 :          0 :         t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source);
      63                 :          0 :         t->dns_udp_fd = safe_close(t->dns_udp_fd);
      64                 :          0 : }
      65                 :            : 
      66                 :          0 : static void dns_transaction_stop_timeout(DnsTransaction *t) {
      67         [ #  # ]:          0 :         assert(t);
      68                 :            : 
      69                 :          0 :         t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
      70                 :          0 : }
      71                 :            : 
      72                 :          0 : DnsTransaction* dns_transaction_free(DnsTransaction *t) {
      73                 :            :         DnsQueryCandidate *c;
      74                 :            :         DnsZoneItem *i;
      75                 :            :         DnsTransaction *z;
      76                 :            : 
      77         [ #  # ]:          0 :         if (!t)
      78                 :          0 :                 return NULL;
      79                 :            : 
      80         [ #  # ]:          0 :         log_debug("Freeing transaction %" PRIu16 ".", t->id);
      81                 :            : 
      82                 :          0 :         dns_transaction_close_connection(t);
      83                 :          0 :         dns_transaction_stop_timeout(t);
      84                 :            : 
      85                 :          0 :         dns_packet_unref(t->sent);
      86                 :          0 :         dns_transaction_reset_answer(t);
      87                 :            : 
      88                 :          0 :         dns_server_unref(t->server);
      89                 :            : 
      90         [ #  # ]:          0 :         if (t->scope) {
      91                 :          0 :                 hashmap_remove_value(t->scope->transactions_by_key, t->key, t);
      92   [ #  #  #  #  :          0 :                 LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
             #  #  #  # ]
      93                 :            : 
      94         [ #  # ]:          0 :                 if (t->id != 0)
      95                 :          0 :                         hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
      96                 :            :         }
      97                 :            : 
      98         [ #  # ]:          0 :         while ((c = set_steal_first(t->notify_query_candidates)))
      99                 :          0 :                 set_remove(c->transactions, t);
     100                 :          0 :         set_free(t->notify_query_candidates);
     101                 :            : 
     102         [ #  # ]:          0 :         while ((c = set_steal_first(t->notify_query_candidates_done)))
     103                 :          0 :                 set_remove(c->transactions, t);
     104                 :          0 :         set_free(t->notify_query_candidates_done);
     105                 :            : 
     106         [ #  # ]:          0 :         while ((i = set_steal_first(t->notify_zone_items)))
     107                 :          0 :                 i->probe_transaction = NULL;
     108                 :          0 :         set_free(t->notify_zone_items);
     109                 :            : 
     110         [ #  # ]:          0 :         while ((i = set_steal_first(t->notify_zone_items_done)))
     111                 :          0 :                 i->probe_transaction = NULL;
     112                 :          0 :         set_free(t->notify_zone_items_done);
     113                 :            : 
     114         [ #  # ]:          0 :         while ((z = set_steal_first(t->notify_transactions)))
     115                 :          0 :                 set_remove(z->dnssec_transactions, t);
     116                 :          0 :         set_free(t->notify_transactions);
     117                 :            : 
     118         [ #  # ]:          0 :         while ((z = set_steal_first(t->notify_transactions_done)))
     119                 :          0 :                 set_remove(z->dnssec_transactions, t);
     120                 :          0 :         set_free(t->notify_transactions_done);
     121                 :            : 
     122                 :          0 :         dns_transaction_flush_dnssec_transactions(t);
     123                 :          0 :         set_free(t->dnssec_transactions);
     124                 :            : 
     125                 :          0 :         dns_answer_unref(t->validated_keys);
     126                 :          0 :         dns_resource_key_unref(t->key);
     127                 :            : 
     128                 :          0 :         return mfree(t);
     129                 :            : }
     130                 :            : 
     131         [ #  # ]:          0 : DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
     132                 :            : 
     133                 :          0 : bool dns_transaction_gc(DnsTransaction *t) {
     134         [ #  # ]:          0 :         assert(t);
     135                 :            : 
     136         [ #  # ]:          0 :         if (t->block_gc > 0)
     137                 :          0 :                 return true;
     138                 :            : 
     139   [ #  #  #  # ]:          0 :         if (set_isempty(t->notify_query_candidates) &&
     140         [ #  # ]:          0 :             set_isempty(t->notify_query_candidates_done) &&
     141         [ #  # ]:          0 :             set_isempty(t->notify_zone_items) &&
     142         [ #  # ]:          0 :             set_isempty(t->notify_zone_items_done) &&
     143         [ #  # ]:          0 :             set_isempty(t->notify_transactions) &&
     144                 :          0 :             set_isempty(t->notify_transactions_done)) {
     145                 :          0 :                 dns_transaction_free(t);
     146                 :          0 :                 return false;
     147                 :            :         }
     148                 :            : 
     149                 :          0 :         return true;
     150                 :            : }
     151                 :            : 
     152                 :          0 : static uint16_t pick_new_id(Manager *m) {
     153                 :            :         uint16_t new_id;
     154                 :            : 
     155                 :            :         /* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the number of
     156                 :            :          * transactions, and it's much lower than the space of IDs. */
     157                 :            : 
     158                 :            :         assert_cc(TRANSACTIONS_MAX < 0xFFFF);
     159                 :            : 
     160                 :            :         do
     161                 :          0 :                 random_bytes(&new_id, sizeof(new_id));
     162         [ #  # ]:          0 :         while (new_id == 0 ||
     163         [ #  # ]:          0 :                hashmap_get(m->dns_transactions, UINT_TO_PTR(new_id)));
     164                 :            : 
     165                 :          0 :         return new_id;
     166                 :            : }
     167                 :            : 
     168                 :          0 : int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) {
     169                 :          0 :         _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
     170                 :            :         int r;
     171                 :            : 
     172         [ #  # ]:          0 :         assert(ret);
     173         [ #  # ]:          0 :         assert(s);
     174         [ #  # ]:          0 :         assert(key);
     175                 :            : 
     176                 :            :         /* Don't allow looking up invalid or pseudo RRs */
     177         [ #  # ]:          0 :         if (!dns_type_is_valid_query(key->type))
     178                 :          0 :                 return -EINVAL;
     179         [ #  # ]:          0 :         if (dns_type_is_obsolete(key->type))
     180                 :          0 :                 return -EOPNOTSUPP;
     181                 :            : 
     182                 :            :         /* We only support the IN class */
     183   [ #  #  #  # ]:          0 :         if (!IN_SET(key->class, DNS_CLASS_IN, DNS_CLASS_ANY))
     184                 :          0 :                 return -EOPNOTSUPP;
     185                 :            : 
     186         [ #  # ]:          0 :         if (hashmap_size(s->manager->dns_transactions) >= TRANSACTIONS_MAX)
     187                 :          0 :                 return -EBUSY;
     188                 :            : 
     189                 :          0 :         r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
     190         [ #  # ]:          0 :         if (r < 0)
     191                 :          0 :                 return r;
     192                 :            : 
     193                 :          0 :         r = hashmap_ensure_allocated(&s->transactions_by_key, &dns_resource_key_hash_ops);
     194         [ #  # ]:          0 :         if (r < 0)
     195                 :          0 :                 return r;
     196                 :            : 
     197                 :          0 :         t = new0(DnsTransaction, 1);
     198         [ #  # ]:          0 :         if (!t)
     199                 :          0 :                 return -ENOMEM;
     200                 :            : 
     201                 :          0 :         t->dns_udp_fd = -1;
     202                 :          0 :         t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
     203                 :          0 :         t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
     204                 :          0 :         t->answer_nsec_ttl = (uint32_t) -1;
     205                 :          0 :         t->key = dns_resource_key_ref(key);
     206                 :          0 :         t->current_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
     207                 :          0 :         t->clamp_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
     208                 :            : 
     209                 :          0 :         t->id = pick_new_id(s->manager);
     210                 :            : 
     211                 :          0 :         r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
     212         [ #  # ]:          0 :         if (r < 0) {
     213                 :          0 :                 t->id = 0;
     214                 :          0 :                 return r;
     215                 :            :         }
     216                 :            : 
     217                 :          0 :         r = hashmap_replace(s->transactions_by_key, t->key, t);
     218         [ #  # ]:          0 :         if (r < 0) {
     219                 :          0 :                 hashmap_remove(s->manager->dns_transactions, UINT_TO_PTR(t->id));
     220                 :          0 :                 return r;
     221                 :            :         }
     222                 :            : 
     223   [ #  #  #  # ]:          0 :         LIST_PREPEND(transactions_by_scope, s->transactions, t);
     224                 :          0 :         t->scope = s;
     225                 :            : 
     226                 :          0 :         s->manager->n_transactions_total++;
     227                 :            : 
     228         [ #  # ]:          0 :         if (ret)
     229                 :          0 :                 *ret = t;
     230                 :            : 
     231                 :          0 :         t = NULL;
     232                 :            : 
     233                 :          0 :         return 0;
     234                 :            : }
     235                 :            : 
     236                 :          0 : static void dns_transaction_shuffle_id(DnsTransaction *t) {
     237                 :            :         uint16_t new_id;
     238         [ #  # ]:          0 :         assert(t);
     239                 :            : 
     240                 :            :         /* Pick a new ID for this transaction. */
     241                 :            : 
     242                 :          0 :         new_id = pick_new_id(t->scope->manager);
     243         [ #  # ]:          0 :         assert_se(hashmap_remove_and_put(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id), UINT_TO_PTR(new_id), t) >= 0);
     244                 :            : 
     245         [ #  # ]:          0 :         log_debug("Transaction %" PRIu16 " is now %" PRIu16 ".", t->id, new_id);
     246                 :          0 :         t->id = new_id;
     247                 :            : 
     248                 :            :         /* Make sure we generate a new packet with the new ID */
     249                 :          0 :         t->sent = dns_packet_unref(t->sent);
     250                 :          0 : }
     251                 :            : 
     252                 :          0 : static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
     253         [ #  # ]:          0 :         _cleanup_free_ char *pretty = NULL;
     254                 :            :         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
     255                 :            :         DnsZoneItem *z;
     256                 :            : 
     257         [ #  # ]:          0 :         assert(t);
     258         [ #  # ]:          0 :         assert(p);
     259                 :            : 
     260         [ #  # ]:          0 :         if (manager_our_packet(t->scope->manager, p) != 0)
     261                 :          0 :                 return;
     262                 :            : 
     263                 :          0 :         (void) in_addr_to_string(p->family, &p->sender, &pretty);
     264                 :            : 
     265   [ #  #  #  # ]:          0 :         log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s got tentative packet from %s.",
     266                 :            :                   t->id,
     267                 :            :                   dns_resource_key_to_string(t->key, key_str, sizeof key_str),
     268                 :            :                   dns_protocol_to_string(t->scope->protocol),
     269                 :            :                   t->scope->link ? t->scope->link->ifname : "*",
     270                 :            :                   af_to_name_short(t->scope->family),
     271                 :            :                   strnull(pretty));
     272                 :            : 
     273                 :            :         /* RFC 4795, Section 4.1 says that the peer with the
     274                 :            :          * lexicographically smaller IP address loses */
     275         [ #  # ]:          0 :         if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
     276         [ #  # ]:          0 :                 log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
     277                 :          0 :                 return;
     278                 :            :         }
     279                 :            : 
     280         [ #  # ]:          0 :         log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
     281                 :            : 
     282                 :          0 :         t->block_gc++;
     283                 :            : 
     284         [ #  # ]:          0 :         while ((z = set_first(t->notify_zone_items))) {
     285                 :            :                 /* First, make sure the zone item drops the reference
     286                 :            :                  * to us */
     287                 :          0 :                 dns_zone_item_probe_stop(z);
     288                 :            : 
     289                 :            :                 /* Secondly, report this as conflict, so that we might
     290                 :            :                  * look for a different hostname */
     291                 :          0 :                 dns_zone_item_conflict(z);
     292                 :            :         }
     293                 :          0 :         t->block_gc--;
     294                 :            : 
     295                 :          0 :         dns_transaction_gc(t);
     296                 :            : }
     297                 :            : 
     298                 :          0 : void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
     299                 :            :         DnsQueryCandidate *c;
     300                 :            :         DnsZoneItem *z;
     301                 :            :         DnsTransaction *d;
     302                 :            :         const char *st;
     303                 :            :         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
     304                 :            : 
     305         [ #  # ]:          0 :         assert(t);
     306   [ #  #  #  # ]:          0 :         assert(!DNS_TRANSACTION_IS_LIVE(state));
     307                 :            : 
     308         [ #  # ]:          0 :         if (state == DNS_TRANSACTION_DNSSEC_FAILED) {
     309                 :          0 :                 dns_resource_key_to_string(t->key, key_str, sizeof key_str);
     310                 :            : 
     311                 :          0 :                 log_struct(LOG_NOTICE,
     312                 :            :                            "MESSAGE_ID=" SD_MESSAGE_DNSSEC_FAILURE_STR,
     313                 :            :                            LOG_MESSAGE("DNSSEC validation failed for question %s: %s", key_str, dnssec_result_to_string(t->answer_dnssec_result)),
     314                 :            :                            "DNS_TRANSACTION=%" PRIu16, t->id,
     315                 :            :                            "DNS_QUESTION=%s", key_str,
     316                 :            :                            "DNSSEC_RESULT=%s", dnssec_result_to_string(t->answer_dnssec_result),
     317                 :            :                            "DNS_SERVER=%s", dns_server_string(t->server),
     318                 :            :                            "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level));
     319                 :            :         }
     320                 :            : 
     321                 :            :         /* Note that this call might invalidate the query. Callers
     322                 :            :          * should hence not attempt to access the query or transaction
     323                 :            :          * after calling this function. */
     324                 :            : 
     325         [ #  # ]:          0 :         if (state == DNS_TRANSACTION_ERRNO)
     326                 :          0 :                 st = errno_to_name(t->answer_errno);
     327                 :            :         else
     328                 :          0 :                 st = dns_transaction_state_to_string(state);
     329                 :            : 
     330   [ #  #  #  #  :          0 :         log_debug("Transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
             #  #  #  # ]
     331                 :            :                   t->id,
     332                 :            :                   dns_resource_key_to_string(t->key, key_str, sizeof key_str),
     333                 :            :                   dns_protocol_to_string(t->scope->protocol),
     334                 :            :                   t->scope->link ? t->scope->link->ifname : "*",
     335                 :            :                   af_to_name_short(t->scope->family),
     336                 :            :                   st,
     337                 :            :                   t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
     338                 :            :                   t->answer_authenticated ? "authenticated" : "unsigned");
     339                 :            : 
     340                 :          0 :         t->state = state;
     341                 :            : 
     342                 :          0 :         dns_transaction_close_connection(t);
     343                 :          0 :         dns_transaction_stop_timeout(t);
     344                 :            : 
     345                 :            :         /* Notify all queries that are interested, but make sure the
     346                 :            :          * transaction isn't freed while we are still looking at it */
     347                 :          0 :         t->block_gc++;
     348                 :            : 
     349   [ #  #  #  #  :          0 :         SET_FOREACH_MOVE(c, t->notify_query_candidates_done, t->notify_query_candidates)
                   #  # ]
     350                 :          0 :                 dns_query_candidate_notify(c);
     351                 :          0 :         SWAP_TWO(t->notify_query_candidates, t->notify_query_candidates_done);
     352                 :            : 
     353   [ #  #  #  #  :          0 :         SET_FOREACH_MOVE(z, t->notify_zone_items_done, t->notify_zone_items)
                   #  # ]
     354                 :          0 :                 dns_zone_item_notify(z);
     355                 :          0 :         SWAP_TWO(t->notify_zone_items, t->notify_zone_items_done);
     356   [ #  #  #  # ]:          0 :         if (t->probing && t->state == DNS_TRANSACTION_ATTEMPTS_MAX_REACHED)
     357                 :          0 :                 (void) dns_scope_announce(t->scope, false);
     358                 :            : 
     359   [ #  #  #  #  :          0 :         SET_FOREACH_MOVE(d, t->notify_transactions_done, t->notify_transactions)
                   #  # ]
     360                 :          0 :                 dns_transaction_notify(d, t);
     361                 :          0 :         SWAP_TWO(t->notify_transactions, t->notify_transactions_done);
     362                 :            : 
     363                 :          0 :         t->block_gc--;
     364                 :          0 :         dns_transaction_gc(t);
     365                 :          0 : }
     366                 :            : 
     367                 :          0 : static int dns_transaction_pick_server(DnsTransaction *t) {
     368                 :            :         DnsServer *server;
     369                 :            : 
     370         [ #  # ]:          0 :         assert(t);
     371         [ #  # ]:          0 :         assert(t->scope->protocol == DNS_PROTOCOL_DNS);
     372                 :            : 
     373                 :            :         /* Pick a DNS server and a feature level for it. */
     374                 :            : 
     375                 :          0 :         server = dns_scope_get_dns_server(t->scope);
     376         [ #  # ]:          0 :         if (!server)
     377                 :          0 :                 return -ESRCH;
     378                 :            : 
     379                 :            :         /* If we changed the server invalidate the feature level clamping, as the new server might have completely
     380                 :            :          * different properties. */
     381         [ #  # ]:          0 :         if (server != t->server)
     382                 :          0 :                 t->clamp_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID;
     383                 :            : 
     384                 :          0 :         t->current_feature_level = dns_server_possible_feature_level(server);
     385                 :            : 
     386                 :            :         /* Clamp the feature level if that is requested. */
     387         [ #  # ]:          0 :         if (t->clamp_feature_level != _DNS_SERVER_FEATURE_LEVEL_INVALID &&
     388         [ #  # ]:          0 :             t->current_feature_level > t->clamp_feature_level)
     389                 :          0 :                 t->current_feature_level = t->clamp_feature_level;
     390                 :            : 
     391         [ #  # ]:          0 :         log_debug("Using feature level %s for transaction %u.", dns_server_feature_level_to_string(t->current_feature_level), t->id);
     392                 :            : 
     393         [ #  # ]:          0 :         if (server == t->server)
     394                 :          0 :                 return 0;
     395                 :            : 
     396                 :          0 :         dns_server_unref(t->server);
     397                 :          0 :         t->server = dns_server_ref(server);
     398                 :            : 
     399                 :          0 :         t->n_picked_servers ++;
     400                 :            : 
     401         [ #  # ]:          0 :         log_debug("Using DNS server %s for transaction %u.", dns_server_string(t->server), t->id);
     402                 :            : 
     403                 :          0 :         return 1;
     404                 :            : }
     405                 :            : 
     406                 :          0 : static void dns_transaction_retry(DnsTransaction *t, bool next_server) {
     407                 :            :         int r;
     408                 :            : 
     409         [ #  # ]:          0 :         assert(t);
     410                 :            : 
     411         [ #  # ]:          0 :         log_debug("Retrying transaction %" PRIu16 ".", t->id);
     412                 :            : 
     413                 :            :         /* Before we try again, switch to a new server. */
     414         [ #  # ]:          0 :         if (next_server)
     415                 :          0 :                 dns_scope_next_dns_server(t->scope);
     416                 :            : 
     417                 :          0 :         r = dns_transaction_go(t);
     418         [ #  # ]:          0 :         if (r < 0) {
     419                 :          0 :                 t->answer_errno = -r;
     420                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
     421                 :            :         }
     422                 :          0 : }
     423                 :            : 
     424                 :          0 : static int dns_transaction_maybe_restart(DnsTransaction *t) {
     425                 :            :         int r;
     426                 :            : 
     427         [ #  # ]:          0 :         assert(t);
     428                 :            : 
     429                 :            :         /* Returns > 0 if the transaction was restarted, 0 if not */
     430                 :            : 
     431         [ #  # ]:          0 :         if (!t->server)
     432                 :          0 :                 return 0;
     433                 :            : 
     434         [ #  # ]:          0 :         if (t->current_feature_level <= dns_server_possible_feature_level(t->server))
     435                 :          0 :                 return 0;
     436                 :            : 
     437                 :            :         /* The server's current feature level is lower than when we sent the original query. We learnt something from
     438                 :            :            the response or possibly an auxiliary DNSSEC response that we didn't know before.  We take that as reason to
     439                 :            :            restart the whole transaction. This is a good idea to deal with servers that respond rubbish if we include
     440                 :            :            OPT RR or DO bit. One of these cases is documented here, for example:
     441                 :            :            https://open.nlnetlabs.nl/pipermail/dnssec-trigger/2014-November/000376.html */
     442                 :            : 
     443         [ #  # ]:          0 :         log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
     444                 :          0 :         dns_transaction_shuffle_id(t);
     445                 :            : 
     446                 :          0 :         r = dns_transaction_go(t);
     447         [ #  # ]:          0 :         if (r < 0)
     448                 :          0 :                 return r;
     449                 :            : 
     450                 :          0 :         return 1;
     451                 :            : }
     452                 :            : 
     453                 :          0 : static void on_transaction_stream_error(DnsTransaction *t, int error) {
     454         [ #  # ]:          0 :         assert(t);
     455                 :            : 
     456                 :          0 :         dns_transaction_close_connection(t);
     457                 :            : 
     458         [ #  # ]:          0 :         if (ERRNO_IS_DISCONNECT(error)) {
     459         [ #  # ]:          0 :                 if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
     460                 :            :                         /* If the LLMNR/TCP connection failed, the host doesn't support LLMNR, and we cannot answer the
     461                 :            :                          * question on this scope. */
     462                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
     463                 :          0 :                         return;
     464                 :            :                 }
     465                 :            : 
     466                 :          0 :                 dns_transaction_retry(t, true);
     467                 :          0 :                 return;
     468                 :            :         }
     469         [ #  # ]:          0 :         if (error != 0) {
     470                 :          0 :                 t->answer_errno = error;
     471                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
     472                 :            :         }
     473                 :            : }
     474                 :            : 
     475                 :          0 : static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) {
     476         [ #  # ]:          0 :         assert(t);
     477         [ #  # ]:          0 :         assert(p);
     478                 :            : 
     479                 :          0 :         dns_transaction_close_connection(t);
     480                 :            : 
     481         [ #  # ]:          0 :         if (dns_packet_validate_reply(p) <= 0) {
     482         [ #  # ]:          0 :                 log_debug("Invalid TCP reply packet.");
     483                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
     484                 :          0 :                 return 0;
     485                 :            :         }
     486                 :            : 
     487                 :          0 :         dns_scope_check_conflicts(t->scope, p);
     488                 :            : 
     489                 :          0 :         t->block_gc++;
     490                 :          0 :         dns_transaction_process_reply(t, p);
     491                 :          0 :         t->block_gc--;
     492                 :            : 
     493                 :            :         /* If the response wasn't useful, then complete the transition
     494                 :            :          * now. After all, we are the worst feature set now with TCP
     495                 :            :          * sockets, and there's really no point in retrying. */
     496         [ #  # ]:          0 :         if (t->state == DNS_TRANSACTION_PENDING)
     497                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
     498                 :            :         else
     499                 :          0 :                 dns_transaction_gc(t);
     500                 :            : 
     501                 :          0 :         return 0;
     502                 :            : }
     503                 :            : 
     504                 :          0 : static int on_stream_complete(DnsStream *s, int error) {
     505         [ #  # ]:          0 :         assert(s);
     506                 :            : 
     507   [ #  #  #  # ]:          0 :         if (ERRNO_IS_DISCONNECT(error) && s->protocol != DNS_PROTOCOL_LLMNR) {
     508         [ #  # ]:          0 :                 log_debug_errno(error, "Connection failure for DNS TCP stream: %m");
     509                 :            : 
     510         [ #  # ]:          0 :                 if (s->transactions) {
     511                 :            :                         DnsTransaction *t;
     512                 :            : 
     513                 :          0 :                         t = s->transactions;
     514                 :          0 :                         dns_server_packet_lost(t->server, IPPROTO_TCP, t->current_feature_level);
     515                 :            :                 }
     516                 :            :         }
     517                 :            : 
     518         [ #  # ]:          0 :         if (error != 0) {
     519                 :            :                 DnsTransaction *t, *n;
     520                 :            : 
     521         [ #  # ]:          0 :                 LIST_FOREACH_SAFE(transactions_by_stream, t, n, s->transactions)
     522                 :          0 :                         on_transaction_stream_error(t, error);
     523                 :            :         }
     524                 :            : 
     525                 :          0 :         return 0;
     526                 :            : }
     527                 :            : 
     528                 :          0 : static int on_stream_packet(DnsStream *s) {
     529                 :          0 :         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
     530                 :            :         DnsTransaction *t;
     531                 :            : 
     532         [ #  # ]:          0 :         assert(s);
     533                 :            : 
     534                 :            :         /* Take ownership of packet to be able to receive new packets */
     535                 :          0 :         p = dns_stream_take_read_packet(s);
     536         [ #  # ]:          0 :         assert(p);
     537                 :            : 
     538                 :          0 :         t = hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
     539         [ #  # ]:          0 :         if (t)
     540                 :          0 :                 return dns_transaction_on_stream_packet(t, p);
     541                 :            : 
     542                 :            :         /* Ignore incorrect transaction id as an old transaction can have been canceled. */
     543         [ #  # ]:          0 :         log_debug("Received unexpected TCP reply packet with id %" PRIu16 ", ignoring.", DNS_PACKET_ID(p));
     544                 :          0 :         return 0;
     545                 :            : }
     546                 :            : 
     547                 :          0 : static uint16_t dns_port_for_feature_level(DnsServerFeatureLevel level) {
     548   [ #  #  #  # ]:          0 :         return DNS_SERVER_FEATURE_LEVEL_IS_TLS(level) ? 853 : 53;
     549                 :            : }
     550                 :            : 
     551                 :          0 : static int dns_transaction_emit_tcp(DnsTransaction *t) {
     552                 :          0 :         _cleanup_(dns_stream_unrefp) DnsStream *s = NULL;
     553                 :          0 :         _cleanup_close_ int fd = -1;
     554                 :            :         union sockaddr_union sa;
     555                 :            :         DnsStreamType type;
     556                 :            :         int r;
     557                 :            : 
     558         [ #  # ]:          0 :         assert(t);
     559                 :            : 
     560                 :          0 :         dns_transaction_close_connection(t);
     561                 :            : 
     562      [ #  #  # ]:          0 :         switch (t->scope->protocol) {
     563                 :            : 
     564                 :          0 :         case DNS_PROTOCOL_DNS:
     565                 :          0 :                 r = dns_transaction_pick_server(t);
     566         [ #  # ]:          0 :                 if (r < 0)
     567                 :          0 :                         return r;
     568                 :            : 
     569   [ #  #  #  # ]:          0 :                 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
     570                 :          0 :                         return -EOPNOTSUPP;
     571                 :            : 
     572                 :          0 :                 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
     573         [ #  # ]:          0 :                 if (r < 0)
     574                 :          0 :                         return r;
     575                 :            : 
     576   [ #  #  #  #  :          0 :                 if (t->server->stream && (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level) == t->server->stream->encrypted))
                   #  # ]
     577                 :          0 :                         s = dns_stream_ref(t->server->stream);
     578                 :            :                 else
     579                 :          0 :                         fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, dns_port_for_feature_level(t->current_feature_level), &sa);
     580                 :            : 
     581                 :          0 :                 type = DNS_STREAM_LOOKUP;
     582                 :          0 :                 break;
     583                 :            : 
     584                 :          0 :         case DNS_PROTOCOL_LLMNR:
     585                 :            :                 /* When we already received a reply to this (but it was truncated), send to its sender address */
     586         [ #  # ]:          0 :                 if (t->received)
     587                 :          0 :                         fd = dns_scope_socket_tcp(t->scope, t->received->family, &t->received->sender, NULL, t->received->sender_port, &sa);
     588                 :          0 :                 else {
     589                 :            :                         union in_addr_union address;
     590                 :          0 :                         int family = AF_UNSPEC;
     591                 :            : 
     592                 :            :                         /* Otherwise, try to talk to the owner of a
     593                 :            :                          * the IP address, in case this is a reverse
     594                 :            :                          * PTR lookup */
     595                 :            : 
     596                 :          0 :                         r = dns_name_address(dns_resource_key_name(t->key), &family, &address);
     597         [ #  # ]:          0 :                         if (r < 0)
     598                 :          0 :                                 return r;
     599         [ #  # ]:          0 :                         if (r == 0)
     600                 :          0 :                                 return -EINVAL;
     601         [ #  # ]:          0 :                         if (family != t->scope->family)
     602                 :          0 :                                 return -ESRCH;
     603                 :            : 
     604                 :          0 :                         fd = dns_scope_socket_tcp(t->scope, family, &address, NULL, LLMNR_PORT, &sa);
     605                 :            :                 }
     606                 :            : 
     607                 :          0 :                 type = DNS_STREAM_LLMNR_SEND;
     608                 :          0 :                 break;
     609                 :            : 
     610                 :          0 :         default:
     611                 :          0 :                 return -EAFNOSUPPORT;
     612                 :            :         }
     613                 :            : 
     614         [ #  # ]:          0 :         if (!s) {
     615         [ #  # ]:          0 :                 if (fd < 0)
     616                 :          0 :                         return fd;
     617                 :            : 
     618                 :          0 :                 r = dns_stream_new(t->scope->manager, &s, type, t->scope->protocol, fd, &sa);
     619         [ #  # ]:          0 :                 if (r < 0)
     620                 :          0 :                         return r;
     621                 :            : 
     622                 :          0 :                 fd = -1;
     623                 :            : 
     624                 :            : #if ENABLE_DNS_OVER_TLS
     625         [ #  # ]:          0 :                 if (t->scope->protocol == DNS_PROTOCOL_DNS &&
     626   [ #  #  #  # ]:          0 :                     DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level)) {
     627                 :            : 
     628         [ #  # ]:          0 :                         assert(t->server);
     629                 :          0 :                         r = dnstls_stream_connect_tls(s, t->server);
     630         [ #  # ]:          0 :                         if (r < 0)
     631                 :          0 :                                 return r;
     632                 :            :                 }
     633                 :            : #endif
     634                 :            : 
     635         [ #  # ]:          0 :                 if (t->server) {
     636                 :          0 :                         dns_server_unref_stream(t->server);
     637                 :          0 :                         s->server = dns_server_ref(t->server);
     638                 :          0 :                         t->server->stream = dns_stream_ref(s);
     639                 :            :                 }
     640                 :            : 
     641                 :          0 :                 s->complete = on_stream_complete;
     642                 :          0 :                 s->on_packet = on_stream_packet;
     643                 :            : 
     644                 :            :                 /* The interface index is difficult to determine if we are
     645                 :            :                  * connecting to the local host, hence fill this in right away
     646                 :            :                  * instead of determining it from the socket */
     647                 :          0 :                 s->ifindex = dns_scope_ifindex(t->scope);
     648                 :            :         }
     649                 :            : 
     650                 :          0 :         t->stream = TAKE_PTR(s);
     651   [ #  #  #  # ]:          0 :         LIST_PREPEND(transactions_by_stream, t->stream->transactions, t);
     652                 :            : 
     653                 :          0 :         r = dns_stream_write_packet(t->stream, t->sent);
     654         [ #  # ]:          0 :         if (r < 0) {
     655                 :          0 :                 dns_transaction_close_connection(t);
     656                 :          0 :                 return r;
     657                 :            :         }
     658                 :            : 
     659                 :          0 :         dns_transaction_reset_answer(t);
     660                 :            : 
     661                 :          0 :         t->tried_stream = true;
     662                 :            : 
     663                 :          0 :         return 0;
     664                 :            : }
     665                 :            : 
     666                 :          0 : static void dns_transaction_cache_answer(DnsTransaction *t) {
     667         [ #  # ]:          0 :         assert(t);
     668                 :            : 
     669                 :            :         /* For mDNS we cache whenever we get the packet, rather than
     670                 :            :          * in each transaction. */
     671   [ #  #  #  # ]:          0 :         if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR))
     672                 :          0 :                 return;
     673                 :            : 
     674                 :            :         /* Caching disabled? */
     675         [ #  # ]:          0 :         if (t->scope->manager->enable_cache == DNS_CACHE_MODE_NO)
     676                 :          0 :                 return;
     677                 :            : 
     678                 :            :         /* We never cache if this packet is from the local host, under
     679                 :            :          * the assumption that a locally running DNS server would
     680                 :            :          * cache this anyway, and probably knows better when to flush
     681                 :            :          * the cache then we could. */
     682         [ #  # ]:          0 :         if (!DNS_PACKET_SHALL_CACHE(t->received))
     683                 :          0 :                 return;
     684                 :            : 
     685                 :          0 :         dns_cache_put(&t->scope->cache,
     686                 :          0 :                       t->scope->manager->enable_cache,
     687                 :            :                       t->key,
     688                 :            :                       t->answer_rcode,
     689                 :            :                       t->answer,
     690                 :          0 :                       t->answer_authenticated,
     691                 :            :                       t->answer_nsec_ttl,
     692                 :            :                       0,
     693                 :          0 :                       t->received->family,
     694                 :          0 :                       &t->received->sender);
     695                 :            : }
     696                 :            : 
     697                 :          0 : static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
     698                 :            :         DnsTransaction *dt;
     699                 :            :         Iterator i;
     700                 :            : 
     701         [ #  # ]:          0 :         assert(t);
     702                 :            : 
     703         [ #  # ]:          0 :         SET_FOREACH(dt, t->dnssec_transactions, i)
     704   [ #  #  #  # ]:          0 :                 if (DNS_TRANSACTION_IS_LIVE(dt->state))
     705                 :          0 :                         return true;
     706                 :            : 
     707                 :          0 :         return false;
     708                 :            : }
     709                 :            : 
     710                 :          0 : static int dns_transaction_dnssec_ready(DnsTransaction *t) {
     711                 :            :         DnsTransaction *dt;
     712                 :            :         Iterator i;
     713                 :            : 
     714         [ #  # ]:          0 :         assert(t);
     715                 :            : 
     716                 :            :         /* Checks whether the auxiliary DNSSEC transactions of our transaction have completed, or are still
     717                 :            :          * ongoing. Returns 0, if we aren't ready for the DNSSEC validation, positive if we are. */
     718                 :            : 
     719         [ #  # ]:          0 :         SET_FOREACH(dt, t->dnssec_transactions, i) {
     720                 :            : 
     721   [ #  #  #  #  :          0 :                 switch (dt->state) {
                      # ]
     722                 :            : 
     723                 :          0 :                 case DNS_TRANSACTION_NULL:
     724                 :            :                 case DNS_TRANSACTION_PENDING:
     725                 :            :                 case DNS_TRANSACTION_VALIDATING:
     726                 :            :                         /* Still ongoing */
     727                 :          0 :                         return 0;
     728                 :            : 
     729                 :          0 :                 case DNS_TRANSACTION_RCODE_FAILURE:
     730   [ #  #  #  # ]:          0 :                         if (!IN_SET(dt->answer_rcode, DNS_RCODE_NXDOMAIN, DNS_RCODE_SERVFAIL)) {
     731         [ #  # ]:          0 :                                 log_debug("Auxiliary DNSSEC RR query failed with rcode=%s.", dns_rcode_to_string(dt->answer_rcode));
     732                 :          0 :                                 goto fail;
     733                 :            :                         }
     734                 :            : 
     735                 :            :                         /* Fall-through: NXDOMAIN/SERVFAIL is good enough for us. This is because some DNS servers
     736                 :            :                          * erroneously return NXDOMAIN/SERVFAIL for empty non-terminals (Akamai...) or missing DS
     737                 :            :                          * records (Facebook), and we need to handle that nicely, when asking for parent SOA or similar
     738                 :            :                          * RRs to make unsigned proofs. */
     739                 :            : 
     740                 :            :                 case DNS_TRANSACTION_SUCCESS:
     741                 :            :                         /* All good. */
     742                 :          0 :                         break;
     743                 :            : 
     744                 :          0 :                 case DNS_TRANSACTION_DNSSEC_FAILED:
     745                 :            :                         /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
     746                 :            :                          * validationr result */
     747                 :            : 
     748         [ #  # ]:          0 :                         log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
     749                 :          0 :                         t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
     750                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
     751                 :          0 :                         return 0;
     752                 :            : 
     753                 :          0 :                 default:
     754         [ #  # ]:          0 :                         log_debug("Auxiliary DNSSEC RR query failed with %s", dns_transaction_state_to_string(dt->state));
     755                 :          0 :                         goto fail;
     756                 :            :                 }
     757                 :            :         }
     758                 :            : 
     759                 :            :         /* All is ready, we can go and validate */
     760                 :          0 :         return 1;
     761                 :            : 
     762                 :          0 : fail:
     763                 :          0 :         t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
     764                 :          0 :         dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
     765                 :          0 :         return 0;
     766                 :            : }
     767                 :            : 
     768                 :          0 : static void dns_transaction_process_dnssec(DnsTransaction *t) {
     769                 :            :         int r;
     770                 :            : 
     771         [ #  # ]:          0 :         assert(t);
     772                 :            : 
     773                 :            :         /* Are there ongoing DNSSEC transactions? If so, let's wait for them. */
     774                 :          0 :         r = dns_transaction_dnssec_ready(t);
     775         [ #  # ]:          0 :         if (r < 0)
     776                 :          0 :                 goto fail;
     777         [ #  # ]:          0 :         if (r == 0) /* We aren't ready yet (or one of our auxiliary transactions failed, and we shouldn't validate now */
     778                 :          0 :                 return;
     779                 :            : 
     780                 :            :         /* See if we learnt things from the additional DNSSEC transactions, that we didn't know before, and better
     781                 :            :          * restart the lookup immediately. */
     782                 :          0 :         r = dns_transaction_maybe_restart(t);
     783         [ #  # ]:          0 :         if (r < 0)
     784                 :          0 :                 goto fail;
     785         [ #  # ]:          0 :         if (r > 0) /* Transaction got restarted... */
     786                 :          0 :                 return;
     787                 :            : 
     788                 :            :         /* All our auxiliary DNSSEC transactions are complete now. Try
     789                 :            :          * to validate our RRset now. */
     790                 :          0 :         r = dns_transaction_validate_dnssec(t);
     791         [ #  # ]:          0 :         if (r == -EBADMSG) {
     792                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
     793                 :          0 :                 return;
     794                 :            :         }
     795         [ #  # ]:          0 :         if (r < 0)
     796                 :          0 :                 goto fail;
     797                 :            : 
     798         [ #  # ]:          0 :         if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER &&
     799         [ #  # ]:          0 :             t->scope->dnssec_mode == DNSSEC_YES) {
     800                 :            : 
     801                 :            :                 /*  We are not in automatic downgrade mode, and the server is bad. Let's try a different server, maybe
     802                 :            :                  *  that works. */
     803                 :            : 
     804         [ #  # ]:          0 :                 if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
     805                 :            :                         /* We tried fewer servers on this transaction than we know, let's try another one then */
     806                 :          0 :                         dns_transaction_retry(t, true);
     807                 :          0 :                         return;
     808                 :            :                 }
     809                 :            : 
     810                 :            :                 /* OK, let's give up, apparently all servers we tried didn't work. */
     811                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
     812                 :          0 :                 return;
     813                 :            :         }
     814                 :            : 
     815   [ #  #  #  # ]:          0 :         if (!IN_SET(t->answer_dnssec_result,
     816                 :            :                     _DNSSEC_RESULT_INVALID,        /* No DNSSEC validation enabled */
     817                 :            :                     DNSSEC_VALIDATED,              /* Answer is signed and validated successfully */
     818                 :            :                     DNSSEC_UNSIGNED,               /* Answer is right-fully unsigned */
     819                 :            :                     DNSSEC_INCOMPATIBLE_SERVER)) { /* Server does not do DNSSEC (Yay, we are downgrade attack vulnerable!) */
     820                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
     821                 :          0 :                 return;
     822                 :            :         }
     823                 :            : 
     824         [ #  # ]:          0 :         if (t->answer_dnssec_result == DNSSEC_INCOMPATIBLE_SERVER)
     825                 :          0 :                 dns_server_warn_downgrade(t->server);
     826                 :            : 
     827                 :          0 :         dns_transaction_cache_answer(t);
     828                 :            : 
     829         [ #  # ]:          0 :         if (t->answer_rcode == DNS_RCODE_SUCCESS)
     830                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
     831                 :            :         else
     832                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
     833                 :            : 
     834                 :          0 :         return;
     835                 :            : 
     836                 :          0 : fail:
     837                 :          0 :         t->answer_errno = -r;
     838                 :          0 :         dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
     839                 :            : }
     840                 :            : 
     841                 :          0 : static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags *flags) {
     842                 :            :         int r;
     843                 :            : 
     844         [ #  # ]:          0 :         assert(t);
     845                 :            : 
     846                 :            :         /* Checks whether the answer is positive, i.e. either a direct
     847                 :            :          * answer to the question, or a CNAME/DNAME for it */
     848                 :            : 
     849                 :          0 :         r = dns_answer_match_key(t->answer, t->key, flags);
     850         [ #  # ]:          0 :         if (r != 0)
     851                 :          0 :                 return r;
     852                 :            : 
     853                 :          0 :         r = dns_answer_find_cname_or_dname(t->answer, t->key, NULL, flags);
     854         [ #  # ]:          0 :         if (r != 0)
     855                 :          0 :                 return r;
     856                 :            : 
     857                 :          0 :         return false;
     858                 :            : }
     859                 :            : 
     860                 :          0 : static int dns_transaction_fix_rcode(DnsTransaction *t) {
     861                 :            :         int r;
     862                 :            : 
     863         [ #  # ]:          0 :         assert(t);
     864                 :            : 
     865                 :            :         /* Fix up the RCODE to SUCCESS if we get at least one matching RR in a response. Note that this contradicts the
     866                 :            :          * DNS RFCs a bit. Specifically, RFC 6604 Section 3 clarifies that the RCODE shall say something about a
     867                 :            :          * CNAME/DNAME chain element coming after the last chain element contained in the message, and not the first
     868                 :            :          * one included. However, it also indicates that not all DNS servers implement this correctly. Moreover, when
     869                 :            :          * using DNSSEC we usually only can prove the first element of a CNAME/DNAME chain anyway, hence let's settle
     870                 :            :          * on always processing the RCODE as referring to the immediate look-up we do, i.e. the first element of a
     871                 :            :          * CNAME/DNAME chain. This way, we uniformly handle CNAME/DNAME chains, regardless if the DNS server
     872                 :            :          * incorrectly implements RCODE, whether DNSSEC is in use, or whether the DNS server only supplied us with an
     873                 :            :          * incomplete CNAME/DNAME chain.
     874                 :            :          *
     875                 :            :          * Or in other words: if we get at least one positive reply in a message we patch NXDOMAIN to become SUCCESS,
     876                 :            :          * and then rely on the CNAME chasing logic to figure out that there's actually a CNAME error with a new
     877                 :            :          * lookup. */
     878                 :            : 
     879         [ #  # ]:          0 :         if (t->answer_rcode != DNS_RCODE_NXDOMAIN)
     880                 :          0 :                 return 0;
     881                 :            : 
     882                 :          0 :         r = dns_transaction_has_positive_answer(t, NULL);
     883         [ #  # ]:          0 :         if (r <= 0)
     884                 :          0 :                 return r;
     885                 :            : 
     886                 :          0 :         t->answer_rcode = DNS_RCODE_SUCCESS;
     887                 :          0 :         return 0;
     888                 :            : }
     889                 :            : 
     890                 :          0 : void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
     891                 :            :         usec_t ts;
     892                 :            :         int r;
     893                 :            : 
     894         [ #  # ]:          0 :         assert(t);
     895         [ #  # ]:          0 :         assert(p);
     896         [ #  # ]:          0 :         assert(t->scope);
     897         [ #  # ]:          0 :         assert(t->scope->manager);
     898                 :            : 
     899         [ #  # ]:          0 :         if (t->state != DNS_TRANSACTION_PENDING)
     900                 :          0 :                 return;
     901                 :            : 
     902                 :            :         /* Note that this call might invalidate the query. Callers
     903                 :            :          * should hence not attempt to access the query or transaction
     904                 :            :          * after calling this function. */
     905                 :            : 
     906         [ #  # ]:          0 :         log_debug("Processing incoming packet on transaction %" PRIu16" (rcode=%s).",
     907                 :            :                   t->id, dns_rcode_to_string(DNS_PACKET_RCODE(p)));
     908                 :            : 
     909   [ #  #  #  # ]:          0 :         switch (t->scope->protocol) {
     910                 :            : 
     911                 :          0 :         case DNS_PROTOCOL_LLMNR:
     912                 :            :                 /* For LLMNR we will not accept any packets from other interfaces */
     913                 :            : 
     914         [ #  # ]:          0 :                 if (p->ifindex != dns_scope_ifindex(t->scope))
     915                 :          0 :                         return;
     916                 :            : 
     917         [ #  # ]:          0 :                 if (p->family != t->scope->family)
     918                 :          0 :                         return;
     919                 :            : 
     920                 :            :                 /* Tentative packets are not full responses but still
     921                 :            :                  * useful for identifying uniqueness conflicts during
     922                 :            :                  * probing. */
     923         [ #  # ]:          0 :                 if (DNS_PACKET_LLMNR_T(p)) {
     924                 :          0 :                         dns_transaction_tentative(t, p);
     925                 :          0 :                         return;
     926                 :            :                 }
     927                 :            : 
     928                 :          0 :                 break;
     929                 :            : 
     930                 :          0 :         case DNS_PROTOCOL_MDNS:
     931                 :            :                 /* For mDNS we will not accept any packets from other interfaces */
     932                 :            : 
     933         [ #  # ]:          0 :                 if (p->ifindex != dns_scope_ifindex(t->scope))
     934                 :          0 :                         return;
     935                 :            : 
     936         [ #  # ]:          0 :                 if (p->family != t->scope->family)
     937                 :          0 :                         return;
     938                 :            : 
     939                 :          0 :                 break;
     940                 :            : 
     941                 :          0 :         case DNS_PROTOCOL_DNS:
     942                 :            :                 /* Note that we do not need to verify the
     943                 :            :                  * addresses/port numbers of incoming traffic, as we
     944                 :            :                  * invoked connect() on our UDP socket in which case
     945                 :            :                  * the kernel already does the needed verification for
     946                 :            :                  * us. */
     947                 :          0 :                 break;
     948                 :            : 
     949                 :          0 :         default:
     950                 :          0 :                 assert_not_reached("Invalid DNS protocol.");
     951                 :            :         }
     952                 :            : 
     953         [ #  # ]:          0 :         if (t->received != p) {
     954                 :          0 :                 dns_packet_unref(t->received);
     955                 :          0 :                 t->received = dns_packet_ref(p);
     956                 :            :         }
     957                 :            : 
     958                 :          0 :         t->answer_source = DNS_TRANSACTION_NETWORK;
     959                 :            : 
     960         [ #  # ]:          0 :         if (p->ipproto == IPPROTO_TCP) {
     961         [ #  # ]:          0 :                 if (DNS_PACKET_TC(p)) {
     962                 :            :                         /* Truncated via TCP? Somebody must be fucking with us */
     963                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
     964                 :          0 :                         return;
     965                 :            :                 }
     966                 :            : 
     967         [ #  # ]:          0 :                 if (DNS_PACKET_ID(p) != t->id) {
     968                 :            :                         /* Not the reply to our query? Somebody must be fucking with us */
     969                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
     970                 :          0 :                         return;
     971                 :            :                 }
     972                 :            :         }
     973                 :            : 
     974         [ #  # ]:          0 :         assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
     975                 :            : 
     976      [ #  #  # ]:          0 :         switch (t->scope->protocol) {
     977                 :            : 
     978                 :          0 :         case DNS_PROTOCOL_DNS:
     979         [ #  # ]:          0 :                 assert(t->server);
     980                 :            : 
     981   [ #  #  #  # ]:          0 :                 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
     982                 :            : 
     983                 :            :                         /* Request failed, immediately try again with reduced features */
     984                 :            : 
     985         [ #  # ]:          0 :                         if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_UDP) {
     986                 :            : 
     987                 :            :                                 /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
     988                 :            :                                  * this transaction anymore, but let's see if it might make sense to send the request
     989                 :            :                                  * to a different DNS server instead. If not let's process the response, and accept the
     990                 :            :                                  * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
     991                 :            :                                  * packet loss, but is not going to give us better rcodes should we actually have
     992                 :            :                                  * managed to get them already at UDP level. */
     993                 :            : 
     994         [ #  # ]:          0 :                                 if (t->n_picked_servers < dns_scope_get_n_dns_servers(t->scope)) {
     995                 :            :                                         /* We tried fewer servers on this transaction than we know, let's try another one then */
     996                 :          0 :                                         dns_transaction_retry(t, true);
     997                 :          0 :                                         return;
     998                 :            :                                 }
     999                 :            : 
    1000                 :            :                                 /* Give up, accept the rcode */
    1001         [ #  # ]:          0 :                                 log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
    1002                 :          0 :                                 break;
    1003                 :            :                         }
    1004                 :            : 
    1005                 :            :                         /* Reduce this feature level by one and try again. */
    1006      [ #  #  # ]:          0 :                         switch (t->current_feature_level) {
    1007                 :          0 :                         case DNS_SERVER_FEATURE_LEVEL_TLS_DO:
    1008                 :          0 :                                 t->clamp_feature_level = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN;
    1009                 :          0 :                                 break;
    1010                 :          0 :                         case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN + 1:
    1011                 :            :                                 /* Skip plain TLS when TLS is not supported */
    1012                 :          0 :                                 t->clamp_feature_level = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN - 1;
    1013                 :          0 :                                 break;
    1014                 :          0 :                         default:
    1015                 :          0 :                                 t->clamp_feature_level = t->current_feature_level - 1;
    1016                 :            :                         }
    1017                 :            : 
    1018         [ #  # ]:          0 :                         log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
    1019                 :            :                                   dns_rcode_to_string(DNS_PACKET_RCODE(p)),
    1020                 :            :                                   dns_server_feature_level_to_string(t->clamp_feature_level));
    1021                 :            : 
    1022                 :          0 :                         dns_transaction_retry(t, false /* use the same server */);
    1023                 :          0 :                         return;
    1024                 :            :                 }
    1025                 :            : 
    1026         [ #  # ]:          0 :                 if (DNS_PACKET_RCODE(p) == DNS_RCODE_REFUSED) {
    1027                 :            :                         /* This server refused our request? If so, try again, use a different server */
    1028         [ #  # ]:          0 :                         log_debug("Server returned REFUSED, switching servers, and retrying.");
    1029                 :          0 :                         dns_transaction_retry(t, true /* pick a new server */);
    1030                 :          0 :                         return;
    1031                 :            :                 }
    1032                 :            : 
    1033         [ #  # ]:          0 :                 if (DNS_PACKET_TC(p))
    1034                 :          0 :                         dns_server_packet_truncated(t->server, t->current_feature_level);
    1035                 :            : 
    1036                 :          0 :                 break;
    1037                 :            : 
    1038                 :          0 :         case DNS_PROTOCOL_LLMNR:
    1039                 :            :         case DNS_PROTOCOL_MDNS:
    1040                 :          0 :                 dns_scope_packet_received(t->scope, ts - t->start_usec);
    1041                 :          0 :                 break;
    1042                 :            : 
    1043                 :          0 :         default:
    1044                 :          0 :                 assert_not_reached("Invalid DNS protocol.");
    1045                 :            :         }
    1046                 :            : 
    1047         [ #  # ]:          0 :         if (DNS_PACKET_TC(p)) {
    1048                 :            : 
    1049                 :            :                 /* Truncated packets for mDNS are not allowed. Give up immediately. */
    1050         [ #  # ]:          0 :                 if (t->scope->protocol == DNS_PROTOCOL_MDNS) {
    1051                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
    1052                 :          0 :                         return;
    1053                 :            :                 }
    1054                 :            : 
    1055         [ #  # ]:          0 :                 log_debug("Reply truncated, retrying via TCP.");
    1056                 :            : 
    1057                 :            :                 /* Response was truncated, let's try again with good old TCP */
    1058                 :          0 :                 r = dns_transaction_emit_tcp(t);
    1059         [ #  # ]:          0 :                 if (r == -ESRCH) {
    1060                 :            :                         /* No servers found? Damn! */
    1061                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
    1062                 :          0 :                         return;
    1063                 :            :                 }
    1064         [ #  # ]:          0 :                 if (r == -EOPNOTSUPP) {
    1065                 :            :                         /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC  */
    1066                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
    1067                 :          0 :                         return;
    1068                 :            :                 }
    1069         [ #  # ]:          0 :                 if (r < 0) {
    1070                 :            :                         /* On LLMNR, if we cannot connect to the host,
    1071                 :            :                          * we immediately give up */
    1072         [ #  # ]:          0 :                         if (t->scope->protocol != DNS_PROTOCOL_DNS)
    1073                 :          0 :                                 goto fail;
    1074                 :            : 
    1075                 :            :                         /* On DNS, couldn't send? Try immediately again, with a new server */
    1076                 :          0 :                         dns_transaction_retry(t, true);
    1077                 :            :                 }
    1078                 :            : 
    1079                 :          0 :                 return;
    1080                 :            :         }
    1081                 :            : 
    1082                 :            :         /* After the superficial checks, actually parse the message. */
    1083                 :          0 :         r = dns_packet_extract(p);
    1084         [ #  # ]:          0 :         if (r < 0) {
    1085                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
    1086                 :          0 :                 return;
    1087                 :            :         }
    1088                 :            : 
    1089         [ #  # ]:          0 :         if (t->server) {
    1090                 :            :                 /* Report that we successfully received a valid packet with a good rcode after we initially got a bad
    1091                 :            :                  * rcode and subsequently downgraded the protocol */
    1092                 :            : 
    1093   [ #  #  #  # ]:          0 :                 if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN) &&
    1094         [ #  # ]:          0 :                     t->clamp_feature_level != _DNS_SERVER_FEATURE_LEVEL_INVALID)
    1095                 :          0 :                         dns_server_packet_rcode_downgrade(t->server, t->clamp_feature_level);
    1096                 :            : 
    1097                 :            :                 /* Report that the OPT RR was missing */
    1098         [ #  # ]:          0 :                 if (!p->opt)
    1099                 :          0 :                         dns_server_packet_bad_opt(t->server, t->current_feature_level);
    1100                 :            : 
    1101                 :            :                 /* Report that we successfully received a packet */
    1102                 :          0 :                 dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, p->size);
    1103                 :            :         }
    1104                 :            : 
    1105                 :            :         /* See if we know things we didn't know before that indicate we better restart the lookup immediately. */
    1106                 :          0 :         r = dns_transaction_maybe_restart(t);
    1107         [ #  # ]:          0 :         if (r < 0)
    1108                 :          0 :                 goto fail;
    1109         [ #  # ]:          0 :         if (r > 0) /* Transaction got restarted... */
    1110                 :          0 :                 return;
    1111                 :            : 
    1112   [ #  #  #  # ]:          0 :         if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS)) {
    1113                 :            : 
    1114                 :            :                 /* When dealing with protocols other than mDNS only consider responses with
    1115                 :            :                  * equivalent query section to the request. For mDNS this check doesn't make
    1116                 :            :                  * sense, because the section 6 of RFC6762 states that "Multicast DNS responses MUST NOT
    1117                 :            :                  * contain any questions in the Question Section". */
    1118         [ #  # ]:          0 :                 if (t->scope->protocol != DNS_PROTOCOL_MDNS) {
    1119                 :          0 :                         r = dns_packet_is_reply_for(p, t->key);
    1120         [ #  # ]:          0 :                         if (r < 0)
    1121                 :          0 :                                 goto fail;
    1122         [ #  # ]:          0 :                         if (r == 0) {
    1123                 :          0 :                                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
    1124                 :          0 :                                 return;
    1125                 :            :                         }
    1126                 :            :                 }
    1127                 :            : 
    1128                 :            :                 /* Install the answer as answer to the transaction */
    1129                 :          0 :                 dns_answer_unref(t->answer);
    1130                 :          0 :                 t->answer = dns_answer_ref(p->answer);
    1131                 :          0 :                 t->answer_rcode = DNS_PACKET_RCODE(p);
    1132                 :          0 :                 t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
    1133                 :          0 :                 t->answer_authenticated = false;
    1134                 :            : 
    1135                 :          0 :                 r = dns_transaction_fix_rcode(t);
    1136         [ #  # ]:          0 :                 if (r < 0)
    1137                 :          0 :                         goto fail;
    1138                 :            : 
    1139                 :            :                 /* Block GC while starting requests for additional DNSSEC RRs */
    1140                 :          0 :                 t->block_gc++;
    1141                 :          0 :                 r = dns_transaction_request_dnssec_keys(t);
    1142                 :          0 :                 t->block_gc--;
    1143                 :            : 
    1144                 :            :                 /* Maybe the transaction is ready for GC'ing now? If so, free it and return. */
    1145         [ #  # ]:          0 :                 if (!dns_transaction_gc(t))
    1146                 :          0 :                         return;
    1147                 :            : 
    1148                 :            :                 /* Requesting additional keys might have resulted in
    1149                 :            :                  * this transaction to fail, since the auxiliary
    1150                 :            :                  * request failed for some reason. If so, we are not
    1151                 :            :                  * in pending state anymore, and we should exit
    1152                 :            :                  * quickly. */
    1153         [ #  # ]:          0 :                 if (t->state != DNS_TRANSACTION_PENDING)
    1154                 :          0 :                         return;
    1155         [ #  # ]:          0 :                 if (r < 0)
    1156                 :          0 :                         goto fail;
    1157         [ #  # ]:          0 :                 if (r > 0) {
    1158                 :            :                         /* There are DNSSEC transactions pending now. Update the state accordingly. */
    1159                 :          0 :                         t->state = DNS_TRANSACTION_VALIDATING;
    1160                 :          0 :                         dns_transaction_close_connection(t);
    1161                 :          0 :                         dns_transaction_stop_timeout(t);
    1162                 :          0 :                         return;
    1163                 :            :                 }
    1164                 :            :         }
    1165                 :            : 
    1166                 :          0 :         dns_transaction_process_dnssec(t);
    1167                 :          0 :         return;
    1168                 :            : 
    1169                 :          0 : fail:
    1170                 :          0 :         t->answer_errno = -r;
    1171                 :          0 :         dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
    1172                 :            : }
    1173                 :            : 
    1174                 :          0 : static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
    1175                 :          0 :         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
    1176                 :          0 :         DnsTransaction *t = userdata;
    1177                 :            :         int r;
    1178                 :            : 
    1179         [ #  # ]:          0 :         assert(t);
    1180         [ #  # ]:          0 :         assert(t->scope);
    1181                 :            : 
    1182                 :          0 :         r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
    1183         [ #  # ]:          0 :         if (ERRNO_IS_DISCONNECT(-r)) {
    1184                 :            :                 usec_t usec;
    1185                 :            : 
    1186                 :            :                 /* UDP connection failure get reported via ICMP and then are possible delivered to us on the next
    1187                 :            :                  * recvmsg(). Treat this like a lost packet. */
    1188                 :            : 
    1189         [ #  # ]:          0 :                 log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
    1190         [ #  # ]:          0 :                 assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
    1191                 :          0 :                 dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level);
    1192                 :            : 
    1193                 :          0 :                 dns_transaction_retry(t, true);
    1194                 :          0 :                 return 0;
    1195                 :            :         }
    1196         [ #  # ]:          0 :         if (r < 0) {
    1197                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_ERRNO);
    1198                 :          0 :                 t->answer_errno = -r;
    1199                 :          0 :                 return 0;
    1200                 :            :         }
    1201                 :            : 
    1202                 :          0 :         r = dns_packet_validate_reply(p);
    1203         [ #  # ]:          0 :         if (r < 0) {
    1204         [ #  # ]:          0 :                 log_debug_errno(r, "Received invalid DNS packet as response, ignoring: %m");
    1205                 :          0 :                 return 0;
    1206                 :            :         }
    1207         [ #  # ]:          0 :         if (r == 0) {
    1208         [ #  # ]:          0 :                 log_debug("Received inappropriate DNS packet as response, ignoring.");
    1209                 :          0 :                 return 0;
    1210                 :            :         }
    1211                 :            : 
    1212         [ #  # ]:          0 :         if (DNS_PACKET_ID(p) != t->id) {
    1213         [ #  # ]:          0 :                 log_debug("Received packet with incorrect transaction ID, ignoring.");
    1214                 :          0 :                 return 0;
    1215                 :            :         }
    1216                 :            : 
    1217                 :          0 :         dns_transaction_process_reply(t, p);
    1218                 :          0 :         return 0;
    1219                 :            : }
    1220                 :            : 
    1221                 :          0 : static int dns_transaction_emit_udp(DnsTransaction *t) {
    1222                 :            :         int r;
    1223                 :            : 
    1224         [ #  # ]:          0 :         assert(t);
    1225                 :            : 
    1226         [ #  # ]:          0 :         if (t->scope->protocol == DNS_PROTOCOL_DNS) {
    1227                 :            : 
    1228                 :          0 :                 r = dns_transaction_pick_server(t);
    1229         [ #  # ]:          0 :                 if (r < 0)
    1230                 :          0 :                         return r;
    1231                 :            : 
    1232   [ #  #  #  #  :          0 :                 if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP || DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level))
                   #  # ]
    1233                 :          0 :                         return -EAGAIN; /* Sorry, can't do UDP, try TCP! */
    1234                 :            : 
    1235   [ #  #  #  # ]:          0 :                 if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
    1236                 :          0 :                         return -EOPNOTSUPP;
    1237                 :            : 
    1238   [ #  #  #  # ]:          0 :                 if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */
    1239                 :            :                         int fd;
    1240                 :            : 
    1241                 :          0 :                         dns_transaction_close_connection(t);
    1242                 :            : 
    1243                 :          0 :                         fd = dns_scope_socket_udp(t->scope, t->server, 53);
    1244         [ #  # ]:          0 :                         if (fd < 0)
    1245                 :          0 :                                 return fd;
    1246                 :            : 
    1247                 :          0 :                         r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
    1248         [ #  # ]:          0 :                         if (r < 0) {
    1249                 :          0 :                                 safe_close(fd);
    1250                 :          0 :                                 return r;
    1251                 :            :                         }
    1252                 :            : 
    1253                 :          0 :                         (void) sd_event_source_set_description(t->dns_udp_event_source, "dns-transaction-udp");
    1254                 :          0 :                         t->dns_udp_fd = fd;
    1255                 :            :                 }
    1256                 :            : 
    1257                 :          0 :                 r = dns_server_adjust_opt(t->server, t->sent, t->current_feature_level);
    1258         [ #  # ]:          0 :                 if (r < 0)
    1259                 :          0 :                         return r;
    1260                 :            :         } else
    1261                 :          0 :                 dns_transaction_close_connection(t);
    1262                 :            : 
    1263                 :          0 :         r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent);
    1264         [ #  # ]:          0 :         if (r < 0)
    1265                 :          0 :                 return r;
    1266                 :            : 
    1267                 :          0 :         dns_transaction_reset_answer(t);
    1268                 :            : 
    1269                 :          0 :         return 0;
    1270                 :            : }
    1271                 :            : 
    1272                 :          0 : static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
    1273                 :          0 :         DnsTransaction *t = userdata;
    1274                 :            : 
    1275         [ #  # ]:          0 :         assert(s);
    1276         [ #  # ]:          0 :         assert(t);
    1277                 :            : 
    1278   [ #  #  #  # ]:          0 :         if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
    1279                 :            :                 /* Timeout reached? Increase the timeout for the server used */
    1280      [ #  #  # ]:          0 :                 switch (t->scope->protocol) {
    1281                 :            : 
    1282                 :          0 :                 case DNS_PROTOCOL_DNS:
    1283         [ #  # ]:          0 :                         assert(t->server);
    1284         [ #  # ]:          0 :                         dns_server_packet_lost(t->server, t->stream ? IPPROTO_TCP : IPPROTO_UDP, t->current_feature_level);
    1285                 :          0 :                         break;
    1286                 :            : 
    1287                 :          0 :                 case DNS_PROTOCOL_LLMNR:
    1288                 :            :                 case DNS_PROTOCOL_MDNS:
    1289                 :          0 :                         dns_scope_packet_lost(t->scope, usec - t->start_usec);
    1290                 :          0 :                         break;
    1291                 :            : 
    1292                 :          0 :                 default:
    1293                 :          0 :                         assert_not_reached("Invalid DNS protocol.");
    1294                 :            :                 }
    1295                 :            : 
    1296         [ #  # ]:          0 :                 if (t->initial_jitter_scheduled)
    1297                 :          0 :                         t->initial_jitter_elapsed = true;
    1298                 :            :         }
    1299                 :            : 
    1300         [ #  # ]:          0 :         log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
    1301                 :            : 
    1302                 :          0 :         dns_transaction_retry(t, true);
    1303                 :          0 :         return 0;
    1304                 :            : }
    1305                 :            : 
    1306                 :          0 : static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
    1307         [ #  # ]:          0 :         assert(t);
    1308         [ #  # ]:          0 :         assert(t->scope);
    1309                 :            : 
    1310   [ #  #  #  # ]:          0 :         switch (t->scope->protocol) {
    1311                 :            : 
    1312                 :          0 :         case DNS_PROTOCOL_DNS:
    1313                 :            : 
    1314                 :            :                 /* When we do TCP, grant a much longer timeout, as in this case there's no need for us to quickly
    1315                 :            :                  * resend, as the kernel does that anyway for us, and we really don't want to interrupt it in that
    1316                 :            :                  * needlessly. */
    1317         [ #  # ]:          0 :                 if (t->stream)
    1318                 :          0 :                         return TRANSACTION_TCP_TIMEOUT_USEC;
    1319                 :            : 
    1320                 :          0 :                 return DNS_TIMEOUT_USEC;
    1321                 :            : 
    1322                 :          0 :         case DNS_PROTOCOL_MDNS:
    1323         [ #  # ]:          0 :                 assert(t->n_attempts > 0);
    1324         [ #  # ]:          0 :                 if (t->probing)
    1325                 :          0 :                         return MDNS_PROBING_INTERVAL_USEC;
    1326                 :            :                 else
    1327                 :          0 :                         return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
    1328                 :            : 
    1329                 :          0 :         case DNS_PROTOCOL_LLMNR:
    1330                 :          0 :                 return t->scope->resend_timeout;
    1331                 :            : 
    1332                 :          0 :         default:
    1333                 :          0 :                 assert_not_reached("Invalid DNS protocol.");
    1334                 :            :         }
    1335                 :            : }
    1336                 :            : 
    1337                 :          0 : static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
    1338                 :            :         int r;
    1339                 :            : 
    1340         [ #  # ]:          0 :         assert(t);
    1341                 :            : 
    1342                 :          0 :         dns_transaction_stop_timeout(t);
    1343                 :            : 
    1344         [ #  # ]:          0 :         if (!dns_scope_network_good(t->scope)) {
    1345                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_NETWORK_DOWN);
    1346                 :          0 :                 return 0;
    1347                 :            :         }
    1348                 :            : 
    1349   [ #  #  #  #  :          0 :         if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
                   #  # ]
    1350                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
    1351                 :          0 :                 return 0;
    1352                 :            :         }
    1353                 :            : 
    1354   [ #  #  #  # ]:          0 :         if (t->scope->protocol == DNS_PROTOCOL_LLMNR && t->tried_stream) {
    1355                 :            :                 /* If we already tried via a stream, then we don't
    1356                 :            :                  * retry on LLMNR. See RFC 4795, Section 2.7. */
    1357                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
    1358                 :          0 :                 return 0;
    1359                 :            :         }
    1360                 :            : 
    1361                 :          0 :         t->n_attempts++;
    1362                 :          0 :         t->start_usec = ts;
    1363                 :            : 
    1364                 :          0 :         dns_transaction_reset_answer(t);
    1365                 :          0 :         dns_transaction_flush_dnssec_transactions(t);
    1366                 :            : 
    1367                 :            :         /* Check the trust anchor. Do so only on classic DNS, since DNSSEC does not apply otherwise. */
    1368         [ #  # ]:          0 :         if (t->scope->protocol == DNS_PROTOCOL_DNS) {
    1369                 :          0 :                 r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, t->key, &t->answer);
    1370         [ #  # ]:          0 :                 if (r < 0)
    1371                 :          0 :                         return r;
    1372         [ #  # ]:          0 :                 if (r > 0) {
    1373                 :          0 :                         t->answer_rcode = DNS_RCODE_SUCCESS;
    1374                 :          0 :                         t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
    1375                 :          0 :                         t->answer_authenticated = true;
    1376                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
    1377                 :          0 :                         return 0;
    1378                 :            :                 }
    1379                 :            : 
    1380         [ #  # ]:          0 :                 if (dns_name_is_root(dns_resource_key_name(t->key)) &&
    1381         [ #  # ]:          0 :                     t->key->type == DNS_TYPE_DS) {
    1382                 :            : 
    1383                 :            :                         /* Hmm, this is a request for the root DS? A
    1384                 :            :                          * DS RR doesn't exist in the root zone, and
    1385                 :            :                          * if our trust anchor didn't know it either,
    1386                 :            :                          * this means we cannot do any DNSSEC logic
    1387                 :            :                          * anymore. */
    1388                 :            : 
    1389         [ #  # ]:          0 :                         if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
    1390                 :            :                                 /* We are in downgrade mode. In this
    1391                 :            :                                  * case, synthesize an unsigned empty
    1392                 :            :                                  * response, so that the any lookup
    1393                 :            :                                  * depending on this one can continue
    1394                 :            :                                  * assuming there was no DS, and hence
    1395                 :            :                                  * the root zone was unsigned. */
    1396                 :            : 
    1397                 :          0 :                                 t->answer_rcode = DNS_RCODE_SUCCESS;
    1398                 :          0 :                                 t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
    1399                 :          0 :                                 t->answer_authenticated = false;
    1400                 :          0 :                                 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
    1401                 :            :                         } else
    1402                 :            :                                 /* If we are not in downgrade mode,
    1403                 :            :                                  * then fail the lookup, because we
    1404                 :            :                                  * cannot reasonably answer it. There
    1405                 :            :                                  * might be DS RRs, but we don't know
    1406                 :            :                                  * them, and the DNS server won't tell
    1407                 :            :                                  * them to us (and even if it would,
    1408                 :            :                                  * we couldn't validate and trust them. */
    1409                 :          0 :                                 dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
    1410                 :            : 
    1411                 :          0 :                         return 0;
    1412                 :            :                 }
    1413                 :            :         }
    1414                 :            : 
    1415                 :            :         /* Check the zone, but only if this transaction is not used
    1416                 :            :          * for probing or verifying a zone item. */
    1417         [ #  # ]:          0 :         if (set_isempty(t->notify_zone_items)) {
    1418                 :            : 
    1419                 :          0 :                 r = dns_zone_lookup(&t->scope->zone, t->key, dns_scope_ifindex(t->scope), &t->answer, NULL, NULL);
    1420         [ #  # ]:          0 :                 if (r < 0)
    1421                 :          0 :                         return r;
    1422         [ #  # ]:          0 :                 if (r > 0) {
    1423                 :          0 :                         t->answer_rcode = DNS_RCODE_SUCCESS;
    1424                 :          0 :                         t->answer_source = DNS_TRANSACTION_ZONE;
    1425                 :          0 :                         t->answer_authenticated = true;
    1426                 :          0 :                         dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
    1427                 :          0 :                         return 0;
    1428                 :            :                 }
    1429                 :            :         }
    1430                 :            : 
    1431                 :            :         /* Check the cache, but only if this transaction is not used
    1432                 :            :          * for probing or verifying a zone item. */
    1433         [ #  # ]:          0 :         if (set_isempty(t->notify_zone_items)) {
    1434                 :            : 
    1435                 :            :                 /* Before trying the cache, let's make sure we figured out a
    1436                 :            :                  * server to use. Should this cause a change of server this
    1437                 :            :                  * might flush the cache. */
    1438                 :          0 :                 (void) dns_scope_get_dns_server(t->scope);
    1439                 :            : 
    1440                 :            :                 /* Let's then prune all outdated entries */
    1441                 :          0 :                 dns_cache_prune(&t->scope->cache);
    1442                 :            : 
    1443                 :          0 :                 r = dns_cache_lookup(&t->scope->cache, t->key, t->clamp_ttl, &t->answer_rcode, &t->answer, &t->answer_authenticated);
    1444         [ #  # ]:          0 :                 if (r < 0)
    1445                 :          0 :                         return r;
    1446         [ #  # ]:          0 :                 if (r > 0) {
    1447                 :          0 :                         t->answer_source = DNS_TRANSACTION_CACHE;
    1448         [ #  # ]:          0 :                         if (t->answer_rcode == DNS_RCODE_SUCCESS)
    1449                 :          0 :                                 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
    1450                 :            :                         else
    1451                 :          0 :                                 dns_transaction_complete(t, DNS_TRANSACTION_RCODE_FAILURE);
    1452                 :          0 :                         return 0;
    1453                 :            :                 }
    1454                 :            :         }
    1455                 :            : 
    1456                 :          0 :         return 1;
    1457                 :            : }
    1458                 :            : 
    1459                 :          0 : static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
    1460                 :            : 
    1461                 :          0 :         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
    1462                 :          0 :         bool add_known_answers = false;
    1463                 :            :         DnsTransaction *other;
    1464                 :            :         Iterator i;
    1465                 :            :         DnsResourceKey *tkey;
    1466                 :          0 :         _cleanup_set_free_ Set *keys = NULL;
    1467                 :            :         unsigned qdcount;
    1468                 :          0 :         unsigned nscount = 0;
    1469                 :            :         usec_t ts;
    1470                 :            :         int r;
    1471                 :            : 
    1472         [ #  # ]:          0 :         assert(t);
    1473         [ #  # ]:          0 :         assert(t->scope->protocol == DNS_PROTOCOL_MDNS);
    1474                 :            : 
    1475                 :            :         /* Discard any previously prepared packet, so we can start over and coalesce again */
    1476                 :          0 :         t->sent = dns_packet_unref(t->sent);
    1477                 :            : 
    1478                 :          0 :         r = dns_packet_new_query(&p, t->scope->protocol, 0, false);
    1479         [ #  # ]:          0 :         if (r < 0)
    1480                 :          0 :                 return r;
    1481                 :            : 
    1482                 :          0 :         r = dns_packet_append_key(p, t->key, 0, NULL);
    1483         [ #  # ]:          0 :         if (r < 0)
    1484                 :          0 :                 return r;
    1485                 :            : 
    1486                 :          0 :         qdcount = 1;
    1487                 :            : 
    1488         [ #  # ]:          0 :         if (dns_key_is_shared(t->key))
    1489                 :          0 :                 add_known_answers = true;
    1490                 :            : 
    1491         [ #  # ]:          0 :         if (t->key->type == DNS_TYPE_ANY) {
    1492                 :          0 :                 r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
    1493         [ #  # ]:          0 :                 if (r < 0)
    1494                 :          0 :                         return r;
    1495                 :            : 
    1496                 :          0 :                 r = set_put(keys, t->key);
    1497         [ #  # ]:          0 :                 if (r < 0)
    1498                 :          0 :                         return r;
    1499                 :            :         }
    1500                 :            : 
    1501                 :            :         /*
    1502                 :            :          * For mDNS, we want to coalesce as many open queries in pending transactions into one single
    1503                 :            :          * query packet on the wire as possible. To achieve that, we iterate through all pending transactions
    1504                 :            :          * in our current scope, and see whether their timing constraints allow them to be sent.
    1505                 :            :          */
    1506                 :            : 
    1507         [ #  # ]:          0 :         assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
    1508                 :            : 
    1509         [ #  # ]:          0 :         LIST_FOREACH(transactions_by_scope, other, t->scope->transactions) {
    1510                 :            : 
    1511                 :            :                 /* Skip ourselves */
    1512         [ #  # ]:          0 :                 if (other == t)
    1513                 :          0 :                         continue;
    1514                 :            : 
    1515         [ #  # ]:          0 :                 if (other->state != DNS_TRANSACTION_PENDING)
    1516                 :          0 :                         continue;
    1517                 :            : 
    1518         [ #  # ]:          0 :                 if (other->next_attempt_after > ts)
    1519                 :          0 :                         continue;
    1520                 :            : 
    1521         [ #  # ]:          0 :                 if (qdcount >= UINT16_MAX)
    1522                 :          0 :                         break;
    1523                 :            : 
    1524                 :          0 :                 r = dns_packet_append_key(p, other->key, 0, NULL);
    1525                 :            : 
    1526                 :            :                 /*
    1527                 :            :                  * If we can't stuff more questions into the packet, just give up.
    1528                 :            :                  * One of the 'other' transactions will fire later and take care of the rest.
    1529                 :            :                  */
    1530         [ #  # ]:          0 :                 if (r == -EMSGSIZE)
    1531                 :          0 :                         break;
    1532                 :            : 
    1533         [ #  # ]:          0 :                 if (r < 0)
    1534                 :          0 :                         return r;
    1535                 :            : 
    1536                 :          0 :                 r = dns_transaction_prepare(other, ts);
    1537         [ #  # ]:          0 :                 if (r <= 0)
    1538                 :          0 :                         continue;
    1539                 :            : 
    1540                 :          0 :                 ts += transaction_get_resend_timeout(other);
    1541                 :            : 
    1542                 :          0 :                 r = sd_event_add_time(
    1543                 :          0 :                                 other->scope->manager->event,
    1544                 :            :                                 &other->timeout_event_source,
    1545                 :            :                                 clock_boottime_or_monotonic(),
    1546                 :            :                                 ts, 0,
    1547                 :            :                                 on_transaction_timeout, other);
    1548         [ #  # ]:          0 :                 if (r < 0)
    1549                 :          0 :                         return r;
    1550                 :            : 
    1551                 :          0 :                 (void) sd_event_source_set_description(other->timeout_event_source, "dns-transaction-timeout");
    1552                 :            : 
    1553                 :          0 :                 other->state = DNS_TRANSACTION_PENDING;
    1554                 :          0 :                 other->next_attempt_after = ts;
    1555                 :            : 
    1556                 :          0 :                 qdcount++;
    1557                 :            : 
    1558         [ #  # ]:          0 :                 if (dns_key_is_shared(other->key))
    1559                 :          0 :                         add_known_answers = true;
    1560                 :            : 
    1561         [ #  # ]:          0 :                 if (other->key->type == DNS_TYPE_ANY) {
    1562                 :          0 :                         r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
    1563         [ #  # ]:          0 :                         if (r < 0)
    1564                 :          0 :                                 return r;
    1565                 :            : 
    1566                 :          0 :                         r = set_put(keys, other->key);
    1567         [ #  # ]:          0 :                         if (r < 0)
    1568                 :          0 :                                 return r;
    1569                 :            :                 }
    1570                 :            :         }
    1571                 :            : 
    1572                 :          0 :         DNS_PACKET_HEADER(p)->qdcount = htobe16(qdcount);
    1573                 :            : 
    1574                 :            :         /* Append known answer section if we're asking for any shared record */
    1575         [ #  # ]:          0 :         if (add_known_answers) {
    1576                 :          0 :                 r = dns_cache_export_shared_to_packet(&t->scope->cache, p);
    1577         [ #  # ]:          0 :                 if (r < 0)
    1578                 :          0 :                         return r;
    1579                 :            :         }
    1580                 :            : 
    1581         [ #  # ]:          0 :         SET_FOREACH(tkey, keys, i) {
    1582         [ #  # ]:          0 :                 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
    1583                 :            :                 bool tentative;
    1584                 :            : 
    1585                 :          0 :                 r = dns_zone_lookup(&t->scope->zone, tkey, t->scope->link->ifindex, &answer, NULL, &tentative);
    1586         [ #  # ]:          0 :                 if (r < 0)
    1587                 :          0 :                         return r;
    1588                 :            : 
    1589                 :          0 :                 r = dns_packet_append_answer(p, answer);
    1590         [ #  # ]:          0 :                 if (r < 0)
    1591                 :          0 :                         return r;
    1592                 :            : 
    1593                 :          0 :                 nscount += dns_answer_size(answer);
    1594                 :            :         }
    1595                 :          0 :         DNS_PACKET_HEADER(p)->nscount = htobe16(nscount);
    1596                 :            : 
    1597                 :          0 :         t->sent = TAKE_PTR(p);
    1598                 :            : 
    1599                 :          0 :         return 0;
    1600                 :            : }
    1601                 :            : 
    1602                 :          0 : static int dns_transaction_make_packet(DnsTransaction *t) {
    1603                 :          0 :         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
    1604                 :            :         int r;
    1605                 :            : 
    1606         [ #  # ]:          0 :         assert(t);
    1607                 :            : 
    1608         [ #  # ]:          0 :         if (t->scope->protocol == DNS_PROTOCOL_MDNS)
    1609                 :          0 :                 return dns_transaction_make_packet_mdns(t);
    1610                 :            : 
    1611         [ #  # ]:          0 :         if (t->sent)
    1612                 :          0 :                 return 0;
    1613                 :            : 
    1614                 :          0 :         r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode != DNSSEC_NO);
    1615         [ #  # ]:          0 :         if (r < 0)
    1616                 :          0 :                 return r;
    1617                 :            : 
    1618                 :          0 :         r = dns_packet_append_key(p, t->key, 0, NULL);
    1619         [ #  # ]:          0 :         if (r < 0)
    1620                 :          0 :                 return r;
    1621                 :            : 
    1622                 :          0 :         DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
    1623                 :          0 :         DNS_PACKET_HEADER(p)->id = t->id;
    1624                 :            : 
    1625                 :          0 :         t->sent = TAKE_PTR(p);
    1626                 :            : 
    1627                 :          0 :         return 0;
    1628                 :            : }
    1629                 :            : 
    1630                 :          0 : int dns_transaction_go(DnsTransaction *t) {
    1631                 :            :         usec_t ts;
    1632                 :            :         int r;
    1633                 :            :         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
    1634                 :            : 
    1635         [ #  # ]:          0 :         assert(t);
    1636                 :            : 
    1637                 :            :         /* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has finished
    1638                 :            :          * now. */
    1639                 :            : 
    1640         [ #  # ]:          0 :         assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
    1641                 :            : 
    1642                 :          0 :         r = dns_transaction_prepare(t, ts);
    1643         [ #  # ]:          0 :         if (r <= 0)
    1644                 :          0 :                 return r;
    1645                 :            : 
    1646   [ #  #  #  # ]:          0 :         log_debug("Transaction %" PRIu16 " for <%s> scope %s on %s/%s.",
    1647                 :            :                   t->id,
    1648                 :            :                   dns_resource_key_to_string(t->key, key_str, sizeof key_str),
    1649                 :            :                   dns_protocol_to_string(t->scope->protocol),
    1650                 :            :                   t->scope->link ? t->scope->link->ifname : "*",
    1651                 :            :                   af_to_name_short(t->scope->family));
    1652                 :            : 
    1653         [ #  # ]:          0 :         if (!t->initial_jitter_scheduled &&
    1654   [ #  #  #  # ]:          0 :             IN_SET(t->scope->protocol, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS)) {
    1655                 :            :                 usec_t jitter, accuracy;
    1656                 :            : 
    1657                 :            :                 /* RFC 4795 Section 2.7 suggests all queries should be
    1658                 :            :                  * delayed by a random time from 0 to JITTER_INTERVAL. */
    1659                 :            : 
    1660                 :          0 :                 t->initial_jitter_scheduled = true;
    1661                 :            : 
    1662                 :          0 :                 random_bytes(&jitter, sizeof(jitter));
    1663                 :            : 
    1664      [ #  #  # ]:          0 :                 switch (t->scope->protocol) {
    1665                 :            : 
    1666                 :          0 :                 case DNS_PROTOCOL_LLMNR:
    1667                 :          0 :                         jitter %= LLMNR_JITTER_INTERVAL_USEC;
    1668                 :          0 :                         accuracy = LLMNR_JITTER_INTERVAL_USEC;
    1669                 :          0 :                         break;
    1670                 :            : 
    1671                 :          0 :                 case DNS_PROTOCOL_MDNS:
    1672                 :          0 :                         jitter %= MDNS_JITTER_RANGE_USEC;
    1673                 :          0 :                         jitter += MDNS_JITTER_MIN_USEC;
    1674                 :          0 :                         accuracy = MDNS_JITTER_RANGE_USEC;
    1675                 :          0 :                         break;
    1676                 :          0 :                 default:
    1677                 :          0 :                         assert_not_reached("bad protocol");
    1678                 :            :                 }
    1679                 :            : 
    1680                 :          0 :                 r = sd_event_add_time(
    1681                 :          0 :                                 t->scope->manager->event,
    1682                 :            :                                 &t->timeout_event_source,
    1683                 :            :                                 clock_boottime_or_monotonic(),
    1684                 :            :                                 ts + jitter, accuracy,
    1685                 :            :                                 on_transaction_timeout, t);
    1686         [ #  # ]:          0 :                 if (r < 0)
    1687                 :          0 :                         return r;
    1688                 :            : 
    1689                 :          0 :                 (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
    1690                 :            : 
    1691                 :          0 :                 t->n_attempts = 0;
    1692                 :          0 :                 t->next_attempt_after = ts;
    1693                 :          0 :                 t->state = DNS_TRANSACTION_PENDING;
    1694                 :            : 
    1695         [ #  # ]:          0 :                 log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
    1696                 :          0 :                 return 0;
    1697                 :            :         }
    1698                 :            : 
    1699                 :            :         /* Otherwise, we need to ask the network */
    1700                 :          0 :         r = dns_transaction_make_packet(t);
    1701         [ #  # ]:          0 :         if (r < 0)
    1702                 :          0 :                 return r;
    1703                 :            : 
    1704   [ #  #  #  # ]:          0 :         if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
    1705         [ #  # ]:          0 :             (dns_name_endswith(dns_resource_key_name(t->key), "in-addr.arpa") > 0 ||
    1706                 :          0 :              dns_name_endswith(dns_resource_key_name(t->key), "ip6.arpa") > 0)) {
    1707                 :            : 
    1708                 :            :                 /* RFC 4795, Section 2.4. says reverse lookups shall
    1709                 :            :                  * always be made via TCP on LLMNR */
    1710                 :          0 :                 r = dns_transaction_emit_tcp(t);
    1711                 :            :         } else {
    1712                 :            :                 /* Try via UDP, and if that fails due to large size or lack of
    1713                 :            :                  * support try via TCP */
    1714                 :          0 :                 r = dns_transaction_emit_udp(t);
    1715         [ #  # ]:          0 :                 if (r == -EMSGSIZE)
    1716         [ #  # ]:          0 :                         log_debug("Sending query via TCP since it is too large.");
    1717         [ #  # ]:          0 :                 else if (r == -EAGAIN)
    1718         [ #  # ]:          0 :                         log_debug("Sending query via TCP since UDP isn't supported.");
    1719   [ #  #  #  # ]:          0 :                 if (IN_SET(r, -EMSGSIZE, -EAGAIN))
    1720                 :          0 :                         r = dns_transaction_emit_tcp(t);
    1721                 :            :         }
    1722                 :            : 
    1723         [ #  # ]:          0 :         if (r == -ESRCH) {
    1724                 :            :                 /* No servers to send this to? */
    1725                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
    1726                 :          0 :                 return 0;
    1727                 :            :         }
    1728         [ #  # ]:          0 :         if (r == -EOPNOTSUPP) {
    1729                 :            :                 /* Tried to ask for DNSSEC RRs, on a server that doesn't do DNSSEC  */
    1730                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
    1731                 :          0 :                 return 0;
    1732                 :            :         }
    1733   [ #  #  #  # ]:          0 :         if (t->scope->protocol == DNS_PROTOCOL_LLMNR && ERRNO_IS_DISCONNECT(-r)) {
    1734                 :            :                 /* On LLMNR, if we cannot connect to a host via TCP when doing reverse lookups. This means we cannot
    1735                 :            :                  * answer this request with this protocol. */
    1736                 :          0 :                 dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
    1737                 :          0 :                 return 0;
    1738                 :            :         }
    1739         [ #  # ]:          0 :         if (r < 0) {
    1740         [ #  # ]:          0 :                 if (t->scope->protocol != DNS_PROTOCOL_DNS)
    1741                 :          0 :                         return r;
    1742                 :            : 
    1743                 :            :                 /* Couldn't send? Try immediately again, with a new server */
    1744                 :          0 :                 dns_scope_next_dns_server(t->scope);
    1745                 :            : 
    1746                 :          0 :                 return dns_transaction_go(t);
    1747                 :            :         }
    1748                 :            : 
    1749                 :          0 :         ts += transaction_get_resend_timeout(t);
    1750                 :            : 
    1751                 :          0 :         r = sd_event_add_time(
    1752                 :          0 :                         t->scope->manager->event,
    1753                 :            :                         &t->timeout_event_source,
    1754                 :            :                         clock_boottime_or_monotonic(),
    1755                 :            :                         ts, 0,
    1756                 :            :                         on_transaction_timeout, t);
    1757         [ #  # ]:          0 :         if (r < 0)
    1758                 :          0 :                 return r;
    1759                 :            : 
    1760                 :          0 :         (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
    1761                 :            : 
    1762                 :          0 :         t->state = DNS_TRANSACTION_PENDING;
    1763                 :          0 :         t->next_attempt_after = ts;
    1764                 :            : 
    1765                 :          0 :         return 1;
    1766                 :            : }
    1767                 :            : 
    1768                 :          0 : static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
    1769                 :            :         DnsTransaction *n;
    1770                 :            :         Iterator i;
    1771                 :            :         int r;
    1772                 :            : 
    1773         [ #  # ]:          0 :         assert(t);
    1774         [ #  # ]:          0 :         assert(aux);
    1775                 :            : 
    1776                 :            :         /* Try to find cyclic dependencies between transaction objects */
    1777                 :            : 
    1778         [ #  # ]:          0 :         if (t == aux)
    1779                 :          0 :                 return 1;
    1780                 :            : 
    1781         [ #  # ]:          0 :         SET_FOREACH(n, aux->dnssec_transactions, i) {
    1782                 :          0 :                 r = dns_transaction_find_cyclic(t, n);
    1783         [ #  # ]:          0 :                 if (r != 0)
    1784                 :          0 :                         return r;
    1785                 :            :         }
    1786                 :            : 
    1787                 :          0 :         return 0;
    1788                 :            : }
    1789                 :            : 
    1790                 :          0 : static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
    1791                 :            :         DnsTransaction *aux;
    1792                 :            :         int r;
    1793                 :            : 
    1794         [ #  # ]:          0 :         assert(t);
    1795         [ #  # ]:          0 :         assert(ret);
    1796         [ #  # ]:          0 :         assert(key);
    1797                 :            : 
    1798                 :          0 :         aux = dns_scope_find_transaction(t->scope, key, true);
    1799         [ #  # ]:          0 :         if (!aux) {
    1800                 :          0 :                 r = dns_transaction_new(&aux, t->scope, key);
    1801         [ #  # ]:          0 :                 if (r < 0)
    1802                 :          0 :                         return r;
    1803                 :            :         } else {
    1804         [ #  # ]:          0 :                 if (set_contains(t->dnssec_transactions, aux)) {
    1805                 :          0 :                         *ret = aux;
    1806                 :          0 :                         return 0;
    1807                 :            :                 }
    1808                 :            : 
    1809                 :          0 :                 r = dns_transaction_find_cyclic(t, aux);
    1810         [ #  # ]:          0 :                 if (r < 0)
    1811                 :          0 :                         return r;
    1812         [ #  # ]:          0 :                 if (r > 0) {
    1813                 :            :                         char s[DNS_RESOURCE_KEY_STRING_MAX], saux[DNS_RESOURCE_KEY_STRING_MAX];
    1814                 :            : 
    1815         [ #  # ]:          0 :                         return log_debug_errno(SYNTHETIC_ERRNO(ELOOP),
    1816                 :            :                                                "Potential cyclic dependency, refusing to add transaction %" PRIu16 " (%s) as dependency for %" PRIu16 " (%s).",
    1817                 :            :                                                aux->id,
    1818                 :            :                                                dns_resource_key_to_string(t->key, s, sizeof s),
    1819                 :            :                                                t->id,
    1820                 :            :                                                dns_resource_key_to_string(aux->key, saux, sizeof saux));
    1821                 :            :                 }
    1822                 :            :         }
    1823                 :            : 
    1824                 :          0 :         r = set_ensure_allocated(&t->dnssec_transactions, NULL);
    1825         [ #  # ]:          0 :         if (r < 0)
    1826                 :          0 :                 goto gc;
    1827                 :            : 
    1828                 :          0 :         r = set_ensure_allocated(&aux->notify_transactions, NULL);
    1829         [ #  # ]:          0 :         if (r < 0)
    1830                 :          0 :                 goto gc;
    1831                 :            : 
    1832                 :          0 :         r = set_ensure_allocated(&aux->notify_transactions_done, NULL);
    1833         [ #  # ]:          0 :         if (r < 0)
    1834                 :          0 :                 goto gc;
    1835                 :            : 
    1836                 :          0 :         r = set_put(t->dnssec_transactions, aux);
    1837         [ #  # ]:          0 :         if (r < 0)
    1838                 :          0 :                 goto gc;
    1839                 :            : 
    1840                 :          0 :         r = set_put(aux->notify_transactions, t);
    1841         [ #  # ]:          0 :         if (r < 0) {
    1842                 :          0 :                 (void) set_remove(t->dnssec_transactions, aux);
    1843                 :          0 :                 goto gc;
    1844                 :            :         }
    1845                 :            : 
    1846                 :          0 :         *ret = aux;
    1847                 :          0 :         return 1;
    1848                 :            : 
    1849                 :          0 : gc:
    1850                 :          0 :         dns_transaction_gc(aux);
    1851                 :          0 :         return r;
    1852                 :            : }
    1853                 :            : 
    1854                 :          0 : static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
    1855                 :          0 :         _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
    1856                 :            :         DnsTransaction *aux;
    1857                 :            :         int r;
    1858                 :            : 
    1859         [ #  # ]:          0 :         assert(t);
    1860         [ #  # ]:          0 :         assert(key);
    1861                 :            : 
    1862                 :            :         /* Try to get the data from the trust anchor */
    1863                 :          0 :         r = dns_trust_anchor_lookup_positive(&t->scope->manager->trust_anchor, key, &a);
    1864         [ #  # ]:          0 :         if (r < 0)
    1865                 :          0 :                 return r;
    1866         [ #  # ]:          0 :         if (r > 0) {
    1867                 :          0 :                 r = dns_answer_extend(&t->validated_keys, a);
    1868         [ #  # ]:          0 :                 if (r < 0)
    1869                 :          0 :                         return r;
    1870                 :            : 
    1871                 :          0 :                 return 0;
    1872                 :            :         }
    1873                 :            : 
    1874                 :            :         /* This didn't work, ask for it via the network/cache then. */
    1875                 :          0 :         r = dns_transaction_add_dnssec_transaction(t, key, &aux);
    1876         [ #  # ]:          0 :         if (r == -ELOOP) /* This would result in a cyclic dependency */
    1877                 :          0 :                 return 0;
    1878         [ #  # ]:          0 :         if (r < 0)
    1879                 :          0 :                 return r;
    1880                 :            : 
    1881         [ #  # ]:          0 :         if (aux->state == DNS_TRANSACTION_NULL) {
    1882                 :          0 :                 r = dns_transaction_go(aux);
    1883         [ #  # ]:          0 :                 if (r < 0)
    1884                 :          0 :                         return r;
    1885                 :            :         }
    1886                 :            : 
    1887                 :          0 :         return 1;
    1888                 :            : }
    1889                 :            : 
    1890                 :          0 : static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) {
    1891                 :            :         int r;
    1892                 :            : 
    1893         [ #  # ]:          0 :         assert(t);
    1894                 :            : 
    1895                 :            :         /* Check whether the specified name is in the NTA
    1896                 :            :          * database, either in the global one, or the link-local
    1897                 :            :          * one. */
    1898                 :            : 
    1899                 :          0 :         r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, name);
    1900         [ #  # ]:          0 :         if (r != 0)
    1901                 :          0 :                 return r;
    1902                 :            : 
    1903         [ #  # ]:          0 :         if (!t->scope->link)
    1904                 :          0 :                 return 0;
    1905                 :            : 
    1906                 :          0 :         return set_contains(t->scope->link->dnssec_negative_trust_anchors, name);
    1907                 :            : }
    1908                 :            : 
    1909                 :          0 : static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) {
    1910                 :            :         int r;
    1911                 :            : 
    1912         [ #  # ]:          0 :         assert(t);
    1913                 :            : 
    1914                 :            :         /* Checks whether the answer is negative, and lacks NSEC/NSEC3
    1915                 :            :          * RRs to prove it */
    1916                 :            : 
    1917                 :          0 :         r = dns_transaction_has_positive_answer(t, NULL);
    1918         [ #  # ]:          0 :         if (r < 0)
    1919                 :          0 :                 return r;
    1920         [ #  # ]:          0 :         if (r > 0)
    1921                 :          0 :                 return false;
    1922                 :            : 
    1923                 :            :         /* Is this key explicitly listed as a negative trust anchor?
    1924                 :            :          * If so, it's nothing we need to care about */
    1925                 :          0 :         r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
    1926         [ #  # ]:          0 :         if (r < 0)
    1927                 :          0 :                 return r;
    1928         [ #  # ]:          0 :         if (r > 0)
    1929                 :          0 :                 return false;
    1930                 :            : 
    1931                 :            :         /* The answer does not contain any RRs that match to the
    1932                 :            :          * question. If so, let's see if there are any NSEC/NSEC3 RRs
    1933                 :            :          * included. If not, the answer is unsigned. */
    1934                 :            : 
    1935                 :          0 :         r = dns_answer_contains_nsec_or_nsec3(t->answer);
    1936         [ #  # ]:          0 :         if (r < 0)
    1937                 :          0 :                 return r;
    1938         [ #  # ]:          0 :         if (r > 0)
    1939                 :          0 :                 return false;
    1940                 :            : 
    1941                 :          0 :         return true;
    1942                 :            : }
    1943                 :            : 
    1944                 :          0 : static int dns_transaction_is_primary_response(DnsTransaction *t, DnsResourceRecord *rr) {
    1945                 :            :         int r;
    1946                 :            : 
    1947         [ #  # ]:          0 :         assert(t);
    1948         [ #  # ]:          0 :         assert(rr);
    1949                 :            : 
    1950                 :            :         /* Check if the specified RR is the "primary" response,
    1951                 :            :          * i.e. either matches the question precisely or is a
    1952                 :            :          * CNAME/DNAME for it. */
    1953                 :            : 
    1954                 :          0 :         r = dns_resource_key_match_rr(t->key, rr, NULL);
    1955         [ #  # ]:          0 :         if (r != 0)
    1956                 :          0 :                 return r;
    1957                 :            : 
    1958                 :          0 :         return dns_resource_key_match_cname_or_dname(t->key, rr->key, NULL);
    1959                 :            : }
    1960                 :            : 
    1961                 :          0 : static bool dns_transaction_dnssec_supported(DnsTransaction *t) {
    1962         [ #  # ]:          0 :         assert(t);
    1963                 :            : 
    1964                 :            :         /* Checks whether our transaction's DNS server is assumed to be compatible with DNSSEC. Returns false as soon
    1965                 :            :          * as we changed our mind about a server, and now believe it is incompatible with DNSSEC. */
    1966                 :            : 
    1967         [ #  # ]:          0 :         if (t->scope->protocol != DNS_PROTOCOL_DNS)
    1968                 :          0 :                 return false;
    1969                 :            : 
    1970                 :            :         /* If we have picked no server, then we are working from the cache or some other source, and DNSSEC might well
    1971                 :            :          * be supported, hence return true. */
    1972         [ #  # ]:          0 :         if (!t->server)
    1973                 :          0 :                 return true;
    1974                 :            : 
    1975                 :            :         /* Note that we do not check the feature level actually used for the transaction but instead the feature level
    1976                 :            :          * the server is known to support currently, as the transaction feature level might be lower than what the
    1977                 :            :          * server actually supports, since we might have downgraded this transaction's feature level because we got a
    1978                 :            :          * SERVFAIL earlier and wanted to check whether downgrading fixes it. */
    1979                 :            : 
    1980                 :          0 :         return dns_server_dnssec_supported(t->server);
    1981                 :            : }
    1982                 :            : 
    1983                 :          0 : static bool dns_transaction_dnssec_supported_full(DnsTransaction *t) {
    1984                 :            :         DnsTransaction *dt;
    1985                 :            :         Iterator i;
    1986                 :            : 
    1987         [ #  # ]:          0 :         assert(t);
    1988                 :            : 
    1989                 :            :         /* Checks whether our transaction our any of the auxiliary transactions couldn't do DNSSEC. */
    1990                 :            : 
    1991         [ #  # ]:          0 :         if (!dns_transaction_dnssec_supported(t))
    1992                 :          0 :                 return false;
    1993                 :            : 
    1994         [ #  # ]:          0 :         SET_FOREACH(dt, t->dnssec_transactions, i)
    1995         [ #  # ]:          0 :                 if (!dns_transaction_dnssec_supported(dt))
    1996                 :          0 :                         return false;
    1997                 :            : 
    1998                 :          0 :         return true;
    1999                 :            : }
    2000                 :            : 
    2001                 :          0 : int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
    2002                 :            :         DnsResourceRecord *rr;
    2003                 :            : 
    2004                 :            :         int r;
    2005                 :            : 
    2006         [ #  # ]:          0 :         assert(t);
    2007                 :            : 
    2008                 :            :         /*
    2009                 :            :          * Retrieve all auxiliary RRs for the answer we got, so that
    2010                 :            :          * we can verify signatures or prove that RRs are rightfully
    2011                 :            :          * unsigned. Specifically:
    2012                 :            :          *
    2013                 :            :          * - For RRSIG we get the matching DNSKEY
    2014                 :            :          * - For DNSKEY we get the matching DS
    2015                 :            :          * - For unsigned SOA/NS we get the matching DS
    2016                 :            :          * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
    2017                 :            :          * - For other unsigned RRs we get the matching SOA RR
    2018                 :            :          * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
    2019                 :            :          * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
    2020                 :            :          * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
    2021                 :            :          */
    2022                 :            : 
    2023         [ #  # ]:          0 :         if (t->scope->dnssec_mode == DNSSEC_NO)
    2024                 :          0 :                 return 0;
    2025         [ #  # ]:          0 :         if (t->answer_source != DNS_TRANSACTION_NETWORK)
    2026                 :          0 :                 return 0; /* We only need to validate stuff from the network */
    2027         [ #  # ]:          0 :         if (!dns_transaction_dnssec_supported(t))
    2028                 :          0 :                 return 0; /* If we can't do DNSSEC anyway there's no point in getting the auxiliary RRs */
    2029                 :            : 
    2030   [ #  #  #  #  :          0 :         DNS_ANSWER_FOREACH(rr, t->answer) {
          #  #  #  #  #  
                      # ]
    2031                 :            : 
    2032         [ #  # ]:          0 :                 if (dns_type_is_pseudo(rr->key->type))
    2033                 :          0 :                         continue;
    2034                 :            : 
    2035                 :            :                 /* If this RR is in the negative trust anchor, we don't need to validate it. */
    2036                 :          0 :                 r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
    2037         [ #  # ]:          0 :                 if (r < 0)
    2038                 :          0 :                         return r;
    2039         [ #  # ]:          0 :                 if (r > 0)
    2040                 :          0 :                         continue;
    2041                 :            : 
    2042   [ #  #  #  #  :          0 :                 switch (rr->key->type) {
                      # ]
    2043                 :            : 
    2044                 :          0 :                 case DNS_TYPE_RRSIG: {
    2045                 :            :                         /* For each RRSIG we request the matching DNSKEY */
    2046      [ #  #  # ]:          0 :                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
    2047                 :            : 
    2048                 :            :                         /* If this RRSIG is about a DNSKEY RR and the
    2049                 :            :                          * signer is the same as the owner, then we
    2050                 :            :                          * already have the DNSKEY, and we don't have
    2051                 :            :                          * to look for more. */
    2052         [ #  # ]:          0 :                         if (rr->rrsig.type_covered == DNS_TYPE_DNSKEY) {
    2053                 :          0 :                                 r = dns_name_equal(rr->rrsig.signer, dns_resource_key_name(rr->key));
    2054         [ #  # ]:          0 :                                 if (r < 0)
    2055                 :          0 :                                         return r;
    2056         [ #  # ]:          0 :                                 if (r > 0)
    2057                 :          0 :                                         continue;
    2058                 :            :                         }
    2059                 :            : 
    2060                 :            :                         /* If the signer is not a parent of our
    2061                 :            :                          * original query, then this is about an
    2062                 :            :                          * auxiliary RRset, but not anything we asked
    2063                 :            :                          * for. In this case we aren't interested,
    2064                 :            :                          * because we don't want to request additional
    2065                 :            :                          * RRs for stuff we didn't really ask for, and
    2066                 :            :                          * also to avoid request loops, where
    2067                 :            :                          * additional RRs from one transaction result
    2068                 :            :                          * in another transaction whose additional RRs
    2069                 :            :                          * point back to the original transaction, and
    2070                 :            :                          * we deadlock. */
    2071                 :          0 :                         r = dns_name_endswith(dns_resource_key_name(t->key), rr->rrsig.signer);
    2072         [ #  # ]:          0 :                         if (r < 0)
    2073                 :          0 :                                 return r;
    2074         [ #  # ]:          0 :                         if (r == 0)
    2075                 :          0 :                                 continue;
    2076                 :            : 
    2077                 :          0 :                         dnskey = dns_resource_key_new(rr->key->class, DNS_TYPE_DNSKEY, rr->rrsig.signer);
    2078         [ #  # ]:          0 :                         if (!dnskey)
    2079                 :          0 :                                 return -ENOMEM;
    2080                 :            : 
    2081         [ #  # ]:          0 :                         log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").",
    2082                 :            :                                   t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag);
    2083                 :          0 :                         r = dns_transaction_request_dnssec_rr(t, dnskey);
    2084         [ #  # ]:          0 :                         if (r < 0)
    2085                 :          0 :                                 return r;
    2086                 :          0 :                         break;
    2087                 :            :                 }
    2088                 :            : 
    2089                 :          0 :                 case DNS_TYPE_DNSKEY: {
    2090                 :            :                         /* For each DNSKEY we request the matching DS */
    2091      [ #  #  # ]:          0 :                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
    2092                 :            : 
    2093                 :            :                         /* If the DNSKEY we are looking at is not for
    2094                 :            :                          * zone we are interested in, nor any of its
    2095                 :            :                          * parents, we aren't interested, and don't
    2096                 :            :                          * request it. After all, we don't want to end
    2097                 :            :                          * up in request loops, and want to keep
    2098                 :            :                          * additional traffic down. */
    2099                 :            : 
    2100                 :          0 :                         r = dns_name_endswith(dns_resource_key_name(t->key), dns_resource_key_name(rr->key));
    2101         [ #  # ]:          0 :                         if (r < 0)
    2102                 :          0 :                                 return r;
    2103         [ #  # ]:          0 :                         if (r == 0)
    2104                 :          0 :                                 continue;
    2105                 :            : 
    2106                 :          0 :                         ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
    2107         [ #  # ]:          0 :                         if (!ds)
    2108                 :          0 :                                 return -ENOMEM;
    2109                 :            : 
    2110         [ #  # ]:          0 :                         log_debug("Requesting DS to validate transaction %" PRIu16" (%s, DNSKEY with key tag: %" PRIu16 ").",
    2111                 :            :                                   t->id, dns_resource_key_name(rr->key), dnssec_keytag(rr, false));
    2112                 :          0 :                         r = dns_transaction_request_dnssec_rr(t, ds);
    2113         [ #  # ]:          0 :                         if (r < 0)
    2114                 :          0 :                                 return r;
    2115                 :            : 
    2116                 :          0 :                         break;
    2117                 :            :                 }
    2118                 :            : 
    2119                 :          0 :                 case DNS_TYPE_SOA:
    2120                 :            :                 case DNS_TYPE_NS: {
    2121      [ #  #  # ]:          0 :                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
    2122                 :            : 
    2123                 :            :                         /* For an unsigned SOA or NS, try to acquire
    2124                 :            :                          * the matching DS RR, as we are at a zone cut
    2125                 :            :                          * then, and whether a DS exists tells us
    2126                 :            :                          * whether the zone is signed. Do so only if
    2127                 :            :                          * this RR matches our original question,
    2128                 :            :                          * however. */
    2129                 :            : 
    2130                 :          0 :                         r = dns_resource_key_match_rr(t->key, rr, NULL);
    2131         [ #  # ]:          0 :                         if (r < 0)
    2132                 :          0 :                                 return r;
    2133         [ #  # ]:          0 :                         if (r == 0) {
    2134                 :            :                                 /* Hmm, so this SOA RR doesn't match our original question. In this case, maybe this is
    2135                 :            :                                  * a negative reply, and we need the a SOA RR's TTL in order to cache a negative entry?
    2136                 :            :                                  * If so, we need to validate it, too. */
    2137                 :            : 
    2138                 :          0 :                                 r = dns_answer_match_key(t->answer, t->key, NULL);
    2139         [ #  # ]:          0 :                                 if (r < 0)
    2140                 :          0 :                                         return r;
    2141         [ #  # ]:          0 :                                 if (r > 0) /* positive reply, we won't need the SOA and hence don't need to validate
    2142                 :            :                                             * it. */
    2143                 :          0 :                                         continue;
    2144                 :            : 
    2145                 :            :                                 /* Only bother with this if the SOA/NS RR we are looking at is actually a parent of
    2146                 :            :                                  * what we are looking for, otherwise there's no value in it for us. */
    2147                 :          0 :                                 r = dns_name_endswith(dns_resource_key_name(t->key), dns_resource_key_name(rr->key));
    2148         [ #  # ]:          0 :                                 if (r < 0)
    2149                 :          0 :                                         return r;
    2150         [ #  # ]:          0 :                                 if (r == 0)
    2151                 :          0 :                                         continue;
    2152                 :            :                         }
    2153                 :            : 
    2154                 :          0 :                         r = dnssec_has_rrsig(t->answer, rr->key);
    2155         [ #  # ]:          0 :                         if (r < 0)
    2156                 :          0 :                                 return r;
    2157         [ #  # ]:          0 :                         if (r > 0)
    2158                 :          0 :                                 continue;
    2159                 :            : 
    2160                 :          0 :                         ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
    2161         [ #  # ]:          0 :                         if (!ds)
    2162                 :          0 :                                 return -ENOMEM;
    2163                 :            : 
    2164         [ #  # ]:          0 :                         log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned SOA/NS RRset).",
    2165                 :            :                                   t->id, dns_resource_key_name(rr->key));
    2166                 :          0 :                         r = dns_transaction_request_dnssec_rr(t, ds);
    2167         [ #  # ]:          0 :                         if (r < 0)
    2168                 :          0 :                                 return r;
    2169                 :            : 
    2170                 :          0 :                         break;
    2171                 :            :                 }
    2172                 :            : 
    2173                 :          0 :                 case DNS_TYPE_DS:
    2174                 :            :                 case DNS_TYPE_CNAME:
    2175                 :            :                 case DNS_TYPE_DNAME: {
    2176      [ #  #  # ]:          0 :                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
    2177                 :            :                         const char *name;
    2178                 :            : 
    2179                 :            :                         /* CNAMEs and DNAMEs cannot be located at a
    2180                 :            :                          * zone apex, hence ask for the parent SOA for
    2181                 :            :                          * unsigned CNAME/DNAME RRs, maybe that's the
    2182                 :            :                          * apex. But do all that only if this is
    2183                 :            :                          * actually a response to our original
    2184                 :            :                          * question.
    2185                 :            :                          *
    2186                 :            :                          * Similar for DS RRs, which are signed when
    2187                 :            :                          * the parent SOA is signed. */
    2188                 :            : 
    2189                 :          0 :                         r = dns_transaction_is_primary_response(t, rr);
    2190         [ #  # ]:          0 :                         if (r < 0)
    2191                 :          0 :                                 return r;
    2192         [ #  # ]:          0 :                         if (r == 0)
    2193                 :          0 :                                 continue;
    2194                 :            : 
    2195                 :          0 :                         r = dnssec_has_rrsig(t->answer, rr->key);
    2196         [ #  # ]:          0 :                         if (r < 0)
    2197                 :          0 :                                 return r;
    2198         [ #  # ]:          0 :                         if (r > 0)
    2199                 :          0 :                                 continue;
    2200                 :            : 
    2201                 :          0 :                         r = dns_answer_has_dname_for_cname(t->answer, rr);
    2202         [ #  # ]:          0 :                         if (r < 0)
    2203                 :          0 :                                 return r;
    2204         [ #  # ]:          0 :                         if (r > 0)
    2205                 :          0 :                                 continue;
    2206                 :            : 
    2207                 :          0 :                         name = dns_resource_key_name(rr->key);
    2208                 :          0 :                         r = dns_name_parent(&name);
    2209         [ #  # ]:          0 :                         if (r < 0)
    2210                 :          0 :                                 return r;
    2211         [ #  # ]:          0 :                         if (r == 0)
    2212                 :          0 :                                 continue;
    2213                 :            : 
    2214                 :          0 :                         soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
    2215         [ #  # ]:          0 :                         if (!soa)
    2216                 :          0 :                                 return -ENOMEM;
    2217                 :            : 
    2218         [ #  # ]:          0 :                         log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
    2219                 :            :                                   t->id, dns_resource_key_name(rr->key));
    2220                 :          0 :                         r = dns_transaction_request_dnssec_rr(t, soa);
    2221         [ #  # ]:          0 :                         if (r < 0)
    2222                 :          0 :                                 return r;
    2223                 :            : 
    2224                 :          0 :                         break;
    2225                 :            :                 }
    2226                 :            : 
    2227                 :          0 :                 default: {
    2228      [ #  #  # ]:          0 :                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
    2229                 :            : 
    2230                 :            :                         /* For other unsigned RRsets (including
    2231                 :            :                          * NSEC/NSEC3!), look for proof the zone is
    2232                 :            :                          * unsigned, by requesting the SOA RR of the
    2233                 :            :                          * zone. However, do so only if they are
    2234                 :            :                          * directly relevant to our original
    2235                 :            :                          * question. */
    2236                 :            : 
    2237                 :          0 :                         r = dns_transaction_is_primary_response(t, rr);
    2238         [ #  # ]:          0 :                         if (r < 0)
    2239                 :          0 :                                 return r;
    2240         [ #  # ]:          0 :                         if (r == 0)
    2241                 :          0 :                                 continue;
    2242                 :            : 
    2243                 :          0 :                         r = dnssec_has_rrsig(t->answer, rr->key);
    2244         [ #  # ]:          0 :                         if (r < 0)
    2245                 :          0 :                                 return r;
    2246         [ #  # ]:          0 :                         if (r > 0)
    2247                 :          0 :                                 continue;
    2248                 :            : 
    2249                 :          0 :                         soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key));
    2250         [ #  # ]:          0 :                         if (!soa)
    2251                 :          0 :                                 return -ENOMEM;
    2252                 :            : 
    2253         [ #  # ]:          0 :                         log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
    2254                 :            :                                   t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr));
    2255                 :          0 :                         r = dns_transaction_request_dnssec_rr(t, soa);
    2256         [ #  # ]:          0 :                         if (r < 0)
    2257                 :          0 :                                 return r;
    2258                 :          0 :                         break;
    2259                 :            :                 }}
    2260                 :            :         }
    2261                 :            : 
    2262                 :            :         /* Above, we requested everything necessary to validate what
    2263                 :            :          * we got. Now, let's request what we need to validate what we
    2264                 :            :          * didn't get... */
    2265                 :            : 
    2266                 :          0 :         r = dns_transaction_has_unsigned_negative_answer(t);
    2267         [ #  # ]:          0 :         if (r < 0)
    2268                 :          0 :                 return r;
    2269         [ #  # ]:          0 :         if (r > 0) {
    2270                 :            :                 const char *name;
    2271                 :          0 :                 uint16_t type = 0;
    2272                 :            : 
    2273                 :          0 :                 name = dns_resource_key_name(t->key);
    2274                 :            : 
    2275                 :            :                 /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
    2276                 :            :                  * could also be used as indication that we are not at a zone apex, but in real world setups there are
    2277                 :            :                  * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
    2278                 :            :                  * though they have further children. If this was a DS request, then it's signed when the parent zone
    2279                 :            :                  * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
    2280                 :            :                  * to see if that is signed. */
    2281                 :            : 
    2282         [ #  # ]:          0 :                 if (t->key->type == DNS_TYPE_DS) {
    2283                 :          0 :                         r = dns_name_parent(&name);
    2284         [ #  # ]:          0 :                         if (r > 0) {
    2285                 :          0 :                                 type = DNS_TYPE_SOA;
    2286         [ #  # ]:          0 :                                 log_debug("Requesting parent SOA (→ %s) to validate transaction %" PRIu16 " (%s, unsigned empty DS response).",
    2287                 :            :                                           name, t->id, dns_resource_key_name(t->key));
    2288                 :            :                         } else
    2289                 :          0 :                                 name = NULL;
    2290                 :            : 
    2291   [ #  #  #  # ]:          0 :                 } else if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS)) {
    2292                 :            : 
    2293                 :          0 :                         type = DNS_TYPE_DS;
    2294         [ #  # ]:          0 :                         log_debug("Requesting DS (→ %s) to validate transaction %" PRIu16 " (%s, unsigned empty SOA/NS response).",
    2295                 :            :                                   name, t->id, name);
    2296                 :            : 
    2297                 :            :                 } else {
    2298                 :          0 :                         type = DNS_TYPE_SOA;
    2299         [ #  # ]:          0 :                         log_debug("Requesting SOA (→ %s) to validate transaction %" PRIu16 " (%s, unsigned empty non-SOA/NS/DS response).",
    2300                 :            :                                   name, t->id, name);
    2301                 :            :                 }
    2302                 :            : 
    2303         [ #  # ]:          0 :                 if (name) {
    2304         [ #  # ]:          0 :                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
    2305                 :            : 
    2306                 :          0 :                         soa = dns_resource_key_new(t->key->class, type, name);
    2307         [ #  # ]:          0 :                         if (!soa)
    2308                 :          0 :                                 return -ENOMEM;
    2309                 :            : 
    2310                 :          0 :                         r = dns_transaction_request_dnssec_rr(t, soa);
    2311         [ #  # ]:          0 :                         if (r < 0)
    2312                 :          0 :                                 return r;
    2313                 :            :                 }
    2314                 :            :         }
    2315                 :            : 
    2316                 :          0 :         return dns_transaction_dnssec_is_live(t);
    2317                 :            : }
    2318                 :            : 
    2319                 :          0 : void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source) {
    2320         [ #  # ]:          0 :         assert(t);
    2321         [ #  # ]:          0 :         assert(source);
    2322                 :            : 
    2323                 :            :         /* Invoked whenever any of our auxiliary DNSSEC transactions completed its work. If the state is still PENDING,
    2324                 :            :            we are still in the loop that adds further DNSSEC transactions, hence don't check if we are ready yet. If
    2325                 :            :            the state is VALIDATING however, we should check if we are complete now. */
    2326                 :            : 
    2327         [ #  # ]:          0 :         if (t->state == DNS_TRANSACTION_VALIDATING)
    2328                 :          0 :                 dns_transaction_process_dnssec(t);
    2329                 :          0 : }
    2330                 :            : 
    2331                 :          0 : static int dns_transaction_validate_dnskey_by_ds(DnsTransaction *t) {
    2332                 :            :         DnsResourceRecord *rr;
    2333                 :            :         int ifindex, r;
    2334                 :            : 
    2335         [ #  # ]:          0 :         assert(t);
    2336                 :            : 
    2337                 :            :         /* Add all DNSKEY RRs from the answer that are validated by DS
    2338                 :            :          * RRs from the list of validated keys to the list of
    2339                 :            :          * validated keys. */
    2340                 :            : 
    2341   [ #  #  #  #  :          0 :         DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, t->answer) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    2342                 :            : 
    2343                 :          0 :                 r = dnssec_verify_dnskey_by_ds_search(rr, t->validated_keys);
    2344         [ #  # ]:          0 :                 if (r < 0)
    2345                 :          0 :                         return r;
    2346         [ #  # ]:          0 :                 if (r == 0)
    2347                 :          0 :                         continue;
    2348                 :            : 
    2349                 :            :                 /* If so, the DNSKEY is validated too. */
    2350                 :          0 :                 r = dns_answer_add_extend(&t->validated_keys, rr, ifindex, DNS_ANSWER_AUTHENTICATED);
    2351         [ #  # ]:          0 :                 if (r < 0)
    2352                 :          0 :                         return r;
    2353                 :            :         }
    2354                 :            : 
    2355                 :          0 :         return 0;
    2356                 :            : }
    2357                 :            : 
    2358                 :          0 : static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *rr) {
    2359                 :            :         int r;
    2360                 :            : 
    2361         [ #  # ]:          0 :         assert(t);
    2362         [ #  # ]:          0 :         assert(rr);
    2363                 :            : 
    2364                 :            :         /* Checks if the RR we are looking for must be signed with an
    2365                 :            :          * RRSIG. This is used for positive responses. */
    2366                 :            : 
    2367         [ #  # ]:          0 :         if (t->scope->dnssec_mode == DNSSEC_NO)
    2368                 :          0 :                 return false;
    2369                 :            : 
    2370         [ #  # ]:          0 :         if (dns_type_is_pseudo(rr->key->type))
    2371                 :          0 :                 return -EINVAL;
    2372                 :            : 
    2373                 :          0 :         r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
    2374         [ #  # ]:          0 :         if (r < 0)
    2375                 :          0 :                 return r;
    2376         [ #  # ]:          0 :         if (r > 0)
    2377                 :          0 :                 return false;
    2378                 :            : 
    2379   [ #  #  #  # ]:          0 :         switch (rr->key->type) {
    2380                 :            : 
    2381                 :          0 :         case DNS_TYPE_RRSIG:
    2382                 :            :                 /* RRSIGs are the signatures themselves, they need no signing. */
    2383                 :          0 :                 return false;
    2384                 :            : 
    2385                 :          0 :         case DNS_TYPE_SOA:
    2386                 :            :         case DNS_TYPE_NS: {
    2387                 :            :                 DnsTransaction *dt;
    2388                 :            :                 Iterator i;
    2389                 :            : 
    2390                 :            :                 /* For SOA or NS RRs we look for a matching DS transaction */
    2391                 :            : 
    2392         [ #  # ]:          0 :                 SET_FOREACH(dt, t->dnssec_transactions, i) {
    2393                 :            : 
    2394         [ #  # ]:          0 :                         if (dt->key->class != rr->key->class)
    2395                 :          0 :                                 continue;
    2396         [ #  # ]:          0 :                         if (dt->key->type != DNS_TYPE_DS)
    2397                 :          0 :                                 continue;
    2398                 :            : 
    2399                 :          0 :                         r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
    2400         [ #  # ]:          0 :                         if (r < 0)
    2401                 :          0 :                                 return r;
    2402         [ #  # ]:          0 :                         if (r == 0)
    2403                 :          0 :                                 continue;
    2404                 :            : 
    2405                 :            :                         /* We found a DS transactions for the SOA/NS
    2406                 :            :                          * RRs we are looking at. If it discovered signed DS
    2407                 :            :                          * RRs, then we need to be signed, too. */
    2408                 :            : 
    2409         [ #  # ]:          0 :                         if (!dt->answer_authenticated)
    2410                 :          0 :                                 return false;
    2411                 :            : 
    2412                 :          0 :                         return dns_answer_match_key(dt->answer, dt->key, NULL);
    2413                 :            :                 }
    2414                 :            : 
    2415                 :            :                 /* We found nothing that proves this is safe to leave
    2416                 :            :                  * this unauthenticated, hence ask inist on
    2417                 :            :                  * authentication. */
    2418                 :          0 :                 return true;
    2419                 :            :         }
    2420                 :            : 
    2421                 :          0 :         case DNS_TYPE_DS:
    2422                 :            :         case DNS_TYPE_CNAME:
    2423                 :            :         case DNS_TYPE_DNAME: {
    2424                 :          0 :                 const char *parent = NULL;
    2425                 :            :                 DnsTransaction *dt;
    2426                 :            :                 Iterator i;
    2427                 :            : 
    2428                 :            :                 /*
    2429                 :            :                  * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
    2430                 :            :                  *
    2431                 :            :                  * DS RRs are signed if the parent is signed, hence also look at the parent SOA
    2432                 :            :                  */
    2433                 :            : 
    2434         [ #  # ]:          0 :                 SET_FOREACH(dt, t->dnssec_transactions, i) {
    2435                 :            : 
    2436         [ #  # ]:          0 :                         if (dt->key->class != rr->key->class)
    2437                 :          0 :                                 continue;
    2438         [ #  # ]:          0 :                         if (dt->key->type != DNS_TYPE_SOA)
    2439                 :          0 :                                 continue;
    2440                 :            : 
    2441         [ #  # ]:          0 :                         if (!parent) {
    2442                 :          0 :                                 parent = dns_resource_key_name(rr->key);
    2443                 :          0 :                                 r = dns_name_parent(&parent);
    2444         [ #  # ]:          0 :                                 if (r < 0)
    2445                 :          0 :                                         return r;
    2446         [ #  # ]:          0 :                                 if (r == 0) {
    2447         [ #  # ]:          0 :                                         if (rr->key->type == DNS_TYPE_DS)
    2448                 :          0 :                                                 return true;
    2449                 :            : 
    2450                 :            :                                         /* A CNAME/DNAME without a parent? That's sooo weird. */
    2451         [ #  # ]:          0 :                                         return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
    2452                 :            :                                                                "Transaction %" PRIu16 " claims CNAME/DNAME at root. Refusing.", t->id);
    2453                 :            :                                 }
    2454                 :            :                         }
    2455                 :            : 
    2456                 :          0 :                         r = dns_name_equal(dns_resource_key_name(dt->key), parent);
    2457         [ #  # ]:          0 :                         if (r < 0)
    2458                 :          0 :                                 return r;
    2459         [ #  # ]:          0 :                         if (r == 0)
    2460                 :          0 :                                 continue;
    2461                 :            : 
    2462                 :          0 :                         return t->answer_authenticated;
    2463                 :            :                 }
    2464                 :            : 
    2465                 :          0 :                 return true;
    2466                 :            :         }
    2467                 :            : 
    2468                 :          0 :         default: {
    2469                 :            :                 DnsTransaction *dt;
    2470                 :            :                 Iterator i;
    2471                 :            : 
    2472                 :            :                 /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
    2473                 :            : 
    2474         [ #  # ]:          0 :                 SET_FOREACH(dt, t->dnssec_transactions, i) {
    2475                 :            : 
    2476         [ #  # ]:          0 :                         if (dt->key->class != rr->key->class)
    2477                 :          0 :                                 continue;
    2478         [ #  # ]:          0 :                         if (dt->key->type != DNS_TYPE_SOA)
    2479                 :          0 :                                 continue;
    2480                 :            : 
    2481                 :          0 :                         r = dns_name_equal(dns_resource_key_name(dt->key), dns_resource_key_name(rr->key));
    2482         [ #  # ]:          0 :                         if (r < 0)
    2483                 :          0 :                                 return r;
    2484         [ #  # ]:          0 :                         if (r == 0)
    2485                 :          0 :                                 continue;
    2486                 :            : 
    2487                 :            :                         /* We found the transaction that was supposed to find
    2488                 :            :                          * the SOA RR for us. It was successful, but found no
    2489                 :            :                          * RR for us. This means we are not at a zone cut. In
    2490                 :            :                          * this case, we require authentication if the SOA
    2491                 :            :                          * lookup was authenticated too. */
    2492                 :          0 :                         return t->answer_authenticated;
    2493                 :            :                 }
    2494                 :            : 
    2495                 :          0 :                 return true;
    2496                 :            :         }}
    2497                 :            : }
    2498                 :            : 
    2499                 :          0 : static int dns_transaction_in_private_tld(DnsTransaction *t, const DnsResourceKey *key) {
    2500                 :            :         DnsTransaction *dt;
    2501                 :            :         const char *tld;
    2502                 :            :         Iterator i;
    2503                 :            :         int r;
    2504                 :            : 
    2505                 :            :         /* If DNSSEC downgrade mode is on, checks whether the
    2506                 :            :          * specified RR is one level below a TLD we have proven not to
    2507                 :            :          * exist. In such a case we assume that this is a private
    2508                 :            :          * domain, and permit it.
    2509                 :            :          *
    2510                 :            :          * This detects cases like the Fritz!Box router networks. Each
    2511                 :            :          * Fritz!Box router serves a private "fritz.box" zone, in the
    2512                 :            :          * non-existing TLD "box". Requests for the "fritz.box" domain
    2513                 :            :          * are served by the router itself, while requests for the
    2514                 :            :          * "box" domain will result in NXDOMAIN.
    2515                 :            :          *
    2516                 :            :          * Note that this logic is unable to detect cases where a
    2517                 :            :          * router serves a private DNS zone directly under
    2518                 :            :          * non-existing TLD. In such a case we cannot detect whether
    2519                 :            :          * the TLD is supposed to exist or not, as all requests we
    2520                 :            :          * make for it will be answered by the router's zone, and not
    2521                 :            :          * by the root zone. */
    2522                 :            : 
    2523         [ #  # ]:          0 :         assert(t);
    2524                 :            : 
    2525         [ #  # ]:          0 :         if (t->scope->dnssec_mode != DNSSEC_ALLOW_DOWNGRADE)
    2526                 :          0 :                 return false; /* In strict DNSSEC mode what doesn't exist, doesn't exist */
    2527                 :            : 
    2528                 :          0 :         tld = dns_resource_key_name(key);
    2529                 :          0 :         r = dns_name_parent(&tld);
    2530         [ #  # ]:          0 :         if (r < 0)
    2531                 :          0 :                 return r;
    2532         [ #  # ]:          0 :         if (r == 0)
    2533                 :          0 :                 return false; /* Already the root domain */
    2534                 :            : 
    2535         [ #  # ]:          0 :         if (!dns_name_is_single_label(tld))
    2536                 :          0 :                 return false;
    2537                 :            : 
    2538         [ #  # ]:          0 :         SET_FOREACH(dt, t->dnssec_transactions, i) {
    2539                 :            : 
    2540         [ #  # ]:          0 :                 if (dt->key->class != key->class)
    2541                 :          0 :                         continue;
    2542                 :            : 
    2543                 :          0 :                 r = dns_name_equal(dns_resource_key_name(dt->key), tld);
    2544         [ #  # ]:          0 :                 if (r < 0)
    2545                 :          0 :                         return r;
    2546         [ #  # ]:          0 :                 if (r == 0)
    2547                 :          0 :                         continue;
    2548                 :            : 
    2549                 :            :                 /* We found an auxiliary lookup we did for the TLD. If
    2550                 :            :                  * that returned with NXDOMAIN, we know the TLD didn't
    2551                 :            :                  * exist, and hence this might be a private zone. */
    2552                 :            : 
    2553                 :          0 :                 return dt->answer_rcode == DNS_RCODE_NXDOMAIN;
    2554                 :            :         }
    2555                 :            : 
    2556                 :          0 :         return false;
    2557                 :            : }
    2558                 :            : 
    2559                 :          0 : static int dns_transaction_requires_nsec(DnsTransaction *t) {
    2560                 :            :         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
    2561                 :            :         DnsTransaction *dt;
    2562                 :            :         const char *name;
    2563                 :          0 :         uint16_t type = 0;
    2564                 :            :         Iterator i;
    2565                 :            :         int r;
    2566                 :            : 
    2567         [ #  # ]:          0 :         assert(t);
    2568                 :            : 
    2569                 :            :         /* Checks if we need to insist on NSEC/NSEC3 RRs for proving
    2570                 :            :          * this negative reply */
    2571                 :            : 
    2572         [ #  # ]:          0 :         if (t->scope->dnssec_mode == DNSSEC_NO)
    2573                 :          0 :                 return false;
    2574                 :            : 
    2575         [ #  # ]:          0 :         if (dns_type_is_pseudo(t->key->type))
    2576                 :          0 :                 return -EINVAL;
    2577                 :            : 
    2578                 :          0 :         r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(t->key));
    2579         [ #  # ]:          0 :         if (r < 0)
    2580                 :          0 :                 return r;
    2581         [ #  # ]:          0 :         if (r > 0)
    2582                 :          0 :                 return false;
    2583                 :            : 
    2584                 :          0 :         r = dns_transaction_in_private_tld(t, t->key);
    2585         [ #  # ]:          0 :         if (r < 0)
    2586                 :          0 :                 return r;
    2587         [ #  # ]:          0 :         if (r > 0) {
    2588                 :            :                 /* The lookup is from a TLD that is proven not to
    2589                 :            :                  * exist, and we are in downgrade mode, hence ignore
    2590                 :            :                  * that fact that we didn't get any NSEC RRs. */
    2591                 :            : 
    2592         [ #  # ]:          0 :                 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
    2593                 :            :                          dns_resource_key_to_string(t->key, key_str, sizeof key_str));
    2594                 :          0 :                 return false;
    2595                 :            :         }
    2596                 :            : 
    2597                 :          0 :         name = dns_resource_key_name(t->key);
    2598                 :            : 
    2599         [ #  # ]:          0 :         if (t->key->type == DNS_TYPE_DS) {
    2600                 :            : 
    2601                 :            :                 /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
    2602                 :            :                  * hence check the parent SOA in this case. */
    2603                 :            : 
    2604                 :          0 :                 r = dns_name_parent(&name);
    2605         [ #  # ]:          0 :                 if (r < 0)
    2606                 :          0 :                         return r;
    2607         [ #  # ]:          0 :                 if (r == 0)
    2608                 :          0 :                         return true;
    2609                 :            : 
    2610                 :          0 :                 type = DNS_TYPE_SOA;
    2611                 :            : 
    2612   [ #  #  #  # ]:          0 :         } else if (IN_SET(t->key->type, DNS_TYPE_SOA, DNS_TYPE_NS))
    2613                 :            :                 /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
    2614                 :          0 :                 type = DNS_TYPE_DS;
    2615                 :            :         else
    2616                 :            :                 /* For all other negative replies, check for the SOA lookup */
    2617                 :          0 :                 type = DNS_TYPE_SOA;
    2618                 :            : 
    2619                 :            :         /* For all other RRs we check the SOA on the same level to see
    2620                 :            :          * if it's signed. */
    2621                 :            : 
    2622         [ #  # ]:          0 :         SET_FOREACH(dt, t->dnssec_transactions, i) {
    2623                 :            : 
    2624         [ #  # ]:          0 :                 if (dt->key->class != t->key->class)
    2625                 :          0 :                         continue;
    2626         [ #  # ]:          0 :                 if (dt->key->type != type)
    2627                 :          0 :                         continue;
    2628                 :            : 
    2629                 :          0 :                 r = dns_name_equal(dns_resource_key_name(dt->key), name);
    2630         [ #  # ]:          0 :                 if (r < 0)
    2631                 :          0 :                         return r;
    2632         [ #  # ]:          0 :                 if (r == 0)
    2633                 :          0 :                         continue;
    2634                 :            : 
    2635                 :          0 :                 return dt->answer_authenticated;
    2636                 :            :         }
    2637                 :            : 
    2638                 :            :         /* If in doubt, require NSEC/NSEC3 */
    2639                 :          0 :         return true;
    2640                 :            : }
    2641                 :            : 
    2642                 :          0 : static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRecord *rr) {
    2643                 :            :         DnsResourceRecord *rrsig;
    2644                 :          0 :         bool found = false;
    2645                 :            :         int r;
    2646                 :            : 
    2647                 :            :         /* Checks whether any of the DNSKEYs used for the RRSIGs for
    2648                 :            :          * the specified RRset is authenticated (i.e. has a matching
    2649                 :            :          * DS RR). */
    2650                 :            : 
    2651                 :          0 :         r = dns_transaction_negative_trust_anchor_lookup(t, dns_resource_key_name(rr->key));
    2652         [ #  # ]:          0 :         if (r < 0)
    2653                 :          0 :                 return r;
    2654         [ #  # ]:          0 :         if (r > 0)
    2655                 :          0 :                 return false;
    2656                 :            : 
    2657   [ #  #  #  #  :          0 :         DNS_ANSWER_FOREACH(rrsig, t->answer) {
          #  #  #  #  #  
                      # ]
    2658                 :            :                 DnsTransaction *dt;
    2659                 :            :                 Iterator i;
    2660                 :            : 
    2661                 :          0 :                 r = dnssec_key_match_rrsig(rr->key, rrsig);
    2662         [ #  # ]:          0 :                 if (r < 0)
    2663                 :          0 :                         return r;
    2664         [ #  # ]:          0 :                 if (r == 0)
    2665                 :          0 :                         continue;
    2666                 :            : 
    2667         [ #  # ]:          0 :                 SET_FOREACH(dt, t->dnssec_transactions, i) {
    2668                 :            : 
    2669         [ #  # ]:          0 :                         if (dt->key->class != rr->key->class)
    2670                 :          0 :                                 continue;
    2671                 :            : 
    2672         [ #  # ]:          0 :                         if (dt->key->type == DNS_TYPE_DNSKEY) {
    2673                 :            : 
    2674                 :          0 :                                 r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
    2675         [ #  # ]:          0 :                                 if (r < 0)
    2676                 :          0 :                                         return r;
    2677         [ #  # ]:          0 :                                 if (r == 0)
    2678                 :          0 :                                         continue;
    2679                 :            : 
    2680                 :            :                                 /* OK, we found an auxiliary DNSKEY
    2681                 :            :                                  * lookup. If that lookup is
    2682                 :            :                                  * authenticated, report this. */
    2683                 :            : 
    2684         [ #  # ]:          0 :                                 if (dt->answer_authenticated)
    2685                 :          0 :                                         return true;
    2686                 :            : 
    2687                 :          0 :                                 found = true;
    2688                 :            : 
    2689         [ #  # ]:          0 :                         } else if (dt->key->type == DNS_TYPE_DS) {
    2690                 :            : 
    2691                 :          0 :                                 r = dns_name_equal(dns_resource_key_name(dt->key), rrsig->rrsig.signer);
    2692         [ #  # ]:          0 :                                 if (r < 0)
    2693                 :          0 :                                         return r;
    2694         [ #  # ]:          0 :                                 if (r == 0)
    2695                 :          0 :                                         continue;
    2696                 :            : 
    2697                 :            :                                 /* OK, we found an auxiliary DS
    2698                 :            :                                  * lookup. If that lookup is
    2699                 :            :                                  * authenticated and non-zero, we
    2700                 :            :                                  * won! */
    2701                 :            : 
    2702         [ #  # ]:          0 :                                 if (!dt->answer_authenticated)
    2703                 :          0 :                                         return false;
    2704                 :            : 
    2705                 :          0 :                                 return dns_answer_match_key(dt->answer, dt->key, NULL);
    2706                 :            :                         }
    2707                 :            :                 }
    2708                 :            :         }
    2709                 :            : 
    2710         [ #  # ]:          0 :         return found ? false : -ENXIO;
    2711                 :            : }
    2712                 :            : 
    2713                 :          0 : static int dns_transaction_known_signed(DnsTransaction *t, DnsResourceRecord *rr) {
    2714         [ #  # ]:          0 :         assert(t);
    2715         [ #  # ]:          0 :         assert(rr);
    2716                 :            : 
    2717                 :            :         /* We know that the root domain is signed, hence if it appears
    2718                 :            :          * not to be signed, there's a problem with the DNS server */
    2719                 :            : 
    2720   [ #  #  #  # ]:          0 :         return rr->key->class == DNS_CLASS_IN &&
    2721                 :          0 :                 dns_name_is_root(dns_resource_key_name(rr->key));
    2722                 :            : }
    2723                 :            : 
    2724                 :          0 : static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
    2725                 :            :         DnsResourceRecord *rr;
    2726                 :            :         int r;
    2727                 :            : 
    2728         [ #  # ]:          0 :         assert(t);
    2729                 :            : 
    2730                 :            :         /* Maybe warn the user that we encountered a revoked DNSKEY
    2731                 :            :          * for a key from our trust anchor. Note that we don't care
    2732                 :            :          * whether the DNSKEY can be authenticated or not. It's
    2733                 :            :          * sufficient if it is self-signed. */
    2734                 :            : 
    2735   [ #  #  #  #  :          0 :         DNS_ANSWER_FOREACH(rr, t->answer) {
          #  #  #  #  #  
                      # ]
    2736                 :          0 :                 r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
    2737         [ #  # ]:          0 :                 if (r < 0)
    2738                 :          0 :                         return r;
    2739                 :            :         }
    2740                 :            : 
    2741                 :          0 :         return 0;
    2742                 :            : }
    2743                 :            : 
    2744                 :          0 : static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
    2745                 :            :         bool changed;
    2746                 :            :         int r;
    2747                 :            : 
    2748         [ #  # ]:          0 :         assert(t);
    2749                 :            : 
    2750                 :            :         /* Removes all DNSKEY/DS objects from t->validated_keys that
    2751                 :            :          * our trust anchors database considers revoked. */
    2752                 :            : 
    2753                 :            :         do {
    2754                 :            :                 DnsResourceRecord *rr;
    2755                 :            : 
    2756                 :          0 :                 changed = false;
    2757                 :            : 
    2758   [ #  #  #  #  :          0 :                 DNS_ANSWER_FOREACH(rr, t->validated_keys) {
          #  #  #  #  #  
                      # ]
    2759                 :          0 :                         r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
    2760         [ #  # ]:          0 :                         if (r < 0)
    2761                 :          0 :                                 return r;
    2762         [ #  # ]:          0 :                         if (r > 0) {
    2763                 :          0 :                                 r = dns_answer_remove_by_rr(&t->validated_keys, rr);
    2764         [ #  # ]:          0 :                                 if (r < 0)
    2765                 :          0 :                                         return r;
    2766                 :            : 
    2767         [ #  # ]:          0 :                                 assert(r > 0);
    2768                 :          0 :                                 changed = true;
    2769                 :          0 :                                 break;
    2770                 :            :                         }
    2771                 :            :                 }
    2772         [ #  # ]:          0 :         } while (changed);
    2773                 :            : 
    2774                 :          0 :         return 0;
    2775                 :            : }
    2776                 :            : 
    2777                 :          0 : static int dns_transaction_copy_validated(DnsTransaction *t) {
    2778                 :            :         DnsTransaction *dt;
    2779                 :            :         Iterator i;
    2780                 :            :         int r;
    2781                 :            : 
    2782         [ #  # ]:          0 :         assert(t);
    2783                 :            : 
    2784                 :            :         /* Copy all validated RRs from the auxiliary DNSSEC transactions into our set of validated RRs */
    2785                 :            : 
    2786         [ #  # ]:          0 :         SET_FOREACH(dt, t->dnssec_transactions, i) {
    2787                 :            : 
    2788   [ #  #  #  # ]:          0 :                 if (DNS_TRANSACTION_IS_LIVE(dt->state))
    2789                 :          0 :                         continue;
    2790                 :            : 
    2791         [ #  # ]:          0 :                 if (!dt->answer_authenticated)
    2792                 :          0 :                         continue;
    2793                 :            : 
    2794                 :          0 :                 r = dns_answer_extend(&t->validated_keys, dt->answer);
    2795         [ #  # ]:          0 :                 if (r < 0)
    2796                 :          0 :                         return r;
    2797                 :            :         }
    2798                 :            : 
    2799                 :          0 :         return 0;
    2800                 :            : }
    2801                 :            : 
    2802                 :            : typedef enum {
    2803                 :            :         DNSSEC_PHASE_DNSKEY,   /* Phase #1, only validate DNSKEYs */
    2804                 :            :         DNSSEC_PHASE_NSEC,     /* Phase #2, only validate NSEC+NSEC3 */
    2805                 :            :         DNSSEC_PHASE_ALL,      /* Phase #3, validate everything else */
    2806                 :            : } Phase;
    2807                 :            : 
    2808                 :          0 : static int dnssec_validate_records(
    2809                 :            :                 DnsTransaction *t,
    2810                 :            :                 Phase phase,
    2811                 :            :                 bool *have_nsec,
    2812                 :            :                 DnsAnswer **validated) {
    2813                 :            : 
    2814                 :            :         DnsResourceRecord *rr;
    2815                 :            :         int r;
    2816                 :            : 
    2817                 :            :         /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
    2818                 :            : 
    2819   [ #  #  #  #  :          0 :         DNS_ANSWER_FOREACH(rr, t->answer) {
             #  #  #  # ]
    2820                 :          0 :                 DnsResourceRecord *rrsig = NULL;
    2821                 :            :                 DnssecResult result;
    2822                 :            : 
    2823   [ #  #  #  # ]:          0 :                 switch (rr->key->type) {
    2824                 :          0 :                 case DNS_TYPE_RRSIG:
    2825         [ #  # ]:          0 :                         continue;
    2826                 :            : 
    2827                 :          0 :                 case DNS_TYPE_DNSKEY:
    2828                 :            :                         /* We validate DNSKEYs only in the DNSKEY and ALL phases */
    2829         [ #  # ]:          0 :                         if (phase == DNSSEC_PHASE_NSEC)
    2830                 :          0 :                                 continue;
    2831                 :          0 :                         break;
    2832                 :            : 
    2833                 :          0 :                 case DNS_TYPE_NSEC:
    2834                 :            :                 case DNS_TYPE_NSEC3:
    2835                 :          0 :                         *have_nsec = true;
    2836                 :            : 
    2837                 :            :                         /* We validate NSEC/NSEC3 only in the NSEC and ALL phases */
    2838         [ #  # ]:          0 :                         if (phase == DNSSEC_PHASE_DNSKEY)
    2839                 :          0 :                                 continue;
    2840                 :          0 :                         break;
    2841                 :            : 
    2842                 :          0 :                 default:
    2843                 :            :                         /* We validate all other RRs only in the ALL phases */
    2844         [ #  # ]:          0 :                         if (phase != DNSSEC_PHASE_ALL)
    2845                 :          0 :                                 continue;
    2846                 :            :                 }
    2847                 :            : 
    2848                 :          0 :                 r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
    2849         [ #  # ]:          0 :                 if (r < 0)
    2850                 :          0 :                         return r;
    2851                 :            : 
    2852         [ #  # ]:          0 :                 log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
    2853                 :            : 
    2854         [ #  # ]:          0 :                 if (result == DNSSEC_VALIDATED) {
    2855                 :            : 
    2856         [ #  # ]:          0 :                         if (rr->key->type == DNS_TYPE_DNSKEY) {
    2857                 :            :                                 /* If we just validated a DNSKEY RRset, then let's add these keys to
    2858                 :            :                                  * the set of validated keys for this transaction. */
    2859                 :            : 
    2860                 :          0 :                                 r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
    2861         [ #  # ]:          0 :                                 if (r < 0)
    2862                 :          0 :                                         return r;
    2863                 :            : 
    2864                 :            :                                 /* Some of the DNSKEYs we just added might already have been revoked,
    2865                 :            :                                  * remove them again in that case. */
    2866                 :          0 :                                 r = dns_transaction_invalidate_revoked_keys(t);
    2867         [ #  # ]:          0 :                                 if (r < 0)
    2868                 :          0 :                                         return r;
    2869                 :            :                         }
    2870                 :            : 
    2871                 :            :                         /* Add the validated RRset to the new list of validated
    2872                 :            :                          * RRsets, and remove it from the unvalidated RRsets.
    2873                 :            :                          * We mark the RRset as authenticated and cacheable. */
    2874                 :          0 :                         r = dns_answer_move_by_key(validated, &t->answer, rr->key, DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE);
    2875         [ #  # ]:          0 :                         if (r < 0)
    2876                 :          0 :                                 return r;
    2877                 :            : 
    2878                 :          0 :                         manager_dnssec_verdict(t->scope->manager, DNSSEC_SECURE, rr->key);
    2879                 :            : 
    2880                 :            :                         /* Exit the loop, we dropped something from the answer, start from the beginning */
    2881                 :          0 :                         return 1;
    2882                 :            :                 }
    2883                 :            : 
    2884                 :            :                 /* If we haven't read all DNSKEYs yet a negative result of the validation is irrelevant, as
    2885                 :            :                  * there might be more DNSKEYs coming. Similar, if we haven't read all NSEC/NSEC3 RRs yet,
    2886                 :            :                  * we cannot do positive wildcard proofs yet, as those require the NSEC/NSEC3 RRs. */
    2887         [ #  # ]:          0 :                 if (phase != DNSSEC_PHASE_ALL)
    2888                 :          0 :                         continue;
    2889                 :            : 
    2890         [ #  # ]:          0 :                 if (result == DNSSEC_VALIDATED_WILDCARD) {
    2891                 :          0 :                         bool authenticated = false;
    2892                 :            :                         const char *source;
    2893                 :            : 
    2894                 :            :                         /* This RRset validated, but as a wildcard. This means we need
    2895                 :            :                          * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
    2896                 :            : 
    2897                 :            :                         /* First step, determine the source of synthesis */
    2898                 :          0 :                         r = dns_resource_record_source(rrsig, &source);
    2899         [ #  # ]:          0 :                         if (r < 0)
    2900                 :          0 :                                 return r;
    2901                 :            : 
    2902                 :          0 :                         r = dnssec_test_positive_wildcard(*validated,
    2903                 :          0 :                                                           dns_resource_key_name(rr->key),
    2904                 :            :                                                           source,
    2905                 :          0 :                                                           rrsig->rrsig.signer,
    2906                 :            :                                                           &authenticated);
    2907                 :            : 
    2908                 :            :                         /* Unless the NSEC proof showed that the key really doesn't exist something is off. */
    2909         [ #  # ]:          0 :                         if (r == 0)
    2910                 :          0 :                                 result = DNSSEC_INVALID;
    2911                 :            :                         else {
    2912                 :          0 :                                 r = dns_answer_move_by_key(validated, &t->answer, rr->key,
    2913         [ #  # ]:          0 :                                                            authenticated ? (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE) : 0);
    2914         [ #  # ]:          0 :                                 if (r < 0)
    2915                 :          0 :                                         return r;
    2916                 :            : 
    2917                 :          0 :                                 manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, rr->key);
    2918                 :            : 
    2919                 :            :                                 /* Exit the loop, we dropped something from the answer, start from the beginning */
    2920                 :          0 :                                 return 1;
    2921                 :            :                         }
    2922                 :            :                 }
    2923                 :            : 
    2924         [ #  # ]:          0 :                 if (result == DNSSEC_NO_SIGNATURE) {
    2925                 :          0 :                         r = dns_transaction_requires_rrsig(t, rr);
    2926         [ #  # ]:          0 :                         if (r < 0)
    2927                 :          0 :                                 return r;
    2928         [ #  # ]:          0 :                         if (r == 0) {
    2929                 :            :                                 /* Data does not require signing. In that case, just copy it over,
    2930                 :            :                                  * but remember that this is by no means authenticated. */
    2931                 :          0 :                                 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
    2932         [ #  # ]:          0 :                                 if (r < 0)
    2933                 :          0 :                                         return r;
    2934                 :            : 
    2935                 :          0 :                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
    2936                 :          0 :                                 return 1;
    2937                 :            :                         }
    2938                 :            : 
    2939                 :          0 :                         r = dns_transaction_known_signed(t, rr);
    2940         [ #  # ]:          0 :                         if (r < 0)
    2941                 :          0 :                                 return r;
    2942         [ #  # ]:          0 :                         if (r > 0) {
    2943                 :            :                                 /* This is an RR we know has to be signed. If it isn't this means
    2944                 :            :                                  * the server is not attaching RRSIGs, hence complain. */
    2945                 :            : 
    2946                 :          0 :                                 dns_server_packet_rrsig_missing(t->server, t->current_feature_level);
    2947                 :            : 
    2948         [ #  # ]:          0 :                                 if (t->scope->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE) {
    2949                 :            : 
    2950                 :            :                                         /* Downgrading is OK? If so, just consider the information unsigned */
    2951                 :            : 
    2952                 :          0 :                                         r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
    2953         [ #  # ]:          0 :                                         if (r < 0)
    2954                 :          0 :                                                 return r;
    2955                 :            : 
    2956                 :          0 :                                         manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
    2957                 :          0 :                                         return 1;
    2958                 :            :                                 }
    2959                 :            : 
    2960                 :            :                                 /* Otherwise, fail */
    2961                 :          0 :                                 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
    2962                 :          0 :                                 return 0;
    2963                 :            :                         }
    2964                 :            : 
    2965                 :          0 :                         r = dns_transaction_in_private_tld(t, rr->key);
    2966         [ #  # ]:          0 :                         if (r < 0)
    2967                 :          0 :                                 return r;
    2968         [ #  # ]:          0 :                         if (r > 0) {
    2969                 :            :                                 char s[DNS_RESOURCE_KEY_STRING_MAX];
    2970                 :            : 
    2971                 :            :                                 /* The data is from a TLD that is proven not to exist, and we are in downgrade
    2972                 :            :                                  * mode, hence ignore the fact that this was not signed. */
    2973                 :            : 
    2974         [ #  # ]:          0 :                                 log_info("Detected RRset %s is in a private DNS zone, permitting unsigned RRs.",
    2975                 :            :                                          dns_resource_key_to_string(rr->key, s, sizeof s));
    2976                 :            : 
    2977                 :          0 :                                 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
    2978         [ #  # ]:          0 :                                 if (r < 0)
    2979                 :          0 :                                         return r;
    2980                 :            : 
    2981                 :          0 :                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
    2982                 :          0 :                                 return 1;
    2983                 :            :                         }
    2984                 :            :                 }
    2985                 :            : 
    2986   [ #  #  #  # ]:          0 :                 if (IN_SET(result,
    2987                 :            :                            DNSSEC_MISSING_KEY,
    2988                 :            :                            DNSSEC_SIGNATURE_EXPIRED,
    2989                 :            :                            DNSSEC_UNSUPPORTED_ALGORITHM)) {
    2990                 :            : 
    2991                 :          0 :                         r = dns_transaction_dnskey_authenticated(t, rr);
    2992   [ #  #  #  # ]:          0 :                         if (r < 0 && r != -ENXIO)
    2993                 :          0 :                                 return r;
    2994         [ #  # ]:          0 :                         if (r == 0) {
    2995                 :            :                                 /* The DNSKEY transaction was not authenticated, this means there's
    2996                 :            :                                  * no DS for this, which means it's OK if no keys are found for this signature. */
    2997                 :            : 
    2998                 :          0 :                                 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
    2999         [ #  # ]:          0 :                                 if (r < 0)
    3000                 :          0 :                                         return r;
    3001                 :            : 
    3002                 :          0 :                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, rr->key);
    3003                 :          0 :                                 return 1;
    3004                 :            :                         }
    3005                 :            :                 }
    3006                 :            : 
    3007                 :          0 :                 r = dns_transaction_is_primary_response(t, rr);
    3008         [ #  # ]:          0 :                 if (r < 0)
    3009                 :          0 :                         return r;
    3010         [ #  # ]:          0 :                 if (r > 0) {
    3011                 :            :                         /* Look for a matching DNAME for this CNAME */
    3012                 :          0 :                         r = dns_answer_has_dname_for_cname(t->answer, rr);
    3013         [ #  # ]:          0 :                         if (r < 0)
    3014                 :          0 :                                 return r;
    3015         [ #  # ]:          0 :                         if (r == 0) {
    3016                 :            :                                 /* Also look among the stuff we already validated */
    3017                 :          0 :                                 r = dns_answer_has_dname_for_cname(*validated, rr);
    3018         [ #  # ]:          0 :                                 if (r < 0)
    3019                 :          0 :                                         return r;
    3020                 :            :                         }
    3021                 :            : 
    3022         [ #  # ]:          0 :                         if (r == 0) {
    3023   [ #  #  #  # ]:          0 :                                 if (IN_SET(result,
    3024                 :            :                                            DNSSEC_INVALID,
    3025                 :            :                                            DNSSEC_SIGNATURE_EXPIRED,
    3026                 :            :                                            DNSSEC_NO_SIGNATURE))
    3027                 :          0 :                                         manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
    3028                 :            :                                 else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
    3029                 :          0 :                                         manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
    3030                 :            : 
    3031                 :            :                                 /* This is a primary response to our question, and it failed validation.
    3032                 :            :                                  * That's fatal. */
    3033                 :          0 :                                 t->answer_dnssec_result = result;
    3034                 :          0 :                                 return 0;
    3035                 :            :                         }
    3036                 :            : 
    3037                 :            :                         /* This is a primary response, but we do have a DNAME RR
    3038                 :            :                          * in the RR that can replay this CNAME, hence rely on
    3039                 :            :                          * that, and we can remove the CNAME in favour of it. */
    3040                 :            :                 }
    3041                 :            : 
    3042                 :            :                 /* This is just some auxiliary data. Just remove the RRset and continue. */
    3043                 :          0 :                 r = dns_answer_remove_by_key(&t->answer, rr->key);
    3044         [ #  # ]:          0 :                 if (r < 0)
    3045                 :          0 :                         return r;
    3046                 :            : 
    3047                 :            :                 /* We dropped something from the answer, start from the beginning. */
    3048                 :          0 :                 return 1;
    3049                 :            :         }
    3050                 :            : 
    3051                 :          0 :         return 2; /* Finito. */
    3052                 :            : }
    3053                 :            : 
    3054                 :          0 : int dns_transaction_validate_dnssec(DnsTransaction *t) {
    3055                 :          0 :         _cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
    3056                 :            :         Phase phase;
    3057                 :            :         DnsAnswerFlags flags;
    3058                 :            :         int r;
    3059                 :            :         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
    3060                 :            : 
    3061         [ #  # ]:          0 :         assert(t);
    3062                 :            : 
    3063                 :            :         /* We have now collected all DS and DNSKEY RRs in
    3064                 :            :          * t->validated_keys, let's see which RRs we can now
    3065                 :            :          * authenticate with that. */
    3066                 :            : 
    3067         [ #  # ]:          0 :         if (t->scope->dnssec_mode == DNSSEC_NO)
    3068                 :          0 :                 return 0;
    3069                 :            : 
    3070                 :            :         /* Already validated */
    3071         [ #  # ]:          0 :         if (t->answer_dnssec_result != _DNSSEC_RESULT_INVALID)
    3072                 :          0 :                 return 0;
    3073                 :            : 
    3074                 :            :         /* Our own stuff needs no validation */
    3075   [ #  #  #  # ]:          0 :         if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
    3076                 :          0 :                 t->answer_dnssec_result = DNSSEC_VALIDATED;
    3077                 :          0 :                 t->answer_authenticated = true;
    3078                 :          0 :                 return 0;
    3079                 :            :         }
    3080                 :            : 
    3081                 :            :         /* Cached stuff is not affected by validation. */
    3082         [ #  # ]:          0 :         if (t->answer_source != DNS_TRANSACTION_NETWORK)
    3083                 :          0 :                 return 0;
    3084                 :            : 
    3085         [ #  # ]:          0 :         if (!dns_transaction_dnssec_supported_full(t)) {
    3086                 :            :                 /* The server does not support DNSSEC, or doesn't augment responses with RRSIGs. */
    3087                 :          0 :                 t->answer_dnssec_result = DNSSEC_INCOMPATIBLE_SERVER;
    3088         [ #  # ]:          0 :                 log_debug("Not validating response for %" PRIu16 ", used server feature level does not support DNSSEC.", t->id);
    3089                 :          0 :                 return 0;
    3090                 :            :         }
    3091                 :            : 
    3092         [ #  # ]:          0 :         log_debug("Validating response from transaction %" PRIu16 " (%s).",
    3093                 :            :                   t->id,
    3094                 :            :                   dns_resource_key_to_string(t->key, key_str, sizeof key_str));
    3095                 :            : 
    3096                 :            :         /* First, see if this response contains any revoked trust
    3097                 :            :          * anchors we care about */
    3098                 :          0 :         r = dns_transaction_check_revoked_trust_anchors(t);
    3099         [ #  # ]:          0 :         if (r < 0)
    3100                 :          0 :                 return r;
    3101                 :            : 
    3102                 :            :         /* Third, copy all RRs we acquired successfully from auxiliary RRs over. */
    3103                 :          0 :         r = dns_transaction_copy_validated(t);
    3104         [ #  # ]:          0 :         if (r < 0)
    3105                 :          0 :                 return r;
    3106                 :            : 
    3107                 :            :         /* Second, see if there are DNSKEYs we already know a
    3108                 :            :          * validated DS for. */
    3109                 :          0 :         r = dns_transaction_validate_dnskey_by_ds(t);
    3110         [ #  # ]:          0 :         if (r < 0)
    3111                 :          0 :                 return r;
    3112                 :            : 
    3113                 :            :         /* Fourth, remove all DNSKEY and DS RRs again that our trust
    3114                 :            :          * anchor says are revoked. After all we might have marked
    3115                 :            :          * some keys revoked above, but they might still be lingering
    3116                 :            :          * in our validated_keys list. */
    3117                 :          0 :         r = dns_transaction_invalidate_revoked_keys(t);
    3118         [ #  # ]:          0 :         if (r < 0)
    3119                 :          0 :                 return r;
    3120                 :            : 
    3121                 :          0 :         phase = DNSSEC_PHASE_DNSKEY;
    3122                 :          0 :         for (;;) {
    3123                 :          0 :                 bool have_nsec = false;
    3124                 :            : 
    3125                 :          0 :                 r = dnssec_validate_records(t, phase, &have_nsec, &validated);
    3126         [ #  # ]:          0 :                 if (r <= 0)
    3127                 :          0 :                         return r;
    3128                 :            : 
    3129                 :            :                 /* Try again as long as we managed to achieve something */
    3130         [ #  # ]:          0 :                 if (r == 1)
    3131                 :          0 :                         continue;
    3132                 :            : 
    3133   [ #  #  #  # ]:          0 :                 if (phase == DNSSEC_PHASE_DNSKEY && have_nsec) {
    3134                 :            :                         /* OK, we processed all DNSKEYs, and there are NSEC/NSEC3 RRs, look at those now. */
    3135                 :          0 :                         phase = DNSSEC_PHASE_NSEC;
    3136                 :          0 :                         continue;
    3137                 :            :                 }
    3138                 :            : 
    3139         [ #  # ]:          0 :                 if (phase != DNSSEC_PHASE_ALL) {
    3140                 :            :                         /* OK, we processed all DNSKEYs and NSEC/NSEC3 RRs, look at all the rest now.
    3141                 :            :                          * Note that in this third phase we start to remove RRs we couldn't validate. */
    3142                 :          0 :                         phase = DNSSEC_PHASE_ALL;
    3143                 :          0 :                         continue;
    3144                 :            :                 }
    3145                 :            : 
    3146                 :            :                 /* We're done */
    3147                 :          0 :                 break;
    3148                 :            :         }
    3149                 :            : 
    3150                 :          0 :         dns_answer_unref(t->answer);
    3151                 :          0 :         t->answer = TAKE_PTR(validated);
    3152                 :            : 
    3153                 :            :         /* At this point the answer only contains validated
    3154                 :            :          * RRsets. Now, let's see if it actually answers the question
    3155                 :            :          * we asked. If so, great! If it doesn't, then see if
    3156                 :            :          * NSEC/NSEC3 can prove this. */
    3157                 :          0 :         r = dns_transaction_has_positive_answer(t, &flags);
    3158         [ #  # ]:          0 :         if (r > 0) {
    3159                 :            :                 /* Yes, it answers the question! */
    3160                 :            : 
    3161         [ #  # ]:          0 :                 if (flags & DNS_ANSWER_AUTHENTICATED) {
    3162                 :            :                         /* The answer is fully authenticated, yay. */
    3163                 :          0 :                         t->answer_dnssec_result = DNSSEC_VALIDATED;
    3164                 :          0 :                         t->answer_rcode = DNS_RCODE_SUCCESS;
    3165                 :          0 :                         t->answer_authenticated = true;
    3166                 :            :                 } else {
    3167                 :            :                         /* The answer is not fully authenticated. */
    3168                 :          0 :                         t->answer_dnssec_result = DNSSEC_UNSIGNED;
    3169                 :          0 :                         t->answer_authenticated = false;
    3170                 :            :                 }
    3171                 :            : 
    3172         [ #  # ]:          0 :         } else if (r == 0) {
    3173                 :            :                 DnssecNsecResult nr;
    3174                 :          0 :                 bool authenticated = false;
    3175                 :            : 
    3176                 :            :                 /* Bummer! Let's check NSEC/NSEC3 */
    3177                 :          0 :                 r = dnssec_nsec_test(t->answer, t->key, &nr, &authenticated, &t->answer_nsec_ttl);
    3178         [ #  # ]:          0 :                 if (r < 0)
    3179                 :          0 :                         return r;
    3180                 :            : 
    3181   [ #  #  #  #  :          0 :                 switch (nr) {
                #  #  # ]
    3182                 :            : 
    3183                 :          0 :                 case DNSSEC_NSEC_NXDOMAIN:
    3184                 :            :                         /* NSEC proves the domain doesn't exist. Very good. */
    3185         [ #  # ]:          0 :                         log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
    3186                 :          0 :                         t->answer_dnssec_result = DNSSEC_VALIDATED;
    3187                 :          0 :                         t->answer_rcode = DNS_RCODE_NXDOMAIN;
    3188                 :          0 :                         t->answer_authenticated = authenticated;
    3189                 :            : 
    3190                 :          0 :                         manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, t->key);
    3191                 :          0 :                         break;
    3192                 :            : 
    3193                 :          0 :                 case DNSSEC_NSEC_NODATA:
    3194                 :            :                         /* NSEC proves that there's no data here, very good. */
    3195         [ #  # ]:          0 :                         log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
    3196                 :          0 :                         t->answer_dnssec_result = DNSSEC_VALIDATED;
    3197                 :          0 :                         t->answer_rcode = DNS_RCODE_SUCCESS;
    3198                 :          0 :                         t->answer_authenticated = authenticated;
    3199                 :            : 
    3200                 :          0 :                         manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, t->key);
    3201                 :          0 :                         break;
    3202                 :            : 
    3203                 :          0 :                 case DNSSEC_NSEC_OPTOUT:
    3204                 :            :                         /* NSEC3 says the data might not be signed */
    3205         [ #  # ]:          0 :                         log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
    3206                 :          0 :                         t->answer_dnssec_result = DNSSEC_UNSIGNED;
    3207                 :          0 :                         t->answer_authenticated = false;
    3208                 :            : 
    3209                 :          0 :                         manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, t->key);
    3210                 :          0 :                         break;
    3211                 :            : 
    3212                 :          0 :                 case DNSSEC_NSEC_NO_RR:
    3213                 :            :                         /* No NSEC data? Bummer! */
    3214                 :            : 
    3215                 :          0 :                         r = dns_transaction_requires_nsec(t);
    3216         [ #  # ]:          0 :                         if (r < 0)
    3217                 :          0 :                                 return r;
    3218         [ #  # ]:          0 :                         if (r > 0) {
    3219                 :          0 :                                 t->answer_dnssec_result = DNSSEC_NO_SIGNATURE;
    3220                 :          0 :                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, t->key);
    3221                 :            :                         } else {
    3222                 :          0 :                                 t->answer_dnssec_result = DNSSEC_UNSIGNED;
    3223                 :          0 :                                 t->answer_authenticated = false;
    3224                 :          0 :                                 manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, t->key);
    3225                 :            :                         }
    3226                 :            : 
    3227                 :          0 :                         break;
    3228                 :            : 
    3229                 :          0 :                 case DNSSEC_NSEC_UNSUPPORTED_ALGORITHM:
    3230                 :            :                         /* We don't know the NSEC3 algorithm used? */
    3231                 :          0 :                         t->answer_dnssec_result = DNSSEC_UNSUPPORTED_ALGORITHM;
    3232                 :          0 :                         manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, t->key);
    3233                 :          0 :                         break;
    3234                 :            : 
    3235                 :          0 :                 case DNSSEC_NSEC_FOUND:
    3236                 :            :                 case DNSSEC_NSEC_CNAME:
    3237                 :            :                         /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
    3238                 :          0 :                         t->answer_dnssec_result = DNSSEC_NSEC_MISMATCH;
    3239                 :          0 :                         manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, t->key);
    3240                 :          0 :                         break;
    3241                 :            : 
    3242                 :          0 :                 default:
    3243                 :          0 :                         assert_not_reached("Unexpected NSEC result.");
    3244                 :            :                 }
    3245                 :            :         }
    3246                 :            : 
    3247                 :          0 :         return 1;
    3248                 :            : }
    3249                 :            : 
    3250                 :            : static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
    3251                 :            :         [DNS_TRANSACTION_NULL] = "null",
    3252                 :            :         [DNS_TRANSACTION_PENDING] = "pending",
    3253                 :            :         [DNS_TRANSACTION_VALIDATING] = "validating",
    3254                 :            :         [DNS_TRANSACTION_RCODE_FAILURE] = "rcode-failure",
    3255                 :            :         [DNS_TRANSACTION_SUCCESS] = "success",
    3256                 :            :         [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
    3257                 :            :         [DNS_TRANSACTION_TIMEOUT] = "timeout",
    3258                 :            :         [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
    3259                 :            :         [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
    3260                 :            :         [DNS_TRANSACTION_ERRNO] = "errno",
    3261                 :            :         [DNS_TRANSACTION_ABORTED] = "aborted",
    3262                 :            :         [DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
    3263                 :            :         [DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
    3264                 :            :         [DNS_TRANSACTION_RR_TYPE_UNSUPPORTED] = "rr-type-unsupported",
    3265                 :            :         [DNS_TRANSACTION_NETWORK_DOWN] = "network-down",
    3266                 :            :         [DNS_TRANSACTION_NOT_FOUND] = "not-found",
    3267                 :            : };
    3268   [ #  #  #  # ]:          0 : DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
    3269                 :            : 
    3270                 :            : static const char* const dns_transaction_source_table[_DNS_TRANSACTION_SOURCE_MAX] = {
    3271                 :            :         [DNS_TRANSACTION_NETWORK] = "network",
    3272                 :            :         [DNS_TRANSACTION_CACHE] = "cache",
    3273                 :            :         [DNS_TRANSACTION_ZONE] = "zone",
    3274                 :            :         [DNS_TRANSACTION_TRUST_ANCHOR] = "trust-anchor",
    3275                 :            : };
    3276   [ #  #  #  # ]:          0 : DEFINE_STRING_TABLE_LOOKUP(dns_transaction_source, DnsTransactionSource);

Generated by: LCOV version 1.14