Browse code

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.

Miklos Tirpak authored on 23/06/2010 15:27:41
Showing 1 changed files
... ...
@@ -2048,10 +2048,56 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
2048 2048
 												  to it */
2049 2049
 				}
2050 2050
 			}
2051
-			dns_cache_add_unsafe(r); /* refcnt++ inside */
2052
-			if (atomic_get(&r->refcnt)==0){
2053
-				/* if cache adding failed and nobody else is interested
2054
-				 * destroy this entry */
2051
+
2052
+			/* add the new record to the cache by default */
2053
+			add_record = 1;
2054
+			if (cfg_get(core, core_cfg, dns_cache_rec_pref) > 0) {
2055
+				/* check whether there is an old record with the
2056
+				 * same type in the cache */
2057
+				rec_name.s = r->name;
2058
+				rec_name.len = r->name_len;
2059
+				old = _dns_hash_find(&rec_name, r->type, &h, &err);
2060
+				if (old) {
2061
+					if (old->type != r->type) {
2062
+						/* probably CNAME found */
2063
+						old = NULL;
2064
+
2065
+					} else if (old->ent_flags & DNS_FLAG_PERMANENT) {
2066
+						/* never overwrite permanent entries */
2067
+						add_record = 0;
2068
+
2069
+					} else if ((old->ent_flags & DNS_FLAG_BAD_NAME) == 0) {
2070
+						/* Non-negative, non-permanent entry found with
2071
+						 * the same type. */
2072
+						add_record =
2073
+							/* prefer new records */
2074
+							((cfg_get(core, core_cfg, dns_cache_rec_pref) == 2)
2075
+							/* prefer the record with the longer lifetime */
2076
+							|| ((cfg_get(core, core_cfg, dns_cache_rec_pref) == 3)
2077
+								&& TICKS_LT(old->expire, r->expire)));
2078
+					}
2079
+				}
2080
+			}
2081
+			if (add_record) {
2082
+				dns_cache_add_unsafe(r); /* refcnt++ inside */
2083
+				if (atomic_get(&r->refcnt)==0){
2084
+					/* if cache adding failed and nobody else is interested
2085
+					 * destroy this entry */
2086
+					dns_destroy_entry(r);
2087
+				}
2088
+				if (old) {
2089
+					_dns_hash_remove(old);
2090
+					old = NULL;
2091
+				}
2092
+			} else {
2093
+				if (old) {
2094
+					if (r == e) {
2095
+						/* this entry has to be returned */
2096
+						e = old;
2097
+						atomic_inc(&e->refcnt);
2098
+					}
2099
+					old = NULL;
2100
+				}
2055 2101
 				dns_destroy_entry(r);
2056 2102
 			}
2057 2103
 		}