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
Showing 1 changed files
... ...
@@ -404,6 +404,34 @@ static struct dtrie_node_t *table2dt(const char *table)
404 404
 
405 405
 
406 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
+
434
+/**
407 435
  * Adds a new table to the list, if the table is
408 436
  * already present, nothing will be done.
409 437
  * \return zero on success, negative on errors
... ...
@@ -413,7 +441,10 @@ static int add_source(const char *table)
413 413
 	/* check if the table is already present */
414 414
 	struct source_t *src = sources->head;
415 415
 	while (src) {
416
-		if (strcmp(table, src->table) == 0) return 0;
416
+		if (strcmp(table, src->table) == 0) {
417
+			LM_DBG("table %s is already present", src->table);
418
+			return 0;
419
+		}
417 420
 		src = src->next;
418 421
 	}
419 422
 
... ...
@@ -424,6 +455,9 @@ static int add_source(const char *table)
424 424
 	}
425 425
 	memset(src, 0, sizeof(struct source_t));
426 426
 
427
+	/* avoids dirty reads when adding source and d-tree */
428
+	lock_get(lock);
429
+
427 430
 	src->next = sources->head;
428 431
 	sources->head = src;
429 432
 
... ...
@@ -431,6 +465,7 @@ static int add_source(const char *table)
431 431
 	if (!src->table) {
432 432
 		SHM_MEM_ERROR;
433 433
 		shm_free(src);
434
+		lock_release(lock);
434 435
 		return -1;
435 436
 	}
436 437
 	strcpy(src->table, table);
... ...
@@ -440,9 +475,17 @@ static int add_source(const char *table)
440 440
 
441 441
 	if (src->dtrie_root == NULL) {
442 442
 		LM_ERR("could not initialize data");
443
+		lock_release(lock);
443 444
 		return -1;
444 445
 	}
445 446
 
447
+	if(load_source(src) < 0) {
448
+		LM_ERR("could not load table data");
449
+		lock_release(lock);
450
+		return -1;
451
+	}
452
+
453
+	lock_release(lock);
446 454
 	return 0;
447 455
 }
448 456
 
... ...
@@ -474,6 +517,42 @@ static int check_globalblacklist_fixup(void** param, int param_no)
474 474
 	return 0;
475 475
 }
476 476
 
477
+static int ki_check_globalblacklist(sip_msg_t *msg)
478
+{
479
+	char * table = globalblacklist_table.s;
480
+	struct check_blacklist_fs_t* arg = NULL;
481
+	int result;
482
+
483
+	if (!table) {
484
+		LM_ERR("no table name\n");
485
+		return -1;
486
+	}
487
+	/* try to add the table */
488
+	if (add_source(table) != 0) {
489
+		LM_ERR("could not add table");
490
+		return -1;
491
+	}
492
+
493
+	gnode = table2dt(table);
494
+	if (!gnode) {
495
+		LM_ERR("invalid table '%s'\n", table);
496
+		return -1;
497
+	}
498
+
499
+	arg = pkg_malloc(sizeof(struct check_blacklist_fs_t));
500
+	if (!arg) {
501
+		PKG_MEM_ERROR;
502
+		return -1;
503
+	}
504
+	memset(arg, 0, sizeof(struct check_blacklist_fs_t));
505
+	arg->dtrie_root = gnode;
506
+
507
+	result = check_blacklist(msg, arg);
508
+	pkg_free(arg);
509
+
510
+	return result;
511
+}
512
+
477 513
 static int check_globalblacklist(sip_msg_t* msg)
478 514
 {
479 515
 	static struct check_blacklist_fs_t* arg = NULL;
... ...
@@ -529,6 +608,43 @@ static int check_blacklist_fixup(void **arg, int arg_no)
529 529
 	return 0;
530 530
 }
531 531
 
532
+static int ki_check_blacklist(sip_msg_t *msg, str* stable)
533
+{
534
+	struct dtrie_node_t *node = NULL;
535
+	struct check_blacklist_fs_t* arg = NULL;
536
+	int result;
537
+
538
+	if(stable==NULL || stable->len<=0) {
539
+		LM_ERR("no table name\n");
540
+		return -1;
541
+	}
542
+
543
+	/* try to add the table */
544
+	if (add_source(stable->s) != 0) {
545
+		LM_ERR("could not add table '%s'\n", stable->s);
546
+		return -1;
547
+	}
548
+
549
+	/* get the node that belongs to the table */
550
+	node = table2dt(stable->s);
551
+	if (!node) {
552
+		LM_ERR("invalid table '%s'\n", stable->s);
553
+		return -1;
554
+	}
555
+
556
+	arg = pkg_malloc(sizeof(struct check_blacklist_fs_t));
557
+	if (!arg) {
558
+		PKG_MEM_ERROR;
559
+		return -1;
560
+	}
561
+	memset(arg, 0, sizeof(struct check_blacklist_fs_t));
562
+	arg->dtrie_root = node;
563
+
564
+	result = check_blacklist(msg, arg);
565
+	pkg_free(arg);
566
+
567
+	return result;
568
+}
532 569
 
533 570
 static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
534 571
 {
... ...
@@ -578,6 +694,44 @@ static int check_blacklist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
578 578
 	return ret;
579 579
 }
580 580
 
581
+static int ki_check_whitelist(sip_msg_t *msg, str* stable)
582
+{
583
+	struct dtrie_node_t *node = NULL;
584
+	struct check_blacklist_fs_t* arg = NULL;
585
+	int result;
586
+
587
+	if(stable==NULL || stable->len<=0) {
588
+		LM_ERR("no table name\n");
589
+		return -1;
590
+	}
591
+
592
+	/* try to add the table */
593
+	if (add_source(stable->s) != 0) {
594
+		LM_ERR("could not add table '%s'\n", stable->s);
595
+		return -1;
596
+	}
597
+
598
+	/* get the node that belongs to the table */
599
+	node = table2dt(stable->s);
600
+	if (!node) {
601
+		LM_ERR("invalid table '%s'\n", stable->s);
602
+		return -1;
603
+	}
604
+
605
+	arg = pkg_malloc(sizeof(struct check_blacklist_fs_t));
606
+	if (!arg) {
607
+		PKG_MEM_ERROR;
608
+		return -1;
609
+	}
610
+	memset(arg, 0, sizeof(struct check_blacklist_fs_t));
611
+	arg->dtrie_root = node;
612
+
613
+	result = check_whitelist(msg, arg);
614
+	pkg_free(arg);
615
+
616
+	return result;
617
+}
618
+
581 619
 static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
582 620
 {
583 621
 	void **nodeflags;
... ...
@@ -599,7 +753,7 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
599 599
 
600 600
 	ptr = req_number;
601 601
 	/* Skip over non-digits.  */
602
-	while (strlen(ptr) > 0 && !isdigit(*ptr)) {
602
+	while (match_mode == 10 && strlen(ptr) > 0 && !isdigit(*ptr)) {
603 603
 		ptr = ptr + 1;
604 604
 	}
605 605
 
... ...
@@ -607,7 +761,7 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
607 607
 
608 608
 	/* avoids dirty reads when updating d-tree */
609 609
 	lock_get(lock);
610
-	nodeflags = dtrie_longest_match(arg1->dtrie_root, ptr, strlen(ptr), NULL, 10);
610
+	nodeflags = dtrie_longest_match(arg1->dtrie_root, ptr, strlen(ptr), NULL, match_mode);
611 611
 	if (nodeflags) {
612 612
 		if (*nodeflags == (void *)MARK_WHITELIST) {
613 613
 			/* LM_DBG("whitelisted"); */
... ...
@@ -633,24 +787,18 @@ static int check_whitelist(sip_msg_t *msg, struct check_blacklist_fs_t *arg1)
633 633
 static int reload_sources(void)
634 634
 {
635 635
 	int result = 0;
636
-	str tmp;
637 636
 	struct source_t *src;
638
-	int n;
639 637
 
640 638
 	/* critical section start: avoids dirty reads when updating d-tree */
641 639
 	lock_get(lock);
642 640
 
643 641
 	src = sources->head;
644 642
 	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);
643
+		LM_INFO("Reloading source table '%s' with dtrie root '%p'\n", src->table, src->dtrie_root);
644
+		if(load_source(src) < 0) {
650 645
 			result = -1;
651 646
 			break;
652 647
 		}
653
-		LM_INFO("got %d entries from '%.*s'\n", n, tmp.len, tmp.s);
654 648
 		src = src->next;
655 649
 	}
656 650
 
... ...
@@ -1157,11 +1305,6 @@ static int blacklist_child_initialized = 0;
1157 1157
 
1158 1158
 static int rpc_child_init(void)
1159 1159
 {
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 1160
 	/* user blacklist init */
1166 1161
 	if(userblacklist_child_initialized)
1167 1162
 		return 0;
... ...
@@ -1172,6 +1315,11 @@ static int rpc_child_init(void)
1172 1172
 		return -1;
1173 1173
 	}
1174 1174
 
1175
+	/* global blacklist init */
1176
+	if (check_globalblacklist_fixup(NULL, 0) != 0) {
1177
+		LM_ERR("could not add global table when init the module");
1178
+	}
1179
+
1175 1180
 	/* because we've added new sources during the fixup */
1176 1181
 	if (reload_sources() != 0) return -1;
1177 1182
 
... ...
@@ -1225,6 +1373,21 @@ static sr_kemi_t sr_kemi_userblacklist_exports[] = {
1225 1225
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
1226 1226
 			SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
1227 1227
 	},
1228
+	{ str_init("userblacklist"), str_init("check_whitelist"),
1229
+		SR_KEMIP_INT, ki_check_whitelist,
1230
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1231
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1232
+	},
1233
+	{ str_init("userblacklist"), str_init("check_blacklist"),
1234
+		SR_KEMIP_INT, ki_check_blacklist,
1235
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1236
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1237
+	},
1238
+	{ str_init("userblacklist"), str_init("check_global_blacklist"),
1239
+		SR_KEMIP_INT, ki_check_globalblacklist,
1240
+		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
1241
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1242
+	},
1228 1243
 
1229 1244
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
1230 1245
 };