diff --git a/edns.c b/edns.c index d77a146e..7a186fde 100644 --- a/edns.c +++ b/edns.c @@ -72,5 +72,6 @@ edns_init_record(edns_record_type *edns) edns->nsid = 0; edns->zoneversion = 0; + edns->cookie_seen = 0; edns->cookie_status = COOKIE_NOT_PRESENT; edns->cookie_len = 0; edns->ede = -1; /* -1 means no Extended DNS Error */ @@ -89,7 +90,7 @@ edns_handle_option(uint16_t optcode, uint16_t optlen, buffer_type* packet, switch(optcode) { case NSID_CODE: /* is NSID enabled? */ - if(nsd->nsid_len > 0) { + if(nsd->nsid_len > 0 && !edns->nsid) { edns->nsid = 1; /* we have to check optlen, and move the buffer along */ buffer_skip(packet, optlen); @@ -102,7 +103,8 @@ edns_handle_option(uint16_t optcode, uint16_t optlen, buffer_type* packet, break; case COOKIE_CODE: /* Cookies enabled? */ - if(nsd->do_answer_cookie) { + if(nsd->do_answer_cookie && !edns->cookie_seen) { + edns->cookie_seen = 1; if (optlen == 8) edns->cookie_status = COOKIE_INVALID; else if (optlen < 16 || optlen > 40) diff --git a/edns.h b/edns.h --- a/edns.h +++ b/edns.h @@ -69,5 +69,6 @@ struct edns_record int nsid; int zoneversion; + int cookie_seen; cookie_status_type cookie_status; size_t cookie_len; uint8_t cookie[40]; diff --git a/query.c b/query.c index 5e5c9361..03cc0bf1 100644 --- a/query.c +++ b/query.c @@ -1783,6 +1783,16 @@ query_process(query_type *q, nsd_type *nsd, uint32_t *now_p) cookie_verify(q, nsd, now_p); query_prepare_response(q); + if(q->reserved_space + QHEADERSZ + (size_t)q->qname->name_size + + 2 /* qtype */ + 2 /* qclass */ > q->maxlen) { + /* Clear out some space, and return error, it does not fit. */ + q->edns.status = EDNS_NOT_PRESENT; + q->tsig.status = TSIG_NOT_PRESENT; + if(q->tcp) + return query_error(q, NSD_RC_SERVFAIL); + TC_SET(q->packet); + return query_error(q, NSD_RC_OK); + } if (q->qclass != CLASS_IN && q->qclass != CLASS_ANY) { if (q->qclass == CLASS_CH) { -- 2.54.0