1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3
4 #include "sd-event.h"
5 #include "in-addr-util.h"
6
7 typedef struct DnsTransaction DnsTransaction;
8 typedef struct DnsTransactionFinder DnsTransactionFinder;
9 typedef enum DnsTransactionState DnsTransactionState;
10 typedef enum DnsTransactionSource DnsTransactionSource;
11
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"
17
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,
39 };
40
41 #define DNS_TRANSACTION_IS_LIVE(state) IN_SET((state), DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING, DNS_TRANSACTION_VALIDATING)
42
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,
50 };
51
52 struct DnsTransaction {
53 DnsScope *scope;
54
55 DnsResourceKey *key; /* For regular lookups the RR key to look for */
56 DnsPacket *bypass; /* For bypass lookups the full original request packet */
57
58 uint64_t query_flags;
59
60 DnsPacket *sent, *received;
61
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 */
68
69 DnsTransactionState state;
70
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;
77
78 /* Contains DNSKEY, DS, SOA RRs we already verified and need
79 * to authenticate this reply */
80 DnsAnswer *validated_keys;
81
82 usec_t start_usec;
83 usec_t next_attempt_after;
84 sd_event_source *timeout_event_source;
85 unsigned n_attempts;
86
87 /* UDP connection logic, if we need it */
88 int dns_udp_fd;
89 sd_event_source *dns_udp_event_source;
90
91 /* TCP connection logic, if we need it */
92 DnsStream *stream;
93
94 /* The active server */
95 DnsServer *server;
96
97 /* The features of the DNS server at time of transaction start */
98 DnsServerFeatureLevel current_feature_level;
99
100 /* If we got SERVFAIL back, we retry the lookup, using a lower feature level than we used
101 * before. Similar, if we get NXDOMAIN in pure EDNS0 mode, we check in EDNS0-less mode before giving
102 * up (as mitigation for DVE-2018-0001). */
103 DnsServerFeatureLevel clamp_feature_level_servfail;
104 DnsServerFeatureLevel clamp_feature_level_nxdomain;
105
106 uint16_t id;
107
108 bool tried_stream:1;
109
110 bool initial_jitter_scheduled:1;
111 bool initial_jitter_elapsed:1;
112
113 bool probing:1;
114
115 /* Query candidates this transaction is referenced by and that
116 * shall be notified about this specific transaction
117 * completing. */
118 Set *notify_query_candidates, *notify_query_candidates_done;
119
120 /* Zone items this transaction is referenced by and that shall
121 * be notified about completion. */
122 Set *notify_zone_items, *notify_zone_items_done;
123
124 /* Other transactions that this transactions is referenced by
125 * and that shall be notified about completion. This is used
126 * when transactions want to validate their RRsets, but need
127 * another DNSKEY or DS RR to do so. */
128 Set *notify_transactions, *notify_transactions_done;
129
130 /* The opposite direction: the transactions this transaction
131 * created in order to request DNSKEY or DS RRs. */
132 Set *dnssec_transactions;
133
134 unsigned n_picked_servers;
135
136 unsigned block_gc;
137
138 LIST_FIELDS(DnsTransaction, transactions_by_scope);
139 LIST_FIELDS(DnsTransaction, transactions_by_stream);
140 LIST_FIELDS(DnsTransaction, transactions_by_key);
141
142 /* Note: fields should be ordered to minimize alignment gaps. Use pahole! */
143 };
144
145 int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key, DnsPacket *bypass, uint64_t flags);
146 DnsTransaction* dns_transaction_free(DnsTransaction *t);
147
148 DnsTransaction* dns_transaction_gc(DnsTransaction *t);
149 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_gc);
150
151 int dns_transaction_go(DnsTransaction *t);
152
153 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypted);
154 void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state);
155
156 void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source);
157 int dns_transaction_validate_dnssec(DnsTransaction *t);
158 int dns_transaction_request_dnssec_keys(DnsTransaction *t);
159
dns_transaction_key(DnsTransaction * t)160 static inline DnsResourceKey *dns_transaction_key(DnsTransaction *t) {
161 assert(t);
162
163 /* Return the lookup key of this transaction. Either takes the lookup key from the bypass packet if
164 * we are a bypass transaction. Or take the configured key for regular transactions. */
165
166 if (t->key)
167 return t->key;
168
169 assert(t->bypass);
170
171 return dns_question_first_key(t->bypass->question);
172 }
173
dns_transaction_source_to_query_flags(DnsTransactionSource s)174 static inline uint64_t dns_transaction_source_to_query_flags(DnsTransactionSource s) {
175
176 switch (s) {
177
178 case DNS_TRANSACTION_NETWORK:
179 return SD_RESOLVED_FROM_NETWORK;
180
181 case DNS_TRANSACTION_CACHE:
182 return SD_RESOLVED_FROM_CACHE;
183
184 case DNS_TRANSACTION_ZONE:
185 return SD_RESOLVED_FROM_ZONE;
186
187 case DNS_TRANSACTION_TRUST_ANCHOR:
188 return SD_RESOLVED_FROM_TRUST_ANCHOR;
189
190 default:
191 return 0;
192 }
193 }
194
195 const char* dns_transaction_state_to_string(DnsTransactionState p) _const_;
196 DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
197
198 const char* dns_transaction_source_to_string(DnsTransactionSource p) _const_;
199 DnsTransactionSource dns_transaction_source_from_string(const char *s) _pure_;
200
201 /* LLMNR Jitter interval, see RFC 4795 Section 7 */
202 #define LLMNR_JITTER_INTERVAL_USEC (100 * USEC_PER_MSEC)
203
204 /* mDNS Jitter interval, see RFC 6762 Section 5.2 */
205 #define MDNS_JITTER_MIN_USEC (20 * USEC_PER_MSEC)
206 #define MDNS_JITTER_RANGE_USEC (100 * USEC_PER_MSEC)
207
208 /* mDNS probing interval, see RFC 6762 Section 8.1 */
209 #define MDNS_PROBING_INTERVAL_USEC (250 * USEC_PER_MSEC)
210
211 /* Maximum attempts to send DNS requests, across all DNS servers */
212 #define DNS_TRANSACTION_ATTEMPTS_MAX 24
213
214 /* Maximum attempts to send LLMNR requests, see RFC 4795 Section 2.7 */
215 #define LLMNR_TRANSACTION_ATTEMPTS_MAX 3
216
217 /* Maximum attempts to send MDNS requests, see RFC 6762 Section 8.1 */
218 #define MDNS_TRANSACTION_ATTEMPTS_MAX 3
219
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))
225