+22 August 2007: Wouter
+ - bogus TTL.
+
21 August 2007: Wouter
- ANY response validation.
- store security status in cache.
# Do not set this unless you are debugging signature inception
# and expiration. "" or "0" turns the feature off.
# val-override-date: ""
+
+ # The time to live for bogus data, rrsets and messages. This avoids
+ # some of the revalidation, until the time interval expires. in secs.
+ # val-bogus-ttl: 900
# Stub zones.
# Create entries like below, to make all queries for 'example.com' and
giving a RRSIG style date, that date is used for verifying RRSIG inception
and expiration dates, instead of the current date. Do not set this unless
you are debugging signature inception and expiration.
+.It \fBval-bogus-ttl:\fR <number>
+The time to live for bogus data. This is data that has failed validation;
+due to invalid signatures or other checks. The TTL from that data cannot be
+trusted, and this value is used instead. The value is in seconds, default 900.
+The time interval prevents repeated revalidation of bogus data.
.El
.Ss Stub Zone Options
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
/* o if current RRset is more trustworthy - insert it */
- if( newd->trust > cached->trust )
+ if( newd->trust > cached->trust ) {
+ /* if the cached rrset is bogus, and this one equal,
+ * do not update the TTL - let it expire. */
+ if(equal && cached->ttl >= timenow &&
+ cached->security == sec_status_bogus)
+ return 0;
return 1;
+ }
/* o item in cache has expired */
if( cached->ttl < timenow )
return 1;
/* if so, see if rrset+rdata is the same */
/* if so, update TTL in cache, even if trust is worse. */
if( newd->ttl > cached->ttl && equal ) {
+ /* if the cached rrset is bogus, and this one equal,
+ * do not update the TTL - let it expire. */
+ if(cached->security == sec_status_bogus)
+ return 0;
/* since all else is the same, use the best trust value */
if(newd->trust < cached->trust) {
newd->trust = cached->trust;
cfg->rrset_cache_slabs = 4;
cfg->host_ttl = 900;
cfg->lame_ttl = 900;
+ cfg->bogus_ttl = 900;
cfg->infra_cache_slabs = 4;
cfg->infra_cache_numhosts = 1000;
cfg->infra_cache_numlame = 1000;
/** if not 0, this value is the validation date for RRSIGs */
int32_t val_date_override;
+ /** this value sets the number of seconds before revalidating bogus */
+ int bogus_ttl;
/** daemonize, i.e. fork into the background. */
int do_daemonize;
trust-anchor-file{COLON} { YDOUT; return VAR_TRUST_ANCHOR_FILE;}
trust-anchor{COLON} { YDOUT; return VAR_TRUST_ANCHOR;}
val-override-date{COLON} { YDOUT; return VAR_VAL_OVERRIDE_DATE;}
+val-bogus-ttl{COLON} { YDOUT; return VAR_BOGUS_TTL;}
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
/* Quoted strings. Strip leading and ending quotes */
%token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
%token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
%token VAR_TRUST_ANCHOR_FILE VAR_TRUST_ANCHOR VAR_VAL_OVERRIDE_DATE
+%token VAR_BOGUS_TTL
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
server_do_not_query_address | server_hide_identity |
server_hide_version | server_identity | server_version |
server_harden_glue | server_module_conf | server_trust_anchor_file |
- server_trust_anchor | server_val_override_date
+ server_trust_anchor | server_val_override_date | server_bogus_ttl
;
stubstart: VAR_STUB_ZONE
{
free($2);
}
;
+server_bogus_ttl: VAR_BOGUS_TTL STRING
+ {
+ OUTYY(("P(server_bogus_ttl:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else cfg_parser->cfg->bogus_ttl = atoi($2);
+ free($2);
+ }
+ ;
+
stub_name: VAR_NAME STRING
{
OUTYY(("P(name:%s)\n", $2));
*/
#include "config.h"
#include "validator/val_utils.h"
+#include "validator/validator.h"
#include "validator/val_kentry.h"
#include "validator/val_sigcrypt.h"
#include "util/data/msgreply.h"
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
/* update rrset security status
- * only improves security status */
+ * only improves security status
+ * and bogus is set only once, even if we rechecked the status */
if(sec > d->security) {
d->security = sec;
if(sec == sec_status_secure)
d->trust = rrset_trust_validated;
+ else if(sec == sec_status_bogus) {
+ /* update ttl for rrset to fixed value. */
+ d->ttl = time(0) + ve->bogus_ttl;
+ /* leave RR specific TTL: not used for determine
+ * if RRset timed out and clients see proper value. */
+ }
}
return sec;
static int
val_apply_cfg(struct val_env* val_env, struct config_file* cfg)
{
+ val_env->bogus_ttl = (uint32_t)cfg->bogus_ttl;
if(!val_env->anchors)
val_env->anchors = anchors_create();
if(!val_env->anchors) {
*
* @param qstate: query state.
* @param vq: validator query state.
+ * @param ve: validator shared global environment.
* @param id: module id.
* @return true if the event should be processed further on return, false if
* not.
*/
static int
-processFinished(struct module_qstate* qstate, struct val_qstate* vq, int id)
+processFinished(struct module_qstate* qstate, struct val_qstate* vq,
+ struct val_env* ve, int id)
{
/* TODO CNAME query restarts */
+ /* if the result is bogus - set message ttl to bogus ttl to avoid
+ * endless bogus revalidation */
+ if(vq->chase_reply->security == sec_status_bogus) {
+ vq->chase_reply->ttl = time(0) + ve->bogus_ttl;
+ }
+
/* store results in cache */
if(!dns_cache_store(qstate->env, &vq->qchase, vq->chase_reply, 0)) {
log_err("out of memory caching validator results");
cont = processValidate(qstate, vq, ve, id);
break;
case VAL_FINISHED_STATE:
- cont = processFinished(qstate, vq, id);
+ cont = processFinished(qstate, vq, ve, id);
break;
default:
log_warn("validator: invalid state %d",
/** for debug testing a fixed validation date can be entered.
* if 0, current time is used for rrsig validation */
int32_t date_override;
+
+ /** TTL for bogus data; used instead of untrusted TTL from data.
+ * Bogus data will not be verified more often than this interval.
+ * seconds. */
+ uint32_t bogus_ttl;
};
/**