"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "query.c" between
nsd-4.3.5.tar.gz and nsd-4.3.6.tar.gz

About: NSD is an authoritative only, high performance, simple name server daemon.

query.c  (nsd-4.3.5):query.c  (nsd-4.3.6)
skipping to change at line 541 skipping to change at line 541
if(!nsd->options->hide_identity) { if(!nsd->options->hide_identity) {
/* Add ID */ /* Add ID */
query_addtxt(q, query_addtxt(q,
buffer_begin(q->packet) + QHEADERSZ, buffer_begin(q->packet) + QHEADERSZ,
CLASS_CH, CLASS_CH,
0, 0,
nsd->identity); nsd->identity);
ANCOUNT_SET(q->packet, ANCOUNT(q->packet) + 1); ANCOUNT_SET(q->packet, ANCOUNT(q->packet) + 1);
} else { } else {
RCODE_SET(q->packet, RCODE_REFUSE); RCODE_SET(q->packet, RCODE_REFUSE);
/* RFC8914 - Extended DNS Errors
* 4.19. Extended DNS Error Code 18 - Prohibited
*/
q->edns.ede = EDE_PROHIBITED;
} }
} else if ((q->qname->name_size == 16 } else if ((q->qname->name_size == 16
&& memcmp(dname_name(q->qname), "\007version\006serve r", 16) == 0) || && memcmp(dname_name(q->qname), "\007version\006serve r", 16) == 0) ||
(q->qname->name_size == 14 (q->qname->name_size == 14
&& memcmp(dname_name(q->qname), "\007version\004bind" , 14) == 0)) && memcmp(dname_name(q->qname), "\007version\004bind" , 14) == 0))
{ {
if(!nsd->options->hide_version) { if(!nsd->options->hide_version) {
/* Add version */ /* Add version */
query_addtxt(q, query_addtxt(q,
buffer_begin(q->packet) + QHEADERSZ, buffer_begin(q->packet) + QHEADERSZ,
CLASS_CH, CLASS_CH,
0, 0,
nsd->version); nsd->version);
ANCOUNT_SET(q->packet, ANCOUNT(q->packet) + 1); ANCOUNT_SET(q->packet, ANCOUNT(q->packet) + 1);
} else { } else {
RCODE_SET(q->packet, RCODE_REFUSE); RCODE_SET(q->packet, RCODE_REFUSE);
/* RFC8914 - Extended DNS Errors
* 4.19. Extended DNS Error Code 18 - Prohibited
*/
q->edns.ede = EDE_PROHIBITED;
} }
} else { } else {
RCODE_SET(q->packet, RCODE_REFUSE); RCODE_SET(q->packet, RCODE_REFUSE);
/* RFC8914 - Extended DNS Errors
* 4.22. Extended DNS Error Code 21 - Not Supported */
q->edns.ede = EDE_NOT_SUPPORTED;
} }
break; break;
default: default:
RCODE_SET(q->packet, RCODE_REFUSE); RCODE_SET(q->packet, RCODE_REFUSE);
/* RFC8914 - Extended DNS Errors
* 4.22. Extended DNS Error Code 21 - Not Supported */
q->edns.ede = EDE_NOT_SUPPORTED;
break; break;
} }
return QUERY_PROCESSED; return QUERY_PROCESSED;
} }
/* /*
* Find the covering NSEC for a non-existent domain name. Normally * Find the covering NSEC for a non-existent domain name. Normally
* the NSEC will be located at CLOSEST_MATCH, except when it is an * the NSEC will be located at CLOSEST_MATCH, except when it is an
* empty non-terminal. In this case the NSEC may be located at the * empty non-terminal. In this case the NSEC may be located at the
skipping to change at line 1130 skipping to change at line 1143
/* stop if DNAME loops, when added second time */ /* stop if DNAME loops, when added second time */
if(dname_is_subdomain(domain_dname(dest), domain_dname(sr c))) { if(dname_is_subdomain(domain_dname(dest), domain_dname(sr c))) {
return; return;
} }
} }
newname = dname_replace(q->region, name, newname = dname_replace(q->region, name,
domain_dname(src), domain_dname(dest)); domain_dname(src), domain_dname(dest));
++q->cname_count; ++q->cname_count;
if(!newname) { /* newname too long */ if(!newname) { /* newname too long */
RCODE_SET(q->packet, RCODE_YXDOMAIN); RCODE_SET(q->packet, RCODE_YXDOMAIN);
/* RFC 8914 - Extended DNS Errors
* 4.21. Extended DNS Error Code 0 - Other */
ASSIGN_EDE_CODE_AND_STRING_LITERAL(q->edns.ede,
EDE_OTHER, "DNAME expansion became too large");
return; return;
} }
DEBUG(DEBUG_QUERY,2, (LOG_INFO, "->result is %s", dname_to_string (newname, NULL))); DEBUG(DEBUG_QUERY,2, (LOG_INFO, "->result is %s", dname_to_string (newname, NULL)));
/* follow the DNAME */ /* follow the DNAME */
(void)namedb_lookup(nsd->db, newname, &closest_match, &closest_en closer); (void)namedb_lookup(nsd->db, newname, &closest_match, &closest_en closer);
/* synthesize CNAME record */ /* synthesize CNAME record */
newnum = query_synthesize_cname(q, answer, name, newname, newnum = query_synthesize_cname(q, answer, name, newname,
src, closest_encloser, &closest_match, rrset->rrs[0].ttl) ; src, closest_encloser, &closest_match, rrset->rrs[0].ttl) ;
if(!newnum) { if(!newnum) {
/* could not synthesize the CNAME. */ /* could not synthesize the CNAME. */
skipping to change at line 1265 skipping to change at line 1282
*/ */
static void static void
answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer, answer_lookup_zone(struct nsd *nsd, struct query *q, answer_type *answer,
size_t domain_number, int exact, domain_type *closest_match, size_t domain_number, int exact, domain_type *closest_match,
domain_type *closest_encloser, const dname_type *qname) domain_type *closest_encloser, const dname_type *qname)
{ {
zone_type* origzone = q->zone; zone_type* origzone = q->zone;
q->zone = domain_find_zone(nsd->db, closest_encloser); q->zone = domain_find_zone(nsd->db, closest_encloser);
if (!q->zone) { if (!q->zone) {
/* no zone for this */ /* no zone for this */
if(q->cname_count == 0) if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_REFUSE); RCODE_SET(q->packet, RCODE_REFUSE);
/* RFC 8914 - Extended DNS Errors
* 4.21. Extended DNS Error Code 20 - Not Authoritative *
/
q->edns.ede = EDE_NOT_AUTHORITATIVE;
}
return; return;
} }
assert(closest_encloser); /* otherwise, no q->zone would be found */ assert(closest_encloser); /* otherwise, no q->zone would be found */
if(q->zone->opts && q->zone->opts->pattern
&& q->zone->opts->pattern->allow_query) {
struct acl_options *why = NULL;
/* check if it passes acl */
if(acl_check_incoming(
q->zone->opts->pattern->allow_query, q, &why) != -1) {
assert(why);
DEBUG(DEBUG_QUERY,1, (LOG_INFO, "query %s passed acl %s %
s",
dname_to_string(q->qname, NULL),
why->ip_address_spec,
why->nokey?"NOKEY":
(why->blocked?"BLOCKED":why->key_name)));
} else {
if (verbosity >= 2) {
char address[128];
addr2str(&q->addr, address, sizeof(address));
VERBOSITY(2, (LOG_INFO, "query %s from %s refused
, %s %s",
dname_to_string(q->qname, NULL),
address,
why ? ( why->nokey ? "NOKEY"
: why->blocked ? "BLOCKED"
: why->key_name )
: "no acl matches",
why?why->ip_address_spec:"."));
}
/* no zone for this */
if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_REFUSE);
/* RFC8914 - Extended DNS Errors
* 4.19. Extended DNS Error Code 18 - Prohibited
*/
q->edns.ede = EDE_PROHIBITED;
}
return;
}
}
if(!q->zone->apex || !q->zone->soa_rrset) { if(!q->zone->apex || !q->zone->soa_rrset) {
/* zone is configured but not loaded */ /* zone is configured but not loaded */
if(q->cname_count == 0) if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_SERVFAIL); RCODE_SET(q->packet, RCODE_SERVFAIL);
/* RFC 8914 - Extended DNS Errors
* 4.15. Extended DNS Error Code 14 - Not Ready */
q->edns.ede = EDE_NOT_READY;
ASSIGN_EDE_CODE_AND_STRING_LITERAL(q->edns.ede,
EDE_NOT_READY, "Zone is configured but not loaded");
}
return; return;
} }
/* /*
* If confine-to-zone is set to yes do not return additional * If confine-to-zone is set to yes do not return additional
* information for a zone with a different apex from the query zone. * information for a zone with a different apex from the query zone.
*/ */
if (nsd->options->confine_to_zone && if (nsd->options->confine_to_zone &&
(origzone != NULL && dname_compare(domain_dname(origzone->apex), domai n_dname(q->zone->apex)) != 0)) { (origzone != NULL && dname_compare(domain_dname(origzone->apex), domai n_dname(q->zone->apex)) != 0)) {
return; return;
skipping to change at line 1310 skipping to change at line 1373
/* /*
* Type DS query at a zone cut, use the responsible * Type DS query at a zone cut, use the responsible
* parent zone to generate the answer if we are * parent zone to generate the answer if we are
* authoritative for the parent zone. * authoritative for the parent zone.
*/ */
zone_type *zone = domain_find_parent_zone(nsd->db, q->zone); zone_type *zone = domain_find_parent_zone(nsd->db, q->zone);
if (zone) { if (zone) {
q->zone = zone; q->zone = zone;
if(!q->zone->apex || !q->zone->soa_rrset) { if(!q->zone->apex || !q->zone->soa_rrset) {
/* zone is configured but not loaded */ /* zone is configured but not loaded */
if(q->cname_count == 0) if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_SERVFAIL); RCODE_SET(q->packet, RCODE_SERVFAIL);
/* RFC 8914 - Extended DNS Errors
* 4.15. Extended DNS Error Code 14 - Not
Ready */
ASSIGN_EDE_CODE_AND_STRING_LITERAL(
q->edns.ede, EDE_NOT_READY,
"Zone is configured but not loaded");
}
return; return;
} }
} }
} }
/* see if the zone has expired (for secondary zones) */ /* see if the zone has expired (for secondary zones) */
if(q->zone && q->zone->opts && q->zone->opts->pattern && if(q->zone && q->zone->opts && q->zone->opts->pattern &&
q->zone->opts->pattern->request_xfr != 0 && !q->zone->is_ok) { q->zone->opts->pattern->request_xfr != 0 && !q->zone->is_ok) {
if(q->cname_count == 0) if(q->cname_count == 0) {
RCODE_SET(q->packet, RCODE_SERVFAIL); RCODE_SET(q->packet, RCODE_SERVFAIL);
/* RFC 8914 - Extended DNS Errors
* 4.25. Extended DNS Error Code 24 - Invalid Data */
ASSIGN_EDE_CODE_AND_STRING_LITERAL(q->edns.ede,
EDE_INVALID_DATA, "Zone has expired");
}
return; return;
} }
if (exact && q->qtype == TYPE_DS && closest_encloser == q->zone->apex) { if (exact && q->qtype == TYPE_DS && closest_encloser == q->zone->apex) {
/* /*
* Type DS query at the zone apex (and the server is * Type DS query at the zone apex (and the server is
* not authoritative for the parent zone). * not authoritative for the parent zone).
*/ */
if (q->qclass == CLASS_ANY) { if (q->qclass == CLASS_ANY) {
AA_CLR(q->packet); AA_CLR(q->packet);
skipping to change at line 1510 skipping to change at line 1584
* perhaps RRSIGs (but not needed), otherwise we do not * perhaps RRSIGs (but not needed), otherwise we do not
* understand what this means. We do not want too many * understand what this means. We do not want too many
* because the high iteration counts slow down. */ * because the high iteration counts slow down. */
if(nscount > 64) return query_formerr(q, nsd); if(nscount > 64) return query_formerr(q, nsd);
for(i=0; i< nscount; i++) for(i=0; i< nscount; i++)
if(!packet_skip_rr(q->packet, 0)) if(!packet_skip_rr(q->packet, 0))
return query_formerr(q, nsd); return query_formerr(q, nsd);
} }
arcount = ARCOUNT(q->packet); arcount = ARCOUNT(q->packet);
if (arcount > 0) { /* A TSIG RR is not allowed before the EDNS OPT RR.
/* According to draft-ietf-dnsext-rfc2671bis-edns0-10: * In RFC6891 (about EDNS) it says:
* "The placement flexibility for the OPT RR does not * "The placement flexibility for the OPT RR does not
* override the need for the TSIG or SIG(0) RRs to be * override the need for the TSIG or SIG(0) RRs to be
* the last in the additional section whenever they are * the last in the additional section whenever they are
* present." * present."
* So we should not have to check for TSIG RR before * And in RFC8945 (about TSIG) it says:
* OPT RR. Keep the code for backwards compatibility. * "If multiple TSIG records are detected or a TSIG record is
*/ * present in any other position, the DNS message is dropped
* and a response with RCODE 1 (FORMERR) MUST be returned."
/* see if tsig is before edns record */ */
if (!tsig_parse_rr(&q->tsig, q->packet))
return query_formerr(q, nsd);
if(q->tsig.status != TSIG_NOT_PRESENT)
--arcount;
}
/* See if there is an OPT RR. */ /* See if there is an OPT RR. */
if (arcount > 0) { if (arcount > 0) {
if (edns_parse_record(&q->edns, q->packet, q, nsd)) if (edns_parse_record(&q->edns, q->packet, q, nsd))
--arcount; --arcount;
} }
/* See if there is a TSIG RR. */ /* See if there is a TSIG RR. */
if (arcount > 0 && q->tsig.status == TSIG_NOT_PRESENT) { if (arcount > 0 && q->tsig.status == TSIG_NOT_PRESENT) {
/* see if tsig is after the edns record */ /* see if tsig is after the edns record */
if (!tsig_parse_rr(&q->tsig, q->packet)) if (!tsig_parse_rr(&q->tsig, q->packet))
return query_formerr(q, nsd); return query_formerr(q, nsd);
skipping to change at line 1583 skipping to change at line 1652
ARCOUNT_SET(q->packet, 0); ARCOUNT_SET(q->packet, 0);
return QUERY_PROCESSED; return QUERY_PROCESSED;
} }
query_prepare_response(q); query_prepare_response(q);
if (q->qclass != CLASS_IN && q->qclass != CLASS_ANY) { if (q->qclass != CLASS_IN && q->qclass != CLASS_ANY) {
if (q->qclass == CLASS_CH) { if (q->qclass == CLASS_CH) {
return answer_chaos(nsd, q); return answer_chaos(nsd, q);
} else { } else {
return query_error(q, NSD_RC_REFUSE); /* RFC8914 - Extended DNS Errors
* 4.22. Extended DNS Error Code 21 - Not Supported */
q->edns.ede = EDE_NOT_SUPPORTED;
return query_error(q, RCODE_REFUSE);
} }
} }
query_state = answer_axfr_ixfr(nsd, q); query_state = answer_axfr_ixfr(nsd, q);
if (query_state == QUERY_PROCESSED || query_state == QUERY_IN_AXFR) { if (query_state == QUERY_PROCESSED || query_state == QUERY_IN_AXFR) {
return query_state; return query_state;
} }
if(q->qtype == TYPE_ANY && nsd->options->refuse_any && !q->tcp) { if(q->qtype == TYPE_ANY && nsd->options->refuse_any && !q->tcp) {
TC_SET(q->packet); TC_SET(q->packet);
return query_error(q, NSD_RC_OK); return query_error(q, NSD_RC_OK);
} }
answer_query(nsd, q); answer_query(nsd, q);
skipping to change at line 1620 skipping to change at line 1691
if (RCODE(q->packet) == RCODE_FORMAT) { if (RCODE(q->packet) == RCODE_FORMAT) {
return; return;
} }
switch (q->edns.status) { switch (q->edns.status) {
case EDNS_NOT_PRESENT: case EDNS_NOT_PRESENT:
break; break;
case EDNS_OK: case EDNS_OK:
if (q->edns.dnssec_ok) edns->ok[7] = 0x80; if (q->edns.dnssec_ok) edns->ok[7] = 0x80;
else edns->ok[7] = 0x00; else edns->ok[7] = 0x00;
buffer_write(q->packet, edns->ok, OPT_LEN); buffer_write(q->packet, edns->ok, OPT_LEN);
/* Add Extended DNS Error (RFC8914)
* to verify that we stay in bounds */
if (q->edns.ede >= 0)
q->edns.opt_reserved_space +=
6 + ( q->edns.ede_text_len
? q->edns.ede_text_len : 0);
if(q->edns.opt_reserved_space == 0 || !buffer_available( if(q->edns.opt_reserved_space == 0 || !buffer_available(
q->packet, 2+q->edns.opt_reserved_space)) { q->packet, 2+q->edns.opt_reserved_space)) {
/* fill with NULLs */ /* fill with NULLs */
buffer_write(q->packet, edns->rdata_none, OPT_RDATA); buffer_write(q->packet, edns->rdata_none, OPT_RDATA);
} else { } else {
/* rdata length */ /* rdata length */
buffer_write_u16(q->packet, q->edns.opt_reserved_space); buffer_write_u16(q->packet, q->edns.opt_reserved_space);
/* edns options */ /* edns options */
if(q->edns.nsid) { if(q->edns.nsid) {
/* nsid opt header */ /* nsid opt header */
buffer_write(q->packet, edns->nsid, OPT_HDR); buffer_write(q->packet, edns->nsid, OPT_HDR);
/* nsid payload */ /* nsid payload */
buffer_write(q->packet, nsd->nsid, nsd->nsid_len) ; buffer_write(q->packet, nsd->nsid, nsd->nsid_len) ;
} }
/* Append Extended DNS Error (RFC8914) option if needed *
/
if (q->edns.ede >= 0) { /* < 0 means no EDE */
/* OPTION-CODE */
buffer_write_u16(q->packet, EDE_CODE);
/* OPTION-LENGTH */
buffer_write_u16(q->packet,
2 + ( q->edns.ede_text_len
? q->edns.ede_text_len : 0));
/* INFO-CODE */
buffer_write_u16(q->packet, q->edns.ede);
/* EXTRA-TEXT */
if (q->edns.ede_text_len)
buffer_write(q->packet,
q->edns.ede_text,
q->edns.ede_text_len);
}
} }
ARCOUNT_SET(q->packet, ARCOUNT(q->packet) + 1); ARCOUNT_SET(q->packet, ARCOUNT(q->packet) + 1);
STATUP(nsd, edns); STATUP(nsd, edns);
ZTATUP(nsd, q->zone, edns); ZTATUP(nsd, q->zone, edns);
break; break;
case EDNS_ERROR: case EDNS_ERROR:
if (q->edns.dnssec_ok) edns->error[7] = 0x80; if (q->edns.dnssec_ok) edns->error[7] = 0x80;
else edns->error[7] = 0x00; else edns->error[7] = 0x00;
buffer_write(q->packet, edns->error, OPT_LEN); buffer_write(q->packet, edns->error, OPT_LEN);
buffer_write(q->packet, edns->rdata_none, OPT_RDATA); buffer_write(q->packet, edns->rdata_none, OPT_RDATA);
 End of changes. 19 change blocks. 
22 lines changed or deleted 125 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)