#include <netdb.h>
#include <signal.h>
+/** size of ID+FLAGS in a DNS message */
+#define DNS_ID_AND_FLAGS 4
/** timeout in seconds for UDP queries to auth servers. TODO: proper rtt */
#define UDP_QUERY_TIMEOUT 4
verbose(VERB_DETAIL, "reply with error");
ldns_buffer_clear(buf);
- ldns_buffer_write_u16(buf, w->query_id);
+ ldns_buffer_write(buf, &w->query_id, sizeof(uint16_t));
flags = (uint16_t)(0x8000 | r); /* QR and retcode*/
flags |= (w->query_flags & 0x0100); /* copy RD bit */
ldns_buffer_write_u16(buf, flags);
struct work_query* w = (struct work_query*)arg;
struct reply_info* rep;
struct msgreply_entry* e;
- verbose(VERB_DETAIL, "reply to query with stored ID %d", w->query_id);
+ verbose(VERB_DETAIL, "reply to query with stored ID %d",
+ ntohs(w->query_id)); /* byteswapped so same as dig prints */
if(error != 0) {
replyerror(LDNS_RCODE_SERVFAIL, w);
return 0;
replyerror(LDNS_RCODE_SERVFAIL, w);
return 0;
}
- rep->replysize = ldns_buffer_limit(c->buffer) - 2; /* minus ID */
+ rep->flags = ldns_buffer_read_u16_at(c->buffer, 2);
+ rep->replysize = ldns_buffer_limit(c->buffer) - DNS_ID_AND_FLAGS;
log_info("got reply of size %d", rep->replysize);
rep->reply = (uint8_t*)malloc(rep->replysize);
if(!rep->reply) {
replyerror(LDNS_RCODE_SERVFAIL, w);
return 0;
}
- memmove(rep->reply, ldns_buffer_at(c->buffer, 2), rep->replysize);
- ldns_buffer_write_u16_at(w->query_reply.c->buffer, 0, w->query_id);
- reply_info_answer(rep, w->query_flags, w->query_reply.c->buffer);
- comm_point_send_reply(&w->query_reply);
+ memmove(rep->reply, ldns_buffer_at(c->buffer, DNS_ID_AND_FLAGS),
+ rep->replysize);
+ reply_info_answer_iov(rep, w->query_id, w->query_flags,
+ &w->query_reply);
req_release(w);
/* store or update reply in the cache */
if(!(e = query_info_entrysetup(&w->qinfo, rep, w->query_hash))) {
worker_process_query(struct worker* worker, struct work_query* w)
{
/* query the forwarding address */
- verbose(VERB_DETAIL, "process_query ID %d", w->query_id);
+ verbose(VERB_DETAIL, "process_query ID %d", ntohs(w->query_id));
pending_udp_query(worker->back, w->query_reply.c->buffer,
&worker->fwd_addr, worker->fwd_addrlen, UDP_QUERY_TIMEOUT,
worker_handle_reply, w, worker->rndstate);
w->query_hash = h;
memcpy(&w->query_reply, repinfo, sizeof(struct comm_reply));
memcpy(&w->qinfo, &qinfo, sizeof(struct query_info));
- w->query_id = LDNS_ID_WIRE(ldns_buffer_begin(c->buffer));
+ memcpy(&w->query_id, ldns_buffer_begin(c->buffer), sizeof(uint16_t));
w->query_flags = ldns_buffer_read_u16_at(c->buffer, 2);
/* answer it */
uint16_t flags;
ldns_buffer_clear(buffer);
ldns_buffer_skip(buffer, 2); /* ID */
- flags = ldns_read_uint16(rep->reply);
- flags |= (qflags & 0x0100); /* copy RD bit */
+ flags = rep->flags | (qflags & 0x0100); /* copy RD bit */
log_assert(flags & 0x8000); /* QR bit must be on in our replies */
ldns_buffer_write_u16(buffer, flags);
- ldns_buffer_write(buffer, rep->reply+2, rep->replysize-2);
+ ldns_buffer_write(buffer, rep->reply, rep->replysize);
ldns_buffer_flip(buffer);
}
/* [0]=tcp, [1]=id, [2]=flags, [3]=message */
struct iovec iov[4];
- qid = htons(qid);
iov[1].iov_base = &qid;
iov[1].iov_len = sizeof(uint16_t);
- flags = ldns_read_uint16(rep->reply);
- flags |= (qflags & 0x0100); /* copy RD bit */
+ flags = rep->flags | (qflags & 0x0100); /* copy RD bit */
log_assert(flags & 0x8000); /* QR bit must be on in our replies */
flags = htons(flags);
iov[2].iov_base = &flags;
iov[2].iov_len = sizeof(uint16_t);
- iov[3].iov_base = rep->reply+2;
- iov[3].iov_len = rep->replysize-2;
+ iov[3].iov_base = rep->reply;
+ iov[3].iov_len = rep->replysize;
comm_point_send_reply_iov(comrep, iov, 4);
}
* the query (RD,CD if not AA). prepend ID.
*/
struct reply_info {
- /** the reply packet, skips ID, starts with flags/opcode/rcode word */
+ /** the reply packet, skips ID and flags,
+ * starts with opcode/rcode word */
uint8_t* reply;
/** the reply size */
size_t replysize;
+ /** the flags for the answer, host order. */
+ uint16_t flags;
};
/**
/**
* Generate and send out answer from reply_info.
* @param rep: reply to fill in.
- * @param qid: query id.
+ * @param qid: query id, in network byte order.
* @param qflags: flags word from the query.
* @param comrep: communication reply point.
*/