mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
temp region kept for use during query processing.
git-svn-id: file:///svn/unbound/trunk@282 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
44ef71ff6c
commit
c74941e3b8
6 changed files with 27 additions and 24 deletions
|
|
@ -47,6 +47,7 @@
|
||||||
#include "daemon/daemon.h"
|
#include "daemon/daemon.h"
|
||||||
#include "util/netevent.h"
|
#include "util/netevent.h"
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
|
#include "util/region-allocator.h"
|
||||||
#include "util/storage/slabhash.h"
|
#include "util/storage/slabhash.h"
|
||||||
#include "services/listen_dnsport.h"
|
#include "services/listen_dnsport.h"
|
||||||
#include "services/outside_network.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,
|
slabhash_insert(worker->daemon->rrset_cache,
|
||||||
rep->rrsets[i]->entry.hash, &rep->rrsets[i]->entry,
|
rep->rrsets[i]->entry.hash, &rep->rrsets[i]->entry,
|
||||||
rep->rrsets[i]->entry.data, &worker->alloc);
|
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)
|
if(LDNS_QDCOUNT(ldns_buffer_begin(c->buffer)) > 1)
|
||||||
return 0; /* too much in the query section */
|
return 0; /* too much in the query section */
|
||||||
/* woohoo a reply! */
|
/* 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)
|
if(r == LDNS_RCODE_SERVFAIL)
|
||||||
log_err("reply_info_parse: out of memory");
|
log_err("reply_info_parse: out of memory");
|
||||||
/* formerr on my parse gives servfail to my client */
|
/* formerr on my parse gives servfail to my client */
|
||||||
replyerror(LDNS_RCODE_SERVFAIL, w);
|
replyerror(LDNS_RCODE_SERVFAIL, w);
|
||||||
|
region_free_all(w->worker->scratchpad);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!reply_info_answer_encode(&qinf, rep, w->query_id, w->query_flags,
|
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);
|
replyerror(LDNS_RCODE_SERVFAIL, w);
|
||||||
query_info_clear(&qinf);
|
query_info_clear(&qinf);
|
||||||
reply_info_parsedelete(rep, &w->worker->alloc);
|
reply_info_parsedelete(rep, &w->worker->alloc);
|
||||||
|
region_free_all(w->worker->scratchpad);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
comm_point_send_reply(&w->query_reply);
|
comm_point_send_reply(&w->query_reply);
|
||||||
|
region_free_all(w->worker->scratchpad);
|
||||||
req_release(w);
|
req_release(w);
|
||||||
query_info_clear(&w->qinfo);
|
query_info_clear(&w->qinfo);
|
||||||
if(rep->ttl == 0) {
|
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 */
|
/** answer query from the cache */
|
||||||
static int
|
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)
|
uint16_t flags, struct comm_reply* repinfo)
|
||||||
{
|
{
|
||||||
struct msgreply_entry* mrentry = (struct msgreply_entry*)e->key;
|
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. */
|
/* locked and ids and ttls are OK. */
|
||||||
if(!reply_info_answer_encode(&mrentry->key, rep, id, flags,
|
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,
|
replyerror_fillbuf(LDNS_RCODE_SERVFAIL, repinfo, id,
|
||||||
flags, &mrentry->key);
|
flags, &mrentry->key);
|
||||||
}
|
}
|
||||||
/* unlock */
|
/* unlock */
|
||||||
for(i=0; i<rep->rrset_count; i++)
|
for(i=0; i<rep->rrset_count; i++)
|
||||||
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
||||||
|
region_free_all(worker->scratchpad);
|
||||||
/* go and return this buffer to the client */
|
/* go and return this buffer to the client */
|
||||||
return 1;
|
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))) {
|
if((e=slabhash_lookup(worker->daemon->msg_cache, h, &qinfo, 0))) {
|
||||||
/* answer from cache - we have acquired a readlock on it */
|
/* answer from cache - we have acquired a readlock on it */
|
||||||
log_info("answer from the cache");
|
log_info("answer from the cache");
|
||||||
if(answer_from_cache(e,
|
if(answer_from_cache(worker, e,
|
||||||
*(uint16_t*)ldns_buffer_begin(c->buffer),
|
*(uint16_t*)ldns_buffer_begin(c->buffer),
|
||||||
ldns_buffer_read_u16_at(c->buffer, 2), repinfo)) {
|
ldns_buffer_read_u16_at(c->buffer, 2), repinfo)) {
|
||||||
lock_rw_unlock(&e->lock);
|
lock_rw_unlock(&e->lock);
|
||||||
|
|
@ -652,6 +658,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||||
server_stats_init(&worker->stats);
|
server_stats_init(&worker->stats);
|
||||||
alloc_init(&worker->alloc, &worker->daemon->superalloc,
|
alloc_init(&worker->alloc, &worker->daemon->superalloc,
|
||||||
worker->thread_num);
|
worker->thread_num);
|
||||||
|
worker->scratchpad = region_create_custom(malloc, free,
|
||||||
|
65536, 8192, 32, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -684,6 +692,7 @@ worker_delete(struct worker* worker)
|
||||||
close(worker->cmd_recv_fd);
|
close(worker->cmd_recv_fd);
|
||||||
worker->cmd_recv_fd = -1;
|
worker->cmd_recv_fd = -1;
|
||||||
alloc_clear(&worker->alloc);
|
alloc_clear(&worker->alloc);
|
||||||
|
region_destroy(worker->scratchpad);
|
||||||
free(worker);
|
free(worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ struct config_file;
|
||||||
struct daemon;
|
struct daemon;
|
||||||
struct listen_port;
|
struct listen_port;
|
||||||
struct ub_randstate;
|
struct ub_randstate;
|
||||||
|
struct region;
|
||||||
|
|
||||||
/** size of table used for random numbers. large to be more secure. */
|
/** size of table used for random numbers. large to be more secure. */
|
||||||
#define RND_STATE_SIZE 256
|
#define RND_STATE_SIZE 256
|
||||||
|
|
@ -133,6 +134,8 @@ struct worker {
|
||||||
struct alloc_cache alloc;
|
struct alloc_cache alloc;
|
||||||
/** per thread statistics */
|
/** per thread statistics */
|
||||||
struct server_stats stats;
|
struct server_stats stats;
|
||||||
|
/** thread scratch region */
|
||||||
|
struct region* scratchpad;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
alloc cache to store released keys.
|
alloc cache to store released keys.
|
||||||
- alloc cache special_release() locks if necessary.
|
- alloc cache special_release() locks if necessary.
|
||||||
- rrset trustworthiness type added.
|
- rrset trustworthiness type added.
|
||||||
|
- thread keeps a scratchpad region for handling messages.
|
||||||
|
|
||||||
3 May 2007: Wouter
|
3 May 2007: Wouter
|
||||||
- fill refs. Use new parse and encode to answer queries.
|
- fill refs. Use new parse and encode to answer queries.
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,7 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
|
||||||
flags = 0;
|
flags = 0;
|
||||||
else memmove(&flags, ldns_buffer_at(pkt, 2), sizeof(flags));
|
else memmove(&flags, ldns_buffer_at(pkt, 2), sizeof(flags));
|
||||||
flags = ntohs(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(ret != 0) {
|
||||||
if(vbmp) printf("parse code %d: %s\n", ret,
|
if(vbmp) printf("parse code %d: %s\n", ret,
|
||||||
ldns_lookup_by_id(ldns_rcodes, ret)->name);
|
ldns_lookup_by_id(ldns_rcodes, ret)->name);
|
||||||
|
|
|
||||||
|
|
@ -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,
|
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. */
|
/* use scratch pad region-allocator during parsing. */
|
||||||
region_type* region = region_create(malloc, free);
|
|
||||||
struct msg_parse* msg;
|
struct msg_parse* msg;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
qinf->qname = NULL;
|
qinf->qname = NULL;
|
||||||
*rep = NULL;
|
*rep = NULL;
|
||||||
if(!(msg = region_alloc(region, sizeof(*msg)))) {
|
if(!(msg = region_alloc(region, sizeof(*msg)))) {
|
||||||
region_free_all(region);
|
|
||||||
region_destroy(region);
|
|
||||||
return LDNS_RCODE_SERVFAIL;
|
return LDNS_RCODE_SERVFAIL;
|
||||||
}
|
}
|
||||||
memset(msg, 0, sizeof(*msg));
|
memset(msg, 0, sizeof(*msg));
|
||||||
|
|
||||||
log_assert(ldns_buffer_position(pkt) == 0);
|
log_assert(ldns_buffer_position(pkt) == 0);
|
||||||
if((ret = parse_packet(pkt, msg, region)) != 0) {
|
if((ret = parse_packet(pkt, msg, region)) != 0) {
|
||||||
region_free_all(region);
|
|
||||||
region_destroy(region);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -372,14 +367,8 @@ int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc,
|
||||||
query_info_clear(qinf);
|
query_info_clear(qinf);
|
||||||
reply_info_parsedelete(*rep, alloc);
|
reply_info_parsedelete(*rep, alloc);
|
||||||
*rep = NULL;
|
*rep = NULL;
|
||||||
region_free_all(region);
|
|
||||||
region_destroy(region);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* exit and cleanup */
|
|
||||||
region_free_all(region);
|
|
||||||
region_destroy(region);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1075,10 +1064,9 @@ int reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||||
int
|
int
|
||||||
reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||||
uint16_t id, uint16_t qflags, ldns_buffer* pkt, uint32_t timenow,
|
uint16_t id, uint16_t qflags, ldns_buffer* pkt, uint32_t timenow,
|
||||||
int cached)
|
int cached, struct region* region)
|
||||||
{
|
{
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
region_type* region = region_create(malloc, free);
|
|
||||||
|
|
||||||
if(!cached) {
|
if(!cached) {
|
||||||
/* original flags, copy RD bit from query. */
|
/* 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");
|
log_err("reply encode: out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
region_destroy(region);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,12 +184,14 @@ int query_info_parse(struct query_info* m, ldns_buffer* query);
|
||||||
* @param alloc: creates packed rrset key structures.
|
* @param alloc: creates packed rrset key structures.
|
||||||
* @param rep: allocated reply_info is returned (only on no error).
|
* @param rep: allocated reply_info is returned (only on no error).
|
||||||
* @param qinf: query_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
|
* @return: zero is OK, or DNS error code in case of error
|
||||||
* o FORMERR for parse errors.
|
* o FORMERR for parse errors.
|
||||||
* o SERVFAIL for memory allocation errors.
|
* o SERVFAIL for memory allocation errors.
|
||||||
*/
|
*/
|
||||||
int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc,
|
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.
|
* Sorts the ref array.
|
||||||
|
|
@ -253,11 +255,12 @@ hashvalue_t query_info_hash(struct query_info *q);
|
||||||
* @param timenow: time to subtract.
|
* @param timenow: time to subtract.
|
||||||
* @param cached: set true if a cached reply (so no AA bit).
|
* @param cached: set true if a cached reply (so no AA bit).
|
||||||
* set false for the first reply.
|
* set false for the first reply.
|
||||||
|
* @param region: where to allocate temp variables (for compression).
|
||||||
* @return: 0 on error (server failure).
|
* @return: 0 on error (server failure).
|
||||||
*/
|
*/
|
||||||
int reply_info_answer_encode(struct query_info* qinf, 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* dest, uint32_t timenow,
|
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.
|
* Regenerate the wireformat from the stored msg reply.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue