[sr-dev] git:master: dns cache: dns_cache_rec_pref config var added
Miklos Tirpak
miklos at iptel.org
Wed Jun 23 17:32:14 CEST 2010
Module: sip-router
Branch: master
Commit: 1b30ae44d71332d7e96221ee444a1aede2d3da01
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1b30ae44d71332d7e96221ee444a1aede2d3da01
Author: Miklos Tirpak <miklos at iptel.org>
Committer: Miklos Tirpak <miklos at iptel.org>
Date: Wed Jun 23 16:34:56 2010 +0200
dns cache: dns_cache_rec_pref config var added
The config variable, dns_cache_rec_pref, can be used
to set the DNS cache preference as follows:
0 - do not check duplicates (default)
1 - prefer old records
2 - prefer new records
3 - prefer records with longer lifetime
This variable is checked when a duplicated record is
tried to be inserted into the cache. For instance the
SRV query answer contains also an A record which is
already in the cache.
If the config var is not 0, then permanent entries
are always preferred.
Note: works only with #define CACHE_RELEVANT_RECS_ONLY
at the moment.
---
NEWS | 6 ++++++
cfg_core.c | 7 +++++++
cfg_core.h | 1 +
dns_cache.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/NEWS b/NEWS
index 0112243..5d691cb 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ core:
See dst_blacklist_udp_imask a.s.o (dst_blacklist_*_imask).
- per message blacklist ignore masks
- route() now supports rvalue expressions (e.g. route("test"+$i))
+ - support for permanent entries in the DNS cache.
new config variables:
- dst_blacklist_udp_imask - global blacklist events ignore mask for udp
@@ -27,6 +28,11 @@ new config variables:
- dst_blacklist_tcp_imask - like dst_blacklist_udp_imask, but for tcp.
- dst_blacklist_tls_imask - like dst_blacklist_tls_imask, but for tcp.
- dst_blacklist_sctp_imask -like dst_blacklist_sctp_imask, but for tcp.
+ - dns_cache_rec_pref - DNS cache record preference:
+ 0 - do not check duplicates (default)
+ 1 - prefer old records
+ 2 - prefer new records
+ 3 - prefer records with longer lifetime
modules:
- blst: functions for ignoring blacklist events per message:
diff --git a/cfg_core.c b/cfg_core.c
index 101ba9f..d819dee 100644
--- a/cfg_core.c
+++ b/cfg_core.c
@@ -102,6 +102,7 @@ struct cfg_group_core default_core_cfg = {
DEFAULT_DNS_CACHE_MAX_TTL, /*!< maximum ttl */
DEFAULT_DNS_MAX_MEM, /*!< dns_cache_max_mem */
0, /*!< dns_cache_del_nonexp -- delete only expired entries by default */
+ 0, /*!< dns_cache_rec_pref -- 0 by default, do not check the existing entries. */
#endif
#ifdef PKG_MALLOC
0, /*!< mem_dump_pkg */
@@ -206,6 +207,12 @@ cfg_def_t core_cfg_def[] = {
{"dns_cache_del_nonexp", CFG_VAR_INT, 0, 1, 0, 0,
"allow deletion of non-expired records from the cache when "
"there is no more space left for new ones"},
+ {"dns_cache_rec_pref", CFG_VAR_INT, 0, 3, 0, 0,
+ "DNS cache record preference: "
+ " 0 - do not check duplicates"
+ " 1 - prefer old records"
+ " 2 - prefer new records"
+ " 3 - prefer records with longer lifetime"},
#endif
#ifdef PKG_MALLOC
{"mem_dump_pkg", CFG_VAR_INT, 0, 0, 0, mem_dump_pkg_cb,
diff --git a/cfg_core.h b/cfg_core.h
index 1e86692..c0d83c8 100644
--- a/cfg_core.h
+++ b/cfg_core.h
@@ -92,6 +92,7 @@ struct cfg_group_core {
unsigned int dns_cache_max_ttl;
unsigned int dns_cache_max_mem;
int dns_cache_del_nonexp;
+ int dns_cache_rec_pref;
#endif
#ifdef PKG_MALLOC
int mem_dump_pkg;
diff --git a/dns_cache.c b/dns_cache.c
index 2ec3d3e..adf2940 100644
--- a/dns_cache.c
+++ b/dns_cache.c
@@ -1874,10 +1874,14 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
struct ip_addr* ip;
str cname_val;
char name_buf[MAX_DNS_NAME];
+ struct dns_hash_entry* old;
+ str rec_name;
+ int add_record, h, err;
e=0;
l=0;
cname_val.s=0;
+ old = NULL;
#ifdef USE_DNS_CACHE_STATS
if (dns_cache_stats)
@@ -1944,10 +1948,55 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
LOCK_DNS_HASH(); /* optimization */
for (r=l; r; r=t){
t=r->next;
- 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);
}
}
More information about the sr-dev
mailing list