1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
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
{
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
,
47 DNS_TRANSACTION_TRUST_ANCHOR
,
48 _DNS_TRANSACTION_SOURCE_MAX
,
49 _DNS_TRANSACTION_SOURCE_INVALID
= -EINVAL
,
52 struct DnsTransaction
{
55 DnsResourceKey
*key
; /* For regular lookups the RR key to look for */
56 DnsPacket
*bypass
; /* For bypass lookups the full original request packet */
60 DnsPacket
*sent
, *received
;
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
;
83 usec_t next_attempt_after
;
84 sd_event_source
*timeout_event_source
;
87 /* UDP connection logic, if we need it */
89 sd_event_source
*dns_udp_event_source
;
91 /* TCP connection logic, if we need it */
94 /* The active 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
;
107 bool initial_jitter_scheduled
:1;
108 bool initial_jitter_elapsed
:1;
114 /* Query candidates this transaction is referenced by and that
115 * shall be notified about this specific transaction
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
;
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
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
) {
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. */
175 return dns_question_first_key(t
->bypass
->question
);
178 static inline uint64_t dns_transaction_source_to_query_flags(DnsTransactionSource 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
;
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)