Browse code

userblacklist: adding new fifo commands

- adding dump_blacklist, check_blacklist, check_whitelist, check_userblacklist,
check_userwhitelist commands

Stefan Mititelu authored on 30/03/2015 05:54:46 • lucian balanceanu committed on 30/03/2015 05:54:46
Showing 2 changed files
... ...
@@ -383,25 +383,138 @@ if (!check_whitelist("globalblacklist")) {
383 383
 </section>
384 384
 
385 385
 <section>
386
-	    <title><acronym>MI</acronym> Commands</title>
386
+	<title><acronym>MI</acronym> Commands</title>
387 387
 		<section>
388
-	    <title>
389
-		<function moreinfo="none">reload_blacklist</function>
390
-	    </title>
391
-	    <para>
392
-		Reload the internal global blacklist cache. This is necessary after
393
-		the database tables for the global blacklist have been changed.
394
-	    </para>
395
-	<example>
396
-		<title><function>reload_blacklist</function> usage</title>
397
-		<programlisting format="linespecific">
398
-...
399
-&ctltool; fifo reload_blacklist
400
-...
401
-		</programlisting>
402
-	    </example>
403
-	</section>
388
+			<title>
389
+				<function moreinfo="none">reload_blacklist</function>
390
+			</title>
391
+			<para>
392
+				Reload the internal global blacklist cache. This is necessary after
393
+				the database tables for the global blacklist have been changed.
394
+			</para>
395
+			<example>
396
+				<title><function>reload_blacklist</function> usage</title>
397
+				<programlisting format="linespecific">
398
+					...
399
+					&ctltool; fifo reload_blacklist
400
+					...
401
+				</programlisting>
402
+	    		</example>
403
+		</section>
404
+
405
+		<section>
406
+			<title>
407
+				<function moreinfo="none">dump_blacklist</function>
408
+			</title>
409
+			<para>
410
+				Dumps the default, in memory, global_blacklist content to stdout.
411
+				Note that a reload_blacklist should be issued before, 
412
+				in order to see the latest content of the database.
413
+			</para>
414
+			<example>
415
+				<title><function>dump_blacklist</function> usage</title>
416
+				<programlisting format="linespecific">
417
+					...
418
+					&ctltool; fifo reload_blacklist
419
+					&ctltool; fifo dump_blacklist
420
+					...
421
+				</programlisting>
422
+	    		</example>
423
+		</section>
424
+
425
+		<section>
426
+			<title>
427
+				<function moreinfo="none">check_blacklist prefix</function>
428
+			</title>
429
+			<para>
430
+				Searches in the default, in memory, global list. 
431
+				Finds the longest prefix that matches the given prefix parameter. 
432
+				Returns true if the prefix is found and the whitelist is <emphasis>not</emphasis> set. 
433
+				Returns false otherwise - either prefix found and whitelist set or prefix not found. 
434
+				Note that a reload_blacklist should be issued before, 
435
+				in order to check through the latest content of the database.
436
+			</para>
437
+			<example>
438
+				<title><function>check_blacklist</function> usage</title>
439
+				<programlisting format="linespecific">
440
+					...
441
+					&ctltool; fifo reload_blacklist
442
+					&ctltool; fifo check_blacklist prefix
443
+					...
444
+				</programlisting>
445
+	    		</example>
446
+		</section>
447
+
448
+		<section>
449
+			<title>
450
+				<function moreinfo="none">check_whitelist prefix</function>
451
+			</title>
452
+			<para>
453
+				Searches in the default, in memory, global list. 
454
+				Finds the longest prefix that matches the given prefix parameter. 
455
+				Returns true if the prefix is found and the whitelist is set. 
456
+				Returns false otherwise - either prefix found and whitelist 
457
+				<emphasis>not</emphasis> set or prefix not found. 
458
+				Note that a reload_blacklist should be issued before, 
459
+				in order to check through the latest content of the database.
460
+			</para>
461
+			<example>
462
+				<title><function>check_whitelist</function> usage</title>
463
+				<programlisting format="linespecific">
464
+					...
465
+					&ctltool; fifo reload_blacklist
466
+					&ctltool; fifo check_whitelist prefix
467
+					...
468
+				</programlisting>
469
+	    		</example>
470
+		</section>
471
+
472
+		<section>
473
+			<title>
474
+				<function moreinfo="none">check_userblacklist user [domain] prefix</function>
475
+			</title>
476
+			<para>
477
+				Searches in the default user list table.
478
+				Finds the longest prefix for the given user@domain that matches the given prefix parameter. 
479
+				Returns true if the prefix is found and the whitelist is <emphasis>not</emphasis> set. 
480
+				Returns false otherwise - either prefix found and whitelist set or prefix not found. 
481
+				Note that the domain parameter is optional. 
482
+				If not given, the second parameter is the considered to be the prefix. 
483
+			</para>
484
+			<example>
485
+				<title><function>check_userblacklist</function> usage</title>
486
+				<programlisting format="linespecific">
487
+					...
488
+					&ctltool; fifo check_userblacklist user [domain] prefix
489
+					...
490
+				</programlisting>
491
+	    		</example>
492
+		</section>
493
+
494
+		<section>
495
+			<title>
496
+				<function moreinfo="none">check_userwhitelist user [domain] prefix</function>
497
+			</title>
498
+			<para>
499
+				Searches in the default user list table.
500
+				Finds the longest prefix for the given user@domain that matches the given prefix parameter. 
501
+				Returns true if the prefix is found and the whitelist is set. 
502
+				Returns false otherwise - either prefix found and whitelist 
503
+				<emphasis>not</emphasis> set or prefix not found. 
504
+				Note that the domain parameter is optional. 
505
+				If not given, the second parameter is the considered to be the prefix. 
506
+			</para>
507
+			<example>
508
+				<title><function>check_userwhitelist</function> usage</title>
509
+				<programlisting format="linespecific">
510
+					...
511
+					&ctltool; fifo check_userwhitelist user [domain] prefix
512
+					...
513
+				</programlisting>
514
+	    		</example>
515
+		</section>
404 516
 </section>
517
+
405 518
     <section>
406 519
 	<title>Installation and Running</title>
407 520
 	<section>
... ...
@@ -58,6 +58,14 @@ MODULE_VERSION
58 58
 
59 59
 #define MAXNUMBERLEN 31
60 60
 
61
+#define BLACKLISTED_S		"blacklisted"
62
+#define BLACKLISTED_LEN		(sizeof(BLACKLISTED_S)-1)
63
+#define WHITELISTED_S		"whitelisted"
64
+#define WHITELISTED_LEN		(sizeof(WHITELISTED_S)-1)
65
+#define TRUE_S			"true"
66
+#define TRUE_LEN		(sizeof(TRUE_S)-1)
67
+#define FALSE_S			"false"
68
+#define FALSE_LEN		(sizeof(FALSE_S)-1)
61 69
 
62 70
 typedef struct _avp_check
63 71
 {
... ...
@@ -71,7 +79,7 @@ struct check_blacklist_fs_t {
71 79
 };
72 80
 
73 81
 str userblacklist_db_url = str_init(DEFAULT_RODB_URL);
74
-int use_domain   = 0;
82
+int use_domain = 0;
75 83
 int match_mode = 10; /* numeric */
76 84
 static struct dtrie_node_t *gnode = NULL;
77 85
 
... ...
@@ -100,6 +108,11 @@ static void mod_destroy(void);
100 108
 
101 109
 /* --- fifo functions */
102 110
 struct mi_root * mi_reload_blacklist(struct mi_root* cmd, void* param);  /* usage: kamctl fifo reload_blacklist */
111
+struct mi_root * mi_dump_blacklist(struct mi_root* cmd, void* param);  /* usage: kamctl fifo dump_blacklist */
112
+struct mi_root * mi_check_blacklist(struct mi_root* cmd, void* param);  /* usage: kamctl fifo check_blacklist prefix */
113
+struct mi_root * mi_check_whitelist(struct mi_root* cmd, void* param);  /* usage: kamctl fifo check_whitelist prefix */
114
+struct mi_root * mi_check_userblacklist(struct mi_root* cmd, void* param);  /* usage: kamctl fifo check_userblacklist */
115
+struct mi_root * mi_check_userwhitelist(struct mi_root* cmd, void* param);  /* usage: kamctl fifo check_userwhitelist */
103 116
 
104 117
 
105 118
 static cmd_export_t cmds[]={
... ...
@@ -123,15 +136,20 @@ static param_export_t params[] = {
123 136
 	userblacklist_DB_COLS
124 137
 	globalblacklist_DB_COLS
125 138
 	{ "use_domain",      INT_PARAM, &use_domain },
126
-	{ "match_mode",	     INT_PARAM, &match_mode},
127
-	{ 0, 0, 0}
139
+	{ "match_mode",	     INT_PARAM, &match_mode },
140
+	{ 0, 0, 0 }
128 141
 };
129 142
 
130 143
 
131 144
 /* Exported MI functions */
132 145
 static mi_export_t mi_cmds[] = {
133 146
 	{ "reload_blacklist", mi_reload_blacklist, MI_NO_INPUT_FLAG, 0, mi_child_init },
134
-	{ 0, 0, 0, 0, 0}
147
+	{ "dump_blacklist", mi_dump_blacklist, MI_NO_INPUT_FLAG, 0, 0},
148
+	{ "check_blacklist", mi_check_blacklist, 0, 0, 0 },
149
+	{ "check_whitelist", mi_check_whitelist, 0, 0, 0 },
150
+	{ "check_userblacklist", mi_check_userblacklist, 0, 0, 0 },
151
+	{ "check_userwhitelist", mi_check_userwhitelist, 0, 0, 0 },
152
+	{ 0, 0, 0, 0, 0 }
135 153
 };
136 154
 
137 155
 
... ...
@@ -673,6 +691,332 @@ static void destroy_shmlock(void)
673 691
 	}
674 692
 }
675 693
 
694
+static void dump_dtrie_mi(const struct dtrie_node_t *root,
695
+	const unsigned int branches, char *prefix, int *length, struct mi_root *reply)
696
+{
697
+	struct mi_node *crt_node;
698
+        unsigned int i;
699
+        char digit, *val;
700
+	int val_len;
701
+
702
+	/* Sanity check - should not reach here anyway */
703
+	if (NULL == root) {
704
+		LM_ERR("root dtrie is NULL\n");
705
+		return ;
706
+	}
707
+
708
+        /* If data found, add a new node to the reply tree */
709
+        if (root->data) {
710
+		/* Create new node and add it to the roots's kids */
711
+		if(!(crt_node = add_mi_node_child(&reply->node, MI_DUP_NAME, prefix,
712
+				*length, 0, 0)) ) {
713
+			LM_ERR("cannot add the child node to the tree\n");
714
+			return ;
715
+		}
716
+
717
+		/* Resolve the value of the whitelist attribute */
718
+		if (root->data == (void *)MARK_BLACKLIST) {
719
+			val = int2str(0, &val_len);
720
+		} else if (root->data == (void *)MARK_WHITELIST) {
721
+			val = int2str(1, &val_len);
722
+		}
723
+
724
+		/* Add the attribute to the current node */
725
+		if((add_mi_attr(crt_node, MI_DUP_VALUE,
726
+				userblacklist_whitelist_col.s,
727
+				userblacklist_whitelist_col.len,
728
+				val, val_len)) == 0) {
729
+			LM_ERR("cannot add attributes to the node\n");
730
+			return ;
731
+		}
732
+        }
733
+
734
+	/* Perform a DFS search */
735
+        for (i = 0; i < branches; i++) {
736
+                /* If child branch found, traverse it */
737
+                if (root->child[i]) {
738
+                        if (branches == 10) {
739
+                                digit = i + '0';
740
+                        } else {
741
+                                digit = i;
742
+                        }
743
+
744
+                        /* Push digit in prefix stack */
745
+			if (*length >= MAXNUMBERLEN + 1) {
746
+				LM_ERR("prefix length exceeds %d\n", MAXNUMBERLEN + 1);
747
+				return ;
748
+			}
749
+                        prefix[(*length)++] = digit;
750
+
751
+                        /* Recursive DFS call */
752
+	                dump_dtrie_mi(root->child[i], branches, prefix, length, reply);
753
+
754
+                        /* Pop digit from prefix stack */
755
+                        (*length)--;
756
+                }
757
+        }
758
+
759
+        return ;
760
+}
761
+
762
+
763
+static struct mi_root * check_list_mi(struct mi_root* cmd, int list_type)
764
+{
765
+	struct mi_root *tmp = NULL;
766
+	struct mi_node *crt_node, *node;
767
+	struct mi_attr *crt_attr;
768
+	void **nodeflags;
769
+	int ret = -1;
770
+	char *ptr;
771
+	char req_prefix[MAXNUMBERLEN + 1];
772
+	str prefix, val, attr;
773
+
774
+	node = cmd->node.kids;
775
+
776
+	/* Get the prefix number */
777
+	if (NULL == node)
778
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
779
+
780
+	if (NULL == node->value.s || node->value.len == 0)
781
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
782
+	prefix = node->value;
783
+	strncpy(req_prefix, prefix.s, prefix.len);
784
+	req_prefix[prefix.len] = '\0';
785
+
786
+	/* Check that just 1 argument is given */
787
+	node = node->next;
788
+	if (node)
789
+		return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
790
+
791
+	/* Check that global blacklist exists */
792
+	if (!gnode) {
793
+		LM_ERR("the global blacklist is NULL\n");
794
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
795
+	}
796
+
797
+	/* Check that reply tree is successfully initialized */
798
+	tmp = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
799
+	if (!tmp) {
800
+		LM_ERR("the MI tree cannot be initialized!\n");
801
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
802
+	}
803
+
804
+	/* Skip over non-digits. */
805
+	ptr = req_prefix;
806
+	while (match_mode == 10 && strlen(ptr) > 0 && !isdigit(*ptr)) {
807
+		ptr = ptr + 1;
808
+	}
809
+
810
+	/* Avoids dirty reads when updating d-tree */
811
+	lock_get(lock);
812
+	nodeflags = dtrie_longest_match(gnode, ptr, strlen(ptr), NULL, match_mode);
813
+	if (nodeflags) {
814
+		if (*nodeflags == (void *)MARK_WHITELIST) {
815
+			LM_DBG("prefix %.*s is whitelisted in table %.*s\n",
816
+				prefix.len, prefix.s, globalblacklist_table.len, globalblacklist_table.s);
817
+			ret = MARK_WHITELIST;
818
+		} else if (*nodeflags == (void *)MARK_BLACKLIST) {
819
+			LM_DBG("prefix %.*s is blacklisted in table %.*s\n",
820
+				prefix.len, prefix.s, globalblacklist_table.len, globalblacklist_table.s);
821
+			ret = MARK_BLACKLIST;
822
+		}
823
+	}
824
+	else {
825
+		LM_DBG("prefix %.*s not found in table %.*s\n",
826
+			prefix.len, prefix.s, globalblacklist_table.len, globalblacklist_table.s);
827
+	}
828
+	lock_release(lock);
829
+
830
+	/* Create new node and add it to the reply roots's kids */
831
+	if(!(crt_node = add_mi_node_child(&tmp->node, MI_DUP_NAME,
832
+			prefix.s, prefix.len, 0, 0)) ) {
833
+		LM_ERR("cannot add the child node to the tree\n");
834
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
835
+	}
836
+
837
+	/* Resolve the value of the attribute to be returned */
838
+	val.s = FALSE_S;
839
+	val.len = FALSE_LEN;
840
+
841
+	switch (list_type) {
842
+		case MARK_WHITELIST:
843
+                        attr.s = WHITELISTED_S;
844
+                        attr.len = WHITELISTED_LEN;
845
+
846
+			if (ret == MARK_WHITELIST) {
847
+				val.s = TRUE_S;
848
+				val.len = TRUE_LEN;
849
+			}
850
+
851
+			break;
852
+		case MARK_BLACKLIST:
853
+                        attr.s = BLACKLISTED_S;
854
+                        attr.len = BLACKLISTED_LEN;
855
+
856
+			if (ret == MARK_BLACKLIST) {
857
+				val.s = TRUE_S;
858
+				val.len = TRUE_LEN;
859
+			}
860
+
861
+			break;
862
+		default:
863
+			LM_ERR("list_type not found\n");
864
+			return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
865
+	}
866
+
867
+	/* Add the attribute to the current node */
868
+	if (!(crt_attr = add_mi_attr(crt_node, MI_DUP_VALUE,
869
+			attr.s, attr.len, val.s, val.len))) {
870
+		LM_ERR("cannot add attribute to the node\n");
871
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
872
+	}
873
+
874
+	return tmp;
875
+}
876
+
877
+
878
+static struct mi_root * check_userlist_mi(struct mi_root* cmd, int list_type)
879
+{
880
+	struct mi_root *tmp = NULL;
881
+	struct mi_node *crt_node, *node;
882
+	struct mi_attr *crt_attr;
883
+	void **nodeflags;
884
+	int ret = -1;
885
+	int local_use_domain = 0;
886
+	char *ptr;
887
+	char req_prefix[MAXNUMBERLEN + 1];
888
+	str user, prefix, table, val, attr, domain;
889
+
890
+	node = cmd->node.kids;
891
+
892
+	/* Get the user number */
893
+	if (NULL == node)
894
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
895
+
896
+	if (NULL == node->value.s || node->value.len == 0)
897
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
898
+	user = node->value;
899
+
900
+	/* Get the domain name */
901
+	node = node->next;
902
+	if (NULL == node)
903
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
904
+
905
+	if (NULL == node->value.s || node->value.len == 0)
906
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
907
+	domain = node->value;
908
+
909
+	/* Get the prefix number */
910
+	node = node->next;
911
+	if (node) {
912
+		/* Got 3 params, the third one is the prefix */
913
+		if (NULL == node->value.s || node->value.len == 0)
914
+			return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
915
+		prefix = node->value;
916
+		local_use_domain = 1;
917
+	} else {
918
+		/* Got 2 params, the second one is the prefix */
919
+		prefix = domain;
920
+		local_use_domain = 0;
921
+	}
922
+
923
+	strncpy(req_prefix, prefix.s, prefix.len);
924
+	req_prefix[prefix.len] = '\0';
925
+
926
+	/* Check that a maximum of 3 arguments are given */
927
+	if (node)
928
+		node = node->next;
929
+	if (node)
930
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
931
+
932
+	/* Build userblacklist dtrie */
933
+	table = userblacklist_table;
934
+	LM_DBG("check entry %s for user %.*s@%.*s in table %.*s, use domain=%d\n",
935
+		req_prefix, user.len, user.s, domain.len, domain.s,
936
+		table.len, table.s, local_use_domain);
937
+	if (db_build_userbl_tree(&user, &domain, &table, dtrie_root, local_use_domain) < 0) {
938
+		LM_ERR("cannot build d-tree\n");
939
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
940
+	}
941
+
942
+	/* Check that reply tree is successfully initialized */
943
+	tmp = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
944
+	if (!tmp) {
945
+		LM_ERR("the MI tree cannot be initialized!\n");
946
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
947
+	}
948
+
949
+	/* Skip over non-digits. */
950
+	ptr = req_prefix;
951
+	while (match_mode == 10 && strlen(ptr) > 0 && !isdigit(*ptr)) {
952
+		ptr = ptr + 1;
953
+	}
954
+
955
+	/* Search for a match in dtrie */
956
+	nodeflags = dtrie_longest_match(dtrie_root, ptr, strlen(ptr), NULL, match_mode);
957
+	if (nodeflags) {
958
+		if (*nodeflags == (void *)MARK_WHITELIST) {
959
+			LM_DBG("user %.*s is whitelisted for prefix %.*s in table %.*s\n",
960
+				user.len, user.s, prefix.len, prefix.s, table.len, table.s);
961
+			ret = MARK_WHITELIST;
962
+		} else if (*nodeflags == (void *)MARK_BLACKLIST) {
963
+			LM_DBG("user %.*s is blacklisted for prefix %.*s in table %.*s\n",
964
+				user.len, user.s, prefix.len, prefix.s, table.len, table.s);
965
+			ret = MARK_BLACKLIST;
966
+		}
967
+	} else {
968
+		LM_DBG("user %.*s, prefix %.*s not found in table %.*s\n",
969
+			user.len, user.s, prefix.len, prefix.s, table.len, table.s);
970
+	}
971
+
972
+
973
+	/* Create new node and add it to the reply roots's kids */
974
+	if(!(crt_node = add_mi_node_child(&tmp->node, MI_DUP_NAME,
975
+			prefix.s, prefix.len, 0, 0)) ) {
976
+		LM_ERR("cannot add the child node to the tree\n");
977
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
978
+	}
979
+
980
+	/* Resolve the value of the attribute to be returned */
981
+	val.s = FALSE_S;
982
+	val.len = FALSE_LEN;
983
+
984
+	switch (list_type) {
985
+		case MARK_WHITELIST:
986
+                        attr.s = WHITELISTED_S;
987
+                        attr.len = WHITELISTED_LEN;
988
+
989
+			if (ret == MARK_WHITELIST) {
990
+				val.s = TRUE_S;
991
+				val.len = TRUE_LEN;
992
+			}
993
+
994
+			break;
995
+		case MARK_BLACKLIST:
996
+                        attr.s = BLACKLISTED_S;
997
+                        attr.len = BLACKLISTED_LEN;
998
+
999
+			if (ret == MARK_BLACKLIST) {
1000
+				val.s = TRUE_S;
1001
+				val.len = TRUE_LEN;
1002
+			}
1003
+
1004
+			break;
1005
+		default:
1006
+			LM_ERR("list_type not found\n");
1007
+			return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
1008
+	}
1009
+
1010
+	/* Add the attribute to the current node */
1011
+	if (!(crt_attr = add_mi_attr(crt_node, MI_DUP_VALUE,
1012
+			attr.s, attr.len, val.s, val.len))) {
1013
+		LM_ERR("cannot add attribute to the node\n");
1014
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
1015
+	}
1016
+
1017
+	return tmp;
1018
+}
1019
+
676 1020
 
677 1021
 struct mi_root * mi_reload_blacklist(struct mi_root* cmd, void* param)
678 1022
 {
... ...
@@ -687,6 +1031,54 @@ struct mi_root * mi_reload_blacklist(struct mi_root* cmd, void* param)
687 1031
 }
688 1032
 
689 1033
 
1034
+struct mi_root * mi_dump_blacklist(struct mi_root* cmd, void* param)
1035
+{
1036
+	char prefix_buff[MAXNUMBERLEN + 1];
1037
+	int length = 0;
1038
+	struct mi_root *tmp = NULL;
1039
+
1040
+	/* Check that global blacklist exists */
1041
+	if (!gnode) {
1042
+		LM_ERR("the global blacklist is NULL\n");
1043
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
1044
+	}
1045
+
1046
+	tmp = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
1047
+	if (!tmp) {
1048
+		LM_ERR("the MI tree cannot be initialized!\n");
1049
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
1050
+	}
1051
+
1052
+	dump_dtrie_mi(gnode, match_mode, prefix_buff, &length, tmp);
1053
+
1054
+	return tmp;
1055
+}
1056
+
1057
+
1058
+struct mi_root * mi_check_blacklist(struct mi_root* cmd, void* param)
1059
+{
1060
+	return check_list_mi(cmd, MARK_BLACKLIST);
1061
+}
1062
+
1063
+
1064
+struct mi_root * mi_check_whitelist(struct mi_root* cmd, void* param)
1065
+{
1066
+	return check_list_mi(cmd, MARK_WHITELIST);
1067
+}
1068
+
1069
+
1070
+struct mi_root * mi_check_userblacklist(struct mi_root* cmd, void* param)
1071
+{
1072
+	return check_userlist_mi(cmd, MARK_BLACKLIST);
1073
+}
1074
+
1075
+
1076
+struct mi_root * mi_check_userwhitelist(struct mi_root* cmd, void* param)
1077
+{
1078
+	return check_userlist_mi(cmd, MARK_WHITELIST);
1079
+}
1080
+
1081
+
690 1082
 static int mod_init(void)
691 1083
 {
692 1084
 	if(register_mi_mod(exports.name, mi_cmds)!=0)
... ...
@@ -710,11 +1102,17 @@ static int child_init(int rank)
710 1102
 	return mi_child_init();
711 1103
 }
712 1104
 
713
-
714 1105
 static int userblacklist_child_initialized = 0;
1106
+static int blacklist_child_initialized = 0;
715 1107
 
716 1108
 static int mi_child_init(void)
717 1109
 {
1110
+	/* global blacklist init */
1111
+	if (check_globalblacklist_fixup(NULL, 0) != 0) {
1112
+		LM_ERR("could not add global table when init the module");
1113
+	}
1114
+
1115
+	/* user blacklist init */
718 1116
 	if(userblacklist_child_initialized)
719 1117
 		return 0;
720 1118
 	if (userblacklist_db_open() != 0) return -1;
... ...
@@ -723,10 +1121,12 @@ static int mi_child_init(void)
723 1121
 		LM_ERR("could not initialize data");
724 1122
 		return -1;
725 1123
 	}
1124
+
726 1125
 	/* because we've added new sources during the fixup */
727 1126
 	if (reload_sources() != 0) return -1;
728 1127
 
729 1128
 	userblacklist_child_initialized = 1;
1129
+	blacklist_child_initialized = 1;
730 1130
 
731 1131
 	return 0;
732 1132
 }