Module: sip-router Branch: master Commit: 0ce55adcdf00d5a04faf8ed26e019a9fac3b7db6 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=0ce55adc...
Author: Miklos Tirpak miklos@iptel.org Committer: Miklos Tirpak miklos@iptel.org Date: Wed Jun 23 17:27:41 2010 +0200
dns cache: dns_cache_rec_pref without #define CACHE_RELEVANT_RECS_ONLY
Added support for the dns_cache_rec_pref config variable when CACHE_RELEVANT_RECS_ONLY is not defined.
---
dns_cache.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/dns_cache.c b/dns_cache.c index adf2940..a501e3e 100644 --- a/dns_cache.c +++ b/dns_cache.c @@ -2048,10 +2048,56 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type) to it */ } } - dns_cache_add_unsafe(r); /* refcnt++ inside */ - if (atomic_get(&r->refcnt)==0){ - /* if cache adding failed and nobody else is interested - * destroy this entry */ + + /* add the new record to the cache by default */ + add_record = 1; + if (cfg_get(core, core_cfg, dns_cache_rec_pref) > 0) { + /* check whether there is an old record with the + * same type in the cache */ + rec_name.s = r->name; + rec_name.len = r->name_len; + old = _dns_hash_find(&rec_name, r->type, &h, &err); + if (old) { + if (old->type != r->type) { + /* probably CNAME found */ + old = NULL; + + } else if (old->ent_flags & DNS_FLAG_PERMANENT) { + /* never overwrite permanent entries */ + add_record = 0; + + } else if ((old->ent_flags & DNS_FLAG_BAD_NAME) == 0) { + /* Non-negative, non-permanent entry found with + * the same type. */ + add_record = + /* prefer new records */ + ((cfg_get(core, core_cfg, dns_cache_rec_pref) == 2) + /* prefer the record with the longer lifetime */ + || ((cfg_get(core, core_cfg, dns_cache_rec_pref) == 3) + && TICKS_LT(old->expire, r->expire))); + } + } + } + if (add_record) { + dns_cache_add_unsafe(r); /* refcnt++ inside */ + if (atomic_get(&r->refcnt)==0){ + /* if cache adding failed and nobody else is interested + * destroy this entry */ + dns_destroy_entry(r); + } + if (old) { + _dns_hash_remove(old); + old = NULL; + } + } else { + if (old) { + if (r == e) { + /* this entry has to be returned */ + e = old; + atomic_inc(&e->refcnt); + } + old = NULL; + } dns_destroy_entry(r); } }