X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fmdnsd.git;a=blobdiff_plain;f=cache.c;h=b5653dd4f02bac38d6598498817da82409e225d4;hp=b244dae14ef75fc103dc99e12c33fe897d799366;hb=d9a8000d2e08085132a5832db0480323c509ad22;hpb=788316ef66136e6a68d881e5b24ccf5a98fa4550 diff --git a/cache.c b/cache.c index b244dae..b5653dd 100644 --- a/cache.c +++ b/cache.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "cache.h" @@ -40,21 +41,16 @@ #include "dns.h" static struct uloop_timeout cache_gc; -struct avl_tree records, entries, types, hosts; +struct avl_tree records, entries, hosts; static struct blob_buf b; +static struct kvlist types; + static void -cache_record_free(struct cache_record *r, int rem) +cache_record_free(struct cache_record *r) { DBG(2, "%s %s\n", dns_type_string(r->type), r->record); - if (rem) - avl_delete(&records, &r->avl); - if (r->record) - free(r->record); - if (r->rdata) - free(r->rdata); - if (r->txt) - free(r->txt); + avl_delete(&records, &r->avl); free(r); } @@ -63,10 +59,6 @@ cache_entry_free(struct cache_entry *s) { DBG(2, "%s\n", s->entry); avl_delete(&entries, &s->avl); - if (s->host) - free(s->host); - if (s->entry) - free(s->entry); free(s); } @@ -87,7 +79,7 @@ cache_gc_timer(struct uloop_timeout *timeout) avl_for_each_element_safe(&records, r, avl, p) if (cache_is_expired(r->time, r->ttl)) - cache_record_free(r, 1); + cache_record_free(r); avl_for_each_element_safe(&entries, s, avl, t) { if (!s->host) @@ -103,41 +95,28 @@ static void cache_load_services(void) { struct blob_attr *cur; - int rem; + int rem; - blob_buf_init(&b, 0); + blob_buf_init(&b, 0); if (!blobmsg_add_json_from_file(&b, "/lib/mdns/service-types")) return; - blob_for_each_attr(cur, b.head, rem) { - struct cache_type *t = malloc(sizeof(struct cache_type)); - - if (!t) - continue; - t->avl.key = t->key = strdup(blobmsg_name(cur)); - t->val = strdup(blobmsg_get_string(cur)); - avl_insert(&types, &t->avl); - } + blob_for_each_attr(cur, b.head, rem) + kvlist_set(&types, blobmsg_name(cur), blobmsg_get_string(cur)); } char* cache_lookup_name(const char *key) { - struct cache_type *t; - - t = avl_find_element(&types, key, t, avl); - if (!t) - return NULL; - - return t->val; + return kvlist_get(&types, key); } int cache_init(void) { + kvlist_init(&types, kvlist_strlen); avl_init(&entries, avl_strcmp, true, NULL); - avl_init(&types, avl_strcmp, false, NULL); avl_init(&records, avl_strcmp, true, NULL); cache_gc.cb = cache_gc_timer; @@ -153,7 +132,7 @@ void cache_cleanup(void) struct cache_entry *s, *t; avl_for_each_element_safe(&records, r, avl, p) - cache_record_free(r, 1); + cache_record_free(r); avl_for_each_element_safe(&entries, s, avl, t) cache_entry_free(s); @@ -169,35 +148,29 @@ cache_scan(void) } static struct cache_entry* -cache_find_entry(char *entry) -{ - struct cache_entry *s; - - avl_for_each_element(&entries, s, avl) - if (!strcmp(s->entry, entry)) - return s; - return NULL; -} - -static struct cache_entry* cache_entry(struct uloop_fd *u, char *entry, int hlen, int ttl) { struct cache_entry *s; + char *entry_buf; + char *host_buf; char *type; - s = cache_find_entry(entry); + s = avl_find_element(&entries, entry, s, avl); if (s) return s; - s = malloc(sizeof(struct cache_entry)); - memset(s, 0, sizeof(struct cache_entry)); - s->avl.key = s->entry = strdup(entry); + s = calloc_a(sizeof(*s), + &entry_buf, strlen(entry) + 1, + &host_buf, hlen ? hlen + 1 : 0); + + s->avl.key = s->entry = strcpy(entry_buf, entry); s->time = time(NULL); s->ttl = ttl; if (hlen) - s->host = strndup(s->entry, hlen); - type = strstr(s->entry, "._"); + s->host = strncpy(host_buf, s->entry, hlen); + + type = strstr(entry_buf, "._"); if (type) type++; if (type) @@ -273,6 +246,8 @@ cache_answer(struct uloop_fd *u, uint8_t *base, int blen, char *name, struct dns struct cache_record *r; int port = 0, dlen = 0, tlen = 0, nlen, rdlength; char *p = NULL; + char *name_buf; + void *rdata_ptr, *txt_ptr; if (!(a->class & CLASS_IN)) return; @@ -351,7 +326,7 @@ cache_answer(struct uloop_fd *u, uint8_t *base, int blen, char *name, struct dns r = cache_record_find(name, a->type, port, dlen, rdata); if (r) { if (!a->ttl) { - cache_record_free(r, 1); + cache_record_free(r); DBG(1, "D -> %s %s ttl:%d\n", dns_type_string(r->type), r->record, r->ttl); } else { r->ttl = a->ttl; @@ -363,32 +338,26 @@ cache_answer(struct uloop_fd *u, uint8_t *base, int blen, char *name, struct dns if (!a->ttl) return; - r = malloc(sizeof(struct cache_record)); - memset(r, 0, sizeof(struct cache_record)); - r->avl.key = r->record = strdup(name); + r = calloc_a(sizeof(*r), + &name_buf, strlen(name) + 1, + &txt_ptr, tlen, + &rdata_ptr, dlen); + + r->avl.key = r->record = strcpy(name_buf, name); r->type = a->type; r->ttl = a->ttl; r->port = port; r->rdlength = dlen; r->time = time(NULL); - if (tlen) { - r->txt = malloc(tlen); - if (r->txt) - memcpy(r->txt, rdata_buffer, tlen); - } + if (tlen) + r->txt = memcpy(txt_ptr, rdata_buffer, tlen); - if (dlen) { - r->rdata = malloc(dlen); - if (!r->rdata) { - cache_record_free(r, 0); - return; - } - memcpy(r->rdata, rdata, dlen); - } + if (dlen) + r->rdata = memcpy(rdata_ptr, rdata, dlen); if (avl_insert(&records, &r->avl)) - cache_record_free(r, 0); + free(r); else DBG(1, "A -> %s %s ttl:%d\n", dns_type_string(r->type), r->record, r->ttl); }