X Tutup
Skip to content

Commit 5bd7ebb

Browse files
committed
resolved: stick CNAME targets into main answer section in stub replies
1 parent d1f8fbe commit 5bd7ebb

File tree

2 files changed

+91
-31
lines changed

2 files changed

+91
-31
lines changed

src/resolve/resolved-dns-answer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ typedef enum DnsAnswerFlags {
2222
DNS_ANSWER_SECTION_ANSWER = 1 << 5, /* When parsing: RR originates from answer section */
2323
DNS_ANSWER_SECTION_AUTHORITY = 1 << 6, /* When parsing: RR originates from authority section */
2424
DNS_ANSWER_SECTION_ADDITIONAL = 1 << 7, /* When parsing: RR originates from additional section */
25+
26+
DNS_ANSWER_MASK_SECTIONS = DNS_ANSWER_SECTION_ANSWER|
27+
DNS_ANSWER_SECTION_AUTHORITY|
28+
DNS_ANSWER_SECTION_ADDITIONAL,
2529
} DnsAnswerFlags;
2630

2731
struct DnsAnswerItem {

src/resolve/resolved-dns-stub.c

Lines changed: 87 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,38 @@ static int stub_packet_compare_func(const DnsPacket *x, const DnsPacket *y) {
139139

140140
DEFINE_HASH_OPS(stub_packet_hash_ops, DnsPacket, stub_packet_hash_func, stub_packet_compare_func);
141141

142+
static int reply_add_with_rrsig(
143+
DnsAnswer **reply,
144+
DnsResourceRecord *rr,
145+
int ifindex,
146+
DnsAnswerFlags flags,
147+
DnsResourceRecord *rrsig,
148+
bool with_rrsig) {
149+
int r;
150+
151+
assert(reply);
152+
assert(rr);
153+
154+
r = dns_answer_add_extend(reply, rr, ifindex, flags, rrsig);
155+
if (r < 0)
156+
return r;
157+
158+
if (with_rrsig && rrsig) {
159+
r = dns_answer_add_extend(reply, rrsig, ifindex, flags, NULL);
160+
if (r < 0)
161+
return r;
162+
}
163+
164+
return 0;
165+
}
166+
142167
static int dns_stub_collect_answer_by_question(
143168
DnsAnswer **reply,
144169
DnsAnswer *answer,
145170
DnsQuestion *question,
146171
bool with_rrsig) { /* Add RRSIG RR matching each RR */
147172

173+
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *redirected_key = NULL;
148174
DnsAnswerItem *item;
149175
int r;
150176

@@ -153,36 +179,71 @@ static int dns_stub_collect_answer_by_question(
153179
/* Copies all RRs from 'answer' into 'reply', if they match 'question'. */
154180

155181
DNS_ANSWER_FOREACH_ITEM(item, answer) {
156-
157182
if (question) {
158-
bool match = false;
159-
160183
r = dns_question_matches_rr(question, item->rr, NULL);
161184
if (r < 0)
162185
return r;
163-
else if (r > 0)
164-
match = true;
165-
else {
166-
r = dns_question_matches_cname_or_dname(question, item->rr, NULL);
186+
if (r == 0) {
187+
_cleanup_free_ char *target = NULL;
188+
189+
/* OK, so the RR doesn't directly match. Let's see if the RR is a matching
190+
* CNAME or DNAME */
191+
192+
r = dns_resource_record_get_cname_target(
193+
question->keys[0],
194+
item->rr,
195+
&target);
196+
if (r == -EUNATCH)
197+
continue; /* Not a CNAME/DNAME or doesn't match */
167198
if (r < 0)
168199
return r;
169-
if (r > 0)
170-
match = true;
171-
}
172200

173-
if (!match)
174-
continue;
201+
dns_resource_key_unref(redirected_key);
202+
203+
/* There can only be one CNAME per name, hence no point in storing more than one here */
204+
redirected_key = dns_resource_key_new(question->keys[0]->class, question->keys[0]->type, target);
205+
if (!redirected_key)
206+
return -ENOMEM;
207+
}
175208
}
176209

177-
r = dns_answer_add_extend(reply, item->rr, item->ifindex, item->flags, item->rrsig);
210+
/* Mask the section info, we want the primary answers to always go without section info, so
211+
* that it is added to the answer section when we synthesize a reply. */
212+
213+
r = reply_add_with_rrsig(
214+
reply,
215+
item->rr,
216+
item->ifindex,
217+
item->flags & ~DNS_ANSWER_MASK_SECTIONS,
218+
item->rrsig,
219+
with_rrsig);
178220
if (r < 0)
179221
return r;
222+
}
180223

181-
if (with_rrsig && item->rrsig) {
182-
r = dns_answer_add_extend(reply, item->rrsig, item->ifindex, item->flags, NULL);
183-
if (r < 0)
184-
return r;
185-
}
224+
if (!redirected_key)
225+
return 0;
226+
227+
/* This is a CNAME/DNAME answer. In this case also append where the redirections point to to the main
228+
* answer section */
229+
230+
DNS_ANSWER_FOREACH_ITEM(item, answer) {
231+
232+
r = dns_resource_key_match_rr(redirected_key, item->rr, NULL);
233+
if (r < 0)
234+
return r;
235+
if (r == 0)
236+
continue;
237+
238+
r = reply_add_with_rrsig(
239+
reply,
240+
item->rr,
241+
item->ifindex,
242+
item->flags & ~DNS_ANSWER_MASK_SECTIONS,
243+
item->rrsig,
244+
with_rrsig);
245+
if (r < 0)
246+
return r;
186247
}
187248

188249
return 0;
@@ -197,7 +258,6 @@ static int dns_stub_collect_answer_by_section(
197258
bool with_dnssec) { /* Include DNSSEC RRs. RRSIG, NSEC, … */
198259

199260
DnsAnswerItem *item;
200-
unsigned c = 0;
201261
int r;
202262

203263
assert(reply);
@@ -218,22 +278,18 @@ static int dns_stub_collect_answer_by_section(
218278
if (((item->flags ^ section) & (DNS_ANSWER_SECTION_ANSWER|DNS_ANSWER_SECTION_AUTHORITY|DNS_ANSWER_SECTION_ADDITIONAL)) != 0)
219279
continue;
220280

221-
r = dns_answer_add_extend(reply, item->rr, item->ifindex, item->flags, item->rrsig);
281+
r = reply_add_with_rrsig(
282+
reply,
283+
item->rr,
284+
item->ifindex,
285+
item->flags,
286+
item->rrsig,
287+
with_dnssec);
222288
if (r < 0)
223289
return r;
224-
225-
c++;
226-
227-
if (with_dnssec && item->rrsig) {
228-
r = dns_answer_add_extend(reply, item->rrsig, item->ifindex, item->flags, NULL);
229-
if (r < 0)
230-
return r;
231-
232-
c++;
233-
}
234290
}
235291

236-
return (int) c;
292+
return 0;
237293
}
238294

239295
static int dns_stub_assign_sections(

0 commit comments

Comments
 (0)
X Tutup