aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2016-06-07 15:32:16 +0200
committerHarald Welte <laforge@gnumonks.org>2016-06-14 22:20:40 +0000
commit0fcd2e2fec966ac4e17222e7f53f2d0e5a7bf0ba (patch)
tree49bb94bc7ad856f277a72fd62c650a16d21e76ea
parente152ffe14d1dfe2ffb4892ada5eede6ccb429338 (diff)
Make random extension range configurable
Previously if subscriber was automatically created it got assigned random MSISDN number between 20000 and 49999. Make it configurable with new vty command "subscriber-create-on-demand random" and expand vty tests to check it. Change-Id: I040a1d227b0c7a1601dc7c33eccb0007941408a6 Related: OS#1658
-rw-r--r--openbsc/include/openbsc/db.h6
-rw-r--r--openbsc/include/openbsc/gsm_data.h2
-rw-r--r--openbsc/include/openbsc/gsm_subscriber.h3
-rw-r--r--openbsc/src/libbsc/net_init.c3
-rw-r--r--openbsc/src/libmsc/ctrl_commands.c5
-rw-r--r--openbsc/src/libmsc/db.c10
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c3
-rw-r--r--openbsc/src/libmsc/gsm_subscriber.c5
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c30
-rw-r--r--openbsc/tests/db/db_test.c6
-rw-r--r--openbsc/tests/vty_test_runner.py21
11 files changed, 78 insertions, 16 deletions
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h
index 6699a8600..6ffe1ade9 100644
--- a/openbsc/include/openbsc/db.h
+++ b/openbsc/include/openbsc/db.h
@@ -35,13 +35,15 @@ int db_prepare(void);
int db_fini(void);
/* subscriber management */
-struct gsm_subscriber *db_create_subscriber(const char *imsi);
+struct gsm_subscriber *db_create_subscriber(const char *imsi, uint64_t smin,
+ uint64_t smax);
struct gsm_subscriber *db_get_subscriber(enum gsm_subscriber_field field,
const char *subscr);
int db_sync_subscriber(struct gsm_subscriber *subscriber);
int db_subscriber_expire(void *priv, void (*callback)(void *priv, long long unsigned int id));
int db_subscriber_alloc_tmsi(struct gsm_subscriber *subscriber);
-int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber);
+int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber, uint64_t smin,
+ uint64_t smax);
int db_subscriber_alloc_token(struct gsm_subscriber *subscriber, uint32_t* token);
int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char *imei);
int db_subscriber_delete(struct gsm_subscriber *subscriber);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 31a4ed5bd..e7cd520d2 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -290,6 +290,8 @@ struct gsm_network {
/* subscriber related features */
int subscr_creation_mode;
+ uint64_t ext_min;
+ uint64_t ext_max;
struct gsm_subscriber_group *subscr_group;
struct gsm_sms_queue *sms_queue;
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h
index 9df989a79..3cba5d1ae 100644
--- a/openbsc/include/openbsc/gsm_subscriber.h
+++ b/openbsc/include/openbsc/gsm_subscriber.h
@@ -90,7 +90,8 @@ enum gsm_subscriber_update_reason {
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
- const char *imsi);
+ const char *imsi, uint64_t smin,
+ uint64_t smax);
struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_subscriber_group *sgrp,
uint32_t tmsi);
struct gsm_subscriber *subscr_get_by_imsi(struct gsm_subscriber_group *sgrp,
diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c
index afcaaf33c..4636d579e 100644
--- a/openbsc/src/libbsc/net_init.c
+++ b/openbsc/src/libbsc/net_init.c
@@ -104,7 +104,8 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
net->stats.bts.rsl_fail = osmo_counter_alloc("net.bts.rsl_fail");
net->mncc_recv = mncc_recv;
-
+ net->ext_min = GSM_MIN_EXTEN;
+ net->ext_max = GSM_MAX_EXTEN;
gsm_net_update_ctype(net);
return net;
diff --git a/openbsc/src/libmsc/ctrl_commands.c b/openbsc/src/libmsc/ctrl_commands.c
index 0d6a37c96..a02db36b9 100644
--- a/openbsc/src/libmsc/ctrl_commands.c
+++ b/openbsc/src/libmsc/ctrl_commands.c
@@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
#include <osmocom/ctrl/control_cmd.h>
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_subscriber.h>
@@ -95,7 +96,9 @@ static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
subscr = subscr_get_by_imsi(net->subscr_group, imsi);
if (!subscr)
- subscr = subscr_create_subscriber(net->subscr_group, imsi);
+ subscr = subscr_create_subscriber(net->subscr_group, imsi,
+ net->ext_min,
+ net->ext_max);
if (!subscr)
goto fail;
diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c
index 9e3fb362f..b3671393a 100644
--- a/openbsc/src/libmsc/db.c
+++ b/openbsc/src/libmsc/db.c
@@ -518,7 +518,8 @@ int db_fini(void)
return 0;
}
-struct gsm_subscriber *db_create_subscriber(const char *imsi)
+struct gsm_subscriber *db_create_subscriber(const char *imsi, uint64_t smin,
+ uint64_t smax)
{
dbi_result result;
struct gsm_subscriber *subscr;
@@ -550,7 +551,7 @@ struct gsm_subscriber *db_create_subscriber(const char *imsi)
strncpy(subscr->imsi, imsi, sizeof(subscr->imsi)-1);
dbi_result_free(result);
LOGP(DDB, LOGL_INFO, "New Subscriber: ID %llu, IMSI %s\n", subscr->id, subscr->imsi);
- db_subscriber_alloc_exten(subscr);
+ db_subscriber_alloc_exten(subscr, smin, smax);
return subscr;
}
@@ -1249,13 +1250,14 @@ int db_subscriber_alloc_tmsi(struct gsm_subscriber *subscriber)
return 0;
}
-int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber)
+int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber, uint64_t smin,
+ uint64_t smax)
{
dbi_result result = NULL;
uint32_t try;
for (;;) {
- try = (rand()%(GSM_MAX_EXTEN-GSM_MIN_EXTEN+1)+GSM_MIN_EXTEN);
+ try = (rand() % (smax - smin + 1) + smin);
result = dbi_conn_queryf(conn,
"SELECT * FROM Subscriber "
"WHERE extension = %i",
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 92c4cfe0e..67044971b 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -537,7 +537,8 @@ static struct gsm_subscriber *subscr_create(const struct gsm_network *net,
if (!subscr_regexp_check(net, imsi))
return NULL;
- return subscr_create_subscriber(net->subscr_group, imsi);
+ return subscr_create_subscriber(net->subscr_group, imsi, net->ext_min,
+ net->ext_max);
}
/* Parse Chapter 9.2.11 Identity Response */
diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c
index 57c10cf7e..1dc2cc26d 100644
--- a/openbsc/src/libmsc/gsm_subscriber.c
+++ b/openbsc/src/libmsc/gsm_subscriber.c
@@ -203,9 +203,10 @@ void subscr_remove_request(struct subscr_request *request)
}
struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
- const char *imsi)
+ const char *imsi, uint64_t smin,
+ uint64_t smax)
{
- struct gsm_subscriber *subscr = db_create_subscriber(imsi);
+ struct gsm_subscriber *subscr = db_create_subscriber(imsi, smin, smax);
if (subscr)
subscr->group = sgrp;
return subscr;
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index 3f67b9aa8..a035bf976 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/src/libmsc/vty_interface_layer3.c
@@ -21,6 +21,8 @@
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
+#include <stdbool.h>
+#include <inttypes.h>
#include <time.h>
#include <osmocom/vty/command.h>
@@ -240,7 +242,9 @@ DEFUN(subscriber_create,
if (subscr)
db_sync_subscriber(subscr);
else {
- subscr = subscr_create_subscriber(gsmnet->subscr_group, argv[0]);
+ subscr = subscr_create_subscriber(gsmnet->subscr_group, argv[0],
+ gsmnet->ext_min,
+ gsmnet->ext_max);
if (!subscr) {
vty_out(vty, "%% No subscriber created for IMSI %s%s",
@@ -1031,6 +1035,25 @@ DEFUN(cfg_nitb, cfg_nitb_cmd,
return CMD_SUCCESS;
}
+/* Note: limit on the parameter length is set by internal vty code limitations */
+DEFUN(cfg_nitb_subscr_random, cfg_nitb_subscr_random_cmd,
+ "subscriber-create-on-demand random <1-9999999999> <2-9999999999>",
+ "Set random parameters for a new record when a subscriber is first seen.\n"
+ "Set random parameters for a new record when a subscriber is first seen.\n"
+ "Minimum for subscriber extension\n""Maximum for subscriber extension\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ uint64_t mi = atoi(argv[0]), ma = atoi(argv[1]);
+ if (mi >= ma) {
+ vty_out(vty, "Incorrect range: %s >= %s, expected MIN < MAX%s",
+ argv[0], argv[1], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ gsmnet->ext_min = mi;
+ gsmnet->ext_max = ma;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_nitb_subscr_create, cfg_nitb_subscr_create_cmd,
"subscriber-create-on-demand [regexp]",
"Make a new record when a subscriber is first seen.\n"
@@ -1080,6 +1103,10 @@ static int config_write_nitb(struct vty *vty)
vty_out(vty, "nitb%s", VTY_NEWLINE);
vty_out(vty, " %ssubscriber-create-on-demand%s%s",
pref, reg, VTY_NEWLINE);
+ if (gsmnet->ext_min != GSM_MIN_EXTEN || gsmnet->ext_max != GSM_MAX_EXTEN)
+ vty_out(vty, " subscriber-create-on-demand random %"PRIu64" %"
+ PRIu64"%s", gsmnet->ext_min, gsmnet->ext_max,
+ VTY_NEWLINE);
vty_out(vty, " %sassign-tmsi%s",
gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE);
return CMD_SUCCESS;
@@ -1134,6 +1161,7 @@ int bsc_vty_init_extra(void)
install_element(CONFIG_NODE, &cfg_nitb_cmd);
install_node(&nitb_node, config_write_nitb);
install_element(NITB_NODE, &cfg_nitb_subscr_create_cmd);
+ install_element(NITB_NODE, &cfg_nitb_subscr_random_cmd);
install_element(NITB_NODE, &cfg_nitb_no_subscr_create_cmd);
install_element(NITB_NODE, &cfg_nitb_assign_tmsi_cmd);
install_element(NITB_NODE, &cfg_nitb_no_assign_tmsi_cmd);
diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c
index ee0cbca5b..dc814813d 100644
--- a/openbsc/tests/db/db_test.c
+++ b/openbsc/tests/db/db_test.c
@@ -164,7 +164,7 @@ static void test_subs(const char *alice_imsi, char *imei1, char *imei2)
struct gsm_subscriber *alice = NULL, *alice_db;
char scratch_str[256];
- alice = db_create_subscriber(alice_imsi);
+ alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN);
db_subscriber_assoc_imei(alice, imei1);
if (imei2)
db_subscriber_assoc_imei(alice, imei2);
@@ -217,7 +217,7 @@ int main()
struct gsm_subscriber *alice_db;
char *alice_imsi = "3243245432345";
- alice = db_create_subscriber(alice_imsi);
+ alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN);
db_sync_subscriber(alice);
alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice->imsi);
COMPARE(alice, alice_db);
@@ -228,7 +228,7 @@ int main()
test_subs("9993245423445", "1234567890", "6543560920");
/* create it again and see it fails */
- alice = db_create_subscriber(alice_imsi);
+ alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN);
OSMO_ASSERT(!alice);
test_sms();
diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py
index c264328a9..9ea988d62 100644
--- a/openbsc/tests/vty_test_runner.py
+++ b/openbsc/tests/vty_test_runner.py
@@ -424,11 +424,13 @@ class TestVTYNITB(TestVTYGenericBSC):
self.vty.enable()
imsi = "204300854013739"
+ imsi2 = "204301824913769"
wrong_imsi = "204300999999999"
# Lets create one
res = self.vty.command('subscriber create imsi '+imsi)
self.assert_(res.find(" IMSI: "+imsi) > 0)
+ self.assert_(res.find("Extension") > 0)
self.vty.verify('subscriber imsi '+wrong_imsi+' name wrong', ['% No subscriber found for imsi '+wrong_imsi])
res = self.vty.command('subscriber imsi '+imsi+' name '+('X' * 160))
@@ -442,9 +444,28 @@ class TestVTYNITB(TestVTYGenericBSC):
self.vty.verify('subscriber imsi '+imsi+' extension '+('1' * 14), [''])
+ # With narrow random interval
+ self.vty.command("configure terminal")
+ self.vty.command("nitb")
+ self.assertTrue(self.vty.verify("subscriber-create-on-demand", ['']))
+ # wrong interval
+ res = self.vty.command("subscriber-create-on-demand random 221 122")
+ self.assert_(res.find("122") > 0)
+ self.assert_(res.find("221") > 0)
+ # correct interval
+ self.assertTrue(self.vty.verify("subscriber-create-on-demand random 221 222", ['']))
+ self.vty.command("end")
+
+ res = self.vty.command('subscriber create imsi ' + imsi2)
+ self.assert_(res.find(" IMSI: " + imsi2) > 0)
+ self.assert_(res.find("221") > 0 or res.find("222") > 0)
+ self.assert_(res.find(" Extension: ") > 0)
+
# Delete it
res = self.vty.command('subscriber delete imsi '+imsi)
self.assert_(res != "")
+ res = self.vty.command('subscriber delete imsi ' + imsi2)
+ self.assert_(res != "")
def testShowPagingGroup(self):
res = self.vty.command("show paging-group 255 1234567")