/** convert data from return_msg into the data buffer */ static int prep_data(struct module_qstate* qstate, struct sldns_buffer* buf) { uint64_t timestamp, expiry; size_t oldlim; struct edns_data edns; memset(&edns, 0, sizeof(edns)); edns.edns_present = 1; edns.bits = EDNS_DO; edns.ext_rcode = 0; edns.edns_version = EDNS_ADVERTISED_VERSION; edns.udp_size = EDNS_ADVERTISED_SIZE; if(!qstate->return_msg || !qstate->return_msg->rep) return 0; /* We don't store the reply if its TTL is 0 unless serve-expired is * enabled. Such a reply won't be reusable and simply be a waste for * the backend. It's also compatible with the default behavior of * dns_cache_store_msg(). */ if(qstate->return_msg->rep->ttl == 0 && !qstate->env->cfg->serve_expired) return 0; if(verbosity >= VERB_ALGO) log_dns_msg("cachedb encoding", &qstate->return_msg->qinfo, 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)) return 0; /* TTLs in the return_msg are relative to time(0) so we have to * store that, we also store the smallest ttl in the packet+time(0) * as the packet expiry time */ /* qstate->return_msg->rep->ttl contains that relative shortest ttl */ timestamp = (uint64_t)*qstate->env->now; expiry = timestamp + (uint64_t)qstate->return_msg->rep->ttl; timestamp = htobe64(timestamp); expiry = htobe64(expiry); oldlim = sldns_buffer_limit(buf); if(oldlim + sizeof(timestamp)+sizeof(expiry) >= sldns_buffer_capacity(buf)) return 0; /* doesn't fit. */ sldns_buffer_set_limit(buf, oldlim + sizeof(timestamp)+sizeof(expiry)); sldns_buffer_write_at(buf, oldlim, ×tamp, sizeof(timestamp)); sldns_buffer_write_at(buf, oldlim+sizeof(timestamp), &expiry, sizeof(expiry)); return 1; }
static int deny_refuse(struct comm_point* c, enum acl_access acl, enum acl_access deny, enum acl_access refuse, struct worker* worker, struct comm_reply* repinfo) { if(acl == deny) { comm_point_drop_reply(repinfo); if(worker->stats.extended) worker->stats.unwanted_queries++; return 0; } else if(acl == refuse) { log_addr(VERB_ALGO, "refused query from", &repinfo->addr, repinfo->addrlen); log_buf(VERB_ALGO, "refuse", c->buffer); if(worker->stats.extended) worker->stats.unwanted_queries++; if(worker_check_request(c->buffer, worker) == -1) { comm_point_drop_reply(repinfo); return 0; /* discard this */ } sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE); sldns_buffer_write_at(c->buffer, 4, (uint8_t*)"\0\0\0\0\0\0\0\0", 8); LDNS_QR_SET(sldns_buffer_begin(c->buffer)); LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), LDNS_RCODE_REFUSED); return 1; } return -1; }
/** test query_dname_tolower */ static void dname_test_qdtl(sldns_buffer* buff) { unit_show_func("util/data/dname.c", "query_dname_tolower"); sldns_buffer_write_at(buff, 0, "\012abCDeaBCde\003cOm\000", 16); query_dname_tolower(sldns_buffer_begin(buff)); unit_assert( memcmp(sldns_buffer_begin(buff), "\012abcdeabcde\003com\000", 16) == 0); sldns_buffer_write_at(buff, 0, "\001+\012abC{e-ZYXe\003NET\000", 18); query_dname_tolower(sldns_buffer_begin(buff)); unit_assert( memcmp(sldns_buffer_begin(buff), "\001+\012abc{e-zyxe\003net\000", 18) == 0); sldns_buffer_write_at(buff, 0, "\000", 1); query_dname_tolower(sldns_buffer_begin(buff)); unit_assert( memcmp(sldns_buffer_begin(buff), "\000", 1) == 0); sldns_buffer_write_at(buff, 0, "\002NL\000", 4); query_dname_tolower(sldns_buffer_begin(buff)); unit_assert( memcmp(sldns_buffer_begin(buff), "\002nl\000", 4) == 0); }