From de0f903d375cdd4a1c544f1404d8f975bc07cbcd Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Tue, 23 Sep 2008 09:23:38 +0000 Subject: [PATCH] load from cache works git-svn-id: file:///svn/unbound/trunk@1265 be551aaa-1e26-0410-a405-d3ace91eadb9 --- daemon/cachedump.c | 139 +++++++++++++++++++++---------------- doc/Changelog | 3 + services/cache/dns.c | 48 ++----------- smallapp/unbound-control.c | 2 +- util/data/packed_rrset.c | 37 ++++++++++ util/data/packed_rrset.h | 13 ++++ 6 files changed, 139 insertions(+), 103 deletions(-) diff --git a/daemon/cachedump.c b/daemon/cachedump.c index b07576add..6b04f10d6 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -86,7 +86,7 @@ to_rr(struct ub_packed_rrset_key* k, struct packed_rrset_data* d, /** dump one rrset zonefile line */ static int dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, - struct packed_rrset_data* d, uint32_t now, int i, uint16_t type) + struct packed_rrset_data* d, uint32_t now, size_t i, uint16_t type) { char* s; ldns_rr* rr = to_rr(k, d, now, i, type); @@ -598,45 +598,100 @@ load_rrset_cache(SSL* ssl, struct worker* worker) return 1; } +/** read qinfo from next three words */ +static char* +load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf, + struct regional* region, SSL* ssl) +{ + /* s is part of the buf */ + char* s = str; + ldns_rr* rr; + ldns_status status; + + /* skip three words */ + s = strchr(str, ' '); + if(s) s = strchr(s+1, ' '); + if(s) s = strchr(s+1, ' '); + if(!s) { + (void)ssl_printf(ssl, "error line too short, %s\n", str); + return NULL; + } + s[0] = 0; + s++; + + /* parse them */ + status = ldns_rr_new_question_frm_str(&rr, str, NULL, NULL); + if(status != LDNS_STATUS_OK) { + (void)ssl_printf(ssl, "error cannot parse: %s %s\n", + ldns_get_errorstr_by_id(status), str); + return NULL; + } + qinfo->qtype = ldns_rr_get_type(rr); + qinfo->qclass = ldns_rr_get_class(rr); + ldns_buffer_clear(buf); + status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr)); + if(status != LDNS_STATUS_OK) { + (void)ssl_printf(ssl, "error cannot dname2wire: %s\n", + ldns_get_errorstr_by_id(status)); + ldns_rr_free(rr); + return NULL; + } + ldns_rr_free(rr); + ldns_buffer_flip(buf); + qinfo->qname_len = ldns_buffer_limit(buf); + qinfo->qname = (uint8_t*)regional_alloc_init(region, + ldns_buffer_begin(buf), ldns_buffer_limit(buf)); + if(!qinfo->qname) { + (void)ssl_printf(ssl, "error out of memory\n"); + return NULL; + } + + return s; +} + /** load a msg rrset reference */ static int load_ref(SSL* ssl, ldns_buffer* buf, struct worker* worker, struct regional *region, struct ub_packed_rrset_key** rrset, int* go_on) { - ldns_rr* rr; - ldns_status status; char* s = (char*)ldns_buffer_begin(buf); + struct query_info qinfo; + unsigned int flags; + struct ub_packed_rrset_key* k; /* read line */ if(!ssl_read_buf(ssl, buf)) return 0; + if(strncmp(s, "BADREF", 6) == 0) { + *go_on = 0; /* its bad, skip it and skip message */ + return 1; + } - s += 4; - /* skip three words */ - s = strchr(s, ' '); - if(s) s = strchr(s+1, ' '); - if(s) s = strchr(s+1, ' '); + s = load_qinfo(s, &qinfo, buf, region, ssl); if(!s) { - (void)ssl_printf(ssl, "error ref line too short, %s\n", s); return 0; } - s[0] = 0; - - status = ldns_rr_new_question_frm_str(&rr, - (char*)ldns_buffer_begin(buf), NULL, NULL); - if(status != LDNS_STATUS_OK) { - (void)ssl_printf(ssl, "error cannot parse ref: %s %s\n", - ldns_get_errorstr_by_id(status), s); - ldns_rr_free(rr); + if(sscanf(s, " %u", &flags) != 1) { + (void)ssl_printf(ssl, "error cannot parse flags: %s\n", s); return 0; } - ldns_rr_free(rr); - /* lookup in cache */ + k = rrset_cache_lookup(worker->env.rrset_cache, qinfo.qname, + qinfo.qname_len, qinfo.qtype, qinfo.qclass, + (uint32_t)flags, *worker->env.now, 0); + if(!k) { + /* not found or expired */ + *go_on = 0; + return 1; + } + /* store in result */ - return 1; + *rrset = packed_rrset_copy_region(k, region, *worker->env.now); + lock_rw_unlock(&k->entry.lock); + + return (*rrset != NULL); } /** load a msg entry */ @@ -647,8 +702,6 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker) struct query_info qinf; struct reply_info rep; char* s = (char*)ldns_buffer_begin(buf); - ldns_rr* rr; - ldns_status status; unsigned int flags, qdcount, ttl, security, an, ns, ar; size_t i; int go_on = 1; @@ -660,51 +713,15 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker) return 0; } s += 4; - /* skip three words */ - s = strchr(s, ' '); - if(s) s = strchr(s+1, ' '); - if(s) s = strchr(s+1, ' '); + s = load_qinfo(s, &qinf, buf, region, ssl); if(!s) { - (void)ssl_printf(ssl, "error msg line too short, %s\n", s); - return 0; - } - s[0] = 0; - - status = ldns_rr_new_question_frm_str(&rr, - (char*)ldns_buffer_at(buf, 4), NULL, NULL); - if(status != LDNS_STATUS_OK) { - (void)ssl_printf(ssl, "error cannot parse query: %s %s\n", - ldns_get_errorstr_by_id(status), s); - ldns_rr_free(rr); return 0; } /* read remainder of line */ - if(sscanf(s+1, " %u %u %u %u %u %u %u", &flags, &qdcount, &ttl, + if(sscanf(s, " %u %u %u %u %u %u %u", &flags, &qdcount, &ttl, &security, &an, &ns, &ar) != 7) { - (void)ssl_printf(ssl, "error cannot parse numbers: %s\n", s+1); - ldns_rr_free(rr); - return 0; - } - - /* fill qinfo and repinfo */ - qinf.qtype = ldns_rr_get_type(rr); - qinf.qclass = ldns_rr_get_class(rr); - ldns_buffer_clear(buf); - status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr)); - if(status != LDNS_STATUS_OK) { - (void)ssl_printf(ssl, "error cannot dname2wire: %s\n", - ldns_get_errorstr_by_id(status)); - ldns_rr_free(rr); - return 0; - } - ldns_rr_free(rr); - ldns_buffer_flip(buf); - qinf.qname_len = ldns_buffer_limit(buf); - qinf.qname = (uint8_t*)regional_alloc_init(region, - ldns_buffer_begin(buf), ldns_buffer_limit(buf)); - if(!qinf.qname) { - (void)ssl_printf(ssl, "error out of memory\n"); + (void)ssl_printf(ssl, "error cannot parse numbers: %s\n", s); return 0; } rep.flags = (uint16_t)flags; diff --git a/doc/Changelog b/doc/Changelog index cadc87eb8..0bf4454ab 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,6 @@ +23 September 2008: Wouter + - Msg cache is loaded. A cache load enables cache responses. + 22 September 2008: Wouter - dump_cache and load_cache statements in unbound-control. RRsets are dumped and loaded correctly. diff --git a/services/cache/dns.c b/services/cache/dns.c index bea8182dc..d9251165e 100644 --- a/services/cache/dns.c +++ b/services/cache/dns.c @@ -101,41 +101,6 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo, slabhash_insert(env->msg_cache, hash, &e->entry, rep, env->alloc); } -/** allocate rrset in region - no more locks needed */ -static struct ub_packed_rrset_key* -copy_rrset(struct ub_packed_rrset_key* key, struct regional* region, - uint32_t now) -{ - struct ub_packed_rrset_key* ck = regional_alloc(region, - sizeof(struct ub_packed_rrset_key)); - struct packed_rrset_data* d; - struct packed_rrset_data* data = (struct packed_rrset_data*) - key->entry.data; - size_t dsize, i; - if(!ck) - return NULL; - ck->id = key->id; - memset(&ck->entry, 0, sizeof(ck->entry)); - ck->entry.hash = key->entry.hash; - ck->entry.key = ck; - ck->rk = key->rk; - ck->rk.dname = regional_alloc_init(region, key->rk.dname, - key->rk.dname_len); - if(!ck->rk.dname) - return NULL; - dsize = packed_rrset_sizeof(data); - d = (struct packed_rrset_data*)regional_alloc_init(region, data, dsize); - if(!d) - return NULL; - ck->entry.data = d; - packed_rrset_ptr_fixup(d); - /* make TTLs relative - once per rrset */ - for(i=0; icount + d->rrsig_count; i++) - d->rr_ttl[i] -= now; - d->ttl -= now; - return ck; -} - /** find closest NS or DNAME and returns the rrset (locked) */ static struct ub_packed_rrset_key* find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen, @@ -171,7 +136,7 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region, struct dns_msg* msg, uint32_t now) { if((msg->rep->rrsets[msg->rep->rrset_count] = - copy_rrset(rrset, region, now))) { + packed_rrset_copy_region(rrset, region, now))) { msg->rep->ar_numrrsets++; msg->rep->rrset_count++; } @@ -271,7 +236,7 @@ find_add_ds(struct module_env* env, struct regional* region, if(rrset) { /* add it to auth section. This is the second rrset. */ if((msg->rep->rrsets[msg->rep->rrset_count] = - copy_rrset(rrset, region, now))) { + packed_rrset_copy_region(rrset, region, now))) { msg->rep->ns_numrrsets++; msg->rep->rrset_count++; } @@ -314,7 +279,7 @@ create_msg(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, (2 + nsdata->count*2)*sizeof(struct ub_packed_rrset_key*)); if(!msg->rep->rrsets) return NULL; - msg->rep->rrsets[0] = copy_rrset(nskey, region, now); + msg->rep->rrsets[0] = packed_rrset_copy_region(nskey, region, now); if(!msg->rep->rrsets[0]) return NULL; msg->rep->ns_numrrsets++; @@ -414,7 +379,8 @@ tomsg(struct module_env* env, struct msgreply_entry* e, struct reply_info* r, if(!rrset_array_lock(r->ref, r->rrset_count, now)) return NULL; for(i=0; irep->rrset_count; i++) { - msg->rep->rrsets[i] = copy_rrset(r->rrsets[i], region, now); + msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i], + region, now); if(!msg->rep->rrsets[i]) { rrset_array_unlock(r->ref, r->rrset_count); return NULL; @@ -446,7 +412,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region, msg->rep->ns_numrrsets = 0; msg->rep->ar_numrrsets = 0; msg->rep->rrset_count = 1; - msg->rep->rrsets[0] = copy_rrset(rrset, region, now); + msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now); if(!msg->rep->rrsets[0]) /* copy CNAME */ return NULL; return msg; @@ -480,7 +446,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region, msg->rep->ns_numrrsets = 0; msg->rep->ar_numrrsets = 0; msg->rep->rrset_count = 1; - msg->rep->rrsets[0] = copy_rrset(rrset, region, now); + msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now); if(!msg->rep->rrsets[0]) /* copy DNAME */ return NULL; /* synth CNAME rrset */ diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index 65fcbe682..c1d04a585 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -203,7 +203,7 @@ setup_ssl(SSL_CTX* ctx, int fd) static void send_file(SSL* ssl, FILE* in, char* buf, size_t sz) { - while(fgets(buf, sz, in)) { + while(fgets(buf, (int)sz, in)) { if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0) ssl_err("could not SSL_write contents"); } diff --git a/util/data/packed_rrset.c b/util/data/packed_rrset.c index 19b77a461..199bf01a2 100644 --- a/util/data/packed_rrset.c +++ b/util/data/packed_rrset.c @@ -45,6 +45,7 @@ #include "util/storage/lookup3.h" #include "util/log.h" #include "util/alloc.h" +#include "util/regional.h" void ub_packed_rrset_parsedelete(struct ub_packed_rrset_key* pkey, @@ -262,3 +263,39 @@ ub_packed_rrset_ttl(struct ub_packed_rrset_key* key) entry.data; return d->ttl; } + +/** allocate rrset in region - no more locks needed */ +struct ub_packed_rrset_key* +packed_rrset_copy_region(struct ub_packed_rrset_key* key, + struct regional* region, uint32_t now) +{ + struct ub_packed_rrset_key* ck = regional_alloc(region, + sizeof(struct ub_packed_rrset_key)); + struct packed_rrset_data* d; + struct packed_rrset_data* data = (struct packed_rrset_data*) + key->entry.data; + size_t dsize, i; + if(!ck) + return NULL; + ck->id = key->id; + memset(&ck->entry, 0, sizeof(ck->entry)); + ck->entry.hash = key->entry.hash; + ck->entry.key = ck; + ck->rk = key->rk; + ck->rk.dname = regional_alloc_init(region, key->rk.dname, + key->rk.dname_len); + if(!ck->rk.dname) + return NULL; + dsize = packed_rrset_sizeof(data); + d = (struct packed_rrset_data*)regional_alloc_init(region, data, dsize); + if(!d) + return NULL; + ck->entry.data = d; + packed_rrset_ptr_fixup(d); + /* make TTLs relative - once per rrset */ + for(i=0; icount + d->rrsig_count; i++) + d->rr_ttl[i] -= now; + d->ttl -= now; + return ck; +} + diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h index 0a796c04a..b61f87534 100644 --- a/util/data/packed_rrset.h +++ b/util/data/packed_rrset.h @@ -43,6 +43,7 @@ #define UTIL_DATA_PACKED_RRSET_H #include "util/storage/lruhash.h" struct alloc_cache; +struct regional; /** type used to uniquely identify rrsets. Cannot be reused without * clearing the cache. */ @@ -363,4 +364,16 @@ const char* rrset_trust_to_string(enum rrset_trust s); */ const char* sec_status_to_string(enum sec_status s); +/** + * Allocate rrset in region - no more locks needed + * @param key: a (just from rrset cache looked up) rrset key + valid, + * packed data record. + * @param region: where to alloc the copy + * @param now: adjust the TTLs to be relative (subtract from all TTLs). + * @return new region-alloced rrset key or NULL on alloc failure. + */ +struct ub_packed_rrset_key* packed_rrset_copy_region( + struct ub_packed_rrset_key* key, struct regional* region, + uint32_t now); + #endif /* UTIL_DATA_PACKED_RRSET_H */