No useless byteswapping.

git-svn-id: file:///svn/unbound/trunk@208 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-03-29 10:00:10 +00:00
parent e082f2ac48
commit 41463a62ae
6 changed files with 26 additions and 21 deletions

View file

@ -57,6 +57,8 @@
#include <netdb.h> #include <netdb.h>
#include <signal.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 */ /** timeout in seconds for UDP queries to auth servers. TODO: proper rtt */
#define UDP_QUERY_TIMEOUT 4 #define UDP_QUERY_TIMEOUT 4
@ -99,7 +101,7 @@ replyerror(int r, struct work_query* w)
verbose(VERB_DETAIL, "reply with error"); verbose(VERB_DETAIL, "reply with error");
ldns_buffer_clear(buf); 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 = (uint16_t)(0x8000 | r); /* QR and retcode*/
flags |= (w->query_flags & 0x0100); /* copy RD bit */ flags |= (w->query_flags & 0x0100); /* copy RD bit */
ldns_buffer_write_u16(buf, flags); ldns_buffer_write_u16(buf, flags);
@ -126,7 +128,8 @@ worker_handle_reply(struct comm_point* c, void* arg, int error,
struct work_query* w = (struct work_query*)arg; struct work_query* w = (struct work_query*)arg;
struct reply_info* rep; struct reply_info* rep;
struct msgreply_entry* e; 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) { if(error != 0) {
replyerror(LDNS_RCODE_SERVFAIL, w); replyerror(LDNS_RCODE_SERVFAIL, w);
return 0; return 0;
@ -145,7 +148,8 @@ worker_handle_reply(struct comm_point* c, void* arg, int error,
replyerror(LDNS_RCODE_SERVFAIL, w); replyerror(LDNS_RCODE_SERVFAIL, w);
return 0; 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); log_info("got reply of size %d", rep->replysize);
rep->reply = (uint8_t*)malloc(rep->replysize); rep->reply = (uint8_t*)malloc(rep->replysize);
if(!rep->reply) { if(!rep->reply) {
@ -154,10 +158,10 @@ worker_handle_reply(struct comm_point* c, void* arg, int error,
replyerror(LDNS_RCODE_SERVFAIL, w); replyerror(LDNS_RCODE_SERVFAIL, w);
return 0; return 0;
} }
memmove(rep->reply, ldns_buffer_at(c->buffer, 2), rep->replysize); memmove(rep->reply, ldns_buffer_at(c->buffer, DNS_ID_AND_FLAGS),
ldns_buffer_write_u16_at(w->query_reply.c->buffer, 0, w->query_id); rep->replysize);
reply_info_answer(rep, w->query_flags, w->query_reply.c->buffer); reply_info_answer_iov(rep, w->query_id, w->query_flags,
comm_point_send_reply(&w->query_reply); &w->query_reply);
req_release(w); req_release(w);
/* store or update reply in the cache */ /* store or update reply in the cache */
if(!(e = query_info_entrysetup(&w->qinfo, rep, w->query_hash))) { if(!(e = query_info_entrysetup(&w->qinfo, rep, w->query_hash))) {
@ -174,7 +178,7 @@ static void
worker_process_query(struct worker* worker, struct work_query* w) worker_process_query(struct worker* worker, struct work_query* w)
{ {
/* query the forwarding address */ /* 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, pending_udp_query(worker->back, w->query_reply.c->buffer,
&worker->fwd_addr, worker->fwd_addrlen, UDP_QUERY_TIMEOUT, &worker->fwd_addr, worker->fwd_addrlen, UDP_QUERY_TIMEOUT,
worker_handle_reply, w, worker->rndstate); worker_handle_reply, w, worker->rndstate);
@ -325,7 +329,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
w->query_hash = h; w->query_hash = h;
memcpy(&w->query_reply, repinfo, sizeof(struct comm_reply)); memcpy(&w->query_reply, repinfo, sizeof(struct comm_reply));
memcpy(&w->qinfo, &qinfo, sizeof(struct query_info)); 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); w->query_flags = ldns_buffer_read_u16_at(c->buffer, 2);
/* answer it */ /* answer it */

View file

@ -76,7 +76,7 @@ struct work_query {
struct query_info qinfo; struct query_info qinfo;
/** hash value of the query qinfo */ /** hash value of the query qinfo */
hashvalue_t query_hash; hashvalue_t query_hash;
/** id of query */ /** id of query, in network byteorder. */
uint16_t query_id; uint16_t query_id;
/** flags uint16 from query */ /** flags uint16 from query */
uint16_t query_flags; uint16_t query_flags;

View file

@ -1,6 +1,8 @@
29 March 2007: Wouter 29 March 2007: Wouter
- writev or sendmsg used when answering from cache. - writev or sendmsg used when answering from cache.
This avoids a copy of the data. This avoids a copy of the data.
- do not do useless byteswap on query id. Store reply flags in uint16
for easier access (and no repeated byteswapping).
28 March 2007: Wouter 28 March 2007: Wouter
- new config option: num-queries-per-thread. - new config option: num-queries-per-thread.

View file

@ -3,4 +3,3 @@ o use real entropy to make random (ID, port) numbers more random.
o in production mode, do not free memory on exit. In debug mode, test leaks. o in production mode, do not free memory on exit. In debug mode, test leaks.
o profile memory allocation, and if performance issues, use special memory o profile memory allocation, and if performance issues, use special memory
allocator. For example, with caches per thread. allocator. For example, with caches per thread.
o do not do useless byteswap on query_id value. store qflags in uint16.

View file

@ -175,11 +175,10 @@ void reply_info_answer(struct reply_info* rep, uint16_t qflags,
uint16_t flags; uint16_t flags;
ldns_buffer_clear(buffer); ldns_buffer_clear(buffer);
ldns_buffer_skip(buffer, 2); /* ID */ ldns_buffer_skip(buffer, 2); /* ID */
flags = ldns_read_uint16(rep->reply); flags = rep->flags | (qflags & 0x0100); /* copy RD bit */
flags |= (qflags & 0x0100); /* copy RD bit */
log_assert(flags & 0x8000); /* QR bit must be on in our replies */ log_assert(flags & 0x8000); /* QR bit must be on in our replies */
ldns_buffer_write_u16(buffer, flags); 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); ldns_buffer_flip(buffer);
} }
@ -191,17 +190,15 @@ reply_info_answer_iov(struct reply_info* rep, uint16_t qid,
/* [0]=tcp, [1]=id, [2]=flags, [3]=message */ /* [0]=tcp, [1]=id, [2]=flags, [3]=message */
struct iovec iov[4]; struct iovec iov[4];
qid = htons(qid);
iov[1].iov_base = &qid; iov[1].iov_base = &qid;
iov[1].iov_len = sizeof(uint16_t); iov[1].iov_len = sizeof(uint16_t);
flags = ldns_read_uint16(rep->reply); flags = rep->flags | (qflags & 0x0100); /* copy RD bit */
flags |= (qflags & 0x0100); /* copy RD bit */
log_assert(flags & 0x8000); /* QR bit must be on in our replies */ log_assert(flags & 0x8000); /* QR bit must be on in our replies */
flags = htons(flags); flags = htons(flags);
iov[2].iov_base = &flags; iov[2].iov_base = &flags;
iov[2].iov_len = sizeof(uint16_t); iov[2].iov_len = sizeof(uint16_t);
iov[3].iov_base = rep->reply+2; iov[3].iov_base = rep->reply;
iov[3].iov_len = rep->replysize-2; iov[3].iov_len = rep->replysize;
comm_point_send_reply_iov(comrep, iov, 4); comm_point_send_reply_iov(comrep, iov, 4);
} }

View file

@ -67,10 +67,13 @@ struct query_info {
* the query (RD,CD if not AA). prepend ID. * the query (RD,CD if not AA). prepend ID.
*/ */
struct reply_info { 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; uint8_t* reply;
/** the reply size */ /** the reply size */
size_t replysize; size_t replysize;
/** the flags for the answer, host order. */
uint16_t flags;
}; };
/** /**
@ -147,7 +150,7 @@ void reply_info_answer(struct reply_info* rep, uint16_t qflags,
/** /**
* Generate and send out answer from reply_info. * Generate and send out answer from reply_info.
* @param rep: reply to fill in. * @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 qflags: flags word from the query.
* @param comrep: communication reply point. * @param comrep: communication reply point.
*/ */