Przeglądaj źródła

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 15 lat temu
rodzic
commit
0ce55adcdf
1 zmienionych plików z 50 dodań i 4 usunięć
  1. 50 4
      dns_cache.c

+ 50 - 4
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);
 			}
 		}