Browse code

secfilter: added locks and an RPC command to reset stats

Jose Luis Verdeguer authored on 12/03/2019 12:19:04
Showing 4 changed files
... ...
@@ -629,6 +629,26 @@
629 629
        </example>
630 630
      </section>
631 631
 
632
+	<section id="secfilter.r.stats_reset">
633
+       <title>
634
+		<function moreinfo="none">secfilter.stats_reset</function>
635
+	  </title>
636
+ 
637
+ 		<para> 
638
+		Reset all statistics.
639
+ 		</para> 
640
+ 
641
+ 		<example>
642
+         <title><function>secfilter.stats_reset</function> usage</title>
643
+ 
644
+         <programlisting format="linespecific">
645
+		...
646
+		&kamcmd; secfilter.stats_reset
647
+		...
648
+		</programlisting>
649
+       </example>
650
+     </section>
651
+
632 652
 	<section id="secfilter.r.add_dst">
633 653
        <title>
634 654
 		<function moreinfo="none">secfilter.add_dst</function>
... ...
@@ -35,7 +35,9 @@
35 35
 MODULE_VERSION
36 36
 
37 37
 secf_data_p secf_data = NULL;
38
+static gen_lock_t *lock = NULL;
38 39
 int *secf_stats;
40
+int total_data = 26;
39 41
 
40 42
 /* Static and shared functions */
41 43
 static int mod_init(void);
... ...
@@ -48,6 +50,7 @@ void secf_free_data(void);
48 48
 static void mod_destroy(void);
49 49
 static int w_check_sqli(str val);
50 50
 static int check_user(struct sip_msg *msg, int type);
51
+void secf_reset_stats(void);
51 52
 
52 53
 /* External functions */
53 54
 static int w_check_ua(struct sip_msg *msg);
... ...
@@ -113,6 +116,7 @@ struct module_exports exports = {
113 113
 static const char *rpc_reload_doc[2] = {"Reload values from database", NULL};
114 114
 static const char *rpc_print_doc[2] = {"Print values from database", NULL};
115 115
 static const char *rpc_stats_doc[2] = {"Print statistics of blocked and allowed messages", NULL};
116
+static const char *rpc_stats_reset_doc[2] = {"Reset statistics", NULL};
116 117
 static const char *rpc_add_dst_doc[2] = {
117 118
 		"Add new values to destination blacklist", NULL};
118 119
 static const char *rpc_add_bl_doc[2] = {"Add new values to blacklist", NULL};
... ...
@@ -122,6 +126,7 @@ rpc_export_t secfilter_rpc[] = {
122 122
 		{"secfilter.reload", secf_rpc_reload, rpc_reload_doc, 0},
123 123
 		{"secfilter.print", secf_rpc_print, rpc_print_doc, 0},
124 124
 		{"secfilter.stats", secf_rpc_stats, rpc_stats_doc, 0},
125
+		{"secfilter.stats_reset", secf_rpc_stats_reset, rpc_stats_reset_doc, 0},
125 126
 		{"secfilter.add_dst", secf_rpc_add_dst, rpc_add_dst_doc, 0},
126 127
 		{"secfilter.add_bl", secf_rpc_add_bl, rpc_add_bl_doc, 0},
127 128
 		{"secfilter.add_wl", secf_rpc_add_wl, rpc_add_wl_doc, 0}, {0, 0, 0, 0}};
... ...
@@ -271,7 +276,9 @@ static int w_check_sqli(str val)
271 271
 			|| strstr(cval, "%27") || strstr(cval, "%24")
272 272
 			|| strstr(cval, "%60")) {
273 273
 		/* Illegal characters found */
274
+		lock_get(lock);
274 275
 		secf_stats[BL_SQL]++;
276
+		lock_release(lock);
275 277
 		res = -1;
276 278
 		goto end;
277 279
 	}
... ...
@@ -303,7 +310,9 @@ static int w_check_dst(struct sip_msg *msg, char *val)
303 303
 			/* Exact match */
304 304
 			if(list->s.len == dst.len) {
305 305
 				if(cmpi_str(&list->s, &dst) == 0) {
306
+					lock_get(lock);
306 307
 					secf_stats[BL_DST]++;
308
+					lock_release(lock);
307 309
 					return -2;
308 310
 				}
309 311
 			}
... ...
@@ -312,7 +321,9 @@ static int w_check_dst(struct sip_msg *msg, char *val)
312 312
 			if(dst.len > list->s.len)
313 313
 				dst.len = list->s.len;
314 314
 			if(cmpi_str(&list->s, &dst) == 0) {
315
+				lock_get(lock);
315 316
 				secf_stats[BL_DST]++;
317
+				lock_release(lock);
316 318
 				return -2;
317 319
 			}
318 320
 		}
... ...
@@ -349,7 +360,9 @@ static int w_check_ua(struct sip_msg *msg)
349 349
 			ua.len = list->s.len;
350 350
 		res = cmpi_str(&list->s, &ua);
351 351
 		if(res == 0) {
352
+			lock_get(lock);
352 353
 			secf_stats[WL_UA]++;
354
+			lock_release(lock);
353 355
 			return 2;
354 356
 		}
355 357
 		list = list->next;
... ...
@@ -363,7 +376,9 @@ static int w_check_ua(struct sip_msg *msg)
363 363
 			ua.len = list->s.len;
364 364
 		res = cmpi_str(&list->s, &ua);
365 365
 		if(res == 0) {
366
+			lock_get(lock);
366 367
 			secf_stats[BL_UA]++;
368
+			lock_release(lock);
367 369
 			return -2;
368 370
 		}
369 371
 		list = list->next;
... ...
@@ -449,6 +464,7 @@ static int check_user(struct sip_msg *msg, int type)
449 449
 		if (name.s != NULL) {
450 450
 			res = cmpi_str(&list->s, &name);
451 451
 			if(res == 0) {
452
+				lock_get(lock);
452 453
 				switch(type) {
453 454
 					case 1:
454 455
 						secf_stats[WL_FNAME]++;
... ...
@@ -460,6 +476,7 @@ static int check_user(struct sip_msg *msg, int type)
460 460
 						secf_stats[WL_CNAME]++;
461 461
 						break;
462 462
 				}
463
+				lock_release(lock);
463 464
 				return 4;
464 465
 			}
465 466
 		}
... ...
@@ -467,6 +484,7 @@ static int check_user(struct sip_msg *msg, int type)
467 467
 			user.len = list->s.len;
468 468
 		res = cmpi_str(&list->s, &user);
469 469
 		if(res == 0) {
470
+			lock_get(lock);
470 471
 			switch(type) {
471 472
 				case 1:
472 473
 					secf_stats[WL_FUSER]++;
... ...
@@ -478,6 +496,7 @@ static int check_user(struct sip_msg *msg, int type)
478 478
 					secf_stats[WL_CUSER]++;
479 479
 					break;
480 480
 			}
481
+			lock_release(lock);
481 482
 			return 2;
482 483
 		}
483 484
 		list = list->next;
... ...
@@ -492,6 +511,7 @@ static int check_user(struct sip_msg *msg, int type)
492 492
 		if (name.s != NULL) {
493 493
 			res = cmpi_str(&list->s, &name);
494 494
 			if(res == 0) {
495
+				lock_get(lock);
495 496
 				switch(type) {
496 497
 					case 1:
497 498
 						secf_stats[BL_FNAME]++;
... ...
@@ -503,6 +523,7 @@ static int check_user(struct sip_msg *msg, int type)
503 503
 						secf_stats[BL_CNAME]++;
504 504
 						break;
505 505
 				}
506
+				lock_release(lock);
506 507
 				return -4;
507 508
 			}
508 509
 		}
... ...
@@ -510,6 +531,7 @@ static int check_user(struct sip_msg *msg, int type)
510 510
 			user.len = list->s.len;
511 511
 		res = cmpi_str(&list->s, &user);
512 512
 		if(res == 0) {
513
+			lock_get(lock);
513 514
 			switch(type) {
514 515
 				case 1:
515 516
 					secf_stats[BL_FUSER]++;
... ...
@@ -521,6 +543,7 @@ static int check_user(struct sip_msg *msg, int type)
521 521
 					secf_stats[BL_CUSER]++;
522 522
 					break;
523 523
 			}
524
+			lock_release(lock);
524 525
 			return -2;
525 526
 		}
526 527
 		list = list->next;
... ...
@@ -535,6 +558,7 @@ static int check_user(struct sip_msg *msg, int type)
535 535
 			domain.len = list->s.len;
536 536
 		res = cmpi_str(&list->s, &domain);
537 537
 		if(res == 0) {
538
+			lock_get(lock);
538 539
 			switch(type) {
539 540
 				case 1:
540 541
 					secf_stats[WL_FDOMAIN]++;
... ...
@@ -546,6 +570,7 @@ static int check_user(struct sip_msg *msg, int type)
546 546
 					secf_stats[WL_CDOMAIN]++;
547 547
 					break;
548 548
 			}
549
+			lock_release(lock);
549 550
 			return 3;
550 551
 		}
551 552
 		list = list->next;
... ...
@@ -558,6 +583,7 @@ static int check_user(struct sip_msg *msg, int type)
558 558
 			domain.len = list->s.len;
559 559
 		res = cmpi_str(&list->s, &domain);
560 560
 		if(res == 0) {
561
+			lock_get(lock);
561 562
 			switch(type) {
562 563
 				case 1:
563 564
 					secf_stats[BL_FDOMAIN]++;
... ...
@@ -569,6 +595,7 @@ static int check_user(struct sip_msg *msg, int type)
569 569
 					secf_stats[BL_CDOMAIN]++;
570 570
 					break;
571 571
 			}
572
+			lock_release(lock);
572 573
 			return -3;
573 574
 		}
574 575
 		list = list->next;
... ...
@@ -608,7 +635,9 @@ static int w_check_ip(struct sip_msg *msg)
608 608
 			ip.len = list->s.len;
609 609
 		res = cmpi_str(&list->s, &ip);
610 610
 		if(res == 0) {
611
+			lock_get(lock);
611 612
 			secf_stats[WL_IP]++;
613
+			lock_release(lock);
612 614
 			return 2;
613 615
 		}
614 616
 		list = list->next;
... ...
@@ -621,7 +650,9 @@ static int w_check_ip(struct sip_msg *msg)
621 621
 			ip.len = list->s.len;
622 622
 		res = cmpi_str(&list->s, &ip);
623 623
 		if(res == 0) {
624
+			lock_get(lock);
624 625
 			secf_stats[BL_IP]++;
626
+			lock_release(lock);
625 627
 			return -2;
626 628
 		}
627 629
 		list = list->next;
... ...
@@ -657,7 +688,9 @@ static int w_check_country(struct sip_msg *msg, char *val)
657 657
 			country.len = list->s.len;
658 658
 		res = cmpi_str(&list->s, &country);
659 659
 		if(res == 0) {
660
+			lock_get(lock);
660 661
 			secf_stats[WL_COUNTRY]++;
662
+			lock_release(lock);
661 663
 			return 2;
662 664
 		}
663 665
 		list = list->next;
... ...
@@ -670,7 +703,9 @@ static int w_check_country(struct sip_msg *msg, char *val)
670 670
 			country.len = list->s.len;
671 671
 		res = cmpi_str(&list->s, &country);
672 672
 		if(res == 0) {
673
+			lock_get(lock);
673 674
 			secf_stats[BL_COUNTRY]++;
675
+			lock_release(lock);
674 676
 			return -2;
675 677
 		}
676 678
 		list = list->next;
... ...
@@ -681,6 +716,14 @@ static int w_check_country(struct sip_msg *msg, char *val)
681 681
 }
682 682
 
683 683
 
684
+void secf_reset_stats(void)
685
+{
686
+	lock_get(lock);
687
+	memset(secf_stats, 0, total_data * sizeof(int));
688
+	lock_release(lock);
689
+}
690
+
691
+
684 692
 /***
685 693
 INIT AND DESTROY FUNCTIONS
686 694
 ***/
... ...
@@ -688,8 +731,6 @@ INIT AND DESTROY FUNCTIONS
688 688
 /* Initialize data */
689 689
 int secf_init_data(void)
690 690
 {
691
-	int i;
692
-
693 691
 	secf_data = (secf_data_p)shm_malloc(sizeof(secf_data_t));
694 692
 	if(!secf_data) {
695 693
 		SHM_MEM_ERROR;
... ...
@@ -697,9 +738,8 @@ int secf_init_data(void)
697 697
 	}
698 698
 	memset(secf_data, 0, sizeof(secf_data_t));
699 699
 
700
-	secf_stats = shm_malloc(26 * sizeof(int));
701
-	for (i=0; i<26; i++)
702
-		secf_stats[i] = 0;
700
+	secf_stats = shm_malloc(total_data * sizeof(int));
701
+	memset(secf_stats, 0, total_data * sizeof(int));
703 702
 	
704 703
 	if(secf_dst_exact_match != 0)
705 704
 		secf_dst_exact_match = 1;
... ...
@@ -723,6 +763,15 @@ static int mod_init(void)
723 723
 		LM_CRIT("cannot initialize lock.\n");
724 724
 		return -1;
725 725
 	}
726
+	lock = lock_alloc();
727
+	if (!lock) {
728
+		LM_CRIT("cannot allocate memory for lock.\n");
729
+		return -1;
730
+	}
731
+	if (lock_init(lock) == 0) {
732
+		LM_CRIT("cannot initialize lock.\n");
733
+		return -1;
734
+	}
726 735
 	/* Init database connection and check version */
727 736
 	if(secf_init_db() == -1)
728 737
 		return -1;
... ...
@@ -758,6 +807,13 @@ static void mod_destroy(void)
758 758
 	lock_destroy(&secf_data->lock);
759 759
 	shm_free(secf_data);
760 760
 	secf_data = NULL;
761
+
762
+	lock_release(&secf_data->lock);
763
+	if (lock) {
764
+		lock_destroy(lock);
765
+		lock_dealloc((void *)lock);
766
+		lock = NULL;
767
+	}
761 768
 }
762 769
 
763 770
 
... ...
@@ -819,7 +875,5 @@ void secf_free_data(void)
819 819
 	memset(&secf_data->bl_last, 0, sizeof(secf_info_t));
820 820
 	LM_DBG("so, ua[%p] should be NULL\n", secf_data->bl.ua);
821 821
 	
822
-	shm_free(secf_stats);
823
-
824
-	lock_release(&secf_data->lock);
822
+	shm_free(lock);
825 823
 }
... ...
@@ -52,8 +52,8 @@ typedef struct _secf_data
52 52
 
53 53
 extern secf_data_p secf_data;
54 54
 
55
-//extern int secf_stats[22];
56 55
 extern int *secf_stats;
56
+void secf_reset_stats(void);
57 57
 
58 58
 int secf_append_rule(int action, int type, str *value);
59 59
 
... ...
@@ -81,6 +81,7 @@ extern int secf_dst_exact_match;
81 81
 void secf_rpc_reload(rpc_t *rpc, void *ctx);
82 82
 void secf_rpc_print(rpc_t *rpc, void *ctx);
83 83
 void secf_rpc_stats(rpc_t *rpc, void *ctx);
84
+void secf_rpc_stats_reset(rpc_t *rpc, void *ctx);
84 85
 void secf_rpc_add_dst(rpc_t *rpc, void *ctx);
85 86
 void secf_rpc_add_bl(rpc_t *rpc, void *ctx);
86 87
 void secf_rpc_add_wl(rpc_t *rpc, void *ctx);
... ...
@@ -305,3 +305,9 @@ void secf_rpc_stats(rpc_t *rpc, void *ctx)
305 305
 	rpc->rpl_printf(ctx, "");
306 306
 }
307 307
 
308
+/* Reset stats */
309
+void secf_rpc_stats_reset(rpc_t *rpc, void *ctx)
310
+{
311
+	secf_reset_stats();
312
+	rpc->rpl_printf(ctx, "The statistics has been reset");
313
+}
308 314
\ No newline at end of file