Browse code

userblacklist: add KEMI functions, adapt source load, fix match_mode for check_whitelist (GH #2190)

- add KEMI functions for userblacklist module
- adapt source loading function after KEMI addition
- fix match mode for alphanumeric characters for check_whitelist function
- merged pull request GH #2190

fsantulli authored on 13/01/2020 20:35:51 • Henning Westerholt committed on 13/01/2020 20:39:26
Showing 1 changed files
... ...
@@ -403,6 +403,34 @@ static struct dtrie_node_t *table2dt(const char *table)
403 403
 }
404 404
 
405 405
 
406
+/**
407
+ * Prepares source d-tree table and loads data.
408
+ * \return entries count on success, -1 otherwise
409
+ */
410
+static int load_source(struct source_t *src)
411
+{
412
+	str tmp;
413
+	int result;
414
+
415
+	if(!src || !src->table) {
416
+		LM_ERR("could not access source or no table defined\n");
417
+		return -1;
418
+	}
419
+
420
+	tmp.s = src->table;
421
+	tmp.len = strlen(src->table);
422
+
423
+	result = db_reload_source(&tmp, src->dtrie_root);
424
+	if (result < 0) {
425
+		LM_ERR("cannot load source from '%.*s'\n", tmp.len, tmp.s);
426
+		return 0;
427
+	}
428
+
429
+	LM_INFO("got %d entries from '%.*s'\n", result, tmp.len, tmp.s);
430
+	return result;
431
+}
432
+
433
+
406 434
 /**
407 435
  * Adds a new table to the list, if the table is
408 436
  * already present, nothing will be done.
... ...
@@ -413,7 +441,10 @@ static int add_source(const char *table)
413 441
 	/* check if the table is already present */
414 442
 	struct source_t *src = sources->head;
415 443
 	while (src) {
416
-		if (strcmp(table, src->table) == 0) return 0;
444
+		if (strcmp(table, src->table) == 0) {
445
+			LM_DBG("table %s is already present", src->table);
446
+			return 0;
447
+		}
417 448
 		src = src->next;
418 449
 	}
419 450
 
... ...
@@ -424,6 +455,9 @@ static int add_source(const char *table)
424 455
 	}
425 456
 	memset(src, 0, sizeof(struct source_t));
426 457
 
458
+	/* avoids dirty reads when adding source and d-tree */
459
+	lock_get(lock);
460
+
427 461
 	src->next = sources->head;
428 462
 	sources->head = src;
429 463
 
... ...
@@ -431,6 +465,7 @@ static int add_source(const char *table)
431 465
 	if (!src->table) {
432 466
 		SHM_MEM_ERROR;
433 467
 		shm_free(src);
468
+		lock_release(lock);
434 469
 		return -1;
435 470
 	}
436 471
 	strcpy(src->table, table);
... ...
@@ -440,9 +475,17 @@ static int add_source(const char *table)
440 475
 
441 476
 	if (src->dtrie_root == NULL) {
442 477
 		LM_ERR("could not initialize data");
478
+		lock_release(lock);
443 479
 		return -1;
444 480
 	}
445 481
 
482
+	if(load_source(src) < 0) {
483
+		LM_ERR("could not load table data");
484
+		lock_release(lock);
485
+		return -1;
486
+	}
487
+
488
+	lock_release(lock);
446 489
 	return 0;
447 490
 }
448 491
 
... ...
@@ -474,6 +517,42 @@ static int check_globalblacklist_fixup(void** param, int param_no)
474 517
 	return 0;
475 518
 }
476 519
 
520
+static int ki_check_globalblacklist(sip_msg_t *msg)
521
+{
522
+	char * table = globalblacklist_table.s;
523
+	struct check_blacklist_fs_t* arg = NULL;
524
+	int result;
525
+
526
+	if (!table) {
527
+		LM_ERR("no table name\n");
528
+		return -1;
529
+	}
530
+	/* try to add the table */
531
+	if (add_source(table) != 0) {
532
+		LM_ERR("could not add table");
533
+		return -1;
534
+	}
535
+
536
+	gnode = table2dt(table);
537
+	if (!gnode) {
538
+		LM_ERR("invalid table '%s'\n", table);
539
+		return -1;
540
+	}
541
+
542
+	arg = pkg_malloc(sizeof(struct check_blacklist_fs_t));
543
+	if (!arg) {
544
+		PKG_MEM_ERROR;
545
+		return -1;
546
+	}
547
+	memset(arg, 0, sizeof(struct check_blacklist_fs_t));
548
+	arg->dtrie_root = gnode;
549
+
550
+	result = check_blacklist(msg, arg);
551
+	pkg_free(arg);
552
+
553
+	return result;
554
+}
555
+
477 556
 static int check_globalblacklist(sip_msg_t* msg)
478 557
 {
479 558
 	static struct check_blacklist_fs_t* arg = NULL;
... ...
@@ -529,6 +608,43 @@ static int check_blacklist_fixup(void **arg, int arg_no)
529 608
 	return 0;
530 609
 }
531 610
 
611
+static int ki_check_blacklist(sip_msg_t *msg, str* stable)
612
+{
613
+	struct dtrie_node_t *node = NULL;
614
+	struct check_blacklist_fs_t* arg = NULL;
615
+	int result;
616
+
617
+	if(stable==NULL || stable->len<=0) {
618
+		LM_ERR("no table name\n");
619
+		return -1;
620
+	}
621
+
622
+	/* try to add the table */
623
+	if (add_source(stable->s) != 0) {
624
+		LM_ERR("could not add table '%s'\n", stable->s);
625
+		return -1;
626
+	}
627
+
628
+	/* get the node that belongs to the table */
629
+	node = table2dt(stable->s);
630
+	if (!node) {
631
+		LM_ERR("invalid table '%s'\n", stable->s);
632
+		return -1;
633
+	}
634
+
635
+	arg = pkg_malloc(sizeof(struct check_blacklist_fs_t));
636
+	if (!arg) {
637
+		PKG_MEM_ERROR;
638
+		return -1;
639
+	}
640
+	memset(arg, 0, sizeof(struct check_blacklist_fs_t));
641
+	arg->dtrie_root = node;
642
+
643
+	result = check_blacklist(msg, arg);
644
+	pkg_free(arg);
645
+
646
+	return result;
647
+}
532 648
 
533 649
 static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
534 650
 {
... ...
@@ -578,6 +694,44 @@ static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
578 694
 	return ret;
579 695
 }
580 696
 
697
+static int ki_check_whitelist(sip_msg_t *msg, str* stable)
698
+{
699
+	struct dtrie_node_t *node = NULL;
700
+	struct check_blacklist_fs_t* arg = NULL;
701
+	int result;
702
+
703
+	if(stable==NULL || stable->len<=0) {
704
+		LM_ERR("no table name\n");
705
+		return -1;
706
+	}
707
+
708
+	/* try to add the table */
709
+	if (add_source(stable->s) != 0) {
710
+		LM_ERR("could not add table '%s'\n", stable->s);
711
+		return -1;
712
+	}
713
+
714
+	/* get the node that belongs to the table */
715
+	node = table2dt(stable->s);
716
+	if (!node) {
717
+		LM_ERR("invalid table '%s'\n", stable->s);
718
+		return -1;
719
+	}
720
+
721
+	arg = pkg_malloc(sizeof(struct check_blacklist_fs_t));
722
+	if (!arg) {
723
+		PKG_MEM_ERROR;
724
+		return -1;
725
+	}
726
+	memset(arg, 0, sizeof(struct check_blacklist_fs_t));
727
+	arg->dtrie_root = node;
728
+
729
+	result = check_whitelist(msg, arg);
730
+	pkg_free(arg);
731
+
732
+	return result;
733
+}
734
+
581 735
 static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
582 736
 {
583 737
 	void **nodeflags;
... ...
@@ -599,7 +753,7 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
599 753
 
600 754
 	ptr = req_number;
601 755
 	/* Skip over non-digits.  */
602
-	while (strlen(ptr) > 0 && !isdigit(*ptr)) {
756
+	while (match_mode == 10 && strlen(ptr) > 0 && !isdigit(*ptr)) {
603 757
 		ptr = ptr + 1;
604 758
 	}
605 759
 
... ...
@@ -607,7 +761,7 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
607 761
 
608 762
 	/* avoids dirty reads when updating d-tree */
609 763
 	lock_get(lock);
610
-	nodeflags = dtrie_longest_match(arg1->dtrie_root, ptr, strlen(ptr), NULL, 10);
764
+	nodeflags = dtrie_longest_match(arg1->dtrie_root, ptr, strlen(ptr), NULL, match_mode);
611 765
 	if (nodeflags) {
612 766
 		if (*nodeflags == (void *)MARK_WHITELIST) {
613 767
 			/* LM_DBG("whitelisted"); */
... ...
@@ -633,24 +787,18 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
633 787
 static int reload_sources(void)
634 788
 {
635 789
 	int result = 0;
636
-	str tmp;
637 790
 	struct source_t *src;
638
-	int n;
639 791
 
640 792
 	/* critical section start: avoids dirty reads when updating d-tree */
641 793
 	lock_get(lock);
642 794
 
643 795
 	src = sources->head;
644 796
 	while (src) {
645
-		tmp.s = src->table;
646
-		tmp.len = strlen(src->table);
647
-		n = db_reload_source(&tmp, src->dtrie_root);
648
-		if (n < 0) {
649
-			LM_ERR("cannot reload source from '%.*s'\n", tmp.len, tmp.s);
797
+		LM_INFO("Reloading source table '%s' with dtrie root '%p'\n", src->table, src->dtrie_root);
798
+		if(load_source(src) < 0) {
650 799
 			result = -1;
651 800
 			break;
652 801
 		}
653
-		LM_INFO("got %d entries from '%.*s'\n", n, tmp.len, tmp.s);
654 802
 		src = src->next;
655 803
 	}
656 804
 
... ...
@@ -1157,11 +1305,6 @@ static int blacklist_child_initialized = 0;
1157 1305
 
1158 1306
 static int rpc_child_init(void)
1159 1307
 {
1160
-	/* global blacklist init */
1161
-	if (check_globalblacklist_fixup(NULL, 0) != 0) {
1162
-		LM_ERR("could not add global table when init the module");
1163
-	}
1164
-
1165 1308
 	/* user blacklist init */
1166 1309
 	if(userblacklist_child_initialized)
1167 1310
 		return 0;
... ...
@@ -1172,6 +1315,11 @@ static int rpc_child_init(void)
1172 1315
 		return -1;
1173 1316
 	}
1174 1317
 
1318
+	/* global blacklist init */
1319
+	if (check_globalblacklist_fixup(NULL, 0) != 0) {
1320
+		LM_ERR("could not add global table when init the module");
1321
+	}
1322
+
1175 1323
 	/* because we've added new sources during the fixup */
1176 1324
 	if (reload_sources() != 0) return -1;
1177 1325
 
... ...
@@ -1225,6 +1373,21 @@ static sr_kemi_t sr_kemi_userblacklist_exports[] = {
1225 1373
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
1226 1374
 			SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
1227 1375
 	},
1376
+	{ str_init("userblacklist"), str_init("check_whitelist"),
1377
+		SR_KEMIP_INT, ki_check_whitelist,
1378
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1379
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1380
+	},
1381
+	{ str_init("userblacklist"), str_init("check_blacklist"),
1382
+		SR_KEMIP_INT, ki_check_blacklist,
1383
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1384
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1385
+	},
1386
+	{ str_init("userblacklist"), str_init("check_global_blacklist"),
1387
+		SR_KEMIP_INT, ki_check_globalblacklist,
1388
+		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1389
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1390
+	},
1228 1391
 
1229 1392
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
1230 1393
 };