resolved-dns-transaction.h revision 51e399bcebefb27d6b147d90de84d07f010fa170
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#pragma once
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/***
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2014 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersentypedef struct DnsTransaction DnsTransaction;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersentypedef enum DnsTransactionState DnsTransactionState;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersentypedef enum DnsTransactionSource DnsTransactionSource;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersenenum DnsTransactionState {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_NULL,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_PENDING,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_VALIDATING,
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DNS_TRANSACTION_RCODE_FAILURE,
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DNS_TRANSACTION_SUCCESS,
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DNS_TRANSACTION_NO_SERVERS,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_TIMEOUT,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_ATTEMPTS_MAX_REACHED,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_INVALID_REPLY,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_RESOURCES,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_CONNECTION_FAILURE,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_ABORTED,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DNS_TRANSACTION_DNSSEC_FAILED,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _DNS_TRANSACTION_STATE_MAX,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _DNS_TRANSACTION_STATE_INVALID = -1
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen};
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#define DNS_TRANSACTION_IS_LIVE(state) IN_SET((state), DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING, DNS_TRANSACTION_VALIDATING)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenenum DnsTransactionSource {
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DNS_TRANSACTION_NETWORK,
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DNS_TRANSACTION_CACHE,
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DNS_TRANSACTION_ZONE,
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DNS_TRANSACTION_TRUST_ANCHOR,
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen _DNS_TRANSACTION_SOURCE_MAX,
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen _DNS_TRANSACTION_SOURCE_INVALID = -1
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen};
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen#include "resolved-dns-answer.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "resolved-dns-packet.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "resolved-dns-question.h"
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen#include "resolved-dns-scope.h"
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersenstruct DnsTransaction {
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DnsScope *scope;
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen DnsResourceKey *key;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen char *key_string;
b9e7a9d870ac41d4db954edd52a1f5dd7d153389Lennart Poettering
b9e7a9d870ac41d4db954edd52a1f5dd7d153389Lennart Poettering DnsTransactionState state;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen uint16_t id;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen bool tried_stream:1;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen bool initial_jitter_scheduled:1;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen bool initial_jitter_elapsed:1;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DnsPacket *sent, *received;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DnsAnswer *answer;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int answer_rcode;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DnssecResult answer_dnssec_result;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DnsTransactionSource answer_source;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* Indicates whether the primary answer is authenticated,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * i.e. whether the RRs from answer which directly match the
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * question are authenticated, or, if there are none, whether
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * the NODATA or NXDOMAIN case is. It says nothing about
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * additional RRs listed in the answer, however they have
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * their own DNS_ANSWER_AUTHORIZED FLAGS. Note that this bit
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * is defined different than the AD bit in DNS packets, as
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * that covers more than just the actual primary answer. */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen bool answer_authenticated;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* Contains DNSKEY, DS, SOA RRs we already verified and need
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * to authenticate this reply */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DnsAnswer *validated_keys;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen usec_t start_usec;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen usec_t next_attempt_after;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen sd_event_source *timeout_event_source;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen unsigned n_attempts;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* UDP connection logic, if we need it */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int dns_udp_fd;
sd_event_source *dns_udp_event_source;
/* TCP connection logic, if we need it */
DnsStream *stream;
/* The active server */
DnsServer *server;
/* The features of the DNS server at time of transaction start */
DnsServerFeatureLevel current_features;
/* Query candidates this transaction is referenced by and that
* shall be notified about this specific transaction
* completing. */
Set *notify_query_candidates;
/* Zone items this transaction is referenced by and that shall
* be notified about completion. */
Set *notify_zone_items;
/* Other transactions that this transactions is referenced by
* and that shall be notified about completion. This is used
* when transactions want to validate their RRsets, but need
* another DNSKEY or DS RR to do so. */
Set *notify_transactions;
/* The opposite direction: the transactions this transaction
* created in order to request DNSKEY or DS RRs. */
Set *dnssec_transactions;
unsigned block_gc;
LIST_FIELDS(DnsTransaction, transactions_by_scope);
};
int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key);
DnsTransaction* dns_transaction_free(DnsTransaction *t);
bool dns_transaction_gc(DnsTransaction *t);
int dns_transaction_go(DnsTransaction *t);
void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p);
void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state);
void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source);
int dns_transaction_validate_dnssec(DnsTransaction *t);
int dns_transaction_request_dnssec_keys(DnsTransaction *t);
const char *dns_transaction_key_string(DnsTransaction *t);
const char* dns_transaction_state_to_string(DnsTransactionState p) _const_;
DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
const char* dns_transaction_source_to_string(DnsTransactionSource p) _const_;
DnsTransactionSource dns_transaction_source_from_string(const char *s) _pure_;
/* LLMNR Jitter interval, see RFC 4795 Section 7 */
#define LLMNR_JITTER_INTERVAL_USEC (100 * USEC_PER_MSEC)
/* mDNS Jitter interval, see RFC 6762 Section 5.2 */
#define MDNS_JITTER_MIN_USEC (20 * USEC_PER_MSEC)
#define MDNS_JITTER_RANGE_USEC (100 * USEC_PER_MSEC)
/* Maximum attempts to send DNS requests, across all DNS servers */
#define DNS_TRANSACTION_ATTEMPTS_MAX 16
/* Maximum attempts to send LLMNR requests, see RFC 4795 Section 2.7 */
#define LLMNR_TRANSACTION_ATTEMPTS_MAX 3
#define TRANSACTION_ATTEMPTS_MAX(p) ((p) == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_ATTEMPTS_MAX : DNS_TRANSACTION_ATTEMPTS_MAX)