qstate->return_msg->rep);
if(!reply_info_answer_encode(&qstate->return_msg->qinfo,
qstate->return_msg->rep, 0, qstate->query_flags,
- buf, 0, 1, qstate->env->scratch, 65535, &edns, 1, 0))
+ buf, 0, 1, qstate->env->scratch, 65535, &edns, 1, 0, 1))
return 0;
/* TTLs in the return_msg are relative to time(0) so we have to
}
if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
repinfo->c->buffer, 0, 1, worker->scratchpad,
- udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
+ udpsize, edns, (int)(edns->bits & EDNS_DO), secure, 1)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO),
- *is_secure_answer)) {
+ *is_secure_answer, 1)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo,
NULL, NULL, LDNS_RCODE_SERVFAIL, edns, repinfo,
worker->scratchpad, worker->env.now_tv))
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2),
buf, 0, 0, temp, udpsize, edns,
- (int)(edns->bits&EDNS_DO), 0)) {
+ (int)(edns->bits&EDNS_DO), 0, 0)) {
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
repinfo, temp, env->now_tv) || !reply_info_answer_encode(qinfo, &rep,
*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
- buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
+ buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0, 0)) {
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r->buf, 0, 1,
m->s.env->scratch, udp_size, &r->edns,
- (int)(r->edns.bits & EDNS_DO), secure))
+ (int)(r->edns.bits & EDNS_DO), secure, 0))
{
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
(*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf,
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r_buffer, 0, 1, m->s.env->scratch,
udp_size, &r->edns, (int)(r->edns.bits & EDNS_DO),
- secure))
+ secure, 0))
{
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, &r->start_time))
repinfo, temp, env->now_tv) ||
!reply_info_answer_encode(qinfo, &rep,
*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
- buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
+ buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0, 0)) {
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
/* encode */
unit_assert(
reply_info_answer_encode(qinfo, rep, 1, rep->flags, pkt,
- 0, 0, region, 65535, edns, 0, 0));
+ 0, 0, region, 65535, edns, 0, 0, 0));
/* buffer ready for reading; skip after the question section */
sldns_buffer_skip(pkt, LDNS_HEADER_SIZE);
(void)query_dname_len(pkt);
SECTION QUESTION
example.com. IN A
SECTION ANSWER
- example.com. 0 IN A 5.6.7.8
+ example.com. 1 IN A 5.6.7.8
SECTION AUTHORITY
- example.com. 3590 IN NS ns.example.com.
+ example.com. 3591 IN NS ns.example.com.
SECTION ADDITIONAL
- ns.example.com. 3590 IN A 1.2.3.4
+ ns.example.com. 3591 IN A 1.2.3.4
ENTRY_END
; If a prefetch triggers the test will fail with 'messages pending'.
reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
uint16_t id, uint16_t qflags, sldns_buffer* pkt, time_t timenow,
int cached, struct regional* region, uint16_t udpsize,
- struct edns_data* edns, int dnssec, int secure)
+ struct edns_data* edns, int dnssec, int secure, int cached_ttl)
{
uint16_t flags;
unsigned int attach_edns = 0;
flags &= ~BIT_AD;
}
log_assert(flags & BIT_QR); /* QR bit must be on in our replies */
+ if(cached_ttl && rep->ttl - timenow == 0) {
+ /* The last remaining second of the TTL for a cached response
+ * is replied. This makes a 0 in the protocol message. The
+ * response is valid for the cache, but the DNS TTL 0 item
+ * causes the received to drop the contents. Even though the
+ * contents are cachable, so the time used is decremented
+ * to change that into 1 second, and it can be cached, and
+ * used for expired response generation, and does not give
+ * repeated queries during that last second. */
+ timenow --;
+ }
if(udpsize < LDNS_HEADER_SIZE)
return 0;
/* currently edns does not change during calculations;
* or if edns_present = 0, it is not included.
* @param dnssec: if 0 DNSSEC records are omitted from the answer.
* @param secure: if 1, the AD bit is set in the reply.
+ * @param cached_ttl: the ttl is from a cache response. So that means it
+ * was some value minus the current time, and not an authoritative
+ * response with an autoritative TTL or a direct upstream response,
+ * that could have upstream TTL 0 items.
* @return: 0 on error (server failure).
*/
int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
uint16_t id, uint16_t qflags, struct sldns_buffer* dest, time_t timenow,
int cached, struct regional* region, uint16_t udpsize,
- struct edns_data* edns, int dnssec, int secure);
+ struct edns_data* edns, int dnssec, int secure, int cached_ttl);
/**
* Regenerate the wireformat from the stored msg reply.