Deleted Added
full compact
iter_scrub.c (356345) iter_scrub.c (361435)
1/*
2 * iterator/iter_scrub.c - scrubbing, normalization, sanitization of DNS msgs.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 171 unchanged lines hidden (view full) ---

180 }
181 }
182 }
183}
184
185/** Get target name of a CNAME */
186static int
187parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
1/*
2 * iterator/iter_scrub.c - scrubbing, normalization, sanitization of DNS msgs.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 171 unchanged lines hidden (view full) ---

180 }
181 }
182 }
183}
184
185/** Get target name of a CNAME */
186static int
187parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
188 size_t* snamelen)
188 size_t* snamelen, sldns_buffer* pkt)
189{
189{
190 size_t oldpos, dlen;
190 if(rrset->rr_count != 1) {
191 struct rr_parse* sig;
192 verbose(VERB_ALGO, "Found CNAME rrset with "
193 "size > 1: %u", (unsigned)rrset->rr_count);
194 /* use the first CNAME! */
195 rrset->rr_count = 1;
196 rrset->size = rrset->rr_first->size;
197 for(sig=rrset->rrsig_first; sig; sig=sig->next)
198 rrset->size += sig->size;
199 rrset->rr_last = rrset->rr_first;
200 rrset->rr_first->next = NULL;
201 }
202 if(rrset->rr_first->size < sizeof(uint16_t)+1)
203 return 0; /* CNAME rdata too small */
204 *sname = rrset->rr_first->ttl_data + sizeof(uint32_t)
205 + sizeof(uint16_t); /* skip ttl, rdatalen */
206 *snamelen = rrset->rr_first->size - sizeof(uint16_t);
191 if(rrset->rr_count != 1) {
192 struct rr_parse* sig;
193 verbose(VERB_ALGO, "Found CNAME rrset with "
194 "size > 1: %u", (unsigned)rrset->rr_count);
195 /* use the first CNAME! */
196 rrset->rr_count = 1;
197 rrset->size = rrset->rr_first->size;
198 for(sig=rrset->rrsig_first; sig; sig=sig->next)
199 rrset->size += sig->size;
200 rrset->rr_last = rrset->rr_first;
201 rrset->rr_first->next = NULL;
202 }
203 if(rrset->rr_first->size < sizeof(uint16_t)+1)
204 return 0; /* CNAME rdata too small */
205 *sname = rrset->rr_first->ttl_data + sizeof(uint32_t)
206 + sizeof(uint16_t); /* skip ttl, rdatalen */
207 *snamelen = rrset->rr_first->size - sizeof(uint16_t);
208
209 if(rrset->rr_first->outside_packet) {
210 if(!dname_valid(*sname, *snamelen))
211 return 0;
212 return 1;
213 }
214 oldpos = sldns_buffer_position(pkt);
215 sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt)));
216 dlen = pkt_dname_len(pkt);
217 sldns_buffer_set_position(pkt, oldpos);
218 if(dlen == 0)
219 return 0; /* parse fail on the rdata name */
220 *snamelen = dlen;
207 return 1;
208}
209
210/** Synthesize CNAME from DNAME, false if too long */
211static int
212synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset,
213 uint8_t* alias, size_t* aliaslen, sldns_buffer* pkt)
214{
215 /* we already know that sname is a strict subdomain of DNAME owner */
216 uint8_t* dtarg = NULL;
217 size_t dtarglen;
221 return 1;
222}
223
224/** Synthesize CNAME from DNAME, false if too long */
225static int
226synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset,
227 uint8_t* alias, size_t* aliaslen, sldns_buffer* pkt)
228{
229 /* we already know that sname is a strict subdomain of DNAME owner */
230 uint8_t* dtarg = NULL;
231 size_t dtarglen;
218 if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen))
232 if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt))
219 return 0;
220 if(qnamelen <= dname_rrset->dname_len)
221 return 0;
222 if(qnamelen == 0)
223 return 0;
224 log_assert(qnamelen > dname_rrset->dname_len);
225 /* DNAME from com. to net. with qname example.com. -> example.net. */
226 /* so: \3com\0 to \3net\0 and qname \7example\3com\0 */

--- 156 unchanged lines hidden (view full) ---

383 "too long");
384 return 0;
385 }
386 if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
387 dname_pkt_compare(pkt, sname, nx->dname) == 0) {
388 /* check next cname */
389 uint8_t* t = NULL;
390 size_t tlen = 0;
233 return 0;
234 if(qnamelen <= dname_rrset->dname_len)
235 return 0;
236 if(qnamelen == 0)
237 return 0;
238 log_assert(qnamelen > dname_rrset->dname_len);
239 /* DNAME from com. to net. with qname example.com. -> example.net. */
240 /* so: \3com\0 to \3net\0 and qname \7example\3com\0 */

--- 156 unchanged lines hidden (view full) ---

397 "too long");
398 return 0;
399 }
400 if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
401 dname_pkt_compare(pkt, sname, nx->dname) == 0) {
402 /* check next cname */
403 uint8_t* t = NULL;
404 size_t tlen = 0;
391 if(!parse_get_cname_target(nx, &t, &tlen))
405 if(!parse_get_cname_target(nx, &t, &tlen, pkt))
392 return 0;
393 if(dname_pkt_compare(pkt, alias, t) == 0) {
394 /* it's OK and better capitalized */
395 prev = rrset;
396 rrset = nx;
397 continue;
398 }
399 /* synth ourselves */

--- 34 unchanged lines hidden (view full) ---

434 /* check if the alias of the DNAME equals
435 * this CNAME */
436 uint8_t alias[LDNS_MAX_DOMAINLEN+1];
437 size_t aliaslen = 0;
438 uint8_t* t = NULL;
439 size_t tlen = 0;
440 if(synth_cname(sname, snamelen, nx, alias,
441 &aliaslen, pkt) &&
406 return 0;
407 if(dname_pkt_compare(pkt, alias, t) == 0) {
408 /* it's OK and better capitalized */
409 prev = rrset;
410 rrset = nx;
411 continue;
412 }
413 /* synth ourselves */

--- 34 unchanged lines hidden (view full) ---

448 /* check if the alias of the DNAME equals
449 * this CNAME */
450 uint8_t alias[LDNS_MAX_DOMAINLEN+1];
451 size_t aliaslen = 0;
452 uint8_t* t = NULL;
453 size_t tlen = 0;
454 if(synth_cname(sname, snamelen, nx, alias,
455 &aliaslen, pkt) &&
442 parse_get_cname_target(rrset, &t, &tlen) &&
456 parse_get_cname_target(rrset, &t, &tlen, pkt) &&
443 dname_pkt_compare(pkt, alias, t) == 0) {
444 /* the synthesized CNAME equals the
445 * current CNAME. This CNAME is the
446 * one that the DNAME creates, and this
447 * CNAME is better capitalised */
448 verbose(VERB_ALGO, "normalize: re-order of DNAME and its CNAME");
449 if(prev) prev->rrset_all_next = nx;
450 else msg->rrset_first = nx;

--- 4 unchanged lines hidden (view full) ---

455 nx->rrset_all_next = rrset;
456 /* prev = nx; unused, enable if there
457 * is other rrset removal code after
458 * this */
459 }
460 }
461
462 /* move to next name in CNAME chain */
457 dname_pkt_compare(pkt, alias, t) == 0) {
458 /* the synthesized CNAME equals the
459 * current CNAME. This CNAME is the
460 * one that the DNAME creates, and this
461 * CNAME is better capitalised */
462 verbose(VERB_ALGO, "normalize: re-order of DNAME and its CNAME");
463 if(prev) prev->rrset_all_next = nx;
464 else msg->rrset_first = nx;

--- 4 unchanged lines hidden (view full) ---

469 nx->rrset_all_next = rrset;
470 /* prev = nx; unused, enable if there
471 * is other rrset removal code after
472 * this */
473 }
474 }
475
476 /* move to next name in CNAME chain */
463 if(!parse_get_cname_target(rrset, &sname, &snamelen))
477 if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt))
464 return 0;
465 prev = rrset;
466 rrset = rrset->rrset_all_next;
467 /* in CNAME ANY response, can have data after CNAME */
468 if(qinfo->qtype == LDNS_RR_TYPE_ANY) {
469 while(rrset && rrset->section ==
470 LDNS_SECTION_ANSWER &&
471 dname_pkt_compare(pkt, oldsname,

--- 358 unchanged lines hidden ---
478 return 0;
479 prev = rrset;
480 rrset = rrset->rrset_all_next;
481 /* in CNAME ANY response, can have data after CNAME */
482 if(qinfo->qtype == LDNS_RR_TYPE_ANY) {
483 while(rrset && rrset->section ==
484 LDNS_SECTION_ANSWER &&
485 dname_pkt_compare(pkt, oldsname,

--- 358 unchanged lines hidden ---