1:255.13-alt1
[systemd_ALT.git] / src / resolve / resolved-dns-transaction.h
blob6be7c5fb70103a60582e16efc9a8a7017b80283c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
4 #include "sd-event.h"
5 #include "in-addr-util.h"
7 typedef struct DnsTransaction DnsTransaction;
8 typedef struct DnsTransactionFinder DnsTransactionFinder;
9 typedef enum DnsTransactionState DnsTransactionState;
10 typedef enum DnsTransactionSource DnsTransactionSource;
12 #include "resolved-dns-answer.h"
13 #include "resolved-dns-dnssec.h"
14 #include "resolved-dns-packet.h"
15 #include "resolved-dns-question.h"
16 #include "resolved-dns-server.h"
18 enum DnsTransactionState {
19 DNS_TRANSACTION_NULL,
20 DNS_TRANSACTION_PENDING,
21 DNS_TRANSACTION_VALIDATING,
22 DNS_TRANSACTION_RCODE_FAILURE,
23 DNS_TRANSACTION_SUCCESS,
24 DNS_TRANSACTION_NO_SERVERS,
25 DNS_TRANSACTION_TIMEOUT,
26 DNS_TRANSACTION_ATTEMPTS_MAX_REACHED,
27 DNS_TRANSACTION_INVALID_REPLY,
28 DNS_TRANSACTION_ERRNO,
29 DNS_TRANSACTION_ABORTED,
30 DNS_TRANSACTION_DNSSEC_FAILED,
31 DNS_TRANSACTION_NO_TRUST_ANCHOR,
32 DNS_TRANSACTION_RR_TYPE_UNSUPPORTED,
33 DNS_TRANSACTION_NETWORK_DOWN,
34 DNS_TRANSACTION_NOT_FOUND, /* like NXDOMAIN, but when LLMNR/TCP connections fail */
35 DNS_TRANSACTION_NO_SOURCE, /* All suitable DnsTransactionSource turned off */
36 DNS_TRANSACTION_STUB_LOOP,
37 _DNS_TRANSACTION_STATE_MAX,
38 _DNS_TRANSACTION_STATE_INVALID = -EINVAL,
41 #define DNS_TRANSACTION_IS_LIVE(state) IN_SET((state), DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING, DNS_TRANSACTION_VALIDATING)
43 enum DnsTransactionSource {
44 DNS_TRANSACTION_NETWORK,
45 DNS_TRANSACTION_CACHE,
46 DNS_TRANSACTION_ZONE,
47 DNS_TRANSACTION_TRUST_ANCHOR,
48 _DNS_TRANSACTION_SOURCE_MAX,
49 _DNS_TRANSACTION_SOURCE_INVALID = -EINVAL,
52 struct DnsTransaction {
53 DnsScope *scope;
55 DnsResourceKey *key; /* For regular lookups the RR key to look for */
56 DnsPacket *bypass; /* For bypass lookups the full original request packet */
58 uint64_t query_flags;
60 DnsPacket *sent, *received;
62 DnsAnswer *answer;
63 int answer_rcode;
64 DnssecResult answer_dnssec_result;
65 DnsTransactionSource answer_source;
66 uint32_t answer_nsec_ttl;
67 int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
69 DnsTransactionState state;
71 /* SD_RESOLVED_AUTHENTICATED here indicates whether the primary answer is authenticated, i.e. whether
72 * the RRs from answer which directly match the question are authenticated, or, if there are none,
73 * whether the NODATA or NXDOMAIN case is. It says nothing about additional RRs listed in the answer,
74 * however they have their own DNS_ANSWER_AUTHORIZED FLAGS. Note that this bit is defined different
75 * than the AD bit in DNS packets, as that covers more than just the actual primary answer. */
76 uint64_t answer_query_flags;
78 /* Contains DNSKEY, DS, SOA RRs we already verified and need
79 * to authenticate this reply */
80 DnsAnswer *validated_keys;
82 usec_t start_usec;
83 usec_t next_attempt_after;
84 sd_event_source *timeout_event_source;
85 unsigned n_attempts;
87 /* UDP connection logic, if we need it */
88 int dns_udp_fd;
89 sd_event_source *dns_udp_event_source;
91 /* TCP connection logic, if we need it */
92 DnsStream *stream;
94 /* The active server */
95 DnsServer *server;
97 /* The features of the DNS server at time of transaction start */
98 DnsServerFeatureLevel current_feature_level;
100 /* If we got SERVFAIL back, we retry the lookup, using a lower feature level than we used before. */
101 DnsServerFeatureLevel clamp_feature_level_servfail;
103 uint16_t id;
105 bool tried_stream:1;
107 bool initial_jitter_scheduled:1;
108 bool initial_jitter_elapsed:1;
110 bool probing:1;
112 bool seen_timeout:1;
114 /* Query candidates this transaction is referenced by and that
115 * shall be notified about this specific transaction
116 * completing. */
117 Set *notify_query_candidates, *notify_query_candidates_done;
119 /* Zone items this transaction is referenced by and that shall
120 * be notified about completion. */
121 Set *notify_zone_items, *notify_zone_items_done;
123 /* Other transactions that this transactions is referenced by
124 * and that shall be notified about completion. This is used
125 * when transactions want to validate their RRsets, but need
126 * another DNSKEY or DS RR to do so. */
127 Set *notify_transactions, *notify_transactions_done;
129 /* The opposite direction: the transactions this transaction
130 * created in order to request DNSKEY or DS RRs. */
131 Set *dnssec_transactions;
133 unsigned n_picked_servers;
135 unsigned block_gc;
137 /* Set when we're willing to let this transaction live beyond it's usefulness for the original query,
138 * for caching purposes. This blocks gc while there is still a chance we might still receive an
139 * answer. */
140 bool wait_for_answer;
142 LIST_FIELDS(DnsTransaction, transactions_by_scope);
143 LIST_FIELDS(DnsTransaction, transactions_by_stream);
144 LIST_FIELDS(DnsTransaction, transactions_by_key);
146 /* Note: fields should be ordered to minimize alignment gaps. Use pahole! */
149 int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key, DnsPacket *bypass, uint64_t flags);
150 DnsTransaction* dns_transaction_free(DnsTransaction *t);
152 DnsTransaction* dns_transaction_gc(DnsTransaction *t);
153 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_gc);
155 int dns_transaction_go(DnsTransaction *t);
157 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypted);
158 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state);
160 void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source);
161 int dns_transaction_validate_dnssec(DnsTransaction *t);
162 int dns_transaction_request_dnssec_keys(DnsTransaction *t);
164 static inline DnsResourceKey *dns_transaction_key(DnsTransaction *t) {
165 assert(t);
167 /* Return the lookup key of this transaction. Either takes the lookup key from the bypass packet if
168 * we are a bypass transaction. Or take the configured key for regular transactions. */
170 if (t->key)
171 return t->key;
173 assert(t->bypass);
175 return dns_question_first_key(t->bypass->question);
178 static inline uint64_t dns_transaction_source_to_query_flags(DnsTransactionSource s) {
180 switch (s) {
182 case DNS_TRANSACTION_NETWORK:
183 return SD_RESOLVED_FROM_NETWORK;
185 case DNS_TRANSACTION_CACHE:
186 return SD_RESOLVED_FROM_CACHE;
188 case DNS_TRANSACTION_ZONE:
189 return SD_RESOLVED_FROM_ZONE;
191 case DNS_TRANSACTION_TRUST_ANCHOR:
192 return SD_RESOLVED_FROM_TRUST_ANCHOR;
194 default:
195 return 0;
199 const char* dns_transaction_state_to_string(DnsTransactionState p) _const_;
200 DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
202 const char* dns_transaction_source_to_string(DnsTransactionSource p) _const_;
203 DnsTransactionSource dns_transaction_source_from_string(const char *s) _pure_;
205 /* LLMNR Jitter interval, see RFC 4795 Section 7 */
206 #define LLMNR_JITTER_INTERVAL_USEC (100 * USEC_PER_MSEC)
208 /* mDNS probing interval, see RFC 6762 Section 8.1 */
209 #define MDNS_PROBING_INTERVAL_USEC (250 * USEC_PER_MSEC)
211 /* Maximum attempts to send DNS requests, across all DNS servers */
212 #define DNS_TRANSACTION_ATTEMPTS_MAX 24
214 /* Maximum attempts to send LLMNR requests, see RFC 4795 Section 2.7 */
215 #define LLMNR_TRANSACTION_ATTEMPTS_MAX 3
217 /* Maximum attempts to send MDNS requests, see RFC 6762 Section 8.1 */
218 #define MDNS_TRANSACTION_ATTEMPTS_MAX 3
220 #define TRANSACTION_ATTEMPTS_MAX(p) ((p) == DNS_PROTOCOL_LLMNR ? \
221 LLMNR_TRANSACTION_ATTEMPTS_MAX : \
222 (p) == DNS_PROTOCOL_MDNS ? \
223 MDNS_TRANSACTION_ATTEMPTS_MAX : \
224 DNS_TRANSACTION_ATTEMPTS_MAX)