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 61
 #include "error.h"
61 62
 #include "rpc.h"
62 63
 #include "rand/fastrand.h"
64
+#ifdef USE_DNS_CACHE_STATS
65
+#include "pt.h"
66
+#endif
63 67
 
64 68
 
65 69
 
... ...
@@ -70,7 +74,7 @@
70 74
 	#define MAX(a,b) ( ((a)>(b))?(a):(b))
71 75
 #endif
72 76
 
73
-#define MAX_DNS_RECORDS 255  /* maximum dns records number  received in a 
77
+#define MAX_DNS_RECORDS 255  /* maximum dns records number  received in a
74 78
 							   dns answer*/
75 79
 
76 80
 #define DNS_HASH_SIZE	1024 /* must be <= 65535 */
... ...
@@ -80,7 +84,7 @@
80 84
 #define DEFAULT_DNS_MAX_MEM 500 /* 500 Kb */
81 85
 #define DEFAULT_DNS_TIMER_INTERVAL 120  /* 2 min. */
82 86
 #define DNS_HE_MAX_ADDR 10  /* maxium addresses returne in a hostent struct */
83
-#define MAX_CNAME_CHAIN  10 
87
+#define MAX_CNAME_CHAIN  10
84 88
 
85 89
 
86 90
 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 95
 unsigned int dns_cache_max_ttl=DEFAULT_DNS_CACHE_MAX_TTL; /* maximum ttl */
92 96
 unsigned int dns_cache_min_ttl=DEFAULT_DNS_CACHE_MIN_TTL; /* minimum ttl */
93 97
 unsigned int dns_timer_interval=DEFAULT_DNS_TIMER_INTERVAL; /* in s */
94
-int dns_flags=0; /* default flags used for the  dns_*resolvehost 
98
+int dns_flags=0; /* default flags used for the  dns_*resolvehost
95 99
                     (compatibility wrappers) */
96 100
 int dns_srv_lb=0; /* off by default */
97 101
 
102
+#ifdef USE_DNS_CACHE_STATS
103
+struct t_dns_cache_stats* dns_cache_stats=0;
104
+#endif
105
+
98 106
 #define LOCK_DNS_HASH()		lock_get(dns_hash_lock)
99 107
 #define UNLOCK_DNS_HASH()	lock_release(dns_hash_lock)
100 108
 
... ...
@@ -135,7 +143,7 @@ static const char* dns_str_errors[]={
135 143
 	"blacklisted ip",
136 144
 	"name too long ", /* try again with a shorter name */
137 145
 	"ip AF mismatch", /* address family mismatch */
138
-	"unresolvable NAPTR request", 
146
+	"unresolvable NAPTR request",
139 147
 	"bug - critical error"
140 148
 };
141 149
 
... ...
@@ -206,7 +214,7 @@ static ticks_t dns_timer(ticks_t ticks, struct timer_ln* tl, void* data)
206 214
 		return (ticks_t)(-1);
207 215
 #endif
208 216
 	if (*dns_cache_mem_used>12*(dns_cache_max_mem/16)){ /* ~ 75% used */
209
-		dns_cache_free_mem(dns_cache_max_mem/2, 1); 
217
+		dns_cache_free_mem(dns_cache_max_mem/2, 1);
210 218
 	}else{
211 219
 		dns_cache_clean(-1, 1); /* all the table, only expired entries */
212 220
 		/* TODO: better strategy? */
... ...
@@ -243,6 +251,10 @@ void destroy_dns_cache()
243 251
 		shm_free(dns_last_used_lst);
244 252
 		dns_last_used_lst=0;
245 253
 	}
254
+#endif
255
+#ifdef USE_DNS_CACHE_STATS
256
+	if (dns_cache_stats)
257
+		shm_free(dns_cache_stats);
246 258
 #endif
247 259
 	if (dns_cache_mem_used){
248 260
 		shm_free((void*)dns_cache_mem_used);
... ...
@@ -256,7 +268,7 @@ int init_dns_cache()
256 268
 {
257 269
 	int r;
258 270
 	int ret;
259
-	
271
+
260 272
 	ret=0;
261 273
 	/* sanity check */
262 274
 	if (E_DNS_CRITICAL>=sizeof(dns_str_errors)/sizeof(char*)){
... ...
@@ -284,7 +296,7 @@ int init_dns_cache()
284 296
 	}
285 297
 	for (r=0; r<DNS_HASH_SIZE; r++)
286 298
 		clist_init(&dns_hash[r], next, prev);
287
-	
299
+
288 300
 	dns_hash_lock=lock_alloc();
289 301
 	if (dns_hash_lock==0){
290 302
 		ret=E_OUT_OF_MEM;
... ...
@@ -305,7 +317,7 @@ int init_dns_cache()
305 317
 	}
306 318
 	atomic_set(dns_servers_up, 1);
307 319
 #endif
308
-	
320
+
309 321
 	/* fix options */
310 322
 	dns_cache_max_mem<<=10; /* Kb */ /* TODO: test with 0 */
311 323
 	/* fix flags */
... ...
@@ -344,13 +356,28 @@ int init_dns_cache()
344 356
 			goto error;
345 357
 		}
346 358
 	}
347
-	
359
+
348 360
 	return 0;
349 361
 error:
350 362
 	destroy_dns_cache();
351 363
 	return ret;
352 364
 }
353 365
 
366
+#ifdef USE_DNS_CACHE_STATS
367
+int init_dns_cache_stats(int iproc_num) {
368
+	/* if it is already initialized */
369
+	if (dns_cache_stats)
370
+		shm_free(dns_cache_stats);
371
+
372
+	dns_cache_stats=shm_malloc(sizeof(*dns_cache_stats) * iproc_num);
373
+	if (dns_cache_stats==0){
374
+		return E_OUT_OF_MEM;
375
+	}
376
+	memset(dns_cache_stats, 0, sizeof(*dns_cache_stats) * iproc_num);
377
+
378
+	return 0;
379
+}
380
+#endif
354 381
 
355 382
 /* hash function, type is not used (obsolete)
356 383
  * params: char* s, int len, int type
... ...
@@ -375,7 +402,7 @@ error:
375 402
 					(l), (l)->next, (l)->prev, \
376 403
 					(l)->prev, (l)->prev->next, (l)->prev->prev, \
377 404
 					(l)->next, (l)->next->next, (l)->next->prev \
378
-				) 
405
+				)
379 406
 
380 407
 #define debug_lu_lst( txt, l) \
381 408
 	do{ \
... ...
@@ -446,7 +473,7 @@ inline static struct dns_hash_entry* _dns_hash_find(str* name, int type,
446 473
 
447 474
 	servers_up = atomic_get(dns_servers_up);
448 475
 #endif
449
-	
476
+
450 477
 	cname_chain=0;
451 478
 	ret=0;
452 479
 	now=get_ticks_raw();
... ...
@@ -496,7 +523,7 @@ again:
496 523
 			debug_lu_lst("_dns_hash_find: cname: post append:",
497 524
 							&e->last_used_lst);
498 525
 #endif
499
-#endif		
526
+#endif
500 527
 			ret=e; /* if this is an unfinished cname chain, we try to
501 528
 					  return the last cname */
502 529
 			/* this is a cname => retry using its value */
... ...
@@ -519,7 +546,7 @@ again:
519 546
 
520 547
 
521 548
 
522
-/* frees cache entries, if expired_only=0 only expired entries will be 
549
+/* frees cache entries, if expired_only=0 only expired entries will be
523 550
  * removed, else all of them
524 551
  * it will process maximum no entries (to process all of them use -1)
525 552
  * returns the number of deleted entries
... ...
@@ -538,7 +565,7 @@ inline static int dns_cache_clean(unsigned int no, int expired_only)
538 565
 	unsigned int h;
539 566
 	static unsigned int start=0;
540 567
 #endif
541
-	
568
+
542 569
 	n=0;
543 570
 	deleted=0;
544 571
 	now=get_ticks_raw();
... ...
@@ -587,9 +614,9 @@ skip:
587 614
 
588 615
 
589 616
 
590
-/* frees cache entries, if expired_only=0 only expired entries will be 
617
+/* frees cache entries, if expired_only=0 only expired entries will be
591 618
  * removed, else all of them
592
- * it will stop when the dns cache used memory reaches target (to process all 
619
+ * it will stop when the dns cache used memory reaches target (to process all
593 620
  * of them use 0)
594 621
  * returns the number of deleted entries */
595 622
 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 632
 	unsigned int h;
606 633
 	static unsigned int start=0;
607 634
 #endif
608
-	
635
+
609 636
 	deleted=0;
610 637
 	now=get_ticks_raw();
611 638
 	LOCK_DNS_HASH();
... ...
@@ -622,7 +649,7 @@ inline static int dns_cache_free_mem(unsigned int target, int expired_only)
622 649
 #else
623 650
 	for(h=start; h!=(start+DNS_HASH_SIZE); h++){
624 651
 		clist_foreach_safe(&dns_hash[h%DNS_HASH_SIZE], e, t, next){
625
-			if (*dns_cache_mem_used<=target) 
652
+			if (*dns_cache_mem_used<=target)
626 653
 				goto skip;
627 654
 			if  ((s_ticks_t)(now-e->expire)>=0){
628 655
 				_dns_hash_remove(e);
... ...
@@ -634,7 +661,7 @@ inline static int dns_cache_free_mem(unsigned int target, int expired_only)
634 661
 	if (!expired_only){
635 662
 		for(h=start; h!=(start+DNS_HASH_SIZE); h++){
636 663
 			clist_foreach_safe(&dns_hash[h%DNS_HASH_SIZE], e, t, next){
637
-				if (*dns_cache_mem_used<=target) 
664
+				if (*dns_cache_mem_used<=target)
638 665
 					goto skip;
639 666
 				if  ((s_ticks_t)(now-e->expire)>=0){
640 667
 					_dns_hash_remove(e);
... ...
@@ -654,7 +681,7 @@ skip:
654 681
 
655 682
 /* locking  version (the dns hash must _not_be locked externally)
656 683
  * returns 0 when not found, the searched entry on success (with CNAMEs
657
- *  followed) or the last CNAME entry from an unfinished CNAME chain, 
684
+ *  followed) or the last CNAME entry from an unfinished CNAME chain,
658 685
  *  if the search matches a CNAME. On error sets *err (e.g. recursive CNAMEs).
659 686
  * it increases the internal refcnt => when finished dns_hash_put() must
660 687
  *  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 690
 													int* err)
664 691
 {
665 692
 	struct dns_hash_entry* e;
666
-	
693
+
667 694
 	LOCK_DNS_HASH();
668 695
 	e=_dns_hash_find(name, type, h, err);
669 696
 	if (e){
... ...
@@ -681,10 +708,13 @@ inline static struct dns_hash_entry* dns_hash_get(str* name, int type, int* h,
681 708
 inline static int dns_cache_add(struct dns_hash_entry* e)
682 709
 {
683 710
 	int h;
684
-	
711
+
685 712
 	/* check space */
686 713
 	/* atomic_add_long(dns_cache_total_used, e->size); */
687 714
 	if ((*dns_cache_mem_used+e->total_size)>=dns_cache_max_mem){
715
+#ifdef USE_DNS_CACHE_STATS
716
+		dns_cache_stats[process_no].dc_lru_cnt++;
717
+#endif
688 718
 		LOG(L_WARN, "WARNING: dns_cache_add: cache full, trying to free...\n");
689 719
 		/* free ~ 12% of the cache */
690 720
 		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 747
 inline static int dns_cache_add_unsafe(struct dns_hash_entry* e)
718 748
 {
719 749
 	int h;
720
-	
750
+
721 751
 	/* check space */
722 752
 	/* atomic_add_long(dns_cache_total_used, e->size); */
723 753
 	if ((*dns_cache_mem_used+e->total_size)>=dns_cache_max_mem){
754
+#ifdef USE_DNS_CACHE_STATS
755
+		dns_cache_stats[process_no].dc_lru_cnt++;
756
+#endif
724 757
 		LOG(L_WARN, "WARNING: dns_cache_add: cache full, trying to free...\n");
725 758
 		/* free ~ 12% of the cache */
726 759
 		UNLOCK_DNS_HASH();
... ...
@@ -757,7 +790,7 @@ inline static struct dns_hash_entry* dns_cache_mk_bad_entry(str* name,
757 790
 	struct dns_hash_entry* e;
758 791
 	int size;
759 792
 	ticks_t now;
760
-	
793
+
761 794
 #ifdef DNS_CACHE_DEBUG
762 795
 	DBG("dns_cache_mk_bad_entry(%.*s, %d, %d, %d)\n", name->len, name->s,
763 796
 									type, ttl, flags);
... ...
@@ -790,7 +823,7 @@ inline static struct dns_hash_entry* dns_cache_mk_ip_entry(str* name,
790 823
 	struct dns_hash_entry* e;
791 824
 	int size;
792 825
 	ticks_t now;
793
-	
826
+
794 827
 	/* everything is allocated in one block: dns_hash_entry + name +
795 828
 	 * + dns_rr + rdata;  dns_rr must start at an aligned adress,
796 829
 	 * 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 835
 	 * dns_rr
803 836
 	 * rdata  (no padding needed, since for ip is just an array of chars)
804 837
 	  */
805
-	size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1)+ 
838
+	size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1)+
806 839
 			sizeof(struct dns_rr)+ ip->len;
807 840
 	e=shm_malloc(size);
808 841
 	if (e==0){
... ...
@@ -838,7 +871,7 @@ static struct dns_hash_entry* dns_cache_mk_srv_entry(str* name,
838 871
 	struct dns_hash_entry* e;
839 872
 	int size;
840 873
 	ticks_t now;
841
-	
874
+
842 875
 	/* everything is allocated in one block: dns_hash_entry + name +
843 876
 	 * + dns_rr + rdata;  dns_rr must start at an aligned adress,
844 877
 	 * 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 883
 	 * padding to multiple of sizeof(long)
851 884
 	 * dns_rr
852 885
 	 * padding to multiple of sizeof(short)
853
-	 * rdata 
886
+	 * rdata
854 887
 	  */
855
-	size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1) + 
888
+	size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1) +
856 889
 		ROUND_SHORT(sizeof(struct dns_rr)) +
857 890
 		sizeof(struct srv_rdata)-1 +
858 891
 		rr_name->len+1;
... ...
@@ -902,15 +935,15 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
902 935
 	ticks_t now;
903 936
 	unsigned int max_ttl;
904 937
 	unsigned int ttl;
905
-	
938
+
906 939
 #define rec_matches(rec, t, n) /*(struct rdata* record, int type, str* name)*/\
907 940
 	(	((rec)->name_len==(n)->len) && ((rec)->type==(t)) && \
908 941
 		(strncasecmp((rec)->name, (n)->s, (n)->len)==0))
909 942
 	/* init */
910 943
 	tmp_lst=0;
911 944
 	tail=&tmp_lst;
912
-	
913
-	
945
+
946
+
914 947
 	/* everything is allocated in one block: dns_hash_entry + name +
915 948
 	 * + dns_rr + rdata_raw+ ....;  dns_rr must start at an aligned adress,
916 949
 	 * 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 954
 	 * name (name_len+1 bytes)  (&e->name[0])
922 955
 	 * padding to multiple of sizeof(char*)
923 956
 	 * dns_rr1 (e->rr_lst)
924
-	 * possible padding: no padding for a_rdata or aaaa_rdata, 
957
+	 * possible padding: no padding for a_rdata or aaaa_rdata,
925 958
 	 *                   multipe of sizeof(short) for srv_rdata,
926 959
 	 *                   multiple of sizeof(long) for naptr_rdata and others
927 960
 	 * 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 980
 	switch(type){
948 981
 		case T_A:
949 982
 			for(; *p;){
950
-				if (!rec_matches((*p), type, name)){ 
983
+				if (!rec_matches((*p), type, name)){
951 984
 					/* skip this record */
952 985
 					p=&(*p)->next; /* advance */
953 986
 					continue;
... ...
@@ -965,7 +998,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
965 998
 			break;
966 999
 		case T_AAAA:
967 1000
 			for(; *p;){
968
-				if (!rec_matches((*p), type, name)){ 
1001
+				if (!rec_matches((*p), type, name)){
969 1002
 					/* skip this record */
970 1003
 					p=&(*p)->next; /* advance */
971 1004
 					continue;
... ...
@@ -984,7 +1017,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
984 1017
 			break;
985 1018
 		case T_SRV:
986 1019
 			for(; *p;){
987
-				if (!rec_matches((*p), type, name)){ 
1020
+				if (!rec_matches((*p), type, name)){
988 1021
 					/* skip this record */
989 1022
 					p=&(*p)->next; /* advance */
990 1023
 					continue;
... ...
@@ -1003,7 +1036,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1003 1036
 			break;
1004 1037
 		case T_NAPTR:
1005 1038
 			for(; *p;){
1006
-				if (!rec_matches((*p), type, name)){ 
1039
+				if (!rec_matches((*p), type, name)){
1007 1040
 					/* skip this record */
1008 1041
 					p=&(*p)->next; /* advance */
1009 1042
 					continue;
... ...
@@ -1022,7 +1055,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1022 1055
 			break;
1023 1056
 		case T_CNAME:
1024 1057
 			for(; *p;){
1025
-				if (!rec_matches((*p), type, name)){ 
1058
+				if (!rec_matches((*p), type, name)){
1026 1059
 					/* skip this record */
1027 1060
 					p=&(*p)->next; /* advance */
1028 1061
 					continue;
... ...
@@ -1110,7 +1143,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1110 1143
 				rr->rdata=(void*)((char*)rr+
1111 1144
 								ROUND_SHORT(sizeof(struct dns_rr)));
1112 1145
 				/* copy the whole srv_rdata block*/
1113
-				memcpy(rr->rdata, l->rdata, 
1146
+				memcpy(rr->rdata, l->rdata,
1114 1147
 						SRV_RDATA_SIZE(*(struct srv_rdata*)l->rdata) );
1115 1148
 				rr->next=(void*)((char*)rr+
1116 1149
 							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 1161
 				rr->rdata=(void*)((char*)rr+
1129 1162
 								ROUND_POINTER(sizeof(struct dns_rr)));
1130 1163
 				/* copy the whole naptr_rdata block*/
1131
-				memcpy(rr->rdata, l->rdata, 
1164
+				memcpy(rr->rdata, l->rdata,
1132 1165
 						NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata) );
1133 1166
 				/* adjust the string pointer */
1134 1167
 				((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 1190
 				rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1158 1191
 				max_ttl=MAX(max_ttl, ttl);
1159 1192
 				rr->rdata=(void*)((char*)rr+sizeof(struct dns_rr));
1160
-				memcpy(rr->rdata, l->rdata, 
1193
+				memcpy(rr->rdata, l->rdata,
1161 1194
 							CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata));
1162 1195
 				rr->next=(void*)((char*)rr+ROUND_POINTER(sizeof(struct dns_rr)+
1163 1196
 							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 1236
 	int r, i;
1204 1237
 	int no_records; /* number of different records */
1205 1238
 	unsigned int ttl;
1206
-	
1207
-	
1208
-	no_records=0; 
1239
+
1240
+
1241
+	no_records=0;
1209 1242
 	rec[0].e=0;
1210 1243
 	/* everything is allocated in one block: dns_hash_entry + name +
1211 1244
 	 * + 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 1250
 	 * name (name_len+1 bytes)  (&e->name[0])
1218 1251
 	 * padding to multiple of sizeof(char*)
1219 1252
 	 * dns_rr1 (e->rr_lst)
1220
-	 * possible padding: no padding for a_rdata or aaaa_rdata, 
1253
+	 * possible padding: no padding for a_rdata or aaaa_rdata,
1221 1254
 	 *                   multipe of sizeof(short) for srv_rdata,
1222 1255
 	 *                   multiple of sizeof(long) for naptr_rdata and others
1223 1256
 	 * 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 1262
 	/* compute size */
1230 1263
 	for(l=rd, i=0; l && (i<MAX_DNS_RECORDS); l=l->next, i++){
1231 1264
 		for (r=0; r<no_records; r++){
1232
-			if ((l->type==rec[r].rd->type) && 
1265
+			if ((l->type==rec[r].rd->type) &&
1233 1266
 					(l->name_len==rec[r].rd->name_len)
1234 1267
 				&& (strncasecmp(l->name, rec[r].rd->name, l->name_len)==0)){
1235 1268
 				/* found */
... ...
@@ -1283,7 +1316,7 @@ found:
1283 1316
 							"supported\n", l->type);
1284 1317
 		}
1285 1318
 	}
1286
-	
1319
+
1287 1320
 	now=get_ticks_raw();
1288 1321
 	/* alloc & init the entries */
1289 1322
 	for (r=0; r<no_records; r++){
... ...
@@ -1298,7 +1331,7 @@ found:
1298 1331
 		rec[r].e->type=rec[r].rd->type;
1299 1332
 		rec[r].e->last_used=now;
1300 1333
 		/* memset makes sure is 0-term. */
1301
-		memcpy(rec[r].e->name, rec[r].rd->name, rec[r].rd->name_len); 
1334
+		memcpy(rec[r].e->name, rec[r].rd->name, rec[r].rd->name_len);
1302 1335
 		rec[r].e->rr_lst=(struct dns_rr*)((char*)rec[r].e+
1303 1336
 				ROUND_POINTER(sizeof(struct dns_hash_entry)+rec[r].e->name_len
1304 1337
 								 -1+1));
... ...
@@ -1347,7 +1380,7 @@ found:
1347 1380
 				rec[r].rr->rdata=(void*)((char*)rec[r].rr+
1348 1381
 								ROUND_SHORT(sizeof(struct dns_rr)));
1349 1382
 				/* copy the whole srv_rdata block*/
1350
-				memcpy(rec[r].rr->rdata, l->rdata, 
1383
+				memcpy(rec[r].rr->rdata, l->rdata,
1351 1384
 						SRV_RDATA_SIZE(*(struct srv_rdata*)l->rdata) );
1352 1385
 				rec[r].rr->next=(void*)((char*)rec[r].rr+
1353 1386
 							ROUND_POINTER( ROUND_SHORT(sizeof(struct dns_rr))+
... ...
@@ -1362,7 +1395,7 @@ found:
1362 1395
 				rec[r].rr->rdata=(void*)((char*)rec[r].rr+
1363 1396
 								ROUND_POINTER(sizeof(struct dns_rr)));
1364 1397
 				/* copy the whole srv_rdata block*/
1365
-				memcpy(rec[r].rr->rdata, l->rdata, 
1398
+				memcpy(rec[r].rr->rdata, l->rdata,
1366 1399
 						NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata) );
1367 1400
 				/* adjust the string pointer */
1368 1401
 				((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 1478
 	struct dns_rr* rr;
1446 1479
 	static int cname_chain_len=0;
1447 1480
 	str tmp;
1448
-	
1481
+
1449 1482
 	ret=0;
1450 1483
 	l=e;
1451 1484
 #ifdef DNS_CACHE_DEBUG
... ...
@@ -1521,10 +1554,10 @@ inline static struct dns_hash_entry* dns_get_related(struct dns_hash_entry* e,
1521 1554
 				clist_append_sublist(l, t, lst_end, next, prev);
1522 1555
 			}else{
1523 1556
 				/* 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 
1557
+				 *  return it (e.g. recs are only CNAME x & x A 1.2.3.4 or
1525 1558
 				 *  CNAME & SRV) */
1526 1559
 				if (t->type==type)
1527
-					ret=t; 
1560
+					ret=t;
1528 1561
 				clist_append(l, t, next, prev);
1529 1562
 			}
1530 1563
 		}
... ...
@@ -1550,11 +1583,16 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
1550 1583
 	struct ip_addr* ip;
1551 1584
 	str cname_val;
1552 1585
 	char name_buf[MAX_DNS_NAME];
1553
-	
1586
+
1554 1587
 	e=0;
1555 1588
 	l=0;
1556 1589
 	cname_val.s=0;
1557
-	
1590
+
1591
+#ifdef USE_DNS_CACHE_STATS
1592
+	if (dns_cache_stats)
1593
+		dns_cache_stats[process_no].dns_req_cnt++;
1594
+#endif /* USE_DNS_CACHE_STATS */
1595
+
1558 1596
 	if (type==T_A){
1559 1597
 		if ((ip=str2ip(name))!=0){
1560 1598
 				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 1630
 			/* e should contain the searched entry (if found) and l
1593 1631
 			 * all the entries (e and related) */
1594 1632
 			if (e){
1595
-				atomic_set(&e->refcnt, 1); /* 1 because we return a 
1633
+				atomic_set(&e->refcnt, 1); /* 1 because we return a
1596 1634
 												ref. to it */
1597 1635
 			}else{
1598 1636
 				/* e==0 => l contains a  cname list => we use the last
1599 1637
 				 * cname from the chain for a new resolve attempt (l->prev) */
1600
-				/* only one cname record is allowed (rfc2181), so we ignore 
1638
+				/* only one cname record is allowed (rfc2181), so we ignore
1601 1639
 				 * the others (we take only the first one) */
1602 1640
 				cname_val.s=
1603 1641
 					((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 1659
 			}
1622 1660
 			UNLOCK_DNS_HASH();
1623 1661
 			/* if only cnames found => try to resolve the last one */
1624
-			if (cname_val.s){ 
1662
+			if (cname_val.s){
1625 1663
 				DBG("dns_cache_do_request: dns_get_entry(cname: %.*s (%d))\n",
1626 1664
 						cname_val.len, cname_val.s, cname_val.len);
1627 1665
 				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 1698
 				}else if ((r->type==type) && (r->name_len==name->len) &&
1661 1699
 							(strncasecmp(r->name, name->s, name->len)==0)){
1662 1700
 					e=r;
1663
-					atomic_set(&e->refcnt, 1); /* 1 because we return a ref. 
1701
+					atomic_set(&e->refcnt, 1); /* 1 because we return a ref.
1664 1702
 												  to it */
1665 1703
 				}
1666 1704
 			}
... ...
@@ -1696,7 +1734,7 @@ inline static struct dns_hash_entry* dns_get_entry(str* name, int type)
1696 1734
 	str cname_val;
1697 1735
 	int err;
1698 1736
 	static int rec_cnt=0; /* recursion protection */
1699
-	
1737
+
1700 1738
 	e=0;
1701 1739
 	if (rec_cnt>MAX_CNAME_CHAIN){
1702 1740
 		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 1743
 	}
1706 1744
 	rec_cnt++;
1707 1745
 	e=dns_hash_get(name, type, &h, &err);
1746
+#ifdef USE_DNS_CACHE_STATS
1747
+	if (e) {
1748
+		if (e->err_flags==DNS_BAD_NAME && dns_cache_stats)
1749
+			/* negative DNS cache hit */
1750
+			dns_cache_stats[process_no].dc_neg_hits_cnt++;
1751
+		else if (!e->err_flags && dns_cache_stats) /* DNS cache hit */
1752
+			dns_cache_stats[process_no].dc_hits_cnt++;
1753
+
1754
+		if (dns_cache_stats)
1755
+			dns_cache_stats[process_no].dns_req_cnt++;
1756
+	}
1757
+#endif /* USE_DNS_CACHE_STATS */
1758
+
1708 1759
 	if ((e==0) && ((err) || ((e=dns_cache_do_request(name, type))==0))){
1709 1760
 		goto error;
1710 1761
 	}else if ((e->type==T_CNAME) && (type!=T_CNAME)){
1711 1762
 		/* cname found instead which couldn't be resolved with the cached
1712 1763
 		 * info => try a dns request */
1713
-		/* only one cname record is allowed (rfc2181), so we ignore 
1764
+		/* only one cname record is allowed (rfc2181), so we ignore
1714 1765
 		 * the others (we take only the first one) */
1715 1766
 		cname_val.s= ((struct cname_rdata*)e->rr_lst->rdata)->name;
1716 1767
 		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 1814
 
1764 1815
 	servers_up = atomic_get(dns_servers_up);
1765 1816
 #endif
1766
-	
1817
+
1767 1818
 	flags=0;
1768 1819
 	for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/
1769 1820
 	for(;rr;rr=rr->next){
... ...
@@ -1808,9 +1859,9 @@ inline static unsigned dns_srv_random(unsigned max)
1808 1859
  * to the RFC2782 server selection mechanism
1809 1860
  * params:
1810 1861
  *    e     is a dns srv hash entry
1811
- *    no    is the start index of the current group (a group is a set of SRV 
1862
+ *    no    is the start index of the current group (a group is a set of SRV
1812 1863
  *          rrs with the same priority)
1813
- *    tried is a bitmap where the tried srv rrs of the same priority are 
1864
+ *    tried is a bitmap where the tried srv rrs of the same priority are
1814 1865
  *          marked
1815 1866
  *    now - current time/ticks value
1816 1867
  * 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 1887
 											 srv_flags_t* tried,
1837 1888
 											 unsigned char* no, ticks_t now)
1838 1889
 {
1839
-#define MAX_SRV_GRP_IDX		(sizeof(srv_flags_t)*8) 
1890
+#define MAX_SRV_GRP_IDX		(sizeof(srv_flags_t)*8)
1840 1891
 	struct dns_rr* rr;
1841 1892
 	struct dns_rr* start_grp;
1842 1893
 	int n;
... ...
@@ -1855,10 +1906,10 @@ inline static struct dns_rr* dns_srv_get_nxt_rr(struct dns_hash_entry* e,
1855 1906
 
1856 1907
 	servers_up = atomic_get(dns_servers_up);
1857 1908
 #endif
1858
-	
1909
+
1859 1910
 	rand_w=0;
1860 1911
 	for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/
1861
-	
1912
+
1862 1913
 retry:
1863 1914
 	if (unlikely(rr==0))
1864 1915
 		goto no_more_rrs;
... ...
@@ -1899,7 +1950,7 @@ retry:
1899 1950
 		goto retry;
1900 1951
 	}else if ((found==1) || ((rand_w=dns_srv_random(sum))==0)){
1901 1952
 		/* 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, 
1953
+		 * 2. if rand_w==0, immediately select a 0 weight record if present,
1903 1954
 		 *     or else the first record found
1904 1955
 		 *  (this takes care of the 0-weight at the beginning requirement) */
1905 1956
 		i=saved_idx; /* saved idx contains either first 0 weight or first
... ...
@@ -1930,10 +1981,10 @@ no_more_rrs:
1930 1981
 
1931 1982
 
1932 1983
 
1933
-/* gethostbyname compatibility: converts a dns_hash_entry structure 
1984
+/* gethostbyname compatibility: converts a dns_hash_entry structure
1934 1985
  * to a statical internal hostent structure
1935 1986
  * returns a pointer to the internal hostent structure on success or
1936
- *          0 on error 
1987
+ *          0 on error
1937 1988
  */
1938 1989
 struct hostent* dns_entry2he(struct dns_hash_entry* e)
1939 1990
 {
... ...
@@ -1947,7 +1998,7 @@ struct hostent* dns_entry2he(struct dns_hash_entry* e)
1947 1998
 	unsigned char rr_no;
1948 1999
 	ticks_t now;
1949 2000
 	int i;
1950
-	
2001
+
1951 2002
 	switch(e->type){
1952 2003
 		case T_A:
1953 2004
 			af=AF_INET;
... ...
@@ -1962,12 +2013,12 @@ struct hostent* dns_entry2he(struct dns_hash_entry* e)
1962 2013
 					e->type, e->name_len, e->name);
1963 2014
 			return 0;
1964 2015
 	}
1965
-	
1966
-	
2016
+
2017
+
1967 2018
 	rr_no=0;
1968 2019
 	now=get_ticks_raw();
1969 2020
 	rr=dns_entry_get_rr(e, &rr_no, now);
1970
-	for(i=0; rr && (i<DNS_HE_MAX_ADDR); i++, 
2021
+	for(i=0; rr && (i<DNS_HE_MAX_ADDR); i++,
1971 2022
 							rr=dns_entry_get_rr(e, &rr_no, now)){
1972 2023
 				p_addr[i]=&address[i*len];
1973 2024
 				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 2028
 				rr_no, e->name_len, e->name, e->type);
1978 2029
 		return 0; /* no good record found */
1979 2030
 	}
1980
-	
2031
+
1981 2032
 	p_addr[i]=0; /* mark the end of the addresses */
1982 2033
 	p_aliases[0]=0; /* no aliases */
1983 2034
 	memcpy(hostname, e->name, e->name_len);
1984 2035
 	hostname[e->name_len]=0;
1985
-	
2036
+
1986 2037
 	he.h_addrtype=af;
1987 2038
 	he.h_length=len;
1988 2039
 	he.h_addr_list=p_addr;
1989 2040
 	he.h_aliases=p_aliases;
1990 2041
 	he.h_name=hostname;
1991
-	
2042
+
1992 2043
 	return &he;
1993 2044
 }
1994 2045
 
1995 2046
 
1996 2047
 
1997
-/* gethostbyname compatibility: performs an a_lookup and returns a pointer 
2048
+/* gethostbyname compatibility: performs an a_lookup and returns a pointer
1998 2049
  * to a statical internal hostent structure
1999 2050
  * returns 0 on success, <0 on error (see the error codes)
2000 2051
  */
... ...
@@ -2003,7 +2054,7 @@ struct hostent* dns_a_get_he(str* name)
2003 2054
 	struct dns_hash_entry* e;
2004 2055
 	struct ip_addr* ip;
2005 2056
 	struct hostent* he;
2006
-	
2057
+
2007 2058
 	e=0;
2008 2059
 	if ((ip=str2ip(name))!=0){
2009 2060
 		return ip_addr2he(name, ip);
... ...
@@ -2018,7 +2069,7 @@ struct hostent* dns_a_get_he(str* name)
2018 2069
 
2019 2070
 
2020 2071
 
2021
-/* gethostbyname compatibility: performs an aaaa_lookup and returns a pointer 
2072
+/* gethostbyname compatibility: performs an aaaa_lookup and returns a pointer
2022 2073
  * to a statical internal hostent structure
2023 2074
  * returns 0 on success, <0 on error (see the error codes)
2024 2075
  */
... ...
@@ -2027,7 +2078,7 @@ struct hostent* dns_aaaa_get_he(str* name)
2027 2078
 	struct dns_hash_entry* e;
2028 2079
 	struct ip_addr* ip;
2029 2080
 	struct hostent* he;
2030
-	
2081
+
2031 2082
 	e=0;
2032 2083
 	if ((ip=str2ip6(name))!=0){
2033 2084
 		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 2126
 struct hostent* dns_get_he(str* name, int flags)
2076 2127
 {
2077 2128
 	struct hostent* he;
2078
-	
2079
-	
2129
+
2130
+
2080 2131
 	if ((flags&(DNS_IPV6_FIRST|DNS_IPV6_ONLY))){
2081 2132
 		he=dns_aaaa_get_he(name);
2082 2133
 		if (he) return he;
... ...
@@ -2105,7 +2156,7 @@ struct hostent* dns_srv_get_he(str* name, unsigned short* port, int flags)
2105 2156
 	struct hostent* he;
2106 2157
 	ticks_t now;
2107 2158
 	unsigned char rr_no;
2108
-	
2159
+
2109 2160
 	rr=0;
2110 2161
 	he=0;
2111 2162
 	now=get_ticks_raw();
... ...
@@ -2136,7 +2187,7 @@ error:
2136 2187
 struct hostent* dns_resolvehost(char* name)
2137 2188
 {
2138 2189
 	str host;
2139
-	
2190
+
2140 2191
 	if ((use_dns_cache==0) || (dns_hash==0)){ /* not init yet */
2141 2192
 		return _resolvehost(name);
2142 2193
 	}
... ...
@@ -2155,14 +2206,14 @@ struct hostent* dns_resolvehost(char* name)
2155 2206
  * returns: hostent struct & *port filled with the port from the SRV record;
2156 2207
  *  0 on error
2157 2208
  */
2158
-struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, 
2209
+struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2159 2210
 										char* proto)
2160 2211
 {
2161 2212
 	struct dns_srv_handle h;
2162 2213
 	struct ip_addr ip;
2163 2214
 	int ret;
2164
-	
2165
-	if ((use_dns_cache==0) || (dns_hash==0)){ 
2215
+
2216
+	if ((use_dns_cache==0) || (dns_hash==0)){
2166 2217
 		/* not init or off => use normal, non-cached version */
2167 2218
 		return _sip_resolvehost(name, port, proto);
2168 2219
 	}
... ...
@@ -2184,7 +2235,7 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2184 2235
  * returns: hostent struct & *port filled with the port from the SRV record;
2185 2236
  *  0 on error
2186 2237
  */
2187
-struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port, 
2238
+struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2188 2239
 										char* proto)
2189 2240
 {
2190 2241
 	struct hostent* he;
... ...
@@ -2194,7 +2245,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2194 2245
 	str srv_name;
2195 2246
 	char srv_proto;
2196 2247
 
2197
-	if ((use_dns_cache==0) || (dns_hash==0)){ 
2248
+	if ((use_dns_cache==0) || (dns_hash==0)){
2198 2249
 		/* not init or off => use normal, non-cached version */
2199 2250
 		return _sip_resolvehost(name, port, proto);
2200 2251
 	}
... ...
@@ -2209,7 +2260,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2209 2260
 	}
2210 2261
 	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
2211 2262
 	if ((port)&&(*port==0)){
2212
-		*port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we 
2263
+		*port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
2213 2264
 														 don't find another */
2214 2265
 		if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
2215 2266
 			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 2275
 				/* we are lucky, this is an ip address */
2225 2276
 				return ip_addr2he(name,ip);
2226 2277
 			}
2227
-			
2278
+
2228 2279
 			switch(srv_proto){
2229 2280
 				case PROTO_NONE: /* no proto specified, use udp */
2230 2281
 					if (proto)
... ...
@@ -2277,7 +2328,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2277 2328
  * params:
2278 2329
  *         naptr_head - naptr dns_rr list head
2279 2330
  *         tried      - bitmap used to keep track of the already tried records
2280
- *                      (no more then sizeof(tried)*8 valid records are 
2331
+ *                      (no more then sizeof(tried)*8 valid records are
2281 2332
  *                      ever walked
2282 2333
  *         srv_name   - if succesfull, it will be set to the selected record
2283 2334
  *                      srv name (naptr repl.)
... ...
@@ -2285,10 +2336,10 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
2285 2336
  *                      protocol
2286 2337
  * returns  0 if no more records found or a pointer to the selected record
2287 2338
  *  and sets  protocol and srv_name
2288
- * WARNING: when calling first time make sure you run first 
2339
+ * WARNING: when calling first time make sure you run first
2289 2340
  *           naptr_iterate_init(&tried)
2290 2341
  */
2291
-struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head, 
2342
+struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head,
2292 2343
 											naptr_bmp_t* tried,
2293 2344
 											str* srv_name, char* proto)
2294 2345
 {
... ...
@@ -2318,7 +2369,7 @@ struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head,
2318 2369
 		}
2319 2370
 #ifdef DNS_CACHE_DEBUG
2320 2371
 		DBG("naptr_iterate: found a valid sip NAPTR rr %.*s,"
2321
-					" proto %d\n", naptr->repl_len, naptr->repl, 
2372
+					" proto %d\n", naptr->repl_len, naptr->repl,
2322 2373
 					(int)naptr_proto);
2323 2374
 #endif
2324 2375
 		if ((naptr_proto_supported(naptr_proto))){
... ...
@@ -2332,7 +2383,7 @@ struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head,
2332 2383
 		/* found something */
2333 2384
 #ifdef DNS_CACHE_DEBUG
2334 2385
 		DBG("naptr_iterate: choosed NAPTR rr %.*s, proto %d"
2335
-					" tried: 0x%x\n", naptr_saved->repl_len, 
2386
+					" tried: 0x%x\n", naptr_saved->repl_len,
2336 2387
 					naptr_saved->repl, (int)saved_proto, *tried);
2337 2388
 #endif
2338 2389
 		*tried|=1<<idx;
... ...
@@ -2347,7 +2398,7 @@ end:
2347 2398
 
2348 2399
 
2349 2400
 
2350
-/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV 
2401
+/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV
2351 2402
  * lookup if *port==0 or normal A/AAAA lookup
2352 2403
  * if *port!=0.
2353 2404
  * when performing SRV lookup (*port==0) it will use proto to look for
... ...
@@ -2355,7 +2406,7 @@ end:
2355 2406
  * returns: hostent struct & *port filled with the port from the SRV record;
2356 2407
  *  0 on error
2357 2408
  */
2358
-struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port, 
2409
+struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port,
2359 2410
 										char* proto)
2360 2411
 {
2361 2412
 	struct hostent* he;
... ...
@@ -2364,7 +2415,7 @@ struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port,
2364 2415
 	struct dns_hash_entry* e;
2365 2416
 	char n_proto;
2366 2417
 	str srv_name;
2367
-	
2418
+
2368 2419
 	he=0;
2369 2420
 	if (dns_hash==0){ /* not init => use normal, non-cached version */
2370 2421
 		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 2448
 												&srv_name, &n_proto)){
2398 2449
 			if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0){
2399 2450
 #ifdef DNS_CACHE_DEBUG
2400
-				DBG("dns_naptr_sip_resolvehost(%.*s, %d, %d) srv, ret=%p\n", 
2451
+				DBG("dns_naptr_sip_resolvehost(%.*s, %d, %d) srv, ret=%p\n",
2401 2452
 							name->len, name->s, (int)*port, (int)*proto, he);
2402 2453
 #endif
2403 2454
 				dns_hash_put(e);
... ...
@@ -2415,7 +2466,7 @@ naptr_not_found:
2415 2466
 
2416 2467
 
2417 2468
 
2418
-/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV 
2469
+/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV
2419 2470
  * lookup if *port==0 or normal A/AAAA lookup
2420 2471
  * if *port!=0.
2421 2472
  * when performing SRV lookup (*port==0) it will use proto to look for
... ...
@@ -2423,7 +2474,7 @@ naptr_not_found:
2423 2474
  * returns: hostent struct & *port filled with the port from the SRV record;
2424 2475
  *  0 on error
2425 2476
  */
2426
-struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, 
2477
+struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2427 2478
 										char* proto)
2428 2479
 {
2429 2480
 #ifdef USE_NAPTR
... ...
@@ -2437,7 +2488,7 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
2437 2488
 
2438 2489
 /* performs an a lookup, fills the dns_entry pointer and the ip addr.
2439 2490
  *  (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 
2491
+ *   to the result, if not it uses the current value and tries to use
2441 2492
  *   the rr_no record from it.
2442 2493
  * params:  e - must contain the "in-use" dns_hash_entry pointer (from
2443 2494
  *               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 2498
  *                 at *rr_no
2448 2499
  *          rr_no - record number to start searching for a good ip from
2449 2500
  *                  (e.g. value from previous call + 1), filled on return
2450
- *                  with the number of the record corresponding to the 
2501
+ *                  with the number of the record corresponding to the
2451 2502
  *                  returned ip
2452 2503
  * returns 0 on success, <0 on error (see the error codes),
2453 2504
  *         fills e, ip and rr_no
... ...
@@ -2474,9 +2525,9 @@ int dns_a_resolve(struct dns_hash_entry** e, unsigned char* rr_no,
2474 2525
 	int ret;
2475 2526
 	ticks_t now;
2476 2527
 	struct ip_addr* tmp;
2477
-	
2528
+
2478 2529
 	rr=0;
2479
-	ret=-E_DNS_NO_IP; 
2530
+	ret=-E_DNS_NO_IP;
2480 2531
 	if (*e==0){ /* do lookup */
2481 2532
 		/* if ip don't set *e */
2482 2533
 		if ((tmp=str2ip(name))!=0){
... ...
@@ -2509,19 +2560,19 @@ error:
2509 2560
 
2510 2561
 /* lookup, fills the dns_entry pointer and the ip addr.
2511 2562
  *  (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 
2563
+ *   to the result, if not it uses the current value and tries to use
2513 2564
  * Same as dns_a_resolve but for aaaa records (see above).
2514 2565
  */
2515
-int dns_aaaa_resolve(struct dns_hash_entry** e, unsigned char* rr_no, 
2566
+int dns_aaaa_resolve(struct dns_hash_entry** e, unsigned char* rr_no,
2516 2567
 						str* name, struct ip_addr* ip)
2517 2568
 {
2518 2569
 	struct dns_rr* rr;
2519 2570
 	int ret;
2520 2571
 	ticks_t now;
2521 2572
 	struct ip_addr* tmp;
2522
-	
2573
+
2523 2574
 	rr=0;
2524
-	ret=-E_DNS_NO_IP; 
2575
+	ret=-E_DNS_NO_IP;
2525 2576
 	if (*e==0){ /* do lookup */
2526 2577
 		/* if ip don't set *e */
2527 2578
 		if ((tmp=str2ip6(name))!=0){
... ...
@@ -2559,12 +2610,12 @@ error:
2559 2610
  *  see dns_a_resolve() for the rest of the params., examples a.s.o
2560 2611
  *  WARNING: don't forget dns_hash_put(*e) when e is not needed anymore
2561 2612
  */
2562
-int dns_ip_resolve(struct dns_hash_entry** e, unsigned char* rr_no, 
2613
+int dns_ip_resolve(struct dns_hash_entry** e, unsigned char* rr_no,
2563 2614
 					str* name, struct ip_addr* ip, int flags)
2564 2615
 {
2565 2616
 	int ret;
2566
-	
2567
-	ret=-E_DNS_NO_IP; 
2617
+
2618
+	ret=-E_DNS_NO_IP;
2568 2619
 	if (*e==0){ /* first call */
2569 2620
 		if ((flags&(DNS_IPV6_FIRST|DNS_IPV6_ONLY))){
2570 2621
 			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 2652
 			ret=dns_a_resolve(e, rr_no, name, ip);
2602 2653
 		}
2603 2654
 	}else{
2604
-		LOG(L_CRIT, "BUG: dns_ip_resolve: invalid record type %d\n", 
2655
+		LOG(L_CRIT, "BUG: dns_ip_resolve: invalid record type %d\n",
2605 2656
 					(*e)->type);
2606 2657
 	}
2607 2658
 	return ret;
... ...
@@ -2631,9 +2682,9 @@ int dns_srv_resolve_nxt(struct dns_hash_entry** e,
2631 2682
 	struct dns_rr* rr;
2632 2683
 	int ret;
2633 2684
 	ticks_t now;
2634
-	
2685
+
2635 2686
 	rr=0;
2636
-	ret=-E_DNS_NO_SRV; 
2687
+	ret=-E_DNS_NO_SRV;
2637 2688
 	if (*e==0){
2638 2689
 		if ((*e=dns_get_entry(name, T_SRV))==0)
2639 2690
 			goto error;
... ...
@@ -2681,13 +2732,13 @@ int dns_srv_resolve_ip(struct dns_srv_handle* h,
2681 2732
 {
2682 2733
 	int ret;
2683 2734
 	str host;
2684
-	
2735
+
2685 2736
 	host.len=0;
2686 2737
 	host.s=0;
2687 2738
 	do{
2688 2739
 		if (h->a==0){
2689 2740
 #ifdef DNS_SRV_LB
2690
-			if ((ret=dns_srv_resolve_nxt(&h->srv, 
2741
+			if ((ret=dns_srv_resolve_nxt(&h->srv,
2691 2742
 								(flags & DNS_SRV_RR_LB)?&h->srv_tried_rrs:0,
2692 2743
 								&h->srv_no,
2693 2744
 								name, &host, port))<0)
... ...
@@ -2713,8 +2764,8 @@ int dns_srv_resolve_ip(struct dns_srv_handle* h,
2713 2764
 	}while(ret<0);
2714 2765
 error:
2715 2766
 #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, 
2767
+	DBG("dns_srv_resolve_ip(\"%.*s\", %d, %d), ret=%d, ip=%s\n",
2768
+			name->len, name->s, h->srv_no, h->ip_no, ret,
2718 2769
 			ip?ZSW(ip_addr2a(ip)):"");
2719 2770
 #endif
2720 2771
 	return ret;
... ...
@@ -2726,7 +2777,7 @@ error:
2726 2777
  * if *port!=0.
2727 2778
  * when performing SRV lookup (*port==0) it will use proto to look for
2728 2779
  * 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 
2780
+ * h must be initialized prior to  calling this function and can be used to
2730 2781
  * get the subsequent ips
2731 2782
  * returns:  <0 on error
2732 2783
  *            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 2846
 						/* proto already set */
2796 2847
 						return 0;
2797 2848
 					}
2798
-					
2849
+
2799 2850
 					switch(srv_proto){
2800 2851
 						case PROTO_NONE: /* no proto specified, use udp */
2801 2852
 							if (proto)
... ...
@@ -2830,7 +2881,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2830 2881
 															port, flags))>=0)
2831 2882
 					{
2832 2883
 #ifdef DNS_CACHE_DEBUG
2833
-						DBG("dns_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n", 
2884
+						DBG("dns_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n",
2834 2885
 							name->len, name->s, h->srv_no, h->ip_no, ret);
2835 2886
 #endif
2836 2887
 						/* proto already set */
... ...
@@ -2849,7 +2900,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2849 2900
 			ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags);
2850 2901
 			if (proto)
2851 2902
 				*proto=h->proto;
2852
-			DBG("dns_sip_resolve(%.*s, %d, %d), srv, ret=%d\n", 
2903
+			DBG("dns_sip_resolve(%.*s, %d, %d), srv, ret=%d\n",
2853 2904
 					name->len, name->s, h->srv_no, h->ip_no, ret);
2854 2905
 			return ret;
2855 2906
 	}
... ...
@@ -2864,7 +2915,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2864 2915
 	if (proto)
2865 2916
 		*proto=h->proto;
2866 2917
 #ifdef DNS_CACHE_DEBUG
2867
-	DBG("dns_sip_resolve(%.*s, %d, %d), ip, ret=%d\n", 
2918
+	DBG("dns_sip_resolve(%.*s, %d, %d), ip, ret=%d\n",
2868 2919
 			name->len, name->s, h->srv_no, h->ip_no, ret);
2869 2920
 #endif
2870 2921
 	return ret;
... ...
@@ -2880,7 +2931,7 @@ int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2880 2931
  * - normal A/AAAA lookup if *port!=0, or port==0
2881 2932
  * when performing SRV lookup (*port==0) it will use proto to look for
2882 2933
  * 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 
2934
+ * h must be initialized prior to  calling this function and can be used to
2884 2935
  * get the subsequent ips
2885 2936
  * returns:  <0 on error
2886 2937
  *            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 2948
 	char n_proto;
2898 2949
 	str srv_name;
2899 2950
 	int ret;
2900
-	
2951
+
2901 2952
 	ret=-E_DNS_NO_NAPTR;
2902 2953
 	if (dns_hash==0){ /* not init => use normal, non-cached version */
2903 2954
 		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 2964
 	if (((h->srv==0) && (h->a==0)) && /* first call */
2914 2965
 			 proto && port && (*proto==0) && (*port==0)){
2915 2966
 		*proto=PROTO_UDP; /* just in case we don't find another */
2916
-		
2967
+
2917 2968
 		/* check if it's an ip address */
2918 2969
 		if ( ((tmp_ip=str2ip(name))!=0)
2919 2970
 #ifdef	USE_IPV6
... ...
@@ -2943,7 +2994,7 @@ int dns_naptr_sip_resolve(struct dns_srv_handle* h,  str* name,
2943 2994
 									from previous dns_srv_sip_resolve calls */
2944 2995
 			if ((ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags))>=0){
2945 2996
 #ifdef DNS_CACHE_DEBUG
2946
-				DBG("dns_naptr_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n", 
2997
+				DBG("dns_naptr_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n",
2947 2998
 								name->len, name->s, h->srv_no, h->ip_no, ret);
2948 2999
 #endif
2949 3000
 				dns_hash_put(e);
... ...
@@ -2971,7 +3022,7 @@ naptr_not_found:
2971 3022
  * - normal A/AAAA lookup if *port!=0, or port==0
2972 3023
  * when performing SRV lookup (*port==0) it will use proto to look for
2973 3024
  * 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 
3025
+ * h must be initialized prior to  calling this function and can be used to
2975 3026
  * get the subsequent ips
2976 3027
  * returns:  <0 on error
2977 3028
  *            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 3047
 	struct dns_hash_entry* e;
2997 3048
 	int ret;
2998 3049
 	unsigned char rr_no;
2999
-	
3050
+
3000 3051
 	e=0;
3001 3052
 	rr_no=0;
3002 3053
 	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 3062
 	struct dns_hash_entry* e;
3012 3063
 	int ret;
3013 3064
 	unsigned char rr_no;
3014
-	
3065
+
3015 3066
 	e=0;
3016 3067
 	rr_no=0;
3017 3068
 	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 3084
 	int ret;
3034 3085
 	struct dns_hash_entry* e;
3035 3086
 	unsigned char rr_no;
3036
-	
3087
+
3037 3088
 	e=0;
3038 3089
 	rr_no=0;
3039 3090
 	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 3101
 {
3051 3102
 	int ret;
3052 3103
 	struct dns_srv_handle h;
3053
-	
3104
+
3054 3105
 	dns_srv_handle_init(&h);
3055 3106
 	ret=dns_srv_resolve_ip(&h, name, ip, port, flags);
3056 3107
 	dns_srv_handle_put(&h);
... ...
@@ -3081,12 +3132,12 @@ void dns_cache_debug(rpc_t* rpc, void* ctx)
3081 3132
 	int h;
3082 3133
 	struct dns_hash_entry* e;
3083 3134
 	ticks_t now;
3084
-	
3135
+
3085 3136
 	now=get_ticks_raw();
3086 3137
 	LOCK_DNS_HASH();
3087 3138
 		for (h=0; h<DNS_HASH_SIZE; h++){
3088 3139
 			clist_foreach(&dns_hash[h], e, next){
3089
-				rpc->add(ctx, "sdddddd", 
3140
+				rpc->add(ctx, "sdddddd",
3090 3141
 								e->name, e->type, e->total_size, e->refcnt.val,
3091 3142
 								(s_ticks_t)(e->expire-now)<0?-1:
3092 3143
 									TICKS_TO_S(e->expire-now),
... ...
@@ -3098,6 +3149,86 @@ void dns_cache_debug(rpc_t* rpc, void* ctx)
3098 3149
 }
3099 3150
 
3100 3151
 
3152
+#ifdef USE_DNS_CACHE_STATS
3153
+void dns_cache_stats_get(rpc_t* rpc, void* c)
3154
+{
3155
+	char *name=NULL;
3156
+	void *handle;
3157
+	int found=0,i=0;
3158
+	int reset=0;
3159
+	char* dns_cache_stats_names[] = {
3160
+		"dns_req_cnt",
3161
+		"dc_hits_cnt",
3162
+		"dc_neg_hits_cnt",
3163
+		"dc_lru_cnt",
3164
+		NULL
3165
+	};
3166
+	unsigned long  stat_sum(int ivar, int breset) {
3167
+		unsigned long isum=0;
3168
+		int i1=0;
3169
+
3170
+		for (; i1 < get_max_procs(); i1++)
3171
+			switch (ivar) {
3172
+				case 0:
3173
+					isum+=dns_cache_stats[i1].dns_req_cnt;
3174
+					if (breset)
3175
+						dns_cache_stats[i1].dns_req_cnt=0;
3176
+					break;
3177
+				case 1:
3178
+					isum+=dns_cache_stats[i1].dc_hits_cnt;
3179
+					if (breset)
3180
+						dns_cache_stats[i1].dc_hits_cnt=0;
3181
+					break;
3182
+				case 2:
3183
+					isum+=dns_cache_stats[i1].dc_neg_hits_cnt;
3184
+					if (breset)
3185
+						dns_cache_stats[i1].dc_neg_hits_cnt=0;
3186
+					break;
3187
+				case 3:
3188
+					isum+=dns_cache_stats[i1].dc_lru_cnt;
3189
+					if (breset)
3190
+						dns_cache_stats[i1].dc_lru_cnt=0;
3191
+					break;
3192
+			}
3193
+
3194
+		return isum;
3195
+	}
3196
+
3197
+
3198
+	if (!use_dns_cache) {
3199
+		rpc->fault(c, 500, "dns cache support disabled");
3200
+		return;
3201
+	}
3202
+	if (rpc->scan(c, "s", &name) < 0)
3203
+		return;
3204
+	if (rpc->scan(c, "d", &reset) < 0)
3205
+		return;
3206
+	if (!strcasecmp(name, DNS_CACHE_ALL_STATS)) {
3207
+		/* dump all the dns cache stat values */
3208
+		rpc->add(c, "{", &handle);
3209
+		for (i=0; dns_cache_stats_names[i]; i++)
3210
+			rpc->struct_add(handle, "d",
3211
+							dns_cache_stats_names[i],
3212
+							stat_sum(i, reset));
3213
+
3214
+		found=1;
3215
+	} else {
3216
+		for (i=0; dns_cache_stats_names[i]; i++)
3217
+			if (!strcasecmp(dns_cache_stats_names[i], name)) {
3218
+				rpc->add(c, "{", &handle);
3219
+				rpc->struct_add(handle, "d",
3220
+								dns_cache_stats_names[i],
3221
+								stat_sum(i, reset));
3222
+				found=1;
3223
+				break;
3224
+			}
3225
+	}
3226
+	if(!found)
3227
+		rpc->fault(c, 500, "unknown dns cache stat parameter");
3228
+
3229
+	return;
3230
+}
3231
+#endif /* USE_DNS_CACHE_STATS */
3101 3232
 
3102 3233
 /* rpc functions */
3103 3234
 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 3239
 	struct ip_addr ip;
3109 3240
 	int i;
3110 3241
 	ticks_t now;
3111
-	
3242
+
3112 3243
 	now=get_ticks_raw();
3113 3244
 	LOCK_DNS_HASH();
3114 3245
 		for (h=0; h<DNS_HASH_SIZE; h++){
3115 3246
 			clist_foreach(&dns_hash[h], e, next){
3116 3247
 				for (i=0, rr=e->rr_lst; rr; i++, rr=rr->next){
3117
-					rpc->add(ctx, "sddddddd", 
3248
+					rpc->add(ctx, "sddddddd",
3118 3249
 								e->name, (int)e->type, i, (int)e->total_size,
3119 3250
 								(int)e->refcnt.val,
3120 3251
 								(int)(s_ticks_t)(e->expire-now)<0?-1:
... ...
@@ -3131,7 +3262,7 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3131 3262
 							}
3132 3263
 							break;
3133 3264
 						case T_SRV:
3134
-							rpc->add(ctx, "ss", "srv", 
3265
+							rpc->add(ctx, "ss", "srv",
3135 3266
 									((struct srv_rdata*)(rr->rdata))->name);
3136 3267
 							break;
3137 3268
 						case T_NAPTR:
... ...
@@ -3139,7 +3270,7 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3139 3270
 								((struct naptr_rdata*)(rr->rdata))->flags);
3140 3271
 							break;
3141 3272
 						case T_CNAME:
3142
-							rpc->add(ctx, "ss", "cname", 
3273
+							rpc->add(ctx, "ss", "cname",
3143 3274
 									((struct cname_rdata*)(rr->rdata))->name);
3144 3275
 							break;
3145 3276
 						default:
... ...
@@ -3183,7 +3314,7 @@ void dns_cache_view(rpc_t* rpc, void* ctx)
3183 3314
 	ticks_t now;
3184 3315
 	void* handle;
3185 3316
 	str s;
3186
-	
3317
+
3187 3318
 	now=get_ticks_raw();
3188 3319
 	LOCK_DNS_HASH();
3189 3320
 		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 3445
 			default:
3315 3446
 				LOG(L_ERR, "ERROR: dns_cache_clone_entry: type %d not supported\n",
3316 3447
 						e->type);
3317
-				return NULL;				
3448
+				return NULL;
3318 3449
 		}
3319 3450
 	} else {
3320 3451
 		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 3497
 					((struct naptr_rdata*)rr->rdata)->repl);
3367 3498
 		}
3368 3499
 	}
3369
-	
3500
+
3370 3501
 
3371 3502
 	if (rdata_size) {
3372 3503
 		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 3540
 	str ip, rr_name;
3410 3541
 	int flags;
3411 3542
 	struct ip_addr *ip_addr;
3412
-	int priority, weight, port; 
3543
+	int priority, weight, port;
3413 3544
 	ticks_t expire;
3414 3545
 	int err, h;
3415 3546
 	int size;
... ...
@@ -3431,10 +3562,10 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3431 3562
 	case T_CNAME:
3432 3563
 	case T_NAPTR:
3433 3564
 		rpc->fault(ctx, 400, "not implemented");
3434
-		return;			
3565
+		return;
3435 3566
 	default:
3436 3567
 		rpc->fault(ctx, 400, "unknown type");
3437
-		return;			
3568
+		return;
3438 3569
 	}
3439 3570
 
3440 3571
 	if (!flags) {
... ...
@@ -3555,7 +3686,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3555 3686
 					rpc->fault(ctx, 400, "Failed to add the entry to the cache");
3556 3687
 					goto error;
3557 3688
 				}
3558
-			
3689
+
3559 3690
 				switch(type) {
3560 3691
 				case T_A:
3561 3692
 				case T_AAAA:
... ...
@@ -3572,7 +3703,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3572 3703
 			}
3573 3704
 		}
3574 3705
 	}
3575
-	
3706
+
3576 3707
 	LOCK_DNS_HASH();
3577 3708
 	if (dns_cache_add_unsafe(new)) {
3578 3709
 		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 65
 enum dns_errors{
65 66
 					E_DNS_OK=0,
66 67
 					E_DNS_EOR, /* no more records (not an error)
67
-					              -- returned only by the dns_resolve* 
68
+					              -- returned only by the dns_resolve*
68 69
 								  functions when called iteratively,; it
69 70
 								  signals the end of the ip/records list */
70 71
 					E_DNS_UNKNOWN /* unkown error */,
... ...
@@ -73,10 +74,10 @@ enum dns_errors{
73 74
 					E_DNS_NO_SRV /* unresolvable srv record */,
74 75
 					E_DNS_BAD_IP_ENTRY,
75 76
 					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 */, 
77
+					E_DNS_BAD_IP /* the ip is invalid */,
78
+					E_DNS_BLACKLIST_IP /* the ip is blacklisted */,
78 79
 					E_DNS_NAME_TOO_LONG /* try again with a shorter name */,
79
-					E_DNS_AF_MISMATCH /* ipv4 or ipv6 only requested, but 
80
+					E_DNS_AF_MISMATCH /* ipv4 or ipv6 only requested, but
80 81
 										 name contains an ip addr. of the
81 82
 										 opossite type */ ,
82 83
 					E_DNS_NO_NAPTR /* unresolvable naptr record */,
... ...
@@ -142,7 +143,7 @@ struct dns_hash_entry{
142 143
 	unsigned short type;
143 144
 	unsigned char err_flags;
144 145
 	unsigned char name_len; /* can be maximum 255 bytes */
145
-	char name[1]; /* variable length, name, null terminated 
146
+	char name[1]; /* variable length, name, null terminated
146 147
 	                 (actual lenght = name_len +1)*/
147 148
 };
148 149
 
... ...
@@ -173,6 +174,10 @@ struct dns_srv_handle{
173 174
 const char* dns_strerror(int err);
174 175
 
175 176
 int init_dns_cache();
177
+#ifdef USE_DNS_CACHE_STATS
178
+int init_dns_cache_stats(int iproc_num);
179
+#define DNS_CACHE_ALL_STATS "dc_all_stats"
180
+#endif
176 181
 void destroy_dns_cache();
177 182
 
178 183
 
... ...
@@ -238,7 +243,7 @@ inline static void dns_srv_handle_put_shm_unsafe(struct dns_srv_handle* h)
238 243
 
239 244
 /* get "next" ip next time a dns_srv_handle function is called
240 245
  * params: h   - struct dns_srv_handler
241
- *         err - return code of the last dns_*_resolve* call 
246
+ *         err - return code of the last dns_*_resolve* call
242 247
  * returns: 0 if it doesn't make sense to try another record,
243 248
  * 1 otherwise
244 249
  */
... ...
@@ -298,7 +303,7 @@ struct hostent* dns_get_he(str* name, int flags);
298 303
 int dns_sip_resolve(struct dns_srv_handle* h,  str* name, struct ip_addr* ip,
299 304
 					unsigned short* port, char* proto, int flags);
300 305
 
301
-/* same as above, but fills su intead of changing port and filling an ip */ 
306
+/* same as above, but fills su intead of changing port and filling an ip */
302 307
 inline static int dns_sip_resolve2su(struct dns_srv_handle* h,
303 308