From: Wouter Wijngaards Date: Fri, 4 May 2007 12:35:01 +0000 (+0000) Subject: temp region kept for use during query processing. X-Git-Tag: release-0.3~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c74941e3b8dd585f061b2024950b6cea9f819347;p=thirdparty%2Funbound.git temp region kept for use during query processing. git-svn-id: file:///svn/unbound/trunk@282 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/worker.c b/daemon/worker.c index a5cde258a..09fe3b945 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -47,6 +47,7 @@ #include "daemon/daemon.h" #include "util/netevent.h" #include "util/config_file.h" +#include "util/region-allocator.h" #include "util/storage/slabhash.h" #include "services/listen_dnsport.h" #include "services/outside_network.h" @@ -188,7 +189,7 @@ worker_store_rrsets(struct worker* worker, struct reply_info* rep) slabhash_insert(worker->daemon->rrset_cache, rep->rrsets[i]->entry.hash, &rep->rrsets[i]->entry, rep->rrsets[i]->entry.data, &worker->alloc); - /* TODO store correct key and id */ + if(e) rep->rrsets[i] = rep->ref[i].key; } } @@ -217,21 +218,25 @@ worker_handle_reply(struct comm_point* c, void* arg, int error, if(LDNS_QDCOUNT(ldns_buffer_begin(c->buffer)) > 1) return 0; /* too much in the query section */ /* woohoo a reply! */ - if((r=reply_info_parse(c->buffer, &w->worker->alloc, &qinf, &rep))!=0) { + if((r=reply_info_parse(c->buffer, &w->worker->alloc, &qinf, &rep, + w->worker->scratchpad))!=0) { if(r == LDNS_RCODE_SERVFAIL) log_err("reply_info_parse: out of memory"); /* formerr on my parse gives servfail to my client */ replyerror(LDNS_RCODE_SERVFAIL, w); + region_free_all(w->worker->scratchpad); return 0; } if(!reply_info_answer_encode(&qinf, rep, w->query_id, w->query_flags, - w->query_reply.c->buffer, 0, 0)) { + w->query_reply.c->buffer, 0, 0, w->worker->scratchpad)) { replyerror(LDNS_RCODE_SERVFAIL, w); query_info_clear(&qinf); reply_info_parsedelete(rep, &w->worker->alloc); + region_free_all(w->worker->scratchpad); return 0; } comm_point_send_reply(&w->query_reply); + region_free_all(w->worker->scratchpad); req_release(w); query_info_clear(&w->qinfo); if(rep->ttl == 0) { @@ -339,7 +344,7 @@ worker_handle_control_cmd(struct comm_point* c, void* arg, int error, /** answer query from the cache */ static int -answer_from_cache(struct lruhash_entry* e, uint16_t id, +answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id, uint16_t flags, struct comm_reply* repinfo) { struct msgreply_entry* mrentry = (struct msgreply_entry*)e->key; @@ -366,13 +371,14 @@ answer_from_cache(struct lruhash_entry* e, uint16_t id, } /* locked and ids and ttls are OK. */ if(!reply_info_answer_encode(&mrentry->key, rep, id, flags, - repinfo->c->buffer, timenow, 1)) { + repinfo->c->buffer, timenow, 1, worker->scratchpad)) { replyerror_fillbuf(LDNS_RCODE_SERVFAIL, repinfo, id, flags, &mrentry->key); } /* unlock */ for(i=0; irrset_count; i++) lock_rw_unlock(&rep->ref[i].key->entry.lock); + region_free_all(worker->scratchpad); /* go and return this buffer to the client */ return 1; } @@ -415,7 +421,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, if((e=slabhash_lookup(worker->daemon->msg_cache, h, &qinfo, 0))) { /* answer from cache - we have acquired a readlock on it */ log_info("answer from the cache"); - if(answer_from_cache(e, + if(answer_from_cache(worker, e, *(uint16_t*)ldns_buffer_begin(c->buffer), ldns_buffer_read_u16_at(c->buffer, 2), repinfo)) { lock_rw_unlock(&e->lock); @@ -652,6 +658,8 @@ worker_init(struct worker* worker, struct config_file *cfg, server_stats_init(&worker->stats); alloc_init(&worker->alloc, &worker->daemon->superalloc, worker->thread_num); + worker->scratchpad = region_create_custom(malloc, free, + 65536, 8192, 32, 1); return 1; } @@ -684,6 +692,7 @@ worker_delete(struct worker* worker) close(worker->cmd_recv_fd); worker->cmd_recv_fd = -1; alloc_clear(&worker->alloc); + region_destroy(worker->scratchpad); free(worker); } diff --git a/daemon/worker.h b/daemon/worker.h index 210889564..50e9722d4 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -55,6 +55,7 @@ struct config_file; struct daemon; struct listen_port; struct ub_randstate; +struct region; /** size of table used for random numbers. large to be more secure. */ #define RND_STATE_SIZE 256 @@ -133,6 +134,8 @@ struct worker { struct alloc_cache alloc; /** per thread statistics */ struct server_stats stats; + /** thread scratch region */ + struct region* scratchpad; }; /** diff --git a/doc/Changelog b/doc/Changelog index faa53bebb..5aec95598 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -5,6 +5,7 @@ alloc cache to store released keys. - alloc cache special_release() locks if necessary. - rrset trustworthiness type added. + - thread keeps a scratchpad region for handling messages. 3 May 2007: Wouter - fill refs. Use new parse and encode to answer queries. diff --git a/testcode/unitmsgparse.c b/testcode/unitmsgparse.c index 14e943b8d..fe5221204 100644 --- a/testcode/unitmsgparse.c +++ b/testcode/unitmsgparse.c @@ -258,7 +258,7 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, flags = 0; else memmove(&flags, ldns_buffer_at(pkt, 2), sizeof(flags)); flags = ntohs(flags); - ret = reply_info_parse(pkt, alloc, &qi, &rep); + ret = reply_info_parse(pkt, alloc, &qi, &rep, region); if(ret != 0) { if(vbmp) printf("parse code %d: %s\n", ret, ldns_lookup_by_id(ldns_rcodes, ret)->name); diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 8dc0687cd..727bdd653 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -343,26 +343,21 @@ parse_create_msg(ldns_buffer* pkt, struct msg_parse* msg, } int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc, - struct query_info* qinf, struct reply_info** rep) + struct query_info* qinf, struct reply_info** rep, struct region* region) { /* use scratch pad region-allocator during parsing. */ - region_type* region = region_create(malloc, free); struct msg_parse* msg; int ret; qinf->qname = NULL; *rep = NULL; if(!(msg = region_alloc(region, sizeof(*msg)))) { - region_free_all(region); - region_destroy(region); return LDNS_RCODE_SERVFAIL; } memset(msg, 0, sizeof(*msg)); log_assert(ldns_buffer_position(pkt) == 0); if((ret = parse_packet(pkt, msg, region)) != 0) { - region_free_all(region); - region_destroy(region); return ret; } @@ -372,14 +367,8 @@ int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc, query_info_clear(qinf); reply_info_parsedelete(*rep, alloc); *rep = NULL; - region_free_all(region); - region_destroy(region); return ret; } - - /* exit and cleanup */ - region_free_all(region); - region_destroy(region); return 0; } @@ -1075,10 +1064,9 @@ int reply_info_encode(struct query_info* qinfo, struct reply_info* rep, int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, uint16_t id, uint16_t qflags, ldns_buffer* pkt, uint32_t timenow, - int cached) + int cached, struct region* region) { uint16_t flags; - region_type* region = region_create(malloc, free); if(!cached) { /* original flags, copy RD bit from query. */ @@ -1093,7 +1081,6 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, log_err("reply encode: out of memory"); return 0; } - region_destroy(region); return 1; } diff --git a/util/data/msgreply.h b/util/data/msgreply.h index e356d0d1f..857733ffe 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -184,12 +184,14 @@ int query_info_parse(struct query_info* m, ldns_buffer* query); * @param alloc: creates packed rrset key structures. * @param rep: allocated reply_info is returned (only on no error). * @param qinf: query_info is returned (only on no error). + * @param region: where to store temporary data (for parsing). * @return: zero is OK, or DNS error code in case of error * o FORMERR for parse errors. * o SERVFAIL for memory allocation errors. */ int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc, - struct query_info* qinf, struct reply_info** rep); + struct query_info* qinf, struct reply_info** rep, + struct region* region); /** * Sorts the ref array. @@ -253,11 +255,12 @@ hashvalue_t query_info_hash(struct query_info *q); * @param timenow: time to subtract. * @param cached: set true if a cached reply (so no AA bit). * set false for the first reply. + * @param region: where to allocate temp variables (for compression). * @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, ldns_buffer* dest, uint32_t timenow, - int cached); + int cached, struct region* region); /** * Regenerate the wireformat from the stored msg reply.