]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
74b2466e LP |
2 | #pragma once |
3 | ||
68527d30 DDM |
4 | #include "in-addr-util.h" |
5 | #include "list.h" | |
68527d30 DDM |
6 | #include "resolved-dns-packet.h" |
7 | #include "resolved-dns-transaction.h" | |
284d7641 DDM |
8 | #include "resolved-forward.h" |
9 | ||
10 | typedef struct DnsQueryCandidate { | |
0e0fd08f ZJS |
11 | unsigned n_ref; |
12 | int error_code; | |
5814acca | 13 | uint64_t generation; |
0e0fd08f | 14 | |
801ad6a6 LP |
15 | DnsQuery *query; |
16 | DnsScope *scope; | |
17 | ||
18 | DnsSearchDomain *search_domain; | |
19 | ||
801ad6a6 | 20 | Set *transactions; |
0da73fab | 21 | sd_event_source *timeout_event_source; |
801ad6a6 LP |
22 | |
23 | LIST_FIELDS(DnsQueryCandidate, candidates_by_query); | |
24 | LIST_FIELDS(DnsQueryCandidate, candidates_by_scope); | |
284d7641 | 25 | } DnsQueryCandidate; |
74b2466e | 26 | |
284d7641 | 27 | typedef struct DnsQuery { |
74b2466e | 28 | Manager *manager; |
45ec7efb | 29 | |
c805014a ZJS |
30 | /* The question, formatted in IDNA for use on classic DNS, and as UTF8 for use in LLMNR or mDNS. Note |
31 | * that even on classic DNS some labels might use UTF8 encoding. Specifically, DNS-SD service names | |
32 | * (in contrast to their domain suffixes) use UTF-8 encoding even on DNS. Thus, the difference | |
33 | * between these two fields is mostly relevant only for explicit *hostname* lookups as well as the | |
1a71fe4e LP |
34 | * domain suffixes of service lookups. |
35 | * | |
36 | * Note that questions may consist of multiple RR keys at once, but they must be for the same domain | |
37 | * name. This is used for A+AAAA and TXT+SRV lookups: we'll allocate a single DnsQuery object for | |
38 | * them instead of two separate ones. That allows us minor optimizations with response handling: | |
39 | * CNAME/DNAMEs of the first reply we get can already be used to follow the CNAME/DNAME chain for | |
40 | * both, and we can take benefit of server replies that oftentimes put A responses into AAAA queries | |
41 | * and vice versa (in the additional section). */ | |
23b298bc LP |
42 | DnsQuestion *question_idna; |
43 | DnsQuestion *question_utf8; | |
44 | ||
775ae354 LP |
45 | /* If this is not a question by ourselves, but a "bypass" request, we propagate the original packet |
46 | * here, and use that instead. */ | |
47 | DnsPacket *question_bypass; | |
48 | ||
72c2d39e LP |
49 | /* When we follow a CNAME redirect, we save the original question here, for informational/monitoring |
50 | * purposes. We'll keep adding to this whenever we go one step in the redirect, so that in the end | |
51 | * this will contain the complete set of CNAME questions. */ | |
52 | DnsQuestion *collected_questions; | |
53 | ||
51323288 LP |
54 | uint64_t flags; |
55 | int ifindex; | |
56 | ||
9079bd32 ZJS |
57 | /* When resolving a service, we first create a TXT+SRV query, and then for the hostnames we discover |
58 | * auxiliary A+AAAA queries. This pointer always points from the auxiliary queries back to the | |
59 | * TXT+SRV query. */ | |
60 | int auxiliary_result; | |
61 | DnsQuery *auxiliary_for; | |
62 | LIST_HEAD(DnsQuery, auxiliary_queries); | |
74b2466e | 63 | |
801ad6a6 | 64 | LIST_HEAD(DnsQueryCandidate, candidates); |
74b2466e LP |
65 | sd_event_source *timeout_event_source; |
66 | ||
322345fd | 67 | /* Discovered data */ |
faa133f3 | 68 | DnsAnswer *answer; |
faa133f3 | 69 | int answer_rcode; |
9ca133e9 RP |
70 | int answer_ede_rcode; |
71 | char *answer_ede_msg; | |
41398e87 | 72 | DnssecResult answer_dnssec_result; |
6f055e43 | 73 | uint64_t answer_query_flags; |
ae6a4bbf LP |
74 | DnsProtocol answer_protocol; |
75 | int answer_family; | |
9079bd32 | 76 | DnsPacket *answer_full_packet; |
801ad6a6 | 77 | DnsSearchDomain *answer_search_domain; |
9079bd32 ZJS |
78 | |
79 | DnsTransactionState state; | |
7cc6ed7b | 80 | int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */ |
9079bd32 ZJS |
81 | |
82 | unsigned block_ready; | |
83 | ||
84 | uint8_t n_auxiliary_queries; | |
85 | uint8_t n_cname_redirects; | |
86 | ||
87 | bool previous_redirect_unauthenticated:1; | |
88 | bool previous_redirect_non_confidential:1; | |
89 | bool previous_redirect_non_synthetic:1; | |
90 | bool request_address_valid:1; | |
74b2466e | 91 | |
9581bb84 | 92 | /* Bus + Varlink client information */ |
c9de4e0f | 93 | sd_bus_message *bus_request; |
25ff515b | 94 | sd_varlink *varlink_request; |
0dd25fb9 | 95 | int request_family; |
74b2466e | 96 | union in_addr_union request_address; |
45ec7efb | 97 | unsigned block_all_complete; |
23b298bc | 98 | char *request_address_string; |
74b2466e | 99 | |
b30bf55d | 100 | /* DNS stub information */ |
775ae354 LP |
101 | DnsPacket *request_packet; |
102 | DnsStream *request_stream; | |
103 | DnsAnswer *reply_answer; | |
104 | DnsAnswer *reply_authoritative; | |
105 | DnsAnswer *reply_additional; | |
0354029b | 106 | DnsStubListenerExtra *stub_listener_extra; |
b30bf55d | 107 | |
322345fd | 108 | /* Completion callback */ |
74b2466e | 109 | void (*complete)(DnsQuery* q); |
faa133f3 | 110 | |
82bd6ddd LP |
111 | sd_bus_track *bus_track; |
112 | ||
74b2466e | 113 | LIST_FIELDS(DnsQuery, queries); |
45ec7efb | 114 | LIST_FIELDS(DnsQuery, auxiliary_queries); |
9079bd32 ZJS |
115 | |
116 | /* Note: fields should be ordered to minimize alignment gaps. Use pahole! */ | |
284d7641 | 117 | } DnsQuery; |
74b2466e | 118 | |
7588460a TG |
119 | enum { |
120 | DNS_QUERY_MATCH, | |
121 | DNS_QUERY_NOMATCH, | |
1db8e6d1 | 122 | DNS_QUERY_CNAME, |
7588460a TG |
123 | }; |
124 | ||
0e0fd08f ZJS |
125 | DnsQueryCandidate* dns_query_candidate_ref(DnsQueryCandidate*); |
126 | DnsQueryCandidate* dns_query_candidate_unref(DnsQueryCandidate*); | |
127 | DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryCandidate*, dns_query_candidate_unref); | |
7877e5ca | 128 | |
547973de | 129 | void dns_query_candidate_notify(DnsQueryCandidate *c); |
801ad6a6 | 130 | |
775ae354 | 131 | int dns_query_new(Manager *m, DnsQuery **q, DnsQuestion *question_utf8, DnsQuestion *question_idna, DnsPacket *question_bypass, int family, uint64_t flags); |
74b2466e | 132 | DnsQuery *dns_query_free(DnsQuery *q); |
322345fd | 133 | |
45ec7efb LP |
134 | int dns_query_make_auxiliary(DnsQuery *q, DnsQuery *auxiliary_for); |
135 | ||
322345fd | 136 | int dns_query_go(DnsQuery *q); |
faa133f3 | 137 | void dns_query_ready(DnsQuery *q); |
74b2466e | 138 | |
1db8e6d1 LP |
139 | int dns_query_process_cname_one(DnsQuery *q); |
140 | int dns_query_process_cname_many(DnsQuery *q); | |
74b2466e | 141 | |
65a01e82 | 142 | void dns_query_complete(DnsQuery *q, DnsTransactionState state); |
82bd6ddd | 143 | |
23b298bc LP |
144 | DnsQuestion* dns_query_question_for_protocol(DnsQuery *q, DnsProtocol protocol); |
145 | ||
bfd5a068 | 146 | const char* dns_query_string(DnsQuery *q); |
23b298bc | 147 | |
74b2466e | 148 | DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free); |
28830a64 LP |
149 | |
150 | bool dns_query_fully_authenticated(DnsQuery *q); | |
43fc4baa | 151 | bool dns_query_fully_confidential(DnsQuery *q); |
9ddf099f | 152 | bool dns_query_fully_authoritative(DnsQuery *q); |
43fc4baa | 153 | |
7cf95470 YW |
154 | int validate_and_mangle_query_flags(Manager *manager, uint64_t *flags, const char *name, uint64_t ok); |
155 | ||
68527d30 | 156 | uint64_t dns_query_reply_flags_make(DnsQuery *q); |