echo "I:check prefetch disabled (${n})"
ret=0
$DIG @10.53.0.7 -p 5300 fetch.example.net txt > dig.out.1.${n} || ret=1
-ttl1=`awk '/"A" "short" "ttl"/ { print $2 - 1 }' dig.out.1.${n}`
+ttl1=`awk '/"A" "short" "ttl"/ { print $2 - 2 }' dig.out.1.${n}`
# sleep so we are in expire range
sleep ${ttl1:-0}
-# look for zero ttl, allow for one miss at getting zero ttl
+# look for ttl = 1, allow for one miss at getting zero ttl
zerotonine="0 1 2 3 4 5 6 7 8 9"
for i in $zerotonine $zerotonine $zerotonine $zerotonine
do
$DIG @10.53.0.7 -p 5300 fetch.example.net txt > dig.out.2.${n} || ret=1
ttl2=`awk '/"A" "short" "ttl"/ { print $2 }' dig.out.2.${n}`
- test ${ttl2:-1} -eq 0 && break
+ test ${ttl2:-2} -eq 1 && break
$PERL -e 'select(undef, undef, undef, 0.05);'
done
-test ${ttl2:-1} -eq 0 || ret=1
+test ${ttl2:-2} -eq 1 || ret=1
# delay so that any prefetched record will have a lower ttl than expected
sleep 3
# check that prefetch has not occured
$DIG @10.53.0.7 -p 5300 fetch.example.net txt > dig.out.3.${n} || ret=1
-ttl=`awk '/"A" "short" "ttl"/ { print $2 - 1 }' dig.out.3.${n}`
+ttl=`awk '/"A" "short" "ttl"/ { print $2 - 2 }' dig.out.3.${n}`
test ${ttl:-0} -eq ${ttl1:-1} || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
status=`expr $status + $ret`
n=`expr $n + 1`
-
echo "I:check that E was logged on EDNS queries in the query log (${n})"
ret=0
$DIG @10.53.0.5 -p 5300 +edns edns.fetchall.tld any > dig.out.2.${n} || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
+n=`expr $n + 1`
+echo "I:check zero ttl not returned for learnt non zero ttl records (${n})"
+ret=0
+# use prefetch disabled server
+$DIG @10.53.0.7 -p 5300 non-zero.example.net txt > dig.out.1.${n} || ret=1
+ttl1=`awk '/"A" "short" "ttl"/ { print $2 - 2 }' dig.out.1.${n}`
+# sleep so we are in expire range
+sleep ${ttl1:-0}
+# look for ttl = 1, allow for one miss at getting zero ttl
+zerotonine="0 1 2 3 4 5 6 7 8 9"
+zerotonine="$zerotonine $zerotonine $zerotonine"
+for i in $zerotonine $zerotonine $zerotonine $zerotonine
+do
+ $DIG @10.53.0.7 -p 5300 non-zero.example.net txt > dig.out.2.${n} || ret=1
+ ttl2=`awk '/"A" "short" "ttl"/ { print $2 }' dig.out.2.${n}`
+ test ${ttl2:-1} -eq 0 && break
+ test ${ttl2:-1} -ge ${ttl1:-0} && break
+ $PERL -e 'select(undef, undef, undef, 0.05);'
+done
+test ${ttl2:-1} -eq 0 && ret=1
+test ${ttl2:-1} -ge ${ttl1:-0} || break
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:check zero ttl is returned for learnt zero ttl records (${n})"
+ret=0
+$DIG @10.53.0.7 -p 5300 zero.example.net txt > dig.out.1.${n} || ret=1
+ttl=`awk '/"A" "zero" "ttl"/ { print $2 }' dig.out.1.${n}`
+test ${ttl:-1} -eq 0 || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status
#define RDATASET_ATTR_NEGATIVE 0x0100
#define RDATASET_ATTR_PREFETCH 0x0200
#define RDATASET_ATTR_CASESET 0x0400
+#define RDATASET_ATTR_ZEROTTL 0x0800
typedef struct acache_cbarg {
dns_rdatasetadditional_t type;
(((header)->attributes & RDATASET_ATTR_PREFETCH) != 0)
#define CASESET(header) \
(((header)->attributes & RDATASET_ATTR_CASESET) != 0)
+#define ZEROTTL(header) \
+ (((header)->attributes & RDATASET_ATTR_ZEROTTL) != 0)
#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */
UNUSED(lock);
#endif
- if (header->rdh_ttl < search->now) {
+ if (header->rdh_ttl < search->now ||
+ (header->rdh_ttl == search->now && !ZEROTTL(header))) {
/*
* This rdataset is stale. If no one else is using the
* node, we can clean it up right now, otherwise we mark
newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
rdataset->covers);
newheader->attributes = 0;
+ if (rdataset->ttl == 0U)
+ newheader->attributes |= RDATASET_ATTR_ZEROTTL;
newheader->noqname = NULL;
newheader->closest = NULL;
newheader->count = init_count++;