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