Browse code

- DNS cache measurements added

Gergely Kovacs authored on 31/07/2007 13:27:09
Showing 2 changed files
... ...
@@ -22,8 +22,8 @@
22 22
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 23
  * GNU General Public License for more details.
24 24
  *
25
- * You should have received a copy of the GNU General Public License 
26
- * along with this program; if not, write to the Free Software 
25
+ * You should have received a copy of the GNU General Public License
26
+ * along with this program; if not, write to the Free Software
27 27
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 28
  */
29 29
 /* History:
... ...
@@ -37,6 +37,7 @@
37 37
  *              that the DNS servers are down (Miklos)
38 38
  *  2008-07-25  various rpc commands to manipulate the content
39 39
  *		of the cache (Miklos)
40
+ *  2007-07-30  DNS cache measurements added (Gergo)
40 41
  */
41 42
 
42 43
 #ifdef USE_DNS_CACHE
... ...
@@ -60,6 +61,9 @@
60 60
 #include "error.h"
61 61
 #include "rpc.h"
62 62
 #include "rand/fastrand.h"
63
+#ifdef USE_DNS_CACHE_STATS
64
+#include "pt.h"
65
+#endif
63 66
 
64 67
 
65 68
 
... ...
@@ -70,7 +74,7 @@
70 70
 	#define MAX(a,b) ( ((a)>(b))?(a):(b))
71 71
 #endif
72 72
 
73
-#define MAX_DNS_RECORDS 255  /* maximum dns records number  received in a 
73
+#define MAX_DNS_RECORDS 255  /* maximum dns records number  received in a
74 74
 							   dns answer*/
75 75
 
76 76
 #define DNS_HASH_SIZE	1024 /* must be <= 65535 */
... ...
@@ -80,7 +84,7 @@
80 80
 #define DEFAULT_DNS_MAX_MEM 500 /* 500 Kb */
81 81
 #define DEFAULT_DNS_TIMER_INTERVAL 120  /* 2 min. */
82 82
 #define DNS_HE_MAX_ADDR 10  /* maxium addresses returne in a hostent struct */
83
-#define MAX_CNAME_CHAIN  10 
83
+#define MAX_CNAME_CHAIN  10
84 84
 
85 85
 
86 86
 static gen_lock_t* dns_hash_lock=0;
... ...
@@ -91,10 +95,14 @@ unsigned int dns_neg_cache_ttl=DEFAULT_DNS_NEG_CACHE_TTL; /* neg. cache ttl */
91 91
 unsigned int dns_cache_max_ttl=DEFAULT_DNS_CACHE_MAX_TTL; /* maximum ttl */
92 92
 unsigned int dns_cache_min_ttl=DEFAULT_DNS_CACHE_MIN_TTL; /* minimum ttl */
93 93
 unsigned int dns_timer_interval=DEFAULT_DNS_TIMER_INTERVAL; /* in s */
94
-int dns_flags=0; /* default flags used for the  dns_*resolvehost 
94
+int dns_flags=0; /* default flags used for the  dns_*resolvehost
95 95
                     (compatibility wrappers) */
96 96
 int dns_srv_lb=0; /* off by default */
97 97
 
98
+#ifdef USE_DNS_CACHE_STATS
99
+struct t_dns_cache_stats* dns_cache_stats=0;
100
+#endif
101
+
98 102
 #define LOCK_DNS_HASH()		lock_get(dns_hash_lock)
99 103
 #define UNLOCK_DNS_HASH()	lock_release(dns_hash_lock)
100 104
 
... ...
@@ -135,7 +143,7 @@ static const char* dns_str_errors[]={
135 135
 	"blacklisted ip",
136 136
 	"name too long ", /* try again with a shorter name */
137 137
 	"ip AF mismatch", /* address family mismatch */
138
-	"unresolvable NAPTR request", 
138
+	"unresolvable NAPTR request",
139 139
 	"bug - critical error"
140 140
 };
141 141
 
... ...
@@ -206,7 +214,7 @@ static ticks_t dns_timer(ticks_t ticks, struct timer_ln* tl, void* data)
206 206
 		return (ticks_t)(-1);
207 207
 #endif
208 208
 	if (*dns_cache_mem_used>12*(dns_cache_max_mem/16)){ /* ~ 75% used */
209
-		dns_cache_free_mem(dns_cache_max_mem/2, 1); 
209
+		dns_cache_free_mem(dns_cache_max_mem/2, 1);
210 210
 	}else{
211 211
 		dns_cache_clean(-1, 1); /* all the table, only expired entries */
212 212
 		/* TODO: better strategy? */
... ...
@@ -244,6 +252,10 @@ void destroy_dns_cache()
244 244
 		dns_last_used_lst=0;
245 245
 	}
246 246
 #endif
247
+#ifdef USE_DNS_CACHE_STATS
248
+	if (dns_cache_stats)
249
+		shm_free(dns_cache_stats);
250
+#endif
247 251
 	if (dns_cache_mem_used){
248 252
 		shm_free((void*)dns_cache_mem_used);
249 253
 		dns_cache_mem_used=0;
... ...
@@ -256,7 +268,7 @@ int init_dns_cache()
256 256
 {
257 257
 	int r;
258 258
 	int ret;
259
-	
259
+
260 260
 	ret=0;
261 261
 	/* sanity check */
262 262
 	if (E_DNS_CRITICAL>=sizeof(dns_str_errors)/sizeof(char*)){
... ...
@@ -284,7 +296,7 @@ int init_dns_cache()
284 284
 	}
285 285
 	for (r=0; r<DNS_HASH_SIZE; r++)
286 286
 		clist_init(&dns_hash[r], next, prev);
287
-	
287
+
288 288
 	dns_hash_lock=lock_alloc();
289 289
 	if (dns_hash_lock==0){
290 290
 		ret=E_OUT_OF_MEM;
... ...
@@ -305,7 +317,7 @@ int init_dns_cache()
305 305
 	}
306 306
 	atomic_set(dns_servers_up, 1);
307 307
 #endif
308
-	
308
+
309 309
 	/* fix options */
310 310
 	dns_cache_max_mem<<=10; /* Kb */ /* TODO: test with 0 */
311 311
 	/* fix flags */
... ...
@@ -344,13 +356,28 @@ int init_dns_cache()
344 344
 			goto error;
345 345
 		}
346 346
 	}
347
-	
347
+
348 348
 	return 0;
349 349
 error:
350 350
 	destroy_dns_cache();
351 351
 	return ret;
352 352
 }
353 353
 
354
+#ifdef USE_DNS_CACHE_STATS
355
+int init_dns_cache_stats(int iproc_num) {
356
+	/* if it is already initialized */
357
+	if (dns_cache_stats)
358
+		shm_free(dns_cache_stats);
359
+
360
+	dns_cache_stats=shm_malloc(sizeof(*dns_cache_stats) * iproc_num);
361
+	if (dns_cache_stats==0){
362
+		return E_OUT_OF_MEM;
363
+	}
364
+	memset(dns_cache_stats, 0, sizeof(*dns_cache_stats) * iproc_num);
365
+
366
+	return 0;
367
+}
368
+#endif
354 369
 
355 370
 /* hash function, type is not used (obsolete)
356 371
  * params: char* s, int len, int type
... ...
@@ -375,7 +402,7 @@ error:
375 375
 					(l), (l)->next, (l)->prev, \
376 376
 					(l)->prev, (l)->prev->next, (l)->prev->prev, \
377 377
 					(l)->next, (l)->next->next, (l)->next->prev \
378
-				) 
378
+				)
379 379
 
380 380
 #define debug_lu_lst( txt, l) \
381 381
 	do{ \
... ...
@@ -446,7 +473,7 @@ inline static struct dns_hash_entry* _dns_hash_find(str* name, int type,
446 446
 
447 447
 	servers_up = atomic_get(dns_servers_up);
448 448
 #endif
449
-	
449
+
450 450
 	cname_chain=0;
451 451
 	ret=0;
452 452
 	now=get_ticks_raw();
... ...
@@ -496,7 +523,7 @@ again:
496 496
 			debug_lu_lst("_dns_hash_find: cname: post append:",
497 497
 							&e->last_used_lst);
498 498
 #endif
499
-#endif		
499
+#endif
500 500
 			ret=e; /* if this is an unfinished cname chain, we try to
501 501
 					  return the last cname */
502 502
 			/* this is a cname => retry using its value */
... ...
@@ -519,7 +546,7 @@ again:
519 519
 
520 520
 
521 521
 
522
-/* frees cache entries, if expired_only=0 only expired entries will be 
522
+/* frees cache entries, if expired_only=0 only expired entries will be
523 523
  * removed, else all of them
524 524
  * it will process maximum no entries (to process all of them use -1)
525 525
  * returns the number of deleted entries
... ...
@@ -538,7 +565,7 @@ inline static int dns_cache_clean(unsigned int no, int expired_only)
538 538
 	unsigned int h;
539 539
 	static unsigned int start=0;
540 540
 #endif
541
-	
541
+
542 542
 	n=0;
543 543
 	deleted=0;
544 544
 	now=get_ticks_raw();
... ...
@@ -587,9 +614,9 @@ skip:
587 587
 
588 588
 
589 589
 
590
-/* frees cache entries, if expired_only=0 only expired entries will be 
590
+/* frees cache entries, if expired_only=0 only expired entries will be
591 591
  * removed, else all of them
592
- * it will stop when the dns cache used memory reaches target (to process all 
592
+ * it will stop when the dns cache used memory reaches target (to process all
593 593
  * of them use 0)
594 594
  * returns the number of deleted entries */
595 595
 inline static int dns_cache_free_mem(unsigned int target, int expired_only)
... ...
@@ -605,7 +632,7 @@ inline static int dns_cache_free_mem(unsigned int target, int expired_only)
605 605
 	unsigned int h;
606 606
 	static unsigned int start=0;
607 607
 #endif
608
-	
608
+
609 609
 	deleted=0;
610 610
 	now=get_ticks_raw();
611 611
 	LOCK_DNS_HASH();
... ...
@@ -622,7 +649,7 @@ inline static int dns_cache_free_mem(unsigned int target, int expired_only)
622 622
 #else
623 623
 	for(h=start; h!=(start+DNS_HASH_SIZE); h++){
624 624
 		clist_foreach_safe(&dns_hash[h%DNS_HASH_SIZE], e, t, next){
625
-			if (*dns_cache_mem_used<=target) 
625
+			if (*dns_cache_mem_used<=target)
626 626
 				goto skip;
627 627
 			if  ((s_ticks_t)(now-e->expire)>=0){
628 628
 				_dns_hash_remove(e);
... ...
@@ -634,7 +661,7 @@ inline static int dns_cache_free_mem(unsigned int target, int expired_only)
634 634
 	if (!expired_only){
635 635
 		for(h=start; h!=(start+DNS_HASH_SIZE); h++){
636 636
 			clist_foreach_safe(&dns_hash[h%DNS_HASH_SIZE], e, t, next){
637
-				if (*dns_cache_mem_used<=target) 
637
+				if (*dns_cache_mem_used<=target)
638 638
 					goto skip;
639 639
 				if  ((s_ticks_t)(now-e->expire)>=0){
640 640
 					_dns_hash_remove(e);
... ...
@@ -654,7 +681,7 @@ skip:
654 654
 
655 655
 /* locking  version (the dns hash must _not_be locked externally)
656 656
  * returns 0 when not found, the searched entry on success (with CNAMEs
657
- *  followed) or the last CNAME entry from an unfinished CNAME chain, 
657
+ *  followed) or the last CNAME entry from an unfinished CNAME chain,
658 658
  *  if the search matches a CNAME. On error sets *err (e.g. recursive CNAMEs).
659 659
  * it increases the internal refcnt => when finished dns_hash_put() must
660 660
  *  be called on the returned entry
... ...
@@ -663,7 +690,7 @@ inline static struct dns_hash_entry* dns_hash_get(str* name, int type, int* h,
663 663
 													int* err)
664 664
 {
665 665
 	struct dns_hash_entry* e;
666
-	
666
+
667 667
 	LOCK_DNS_HASH();
668 668
 	e=_dns_hash_find(name, type, h, err);
669 669
 	if (e){
... ...
@@ -681,10 +708,13 @@ inline static struct dns_hash_entry* dns_hash_get(str* name, int type, int* h,
681 681
 inline static int dns_cache_add(struct dns_hash_entry* e)
682 682
 {
683 683
 	int h;
684
-	
684
+
685 685
 	/* check space */
686 686
 	/* atomic_add_long(dns_cache_total_used, e->size); */
687 687
 	if ((*dns_cache_mem_used+e->total_size)>=dns_cache_max_mem){
688
+#ifdef USE_DNS_CACHE_STATS
689
+		dns_cache_stats[process_no].dc_lru_cnt++;
690
+#endif
688 691
 		LOG(L_WARN, "WARNING: dns_cache_add: cache full, trying to free...\n");
689 692
 		/* free ~ 12% of the cache */
690 693
 		dns_cache_free_mem(*dns_cache_mem_used/16*14, 1);
... ...
@@ -717,10 +747,13 @@ inline static int dns_cache_add(struct dns_hash_entry* e)
717 717
 inline static int dns_cache_add_unsafe(struct dns_hash_entry* e)
718 718
 {
719 719
 	int h;
720
-	
720
+
721 721
 	/* check space */
722 722
 	/* atomic_add_long(dns_cache_total_used, e->size); */
723 723
 	if ((*dns_cache_mem_used+e->total_size)>=dns_cache_max_mem){
724
+#ifdef USE_DNS_CACHE_STATS
725
+		dns_cache_stats[process_no].dc_lru_cnt++;
726
+#endif
724 727
 		LOG(L_WARN, "WARNING: dns_cache_add: cache full, trying to free...\n");
725 728
 		/* free ~ 12% of the cache */
726 729
 		UNLOCK_DNS_HASH();
... ...
@@ -757,7 +790,7 @@ inline static struct dns_hash_entry* dns_cache_mk_bad_entry(str* name,
757 757
 	struct dns_hash_entry* e;
758 758
 	int size;
759 759
 	ticks_t now;
760
-	
760
+
761 761
 #ifdef DNS_CACHE_DEBUG
762 762
 	DBG("dns_cache_mk_bad_entry(%.*s, %d, %d, %d)\n", name->len, name->s,
763 763
 									type, ttl, flags);
... ...
@@ -790,7 +823,7 @@ inline static struct dns_hash_entry* dns_cache_mk_ip_entry(str* name,
790 790
 	struct dns_hash_entry* e;
791 791
 	int size;
792 792
 	ticks_t now;
793
-	
793
+
794 794
 	/* everything is allocated in one block: dns_hash_entry + name +
795 795
 	 * + dns_rr + rdata;  dns_rr must start at an aligned adress,
796 796
 	 * hence we need to round dns_hash_entry+name size to a sizeof(long)
... ...
@@ -802,7 +835,7 @@ inline static struct dns_hash_entry* dns_cache_mk_ip_entry(str* name,
802 802
 	 * dns_rr
803 803
 	 * rdata  (no padding needed, since for ip is just an array of chars)
804 804
 	  */
805
-	size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1)+ 
805
+	size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1)+
806 806
 			sizeof(struct dns_rr)+ ip->len;
807 807
 	e=shm_malloc(size);
808 808
 	if (e==0){
... ...
@@ -838,7 +871,7 @@ static struct dns_hash_entry* dns_cache_mk_srv_entry(str* name,
838 838
 	struct dns_hash_entry* e;
839 839
 	int size;
840 840
 	ticks_t now;
841
-	
841
+
842 842
 	/* everything is allocated in one block: dns_hash_entry + name +
843 843
 	 * + dns_rr + rdata;  dns_rr must start at an aligned adress,
844 844
 	 * hence we need to round dns_hash_entry+name size to a sizeof(long),
... ...
@@ -850,9 +883,9 @@ static struct dns_hash_entry* dns_cache_mk_srv_entry(str* name,
850 850
 	 * padding to multiple of sizeof(long)
851 851
 	 * dns_rr
852 852
 	 * padding to multiple of sizeof(short)
853
-	 * rdata 
853
+	 * rdata
854 854
 	  */
855
-	size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1) + 
855
+	size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1) +
856 856
 		ROUND_SHORT(sizeof(struct dns_rr)) +
857 857
 		sizeof(struct srv_rdata)-1 +
858 858
 		rr_name->len+1;
... ...
@@ -902,15 +935,15 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
902 902
 	ticks_t now;
903 903
 	unsigned int max_ttl;
904 904
 	unsigned int ttl;
905
-	
905
+
906 906
 #define rec_matches(rec, t, n) /*(struct rdata* record, int type, str* name)*/\
907 907
 	(	((rec)->name_len==(n)->len) && ((rec)->type==(t)) && \
908 908
 		(strncasecmp((rec)->name, (n)->s, (n)->len)==0))
909 909
 	/* init */
910 910
 	tmp_lst=0;
911 911
 	tail=&tmp_lst;
912
-	
913
-	
912
+
913
+
914 914
 	/* everything is allocated in one block: dns_hash_entry + name +
915 915
 	 * + dns_rr + rdata_raw+ ....;  dns_rr must start at an aligned adress,
916 916
 	 * hence we need to round dns_hash_entry+name size to a sizeof(long)
... ...
@@ -921,7 +954,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
921 921
 	 * name (name_len+1 bytes)  (&e->name[0])
922 922
 	 * padding to multiple of sizeof(char*)
923 923
 	 * dns_rr1 (e->rr_lst)
924
-	 * possible padding: no padding for a_rdata or aaaa_rdata, 
924
+	 * possible padding: no padding for a_rdata or aaaa_rdata,
925 925
 	 *                   multipe of sizeof(short) for srv_rdata,
926 926
 	 *                   multiple of sizeof(long) for naptr_rdata and others
927 927
 	 * dns_rr1->rdata  (e->rr_lst->rdata)
... ...
@@ -947,7 +980,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
947 947
 	switch(type){
948 948
 		case T_A:
949 949
 			for(; *p;){
950
-				if (!rec_matches((*p), type, name)){ 
950
+				if (!rec_matches((*p), type, name)){
951 951
 					/* skip this record */
952 952
 					p=&(*p)->next; /* advance */
953 953
 					continue;
... ...
@@ -965,7 +998,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
965 965
 			break;
966 966
 		case T_AAAA:
967 967
 			for(; *p;){
968
-				if (!rec_matches((*p), type, name)){ 
968
+				if (!rec_matches((*p), type, name)){
969 969
 					/* skip this record */
970 970
 					p=&(*p)->next; /* advance */
971 971
 					continue;
... ...
@@ -984,7 +1017,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
984 984
 			break;
985 985
 		case T_SRV:
986 986
 			for(; *p;){
987
-				if (!rec_matches((*p), type, name)){ 
987
+				if (!rec_matches((*p), type, name)){
988 988
 					/* skip this record */
989 989
 					p=&(*p)->next; /* advance */
990 990
 					continue;
... ...
@@ -1003,7 +1036,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1003 1003
 			break;
1004 1004
 		case T_NAPTR:
1005 1005
 			for(; *p;){
1006
-				if (!rec_matches((*p), type, name)){ 
1006
+				if (!rec_matches((*p), type, name)){
1007 1007
 					/* skip this record */
1008 1008
 					p=&(*p)->next; /* advance */
1009 1009
 					continue;
... ...
@@ -1022,7 +1055,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1022 1022
 			break;
1023 1023
 		case T_CNAME:
1024 1024
 			for(; *p;){
1025
-				if (!rec_matches((*p), type, name)){ 
1025
+				if (!rec_matches((*p), type, name)){
1026 1026
 					/* skip this record */
1027 1027
 					p=&(*p)->next; /* advance */
1028 1028
 					continue;
... ...
@@ -1110,7 +1143,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1110 1110
 				rr->rdata=(void*)((char*)rr+
1111 1111
 								ROUND_SHORT(sizeof(struct dns_rr)));
1112 1112
 				/* copy the whole srv_rdata block*/
1113
-				memcpy(rr->rdata, l->rdata, 
1113
+				memcpy(rr->rdata, l->rdata,
1114 1114
 						SRV_RDATA_SIZE(*(struct srv_rdata*)l->rdata) );
1115 1115
 				rr->next=(void*)((char*)rr+
1116 1116
 							ROUND_POINTER( ROUND_SHORT(sizeof(struct dns_rr))+
... ...
@@ -1128,7 +1161,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1128 1128
 				rr->rdata=(void*)((char*)rr+
1129 1129
 								ROUND_POINTER(sizeof(struct dns_rr)));
1130 1130
 				/* copy the whole naptr_rdata block*/
1131
-				memcpy(rr->rdata, l->rdata, 
1131
+				memcpy(rr->rdata, l->rdata,
1132 1132
 						NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata) );
1133 1133
 				/* adjust the string pointer */
1134 1134
 				((struct naptr_rdata*)rr->rdata)->flags=
... ...
@@ -1157,7 +1190,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1157 1157
 				rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1158 1158
 				max_ttl=MAX(max_ttl, ttl);
1159 1159
 				rr->rdata=(void*)((char*)rr+sizeof(struct dns_rr));
1160
-				memcpy(rr->rdata, l->rdata, 
1160
+				memcpy(rr->rdata, l->rdata,
1161 1161
 							CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata));
1162 1162
 				rr->next=(void*)((char*)rr+ROUND_POINTER(sizeof(struct dns_rr)+
1163 1163
 							CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata)));
... ...
@@ -1203,9 +1236,9 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry2(struct rdata* rd)
1203 1203
 	int r, i;
1204 1204
 	int no_records; /* number of different records */
1205 1205
 	unsigned int ttl;
1206
-	
1207
-	
1208
-	no_records=0; 
1206
+
1207
+
1208
+	no_records=0;
1209 1209
 	rec[0].e=0;
1210 1210
 	/* everything is allocated in one block: dns_hash_entry + name +
1211 1211
 	 * + dns_rr + rdata_raw+ ....;  dns_rr must start at an aligned adress,
... ...
@@ -1217,7 +1250,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry2(struct rdata* rd)
1217 1217
 	 * name (name_len+1 bytes)  (&e->name[0])
1218 1218
 	 * padding to multiple of sizeof(char*)
1219 1219
 	 * dns_rr1 (e->rr_lst)
1220
-	 * possible padding: no padding for a_rdata or aaaa_rdata, 
1220
+	 * possible padding: no padding for a_rdata or aaaa_rdata,
1221 1221
 	 *                   multipe of sizeof(short) for srv_rdata,
1222 1222
 	 *                   multiple of sizeof(long) for naptr_rdata and others
1223 1223
 	 * dns_rr1->rdata  (e->rr_lst->rdata)
... ...
@@ -1229,7 +1262,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry2(struct rdata* rd)
1229 1229
 	/* compute size */
1230 1230
 	for(l=rd, i=0; l && (i<MAX_DNS_RECORDS); l=l->next, i++){
1231 1231
 		for (r=0; r<no_records; r++){
1232
-			if ((l->type==rec[r].rd->type) && 
1232
+			if ((l->type==rec[r].rd->type) &&
1233 1233
 					(l->name_len==rec[r].rd->name_len)
1234 1234
 				&& (strncasecmp(l->name, rec[r].rd->name, l->name_len)==0)){
1235 1235
 				/* found */
... ...
@@ -1283,7 +1316,7 @@ found:
1283 1283
 							"supported\n", l->type);
1284 1284
 		}
1285 1285
 	}
1286
-	
1286
+
1287 1287
 	now=get_ticks_raw();
1288 1288
 	/* alloc & init the entries */
1289 1289
 	for (r=0; r<no_records; r++){
... ...
@@ -1298,7 +1331,7 @@ found:
1298 1298
 		rec[r].e->type=rec[r].rd->type;
1299 1299
 		rec[r].e->last_used=now;
1300 1300
 		/* memset makes sure is 0-term. */
1301
-		memcpy(rec[r].e->name, rec[r].rd->name, rec[r].rd->name_len); 
1301
+		memcpy(rec[r].e->name, rec[r].rd->name, rec[r].rd->name_len);
1302 1302
 		rec[r].e->rr_lst=(struct dns_rr*)((char*)rec[r].e+
1303 1303
 				ROUND_POINTER(sizeof(struct dns_hash_entry)+rec[r].e->name_len
1304 1304
 								 -1+1));
... ...
@@ -1347,7 +1380,7 @@ found:
1347 1347
 				rec[r].rr->rdata=(void*)((char*)rec[r].rr+
1348 1348
 								ROUND_SHORT(sizeof(struct dns_rr)));
1349 1349
 				/* copy the whole srv_rdata block*/
1350
-				memcpy(rec[r].rr->rdata, l->rdata, 
1350
+				memcpy(rec[r].rr->rdata, l->rdata,
1351 1351
 						SRV_RDATA_SIZE(*(struct srv_rdata*)l->rdata) );
1352 1352
 				rec[r].rr->next=(void*)((char*)rec[r].rr+
1353 1353
 							ROUND_POINTER( ROUND_SHORT(sizeof(struct dns_rr))+
... ...
@@ -1362,7 +1395,7 @@ found:
1362 1362
 				rec[r].rr->rdata=(void*)((char*)rec[r].rr+
1363 1363
 								ROUND_POINTER(sizeof(struct dns_rr)));
1364 1364
 				/* copy the whole srv_rdata block*/
1365
-				memcpy(rec[r].rr->rdata, l->rdata, 
1365
+				memcpy(rec[r].rr->rdata, l->rdata,
1366 1366
 						NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata) );
1367 1367
 				/* adjust the string pointer */
1368 1368
 				((struct naptr_rdata*)rec[r].rr->rdata)->flags=
... ...
@@ -1445,7 +1478,7 @@ inline static struct dns_hash_entry* dns_get_related(struct dns_hash_entry* e,
1445 1445
 	struct dns_rr* rr;
1446 1446
 	static int cname_chain_len=0;
1447 1447
 	str tmp;
1448
-	
1448
+
1449 1449
 	ret=0;
1450 1450
 	l=e;
1451 1451
 #ifdef DNS_CACHE_DEBUG
... ...
@@ -1521,10 +1554,10 @@ inline static struct dns_hash_entry* dns_get_related(struct dns_hash_entry* e,
1521 1521
 				clist_append_sublist(l, t, lst_end, next, prev);
1522 1522
 			}else{
1523 1523
 				/* if no more recs, but we found the orig. target anyway,
1524
-				 *  return it (e.g. recs are only CNAME x & x A 1.2.3.4 or 
1524
+				 *  return it (e.g. recs are only CNAME x & x A 1.2.3.4 or
1525 1525
 				 *  CNAME & SRV) */
1526 1526
 				if (t->type==type)
1527
-					ret=t; 
1527
+					ret=t;
1528 1528
 				clist_append(l, t, next, prev);
1529 1529
 			}
1530 1530
 		}
... ...
@@ -1550,11 +1583,16 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
1550 1550
 	struct ip_addr* ip;
1551 1551
 	str cname_val;
1552 1552
 	char name_buf[MAX_DNS_NAME];
1553
-	
1553
+
1554 1554
 	e=0;
1555 1555
 	l=0;
1556 1556
 	cname_val.s=0;
1557
-	
1557
+
1558
+#ifdef USE_DNS_CACHE_STATS
1559
+	if (dns_cache_stats)
1560
+		dns_cache_stats[process_no].dns_req_cnt++;
1561
+#endif /* USE_DNS_CACHE_STATS */
1562
+
1558 1563
 	if (type==T_A){
1559 1564
 		if ((ip=str2ip(name))!=0){
1560 1565
 				e=dns_cache_mk_ip_entry(name, ip);
... ...
@@ -1592,12 +1630,12 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
1592 1592
 			/* e should contain the searched entry (if found) and l
1593 1593
 			 * all the entries (e and related) */
1594 1594
 			if (e){
1595
-				atomic_set(&e->refcnt, 1); /* 1 because we return a 
1595
+				atomic_set(&e->refcnt, 1); /* 1 because we return a
1596 1596
 												ref. to it */
1597 1597
 			}else{
1598 1598
 				/* e==0 => l contains a  cname list => we use the last
1599 1599
 				 * cname from the chain for a new resolve attempt (l->prev) */
1600
-				/* only one cname record is allowed (rfc2181), so we ignore 
1600
+				/* only one cname record is allowed (rfc2181), so we ignore
1601 1601
 				 * the others (we take only the first one) */
1602 1602
 				cname_val.s=
1603 1603
 					((struct cname_rdata*)l->prev->rr_lst->rdata)->name;
... ...
@@ -1621,7 +1659,7 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
1621 1621
 			}
1622 1622
 			UNLOCK_DNS_HASH();
1623 1623
 			/* if only cnames found => try to resolve the last one */
1624
-			if (cname_val.s){ 
1624
+			if (cname_val.s){
1625 1625
 				DBG("dns_cache_do_request: dns_get_entry(cname: %.*s (%d))\n",
1626 1626
 						cname_val.len, cname_val.s, cname_val.len);
1627 1627
 				e=dns_get_entry(&cname_val, type);
... ...
@@ -1660,7 +1698,7 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
1660 1660
 				}else if ((r->type==type) && (r->name_len==name->len) &&
1661 1661
 							(strncasecmp(r->name, name->s, name->len)==0)){
1662 1662
 					e=r;
1663
-					atomic_set(&e->refcnt, 1); /* 1 because we return a ref. 
1663
+					atomic_set(&e->refcnt, 1); /* 1 because we return a ref.
1664 1664
 												  to it */
1665 1665
 				}
1666 1666
 			}
... ...
@@ -1696,7 +1734,7 @@ inline static struct dns_hash_entry* dns_get_entry(str* name, int type)
1696 1696
 	str cname_val;
1697 1697
 	int err;
1698 1698
 	static int rec_cnt=0; /* recursion protection */
1699
-	
1699
+
1700 1700
 	e=0;
1701 1701
 	if (rec_cnt>MAX_CNAME_CHAIN){
1702 1702
 		LOG(L_WARN, "WARNING: dns_get_entry: CNAME chain too long or"
... ...
@@ -1705,12 +1743,25 @@ inline static struct dns_hash_entry* dns_get_entry(str* name, int type)
1705 1705
 	}
1706 1706
 	rec_cnt++;
1707 1707
 	e=dns_hash_get(name, type, &h, &err);
1708
+#ifdef USE_DNS_CACHE_STATS
1709
+	if (e) {
1710
+		if (e->err_flags==DNS_BAD_NAME && dns_cache_stats)
1711
+			/* negative DNS cache hit */
1712
+			dns_cache_stats[process_no].dc_neg_hits_cnt++;
1713
+		else if (!e->err_flags && dns_cache_stats) /* DNS cache hit */
1714
+			dns_cache_stats[process_no].dc_hits_cnt++;
1715
+
1716
+		if (dns_cache_stats)
1717
+			dns_cache_stats[process_no].dns_req_cnt++;
1718
+	}
1719
+#endif /* USE_DNS_CACHE_STATS */
1720
+
1708 1721
 	if ((e==0) && ((err) || ((e=dns_cache_do_request(name, type))==0))){
1709 1722
 		goto error;
1710 1723
 	}else if ((e->type==T_CNAME) && (type!=T_CNAME)){
1711 1724
 		/* cname found instead which couldn't be resolved with the cached
1712 1725
 		 * info => try a dns request */
1713
-		/* only one cname record is allowed (rfc2181), so we ignore 
1726
+		/* only one cname record is allowed (rfc2181), so we ignore
1714 1727
 		 * the others (we take only the first one) */
1715 1728
 		cname_val.s= ((struct cname_rdata*)e->rr_lst->rdata)->name;
1716 1729
 		cname_val.len=((struct cname_rdata*)e->rr_lst->rdata)->name_len;
... ...
@@ -1763,7 +1814,7 @@ inline static struct dns_rr* dns_entry_get_rr(	struct dns_hash_entry* e,
1763 1763
 
1764 1764
 	servers_up = atomic_get(dns_servers_up);
1765 1765
 #endif
1766
-	
1766
+
1767 1767
 	flags=0;
1768 1768
 	for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/
1769 1769
 	for(;rr;rr=rr->next){
... ...
@@ -1808,9 +1859,9 @@ inline static unsigned dns_srv_random(unsigned max)
1808 1808
  * to the RFC2782 server selection mechanism
1809 1809
  * params:
1810 1810
  *    e     is a dns srv hash entry
1811
- *    no    is the start index of the current group (a group is a set of SRV 
1811
+ *    no    is the start index of the current group (a group is a set of SRV
1812 1812
  *          rrs with the same priority)
1813
- *    tried is a bitmap where the tried srv rrs of the same priority are 
1813
+ *    tried is a bitmap where the tried srv rrs of the same priority are
1814 1814
  *          marked
1815 1815
  *    now - current time/ticks value
1816 1816
  * returns pointer to the rr on success and sets no to the rr number
... ...
@@ -1836,7 +1887,7 @@ inline static struct dns_rr* dns_srv_get_nxt_rr(struct dns_hash_entry* e,
1836 1836
 											 srv_flags_t* tried,
1837 1837
 											 unsigned char* no, ticks_t now)
1838 1838
 {
1839
-#define MAX_SRV_GRP_IDX		(sizeof(srv_flags_t)*8) 
1839
+#define MAX_SRV_GRP_IDX		(sizeof(srv_flags_t)*8)
1840 1840
 	struct dns_rr* rr;
1841 1841
 	struct dns_rr* start_grp;
1842 1842
 	int n;
... ...
@@ -1855,10 +1906,10 @@ inline static struct dns_rr* dns_srv_get_nxt_rr(struct dns_hash_entry* e,
1855 1855
 
1856 1856
 	servers_up = atomic_get(dns_servers_up);
1857 1857
 #endif
1858
-	
1858
+
1859 1859
 	rand_w=0;
1860 1860
 	for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/
1861
-	
1861
+
1862 1862
 retry:
1863 1863
 	if (unlikely(rr==0))
1864 1864
 		goto no_more_rrs;
... ...
@@ -1899,7 +1950,7 @@ retry:
1899 1899
 		goto retry;
1900 1900
 	}else if ((found==1) || ((rand_w=dns_srv_random(sum))==0)){
1901 1901
 		/* 1. if only one found, avoid a useless random() call or
1902
-		 * 2. if rand_w==0, immediately select a 0 weight record if present, 
1902
+		 * 2. if rand_w==0, immediately select a 0 weight record if present,
1903 1903
 		 *     or else the first record found
1904 1904
 		 *  (this takes care of the 0-weight at the beginning requirement) */
1905 1905
 		i=saved_idx; /* saved idx contains either first 0 weight or first
... ...
@@ -1930,10 +1981,10 @@ no_more_rrs:
1930 1930
 
1931 1931
 
1932 1932
 
1933
-/* gethostbyname compatibility: converts a dns_hash_entry structure 
1933
+/* gethostbyname compatibility: converts a dns_hash_entry structure
1934 1934
  * to a statical internal hostent structure
1935 1935
  * returns a pointer to the internal hostent structure on success or
1936
- *          0 on error 
1936
+ *          0 on error
1937 1937
  */
1938 1938
 struct hostent* dns_entry2he(struct dns_hash_entry* e)
1939 1939
 {
... ...
@@ -1947,7 +1998,7 @@ struct hostent* dns_entry2he(struct dns_hash_entry* e)
1947 1947
 	unsigned char rr_no;
1948 1948
 	ticks_t now;
1949 1949
 	int i;
1950
-	
1950
+
1951 1951
 	switch(e->type){
1952 1952
 		case T_A:
1953 1953
 			af=AF_INET;
... ...
@@ -1962,12 +2013,12 @@ struct hostent* dns_entry2he(struct dns_hash_entry* e)
1962 1962
 					e->type, e->name_len, e->name);
1963 1963
 			return 0;
1964 1964
 	}
1965
-	
1966
-	
1965
+
1966
+
1967 1967
 	rr_no=0;
1968 1968
 	now=get_ticks_raw();
1969 1969
 	rr=dns_entry_get_rr(e, &rr_no, now);
1970
-	for(i=0; rr && (i<DNS_HE_MAX_ADDR); i++, 
1970
+	for(i=0; rr && (i<DNS_HE_MAX_ADDR); i++,
1971 1971
 							rr=dns_entry_get_rr(e, &rr_no, now)){
1972 1972
 				p_addr[i]=&address[i*len];
1973 1973
 				memcpy(p_addr[i], ((struct a_rdata*)rr->rdata)->ip, len);
... ...
@@ -1977,24 +2028,24 @@ struct hostent* dns_entry2he(struct dns_hash_entry* e)
1977 1977
 				rr_no, e->name_len, e->name, e->type);
1978 1978
 		return 0; /* no good record found */
1979 1979
 	}
1980
-	
1980
+
1981 1981
 	p_addr[i]=0; /* mark the end of the addresses */
1982 1982
 	p_aliases[0]=0; /* no aliases */
1983 1983
 	memcpy(hostname, e->name, e->name_len);
1984 1984
 	hostname[e->name_len]=0;
1985
-	
1985
+
1986 1986
 	he.h_addrtype=af;
1987 1987
 	he.h_length=len;
1988 1988
 	he.h_addr_list=p_addr;
1989 1989
 	he.h_aliases=p_aliases;
1990 1990
 	he.h_name=hostname;
1991
-	
1991
+
1992 1992
 	return &he;
1993 1993
 }
1994 1994
 
1995 1995
 
1996 1996
 
1997
-/* gethostbyname compatibility: performs an a_lookup and returns a pointer 
1997
+/* gethostbyname compatibility: performs an a_lookup and returns a pointer
1998 1998
  * to a statical internal hostent structure
1999 1999
  * returns 0 on success, <0 on error (see the error codes)
2000 2000
  */
... ...
@@ -2003,7 +2054,7 @@ struct hostent* dns_a_get_he(str* name)
2003 2003
 	struct dns_hash_entry* e;
2004 2004
 	struct ip_addr* ip;
2005 2005
 	struct hostent* he;
2006
-	
2006
+
2007 2007
 	e=0;
2008 2008
 	if ((ip=str2ip(name))!=0){
2009 2009
 		return ip_addr2he(name, ip);
... ...
@@ -2018,7 +2069,7 @@ struct hostent* dns_a_get_he(str* name)
2018 2018
 
2019 2019
 
2020 2020
 
2021
-/* gethostbyname compatibility: performs an aaaa_lookup and returns a pointer 
2021
+/* gethostbyname compatibility: performs an aaaa_lookup and returns a pointer
2022 2022
  * to a statical internal hostent structure
2023 2023
  * returns 0 on success, <0 on error (see the error codes)
2024 2024
  */
... ...
@@ -2027,7 +2078,7 @@ struct hostent* dns_aaaa_get_he(str* name)
2027 2027
 	struct dns_hash_entry* e;
2028 2028
 	struct ip_addr* ip;
2029 2029
 	struct hostent* he;
2030
-	
2030
+
2031 2031
 	e=0;
2032 2032
 	if ((ip=str2ip6(name))!=0){
2033 2033
 		return ip_addr2he(name, ip);
... ...
@@ -2075,8 +2126,8 @@ inline static int dns_rr2ip(int type, struct dns_rr* rr, struct ip_addr* ip)
2075 2075
 struct hostent* dns_get_he(str* name, int flags)
2076 2076
 {
2077 2077
 	struct hostent* he;
2078
-	
2079
-	
2078
+
2079
+
2080 2080
 	if ((flags&(DNS_IPV6_FIRST|DNS_IPV6_ONLY))){
2081 2081
 		he=dns_aaaa_get_he(name);
2082 2082
 		if (he) return he;
... ...
@@ -2105,7 +2156,7 @@ struct hostent* dns_srv_get_he(str* name, unsigned short* port, int flags)
2105 2105
 	struct hostent* he;
2106 2106
 	ticks_t now;
2107 2107
 	unsigned char rr_no;
2108
-	
2108
+
2109 2109
 	rr=0;
2110 2110
 	he=0;
2111 2111
 	now=get_ticks_raw();
... ...
@@ -2136,7 +2187,7 @@ error:
2136 2136
 struct hostent* dns_resolvehost(char* name)
2137 2137
 {
2138 2138
 	str host;
2139
-	
2139
+
2140 2140
 	if ((use_dns_cache==0) || (dns_hash==0)){ /* not init yet */
2141 2141
 		return _resolvehost(name);
2142 2142
 	}
... ...
@@ -2155,14 +2206,14 @@ struct hostent* dns_resolvehost(char* name)
2155 2155
  * returns: hostent struct & *port filled with the port from the SRV record;
2156 2156
  *  0 on error
2157 2157
  */
2158
-struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, 
2158
+struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2159 2159
 										char* proto)
2160 2160
 {
2161 2161
 	struct dns_srv_handle h;
2162 2162
 	struct ip_addr ip;
2163 2163
 	int ret;
2164
-	
2165
-	if ((use_dns_cache==0) || (dns_hash==0)){ 
2164
+
2165
+	if ((use_dns_cache==0) || (dns_hash==0)){
2166 2166
 		/* not init or off => use normal, non-cached version */
2167 2167
 		return _sip_resolvehost(name, port, proto);
2168 2168
 	}
... ...
@@ -2184,7 +2235,7 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2184 2184
  * returns: hostent struct & *port filled with the port from the SRV record;
2185 2185
  *  0 on error
2186 2186
  */
2187
-struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port, 
2187
+struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2188 2188
 										char* proto)
2189 2189
 {
2190 2190
 	struct hostent* he;
... ...
@@ -2194,7 +2245,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2194 2194
 	str srv_name;
2195 2195
 	char srv_proto;
2196 2196
 
2197
-	if ((use_dns_cache==0) || (dns_hash==0)){ 
2197
+	if ((use_dns_cache==0) || (dns_hash==0)){
2198 2198
 		/* not init or off => use normal, non-cached version */
2199 2199
 		return _sip_resolvehost(name, port, proto);
2200 2200
 	}
... ...
@@ -2209,7 +2260,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2209 2209
 	}
2210 2210
 	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
2211 2211
 	if ((port)&&(*port==0)){
2212
-		*port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we 
2212
+		*port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
2213 2213
 														 don't find another */
2214 2214
 		if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
2215 2215
 			LOG(L_WARN, "WARNING: dns_sip_resolvehost: domain name too long"
... ...
@@ -2224,7 +2275,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2224 2224
 				/* we are lucky, this is an ip address */
2225 2225
 				return ip_addr2he(name,ip);
2226 2226
 			}
2227
-			
2227
+
2228 2228
 			switch(srv_proto){
2229 2229
 				case PROTO_NONE: /* no proto specified, use udp */
2230 2230
 					if (proto)
... ...
@@ -2277,7 +2328,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2277 2277
  * params:
2278 2278
  *         naptr_head - naptr dns_rr list head
2279 2279
  *         tried      - bitmap used to keep track of the already tried records
2280
- *                      (no more then sizeof(tried)*8 valid records are 
2280
+ *                      (no more then sizeof(tried)*8 valid records are
2281 2281
  *                      ever walked
2282 2282
  *         srv_name   - if succesfull, it will be set to the selected record
2283 2283
  *                      srv name (naptr repl.)
... ...
@@ -2285,10 +2336,10 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2285 2285
  *                      protocol
2286 2286
  * returns  0 if no more records found or a pointer to the selected record
2287 2287
  *  and sets  protocol and srv_name
2288
- * WARNING: when calling first time make sure you run first 
2288
+ * WARNING: when calling first time make sure you run first
2289 2289
  *           naptr_iterate_init(&tried)
2290 2290
  */
2291
-struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head, 
2291
+struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head,
2292 2292
 											naptr_bmp_t* tried,
2293 2293
 											str* srv_name, char* proto)
2294 2294
 {
... ...
@@ -2318,7 +2369,7 @@ struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head,
2318 2318
 		}
2319 2319
 #ifdef DNS_CACHE_DEBUG
2320 2320
 		DBG("naptr_iterate: found a valid sip NAPTR rr %.*s,"
2321
-					" proto %d\n", naptr->repl_len, naptr->repl, 
2321
+					" proto %d\n", naptr->repl_len, naptr->repl,
2322 2322
 					(int)naptr_proto);
2323 2323
 #endif
2324 2324
 		if ((naptr_proto_supported(naptr_proto))){
... ...
@@ -2332,7 +2383,7 @@ struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head,
2332 2332
 		/* found something */
2333 2333
 #ifdef DNS_CACHE_DEBUG
2334 2334
 		DBG("naptr_iterate: choosed NAPTR rr %.*s, proto %d"
2335
-					" tried: 0x%x\n", naptr_saved->repl_len, 
2335
+					" tried: 0x%x\n", naptr_saved->repl_len,
2336 2336
 					naptr_saved->repl, (int)saved_proto, *tried);
2337 2337
 #endif
2338 2338
 		*tried|=1<<idx;
... ...
@@ -2347,7 +2398,7 @@ end:
2347 2347
 
2348 2348
 
2349 2349
 
2350
-/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV 
2350
+/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV
2351 2351
  * lookup if *port==0 or normal A/AAAA lookup
2352 2352
  * if *port!=0.
2353 2353
  * when performing SRV lookup (*port==0) it will use proto to look for
... ...
@@ -2355,7 +2406,7 @@ end:
2355 2355
  * returns: hostent struct & *port filled with the port from the SRV record;
2356 2356
  *  0 on error
2357 2357
  */
2358
-struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port, 
2358
+struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port,
2359 2359
 										char* proto)
2360 2360
 {
2361 2361
 	struct hostent* he;
... ...
@@ -2364,7 +2415,7 @@ struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port,
2364 2364
 	struct dns_hash_entry* e;
2365 2365
 	char n_proto;
2366 2366
 	str srv_name;
2367
-	
2367
+
2368 2368
 	he=0;
2369 2369
 	if (dns_hash==0){ /* not init => use normal, non-cached version */
2370 2370
 		LOG(L_WARN, "WARNING: dns_sip_resolvehost: called before dns cache"
... ...
@@ -2397,7 +2448,7 @@ struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port,
2397 2397
 												&srv_name, &n_proto)){
2398 2398
 			if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0){
2399 2399
 #ifdef DNS_CACHE_DEBUG
2400
-				DBG("dns_naptr_sip_resolvehost(%.*s, %d, %d) srv, ret=%p\n", 
2400
+				DBG("dns_naptr_sip_resolvehost(%.*s, %d, %d) srv, ret=%p\n",
2401 2401
 							name->len, name->s, (int)*port, (int)*proto, he);
2402 2402
 #endif
2403 2403
 				dns_hash_put(e);
... ...
@@ -2415,7 +2466,7 @@ naptr_not_found:
2415 2415
 
2416 2416
 
2417 2417
 
2418
-/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV 
2418
+/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV
2419 2419
  * lookup if *port==0 or normal A/AAAA lookup
2420 2420
  * if *port!=0.
2421 2421
  * when performing SRV lookup (*port==0) it will use proto to look for
... ...
@@ -2423,7 +2474,7 @@ naptr_not_found:
2423 2423
  * returns: hostent struct & *port filled with the port from the SRV record;
2424 2424
  *  0 on error
2425 2425
  */
2426
-struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, 
2426
+struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2427 2427
 										char* proto)
2428 2428
 {
2429 2429
 #ifdef USE_NAPTR
... ...
@@ -2437,7 +2488,7 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2437 2437
 
2438 2438
 /* performs an a lookup, fills the dns_entry pointer and the ip addr.
2439 2439
  *  (with the first good ip). if *e ==0 does the a lookup, and changes it
2440
- *   to the result, if not it uses the current value and tries to use 
2440
+ *   to the result, if not it uses the current value and tries to use
2441 2441
  *   the rr_no record from it.
2442 2442
  * params:  e - must contain the "in-use" dns_hash_entry pointer (from
2443 2443
  *               a previous call) or *e==0 (for the first call)
... ...
@@ -2447,7 +2498,7 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2447 2447
  *                 at *rr_no
2448 2448
  *          rr_no - record number to start searching for a good ip from
2449 2449
  *                  (e.g. value from previous call + 1), filled on return
2450
- *                  with the number of the record corresponding to the 
2450
+ *                  with the number of the record corresponding to the
2451 2451
  *                  returned ip
2452 2452
  * returns 0 on success, <0 on error (see the error codes),
2453 2453
  *         fills e, ip and rr_no
... ...
@@ -2474,9 +2525,9 @@ int dns_a_resolve(struct dns_hash_entry** e, unsigned char* rr_no,
2474 2474
 	int ret;
2475 2475
 	ticks_t now;
2476 2476
 	struct ip_addr* tmp;
2477
-	
2477
+
2478 2478
 	rr=0;
2479
-	ret=-E_DNS_NO_IP; 
2479
+	ret=-E_DNS_NO_IP;
2480 2480
 	if (*e==0){ /* do lookup */
2481 2481
 		/* if ip don't set *e */
2482 2482
 		if ((tmp=str2ip(name))!=0){
... ...
@@ -2509,19 +2560,19 @@ error:
2509 2509
 
2510 2510
 /* lookup, fills the dns_entry pointer and the ip addr.
2511 2511
  *  (with the first good ip). if *e ==0 does the a lookup, and changes it
2512
- *   to the result, if not it uses the current value and tries to use 
2512
+ *   to the result, if not it uses the current value and tries to use
2513 2513
  * Same as dns_a_resolve but for aaaa records (see above).
2514 2514
  */
2515
-int dns_aaaa_resolve(struct dns_hash_entry** e, unsigned char* rr_no, 
2515
+int dns_aaaa_resolve(struct dns_hash_entry** e, unsigned char* rr_no,
2516 2516
 						str* name, struct ip_addr* ip)
2517 2517
 {
2518 2518
 	struct dns_rr* rr;
2519 2519
 	int ret;
2520 2520
 	ticks_t now;
2521 2521
 	struct ip_addr* tmp;
2522
-	
2522
+
2523 2523
 	rr=0;
2524
-	ret=-E_DNS_NO_IP; 
2524
+	ret=-E_DNS_NO_IP;
2525 2525
 	if (*e==0){ /* do lookup */
2526 2526
 		/* if ip don't set *e */
2527 2527
 		if ((tmp=str2ip6(name))!=0){
... ...
@@ -2559,12 +2610,12 @@ error:
2559 2559
  *  see dns_a_resolve() for the rest of the params., examples a.s.o
2560 2560
  *  WARNING: don't forget dns_hash_put(*e) when e is not needed anymore
2561 2561
  */
2562
-int dns_ip_resolve(struct dns_hash_entry** e, unsigned char* rr_no, 
2562
+int dns_ip_resolve(struct dns_hash_entry** e, unsigned char* rr_no,
2563 2563
 					str* name, struct ip_addr* ip, int flags)
2564 2564
 {
2565 2565
 	int ret;
2566
-	
2567
-	ret=-E_DNS_NO_IP; 
2566
+
2567
+	ret=-E_DNS_NO_IP;
2568 2568
 	if (*e==0){ /* first call */
2569 2569
 		if ((flags&(DNS_IPV6_FIRST|DNS_IPV6_ONLY))){
2570 2570
 			ret=dns_aaaa_resolve(e, rr_no, name, ip);
... ...
@@ -2601,7 +2652,7 @@ int dns_ip_resolve(struct dns_hash_entry** e, unsigned char* rr_no,
2601 2601
 			ret=dns_a_resolve(e, rr_no, name, ip);
2602 2602
 		}
2603 2603
 	}else{
2604
-		LOG(L_CRIT, "BUG: dns_ip_resolve: invalid record type %d\n", 
2604
+		LOG(L_CRIT, "BUG: dns_ip_resolve: invalid record type %d\n",
2605 2605
 					(*e)->type);
2606 2606
 	}
2607 2607
 	return ret;
... ...
@@ -2631,9 +2682,9 @@ int dns_srv_resolve_nxt(struct dns_hash_entry** e,
2631 2631
 	struct dns_rr* rr;
2632 2632
 	int ret;
2633 2633
 	ticks_t now;
2634
-	
2634
+
2635 2635
 	rr=0;
2636
-	ret=-E_DNS_NO_SRV; 
2636
+	ret=-E_DNS_NO_SRV;
2637 2637
 	if (*e==0){
2638 2638
 		if ((*e=dns_get_entry(name, T_SRV))==0)
2639 2639
 			goto error;
... ...
@@ -2681,13 +2732,13 @@ int dns_srv_resolve_ip(struct dns_srv_handle* h,
2681 2681
 {
2682 2682
 	int ret;
2683 2683
 	str host;
2684
-	
2684
+
2685 2685
 	host.len=0;
2686 2686
 	host.s=0;
2687 2687
 	do{
2688 2688
 		if (h->a==0){
2689 2689
 #ifdef DNS_SRV_LB
2690
-			if ((ret=dns_srv_resolve_nxt(&h->srv, 
2690
+			if ((ret=dns_srv_resolve_nxt(&h->srv,
2691 2691
 								(flags & DNS_SRV_RR_LB)?&h->srv_tried_rrs:0,
2692 2692
 								&h->srv_no,
2693 2693
 								name, &host, port))<0)
... ...
@@ -2713,8 +2764,8 @@ int dns_srv_resolve_ip(struct dns_srv_handle* h,
2713 2713
 	}while(ret<0);
2714 2714
 error:
2715 2715
 #ifdef DNS_CACHE_DEBUG
2716
-	DBG("dns_srv_resolve_ip(\"%.*s\", %d, %d), ret=%d, ip=%s\n", 
2717
-			name->len, name->s, h->srv_no, h->ip_no, ret, 
2716
+	DBG("dns_srv_resolve_ip(\"%.*s\", %d, %d), ret=%d, ip=%s\n",
2717
+			name->len, name->s, h->srv_no, h->ip_no, ret,
2718 2718
 			ip?ZSW(ip_addr2a(ip)):"");
2719 2719
 #endif
2720 2720
 	return ret;
... ...
@@ -2726,7 +2777,7 @@ error:
2726 2726
  * if *port!=0.
2727 2727
  * when performing SRV lookup (*port==0) it will use proto to look for
2728 2728
  * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
2729
- * h must be initialized prior to  calling this function and can be used to 
2729
+ * h must be initialized prior to  calling this function and can be used to
2730 2730
  * get the subsequent ips
2731 2731
  * returns:  <0 on error
2732 2732
  *            0 on success and it fills *ip, *port, dns_sip_resolve_h
... ...
@@ -2795,7 +2846,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2795 2795
 						/* proto already set */
2796 2796
 						return 0;
2797 2797
 					}
2798
-					
2798
+
2799 2799
 					switch(srv_proto){
2800 2800
 						case PROTO_NONE: /* no proto specified, use udp */
2801 2801
 							if (proto)
... ...
@@ -2830,7 +2881,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2830 2830
 															port, flags))>=0)
2831 2831
 					{
2832 2832
 #ifdef DNS_CACHE_DEBUG
2833
-						DBG("dns_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n", 
2833
+						DBG("dns_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n",
2834 2834
 							name->len, name->s, h->srv_no, h->ip_no, ret);
2835 2835
 #endif
2836 2836
 						/* proto already set */
... ...
@@ -2849,7 +2900,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2849 2849
 			ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags);
2850 2850
 			if (proto)
2851 2851
 				*proto=h->proto;
2852
-			DBG("dns_sip_resolve(%.*s, %d, %d), srv, ret=%d\n", 
2852
+			DBG("dns_sip_resolve(%.*s, %d, %d), srv, ret=%d\n",
2853 2853
 					name->len, name->s, h->srv_no, h->ip_no, ret);
2854 2854
 			return ret;
2855 2855
 	}
... ...
@@ -2864,7 +2915,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2864 2864
 	if (proto)
2865 2865
 		*proto=h->proto;
2866 2866
 #ifdef DNS_CACHE_DEBUG
2867
-	DBG("dns_sip_resolve(%.*s, %d, %d), ip, ret=%d\n", 
2867
+	DBG("dns_sip_resolve(%.*s, %d, %d), ip, ret=%d\n",
2868 2868
 			name->len, name->s, h->srv_no, h->ip_no, ret);
2869 2869
 #endif
2870 2870
 	return ret;
... ...
@@ -2880,7 +2931,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2880 2880
  * - normal A/AAAA lookup if *port!=0, or port==0
2881 2881
  * when performing SRV lookup (*port==0) it will use proto to look for
2882 2882
  * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
2883
- * h must be initialized prior to  calling this function and can be used to 
2883
+ * h must be initialized prior to  calling this function and can be used to
2884 2884
  * get the subsequent ips
2885 2885
  * returns:  <0 on error
2886 2886
  *            0 on success and it fills *ip, *port, dns_sip_resolve_h
... ...
@@ -2897,7 +2948,7 @@ int dns_naptr_sip_resolve(struct dns_srv_handle* h,  str* name,
2897 2897
 	char n_proto;
2898 2898
 	str srv_name;
2899 2899
 	int ret;
2900
-	
2900
+
2901 2901
 	ret=-E_DNS_NO_NAPTR;
2902 2902
 	if (dns_hash==0){ /* not init => use normal, non-cached version */
2903 2903
 		LOG(L_WARN, "WARNING: dns_sip_resolve: called before dns cache"
... ...
@@ -2913,7 +2964,7 @@ int dns_naptr_sip_resolve(struct dns_srv_handle* h,  str* name,
2913 2913
 	if (((h->srv==0) && (h->a==0)) && /* first call */
2914 2914
 			 proto && port && (*proto==0) && (*port==0)){
2915 2915
 		*proto=PROTO_UDP; /* just in case we don't find another */
2916
-		
2916
+
2917 2917
 		/* check if it's an ip address */
2918 2918
 		if ( ((tmp_ip=str2ip(name))!=0)
2919 2919
 #ifdef	USE_IPV6
... ...
@@ -2943,7 +2994,7 @@ int dns_naptr_sip_resolve(struct dns_srv_handle* h,  str* name,
2943 2943
 									from previous dns_srv_sip_resolve calls */
2944 2944
 			if ((ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags))>=0){
2945 2945
 #ifdef DNS_CACHE_DEBUG
2946
-				DBG("dns_naptr_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n", 
2946
+				DBG("dns_naptr_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n",
2947 2947
 								name->len, name->s, h->srv_no, h->ip_no, ret);
2948 2948
 #endif
2949 2949
 				dns_hash_put(e);
... ...
@@ -2971,7 +3022,7 @@ naptr_not_found:
2971 2971
  * - normal A/AAAA lookup if *port!=0, or port==0
2972 2972
  * when performing SRV lookup (*port==0) it will use proto to look for
2973 2973
  * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
2974
- * h must be initialized prior to  calling this function and can be used to 
2974
+ * h must be initialized prior to  calling this function and can be used to
2975 2975
  * get the subsequent ips
2976 2976
  * returns:  <0 on error
2977 2977
  *            0 on success and it fills *ip, *port, dns_sip_resolve_h
... ...
@@ -2996,7 +3047,7 @@ int dns_a_get_ip(str* name, struct ip_addr* ip)
2996 2996
 	struct dns_hash_entry* e;
2997 2997
 	int ret;
2998 2998
 	unsigned char rr_no;
2999
-	
2999
+
3000 3000
 	e=0;
3001 3001
 	rr_no=0;
3002 3002
 	ret=dns_a_resolve(&e, &rr_no, name, ip);
... ...
@@ -3011,7 +3062,7 @@ int dns_aaaa_get_ip(str* name, struct ip_addr* ip)
3011 3011
 	struct dns_hash_entry* e;
3012 3012
 	int ret;
3013 3013
 	unsigned char rr_no;
3014
-	
3014
+
3015 3015
 	e=0;
3016 3016
 	rr_no=0;
3017 3017
 	ret=dns_aaaa_resolve(&e, &rr_no, name, ip);
... ...
@@ -3033,7 +3084,7 @@ int dns_get_ip(str* name, struct ip_addr* ip, int flags)
3033 3033
 	int ret;
3034 3034
 	struct dns_hash_entry* e;
3035 3035
 	unsigned char rr_no;
3036
-	
3036
+
3037 3037
 	e=0;
3038 3038
 	rr_no=0;
3039 3039
 	ret=dns_ip_resolve(&e, &rr_no, name, ip, flags);
... ...
@@ -3050,7 +3101,7 @@ int dns_srv_get_ip(str* name, struct ip_addr* ip, unsigned short* port,
3050 3050
 {
3051 3051
 	int ret;
3052 3052
 	struct dns_srv_handle h;
3053
-	
3053
+
3054 3054
 	dns_srv_handle_init(&h);
3055 3055
 	ret=dns_srv_resolve_ip(&h, name, ip, port, flags);
3056 3056
 	dns_srv_handle_put(&h);
... ...
@@ -3081,12 +3132,12 @@ void dns_cache_debug(rpc_t* rpc, void* ctx)
3081 3081
 	int h;
3082 3082
 	struct dns_hash_entry* e;
3083 3083
 	ticks_t now;
3084
-	
3084
+
3085 3085
 	now=get_ticks_raw();
3086 3086
 	LOCK_DNS_HASH();
3087 3087
 		for (h=0; h<DNS_HASH_SIZE; h++){
3088 3088
 			clist_foreach(&dns_hash[h], e, next){
3089
-				rpc->add(ctx, "sdddddd", 
3089
+				rpc->add(ctx, "sdddddd",
3090 3090
 								e->name, e->type, e->total_size, e->refcnt.val,
3091 3091
 								(s_ticks_t)(e->expire-now)<0?-1:
3092 3092
 									TICKS_TO_S(e->expire-now),
... ...
@@ -3098,6 +3149,86 @@ void dns_cache_debug(rpc_t* rpc, void* ctx)
3098 3098
 }
3099 3099
 
3100 3100
 
3101
+#ifdef USE_DNS_CACHE_STATS
3102
+void dns_cache_stats_get(rpc_t* rpc, void* c)
3103
+{
3104
+	char *name=NULL;
3105
+	void *handle;
3106
+	int found=0,i=0;
3107
+	int reset=0;
3108
+	char* dns_cache_stats_names[] = {
3109
+		"dns_req_cnt",
3110
+		"dc_hits_cnt",
3111
+		"dc_neg_hits_cnt",
3112
+		"dc_lru_cnt",
3113
+		NULL
3114
+	};
3115
+	unsigned long  stat_sum(int ivar, int breset) {
3116
+		unsigned long isum=0;
3117
+		int i1=0;
3118
+
3119
+		for (; i1 < get_max_procs(); i1++)
3120
+			switch (ivar) {
3121
+				case 0:
3122
+					isum+=dns_cache_stats[i1].dns_req_cnt;
3123
+					if (breset)
3124
+						dns_cache_stats[i1].dns_req_cnt=0;
3125
+					break;
3126
+				case 1:
3127
+					isum+=dns_cache_stats[i1].dc_hits_cnt;
3128
+					if (breset)
3129
+						dns_cache_stats[i1].dc_hits_cnt=0;
3130
+					break;
3131
+				case 2:
3132
+					isum+=dns_cache_stats[i1].dc_neg_hits_cnt;
3133
+					if (breset)
3134
+						dns_cache_stats[i1].dc_neg_hits_cnt=0;
3135
+					break;
3136
+				case 3:
3137
+					isum+=dns_cache_stats[i1].dc_lru_cnt;
3138
+					if (breset)
3139
+						dns_cache_stats[i1].dc_lru_cnt=0;
3140
+					break;
3141
+			}
3142
+
3143
+		return isum;
3144
+	}
3145
+
3146
+
3147
+	if (!use_dns_cache) {
3148
+		rpc->fault(c, 500, "dns cache support disabled");
3149
+		return;
3150
+	}
3151
+	if (rpc->scan(c, "s", &name) < 0)
3152
+		return;
3153
+	if (rpc->scan(c, "d", &reset) < 0)
3154
+		return;
3155
+	if (!strcasecmp(name, DNS_CACHE_ALL_STATS)) {
3156
+		/* dump all the dns cache stat values */
3157
+		rpc->add(c, "{", &handle);
3158
+		for (i=0; dns_cache_stats_names[i]; i++)
3159
+			rpc->struct_add(handle, "d",
3160
+							dns_cache_stats_names[i],
3161
+							stat_sum(i, reset));
3162
+
3163
+		found=1;
3164
+	} else {
3165
+		for (i=0; dns_cache_stats_names[i]; i++)
3166
+			if (!strcasecmp(dns_cache_stats_names[i], name)) {
3167
+				rpc->add(c, "{", &handle);
3168
+				rpc->struct_add(handle, "d",
3169
+								dns_cache_stats_names[i],
3170
+								stat_sum(i, reset));
3171
+				found=1;
3172
+				break;
3173
+			}
3174
+	}
3175
+	if(!found)
3176
+		rpc->fault(c, 500, "unknown dns cache stat parameter");
3177
+
3178
+	return;
3179
+}
3180
+#endif /* USE_DNS_CACHE_STATS */
3101 3181
 
3102 3182
 /* rpc functions */
3103 3183
 void dns_cache_debug_all(rpc_t* rpc, void* ctx)
... ...
@@ -3108,13 +3239,13 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3108 3108
 	struct ip_addr ip;
3109 3109
 	int i;
3110 3110
 	ticks_t now;
3111
-	
3111
+
3112 3112
 	now=get_ticks_raw();
3113 3113
 	LOCK_DNS_HASH();
3114 3114
 		for (h=0; h<DNS_HASH_SIZE; h++){
3115 3115
 			clist_foreach(&dns_hash[h], e, next){
3116 3116
 				for (i=0, rr=e->rr_lst; rr; i++, rr=rr->next){
3117
-					rpc->add(ctx, "sddddddd", 
3117
+					rpc->add(ctx, "sddddddd",
3118 3118
 								e->name, (int)e->type, i, (int)e->total_size,
3119 3119
 								(int)e->refcnt.val,
3120 3120
 								(int)(s_ticks_t)(e->expire-now)<0?-1:
... ...
@@ -3131,7 +3262,7 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3131 3131
 							}
3132 3132
 							break;
3133 3133
 						case T_SRV:
3134
-							rpc->add(ctx, "ss", "srv", 
3134
+							rpc->add(ctx, "ss", "srv",
3135 3135
 									((struct srv_rdata*)(rr->rdata))->name);
3136 3136
 							break;
3137 3137
 						case T_NAPTR:
... ...
@@ -3139,7 +3270,7 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3139 3139
 								((struct naptr_rdata*)(rr->rdata))->flags);
3140 3140
 							break;
3141 3141
 						case T_CNAME:
3142
-							rpc->add(ctx, "ss", "cname", 
3142
+							rpc->add(ctx, "ss", "cname",
3143 3143
 									((struct cname_rdata*)(rr->rdata))->name);
3144 3144
 							break;
3145 3145
 						default:
... ...
@@ -3183,7 +3314,7 @@ void dns_cache_view(rpc_t* rpc, void* ctx)
3183 3183
 	ticks_t now;
3184 3184
 	void* handle;
3185 3185
 	str s;
3186
-	
3186
+
3187 3187
 	now=get_ticks_raw();
3188 3188
 	LOCK_DNS_HASH();
3189 3189
 		for (h=0; h<DNS_HASH_SIZE; h++){
... ...
@@ -3314,7 +3445,7 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e, in
3314 3314
 			default:
3315 3315
 				LOG(L_ERR, "ERROR: dns_cache_clone_entry: type %d not supported\n",
3316 3316
 						e->type);
3317
-				return NULL;				
3317
+				return NULL;
3318 3318
 		}
3319 3319
 	} else {
3320 3320
 		rounded_size = size; /* no need to round the size, we just clone the entry
... ...
@@ -3366,7 +3497,7 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e, in
3366 3366
 					((struct naptr_rdata*)rr->rdata)->repl);
3367 3367
 		}
3368 3368
 	}
3369
-	
3369
+
3370 3370
 
3371 3371
 	if (rdata_size) {
3372 3372
 		memset(new+size, 0, rounded_size-size+rr_size+rdata_size);
... ...
@@ -3409,7 +3540,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3409 3409
 	str ip, rr_name;
3410 3410
 	int flags;
3411 3411
 	struct ip_addr *ip_addr;
3412
-	int priority, weight, port; 
3412
+	int priority, weight, port;
3413 3413
 	ticks_t expire;
3414 3414
 	int err, h;
3415 3415
 	int size;
... ...
@@ -3431,10 +3562,10 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3431 3431
 	case T_CNAME:
3432 3432
 	case T_NAPTR:
3433 3433
 		rpc->fault(ctx, 400, "not implemented");
3434
-		return;			
3434
+		return;
3435 3435
 	default:
3436 3436
 		rpc->fault(ctx, 400, "unknown type");
3437
-		return;			
3437
+		return;
3438 3438
 	}
3439 3439
 
3440 3440
 	if (!flags) {
... ...
@@ -3555,7 +3686,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3555 3555
 					rpc->fault(ctx, 400, "Failed to add the entry to the cache");
3556 3556
 					goto error;
3557 3557
 				}
3558
-			
3558
+
3559 3559
 				switch(type) {
3560 3560
 				case T_A:
3561 3561
 				case T_AAAA:
... ...
@@ -3572,7 +3703,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3572 3572
 			}
3573 3573
 		}
3574 3574
 	}
3575
-	
3575
+
3576 3576
 	LOCK_DNS_HASH();
3577 3577
 	if (dns_cache_add_unsafe(new)) {
3578 3578
 		rpc->fault(ctx, 400, "Failed to add the entry to the cache");
... ...
@@ -22,14 +22,15 @@
22 22
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 23
  * GNU General Public License for more details.
24 24
  *
25
- * You should have received a copy of the GNU General Public License 
26
- * along with this program; if not, write to the Free Software 
25
+ * You should have received a copy of the GNU General Public License
26
+ * along with this program; if not, write to the Free Software
27 27
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 28
  */
29 29
 /* History:
30 30
  * --------
31 31
  *  2006-07-13  created by andrei
32 32
  *  2007-06-16  naptr support (andrei)
33
+ *  2007-07-30  DNS cache measurements added (Gergo)
33 34
  */
34 35
 
35 36
 
... ...
@@ -64,7 +65,7 @@
64 64
 enum dns_errors{
65 65
 					E_DNS_OK=0,
66 66
 					E_DNS_EOR, /* no more records (not an error)
67
-					              -- returned only by the dns_resolve* 
67
+					              -- returned only by the dns_resolve*
68 68
 								  functions when called iteratively,; it
69 69
 								  signals the end of the ip/records list */
70 70
 					E_DNS_UNKNOWN /* unkown error */,
... ...
@@ -73,10 +74,10 @@ enum dns_errors{
73 73
 					E_DNS_NO_SRV /* unresolvable srv record */,
74 74
 					E_DNS_BAD_IP_ENTRY,
75 75
 					E_DNS_NO_IP /* unresolvable a or aaaa records*/,
76
-					E_DNS_BAD_IP /* the ip is invalid */, 
77
-					E_DNS_BLACKLIST_IP /* the ip is blacklisted */, 
76
+					E_DNS_BAD_IP /* the ip is invalid */,
77
+					E_DNS_BLACKLIST_IP /* the ip is blacklisted */,
78 78
 					E_DNS_NAME_TOO_LONG /* try again with a shorter name */,
79
-					E_DNS_AF_MISMATCH /* ipv4 or ipv6 only requested, but 
79
+					E_DNS_AF_MISMATCH /* ipv4 or ipv6 only requested, but
80 80
 										 name contains an ip addr. of the
81 81
 										 opossite type */ ,
82 82
 					E_DNS_NO_NAPTR /* unresolvable naptr record */,
... ...
@@ -142,7 +143,7 @@ struct dns_hash_entry{
142 142
 	unsigned short type;
143 143
 	unsigned char err_flags;
144 144
 	unsigned char name_len; /* can be maximum 255 bytes */
145
-	char name[1]; /* variable length, name, null terminated 
145
+	char name[1]; /* variable length, name, null terminated
146 146
 	                 (actual lenght = name_len +1)*/
147 147
 };
148 148
 
... ...
@@ -173,6 +174,10 @@ struct dns_srv_handle{
173 173
 const char* dns_strerror(int err);
174 174
 
175 175
 int init_dns_cache();
176
+#ifdef USE_DNS_CACHE_STATS
177
+int init_dns_cache_stats(int iproc_num);
178
+#define DNS_CACHE_ALL_STATS "dc_all_stats"
179
+#endif
176 180
 void destroy_dns_cache();
177 181
 
178 182
 
... ...
@@ -238,7 +243,7 @@ inline static void dns_srv_handle_put_shm_unsafe(struct dns_srv_handle* h)
238 238
 
239 239
 /* get "next" ip next time a dns_srv_handle function is called
240 240
  * params: h   - struct dns_srv_handler
241
- *         err - return code of the last dns_*_resolve* call 
241
+ *         err - return code of the last dns_*_resolve* call
242 242
  * returns: 0 if it doesn't make sense to try another record,
243 243
  * 1 otherwise
244 244
  */
... ...
@@ -298,7 +303,7 @@ struct hostent* dns_get_he(str* name, int flags);
298 298
 int dns_sip_resolve(struct dns_srv_handle* h,  str* name, struct ip_addr* ip,
299 299
 					unsigned short* port, char* proto, int flags);
300 300
 
301
-/* same as above, but fills su intead of changing port and filling an ip */ 
301
+/* same as above, but fills su intead of changing port and filling an ip */
302 302
 inline static int dns_sip_resolve2su(struct dns_srv_handle* h,
303 303
 									 union sockaddr_union* su,
<