mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 14:47:09 +00:00
load from cache works
git-svn-id: file:///svn/unbound/trunk@1265 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
67bec33e20
commit
de0f903d37
@ -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;
|
||||
|
@ -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.
|
||||
|
48
services/cache/dns.c
vendored
48
services/cache/dns.c
vendored
@ -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; i<d->count + 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; i<msg->rep->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 */
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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; i<d->count + d->rrsig_count; i++)
|
||||
d->rr_ttl[i] -= now;
|
||||
d->ttl -= now;
|
||||
return ck;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user