/** answer query from the cache */
static int
-answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
- uint16_t flags, struct comm_reply* repinfo, struct edns_data* edns)
+answer_from_cache(struct worker* worker, struct query_info* qinfo,
+ struct reply_info* rep, uint16_t id, uint16_t flags,
+ struct comm_reply* repinfo, struct edns_data* edns)
{
- struct msgreply_entry* mrentry = (struct msgreply_entry*)e->key;
- struct reply_info* rep = (struct reply_info*)e->data;
uint32_t timenow = *worker->env.now;
uint16_t udpsize = edns->udp_size;
int secure;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
- &mrentry->key, id, flags, edns);
+ qinfo, id, flags, edns);
rrset_array_unlock_touch(worker->env.rrset_cache,
worker->scratchpad, rep->ref, rep->rrset_count);
regional_free_all(worker->scratchpad);
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
- if(!reply_info_answer_encode(&mrentry->key, rep, id, flags,
+ if(!reply_info_answer_encode(qinfo, rep, id, flags,
repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
- &mrentry->key, id, flags, edns);
+ qinfo, id, flags, edns);
}
/* cannot send the reply right now, because blocking network syscall
* is bad while holding locks. */
h = query_info_hash(&qinfo);
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
- if(answer_from_cache(worker, e,
+ if(answer_from_cache(worker, &qinfo,
+ (struct reply_info*)e->data,
*(uint16_t*)ldns_buffer_begin(c->buffer),
ldns_buffer_read_u16_at(c->buffer, 2), repinfo,
&edns)) {
worker->stats.num_query_list_exceeded++;
comm_point_drop_reply(repinfo);
return 0;
- } else if(worker->env.mesh->num_reply_addrs >
- worker->request_size*256) {
+ } else if(worker->env.mesh->num_reply_addrs>worker->request_size*16) {
verbose(VERB_ALGO, "Too many requests queued. "
"dropping incoming query.");
worker->stats.num_query_list_exceeded++;
- delay utility delays TCP as well. If the server that is forwarded
to has a TCP error, the delay utility closes the connection.
- delay does REUSE_ADDR, and can handle a server that closes its end.
+ - answers use casing from query.
25 February 2008: Wouter
- delay utility works. Gets decent thoughput too (>20000).
LDNS_RCODE_SERVFAIL);
}
}
- if(query_dname_compare(qstate->qinfo.qname,
- iq->response->qinfo.qname) == 0) {
- /* use server supplied upper/lower case */
- qstate->qinfo.qname = iq->response->qinfo.qname;
- }
qstate->return_rcode = LDNS_RCODE_NOERROR;
qstate->return_msg = iq->response;
return 0;
if(!s->reply_list && !s->cb_list)
was_noreply = 1;
/* add reply to s */
- if(!mesh_state_add_reply(s, edns, rep, qid, qflags)) {
+ if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo->qname)) {
log_err("mesh_new_client: out of memory; SERVFAIL");
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns);
prev->query_reply.c->buffer);
ldns_buffer_write_at(r->query_reply.c->buffer, 0,
&r->qid, sizeof(uint16_t));
+ ldns_buffer_write_at(r->query_reply.c->buffer, 12,
+ r->qname, m->s.qinfo.qname_len);
comm_point_send_reply(&r->query_reply);
} else if(rcode) {
+ m->s.qinfo.qname = r->qname;
error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
r->qid, r->qflags, &r->edns);
comm_point_send_reply(&r->query_reply);
r->edns.udp_size = EDNS_ADVERTISED_SIZE;
r->edns.ext_rcode = 0;
r->edns.bits &= EDNS_DO;
+ m->s.qinfo.qname = r->qname;
if(!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r->query_reply.c->buffer, 0, 1,
m->s.env->scratch, udp_size, &r->edns,
}
int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
- struct comm_reply* rep, uint16_t qid, uint16_t qflags)
+ struct comm_reply* rep, uint16_t qid, uint16_t qflags, uint8_t* qname)
{
struct mesh_reply* r = regional_alloc(s->s.region,
sizeof(struct mesh_reply));
r->qflags = qflags;
r->start_time = *s->s.env->now_tv;
r->next = s->reply_list;
+ r->qname = regional_alloc_init(s->s.region, qname,
+ s->s.qinfo.qname_len);
+ if(!r->qname)
+ return 0;
s->reply_list = r;
return 1;
uint16_t qid;
/** flags of query, for reply flags */
uint16_t qflags;
+ /** qname from this query. len same as mesh qinfo. */
+ uint8_t* qname;
};
/**
* @param rep: comm point reply info.
* @param qid: ID of reply.
* @param qflags: original query flags.
+ * @param qname: original query name.
* @return: 0 on alloc error.
*/
int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
- struct comm_reply* rep, uint16_t qid, uint16_t qflags);
+ struct comm_reply* rep, uint16_t qid, uint16_t qflags, uint8_t* qname);
/**
* Create new callback structure and attach it to a mesh state.