aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-04-23 23:31:31 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-04-26 09:36:19 +0200
commite188010512388acdb1408f3d1a0749c25c2c99e3 (patch)
tree5df9a436d79f1bf3674a0316474af66aa9a26d9c /openbsc
parent2a9eeaa588a2a3b63fadd94d6760879b44b14af5 (diff)
bsc: Allow to have a list of MSCs/MUXs to connect to
Be able to configure a list of destinations (duplicates allowed) that will be tried in a round robin fashion. The change is in the bsc_msc_connection to operate on a list. We achieve the round robin nature with the same trick used in the paging code to delete and append the current entry. The nat code was updated to compile but one can only configure one destination.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/bsc_msc.h16
-rw-r--r--openbsc/include/openbsc/bsc_nat.h8
-rw-r--r--openbsc/include/openbsc/osmo_msc_data.h6
-rw-r--r--openbsc/src/libbsc/bsc_msc.c32
-rw-r--r--openbsc/src/libcommon/gsm_data.c3
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_msc.c4
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_vty.c72
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat.c6
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_utils.c20
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_vty.c9
10 files changed, 112 insertions, 64 deletions
diff --git a/openbsc/include/openbsc/bsc_msc.h b/openbsc/include/openbsc/bsc_msc.h
index ddaad3ba7..e3653ac12 100644
--- a/openbsc/include/openbsc/bsc_msc.h
+++ b/openbsc/include/openbsc/bsc_msc.h
@@ -25,14 +25,22 @@
#include <osmocom/core/write_queue.h>
#include <osmocom/core/timer.h>
+struct bsc_msc_dest {
+ struct llist_head list;
+
+ char *ip;
+ int port;
+ int dscp;
+};
+
+
struct bsc_msc_connection {
struct write_queue write_queue;
int is_connected;
int is_authenticated;
int first_contact;
- const char *ip;
- int port;
- int prio;
+
+ struct llist_head *dests;
void (*connection_loss) (struct bsc_msc_connection *);
void (*connected) (struct bsc_msc_connection *);
@@ -40,7 +48,7 @@ struct bsc_msc_connection {
struct timer_list timeout_timer;
};
-struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio);
+struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dest);
int bsc_msc_connect(struct bsc_msc_connection *);
void bsc_msc_schedule_connect(struct bsc_msc_connection *);
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index 8d552e254..8fbed5be7 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -1,6 +1,6 @@
/*
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
+ * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -236,8 +236,8 @@ struct bsc_nat {
int mgcp_length;
/* msc things */
- char *msc_ip;
- int msc_port;
+ struct llist_head dests;
+ struct bsc_msc_dest *main_dest;
struct bsc_msc_connection *msc_con;
char *token;
diff --git a/openbsc/include/openbsc/osmo_msc_data.h b/openbsc/include/openbsc/osmo_msc_data.h
index a35e6f244..f360da584 100644
--- a/openbsc/include/openbsc/osmo_msc_data.h
+++ b/openbsc/include/openbsc/osmo_msc_data.h
@@ -41,9 +41,6 @@ struct osmo_msc_data {
/* Connection data */
char *bsc_token;
- int msc_port;
- int msc_ip_dscp;
- char *msc_ip;
int ping_timeout;
int pong_timeout;
struct timer_list ping_timer;
@@ -57,6 +54,9 @@ struct osmo_msc_data {
struct gsm_audio_support **audio_support;
int audio_length;
+ /* destinations */
+ struct llist_head dests;
+
/* mgcp agent */
struct write_queue mgcp_agent;
diff --git a/openbsc/src/libbsc/bsc_msc.c b/openbsc/src/libbsc/bsc_msc.c
index aa084b83e..8eef6f4e6 100644
--- a/openbsc/src/libbsc/bsc_msc.c
+++ b/openbsc/src/libbsc/bsc_msc.c
@@ -130,11 +130,24 @@ static void setnonblocking(struct bsc_fd *fd)
int bsc_msc_connect(struct bsc_msc_connection *con)
{
+ struct bsc_msc_dest *dest;
struct bsc_fd *fd;
struct sockaddr_in sin;
int on = 1, ret;
- LOGP(DMSC, LOGL_NOTICE, "Attempting to connect MSC at %s:%d\n", con->ip, con->port);
+ if (llist_empty(con->dests)) {
+ LOGP(DMSC, LOGL_ERROR, "No MSC connections configured.\n");
+ connection_loss(con);
+ return -1;
+ }
+
+ /* move to the next connection */
+ dest = (struct bsc_msc_dest *) con->dests->next;
+ llist_del(&dest->list);
+ llist_add_tail(&dest->list, con->dests);
+
+ LOGP(DMSC, LOGL_NOTICE, "Attempting to connect MSC at %s:%d\n",
+ dest->ip, dest->port);
con->is_connected = 0;
@@ -152,15 +165,15 @@ int bsc_msc_connect(struct bsc_msc_connection *con)
/* set the socket priority */
ret = setsockopt(fd->fd, IPPROTO_IP, IP_TOS,
- &con->prio, sizeof(con->prio));
+ &dest->dscp, sizeof(dest->dscp));
if (ret != 0)
- LOGP(DMSC, LOGL_ERROR, "Failed to set prio to %d. %s\n",
- con->prio, strerror(errno));
+ LOGP(DMSC, LOGL_ERROR, "Failed to set DSCP to %d. %s\n",
+ dest->dscp, strerror(errno));
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
- sin.sin_port = htons(con->port);
- inet_aton(con->ip, &sin.sin_addr);
+ sin.sin_port = htons(dest->port);
+ inet_aton(dest->ip, &sin.sin_addr);
setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));
@@ -194,7 +207,7 @@ int bsc_msc_connect(struct bsc_msc_connection *con)
return ret;
}
-struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio)
+struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dests)
{
struct bsc_msc_connection *con;
@@ -204,9 +217,8 @@ struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio)
return NULL;
}
- con->ip = ip;
- con->port = port;
- con->prio = prio;
+ con->dests = dests;
+ con->write_queue.bfd.fd = -1;
write_queue_init(&con->write_queue, 100);
return con;
}
diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c
index fa75654e4..5437548bc 100644
--- a/openbsc/src/libcommon/gsm_data.c
+++ b/openbsc/src/libcommon/gsm_data.c
@@ -323,8 +323,7 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
net->mncc_recv = mncc_recv;
- net->msc_data->msc_ip = talloc_strdup(net, "127.0.0.1");
- net->msc_data->msc_port = 5000;
+ INIT_LLIST_HEAD(&net->msc_data->dests);
net->msc_data->ping_timeout = 20;
net->msc_data->pong_timeout = 5;
net->msc_data->core_ncc = -1;
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_msc.c b/openbsc/src/osmo-bsc/osmo_bsc_msc.c
index e42d8b490..66d18c8a9 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c
@@ -399,9 +399,7 @@ int osmo_bsc_msc_init(struct gsm_network *network)
if (mgcp_create_port(data) != 0)
return -1;
- data->msc_con = bsc_msc_create(data->msc_ip,
- data->msc_port,
- data->msc_ip_dscp);
+ data->msc_con = bsc_msc_create(data, &data->dests);
if (!data->msc_con) {
LOGP(DMSC, LOGL_ERROR, "Creating the MSC network connection failed.\n");
return -1;
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
index 1fb1d6400..055f27ddb 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_vty.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
@@ -1,6 +1,6 @@
/* Osmo BSC VTY Configuration */
/* (C) 2009-2011 by Holger Hans Peter Freyther
- * (C) 2009-2010 by On-Waves
+ * (C) 2009-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -51,6 +51,7 @@ DEFUN(cfg_net_msc, cfg_net_msc_cmd,
static int config_write_msc(struct vty *vty)
{
+ struct bsc_msc_dest *dest;
struct osmo_msc_data *data = osmo_msc_data(vty);
vty_out(vty, "msc%s", VTY_NEWLINE);
@@ -63,9 +64,6 @@ static int config_write_msc(struct vty *vty)
vty_out(vty, " core-mobile-country-code %d%s",
data->core_mcc, VTY_NEWLINE);
vty_out(vty, " ip.access rtp-base %d%s", data->rtp_base, VTY_NEWLINE);
- vty_out(vty, " ip %s%s", data->msc_ip, VTY_NEWLINE);
- vty_out(vty, " port %d%s", data->msc_port, VTY_NEWLINE);
- vty_out(vty, " ip-dscp %d%s", data->msc_ip_dscp, VTY_NEWLINE);
vty_out(vty, " timeout-ping %d%s", data->ping_timeout, VTY_NEWLINE);
vty_out(vty, " timeout-pong %d%s", data->pong_timeout, VTY_NEWLINE);
if (data->mid_call_txt)
@@ -94,6 +92,10 @@ static int config_write_msc(struct vty *vty)
}
+ llist_for_each_entry(dest, &data->dests, list)
+ vty_out(vty, " dest %s %d %d%s", dest->ip, dest->port,
+ dest->dscp, VTY_NEWLINE);
+
return CMD_SUCCESS;
}
@@ -200,34 +202,55 @@ error:
return CMD_ERR_INCOMPLETE;
}
-DEFUN(cfg_net_msc_ip,
- cfg_net_msc_ip_cmd,
- "ip A.B.C.D", "Set the MSC/MUX IP address.")
+DEFUN(cfg_net_msc_dest,
+ cfg_net_msc_dest_cmd,
+ "dest A.B.C.D <1-65000> <0-255>",
+ "Add a destination to a MUX/MSC\n"
+ "IP Address\n" "Port\n" "DSCP\n")
{
+ struct bsc_msc_dest *dest;
struct osmo_msc_data *data = osmo_msc_data(vty);
- bsc_replace_string(data, &data->msc_ip, argv[0]);
+ dest = talloc_zero(data, struct bsc_msc_dest);
+ if (!dest) {
+ vty_out(vty, "%%Failed to create structure.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ dest->ip = talloc_strdup(data, argv[0]);
+ if (!dest->ip) {
+ vty_out(vty, "%%Failed to copy dest ip.%s", VTY_NEWLINE);
+ talloc_free(dest);
+ return CMD_WARNING;
+ }
+
+ dest->port = atoi(argv[1]);
+ dest->dscp = atoi(argv[2]);
+ llist_add_tail(&dest->list, &data->dests);
return CMD_SUCCESS;
}
-DEFUN(cfg_net_msc_port,
- cfg_net_msc_port_cmd,
- "port <1-65000>",
- "Set the MSC/MUX port.")
+DEFUN(cfg_net_msc_no_dest,
+ cfg_net_msc_no_dest_cmd,
+ "no dest A.B.C.D <1-65000> <0-255>",
+ NO_STR "Remove a destination to a MUX/MSC\n"
+ "IP Address\n" "Port\n" "DSCP\n")
{
+ struct bsc_msc_dest *dest, *tmp;
struct osmo_msc_data *data = osmo_msc_data(vty);
- data->msc_port = atoi(argv[0]);
- return CMD_SUCCESS;
-}
+ int port = atoi(argv[1]);
+ int dscp = atoi(argv[2]);
+
+ llist_for_each_entry_safe(dest, tmp, &data->dests, list) {
+ if (port != dest->port || dscp != dest->dscp
+ || strcmp(dest->ip, argv[0]) != 0)
+ continue;
+
+ llist_del(&dest->list);
+ talloc_free(dest);
+ }
-DEFUN(cfg_net_msc_prio,
- cfg_net_msc_prio_cmd,
- "ip-dscp <0-255>",
- "Set the IP_TOS socket attribite")
-{
- struct osmo_msc_data *data = osmo_msc_data(vty);
- data->msc_ip_dscp = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -312,9 +335,8 @@ int bsc_vty_init_extra(void)
install_element(MSC_NODE, &cfg_net_bsc_mcc_cmd);
install_element(MSC_NODE, &cfg_net_bsc_rtp_base_cmd);
install_element(MSC_NODE, &cfg_net_bsc_codec_list_cmd);
- install_element(MSC_NODE, &cfg_net_msc_ip_cmd);
- install_element(MSC_NODE, &cfg_net_msc_port_cmd);
- install_element(MSC_NODE, &cfg_net_msc_prio_cmd);
+ install_element(MSC_NODE, &cfg_net_msc_dest_cmd);
+ install_element(MSC_NODE, &cfg_net_msc_no_dest_cmd);
install_element(MSC_NODE, &cfg_net_msc_ping_time_cmd);
install_element(MSC_NODE, &cfg_net_msc_pong_time_cmd);
install_element(MSC_NODE, &cfg_net_msc_mid_call_text_cmd);
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c
index bbb2ae35c..2146da1c4 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c
@@ -1,8 +1,8 @@
/* BSC Multiplexer/NAT */
/*
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
+ * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2011 by On-Waves
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
* All Rights Reserved
*
@@ -1432,7 +1432,7 @@ int main(int argc, char **argv)
return -4;
/* connect to the MSC */
- nat->msc_con = bsc_msc_create(nat->msc_ip, nat->msc_port, 0);
+ nat->msc_con = bsc_msc_create(nat, &nat->dests);
if (!nat->msc_con) {
fprintf(stderr, "Creating a bsc_msc_connection failed.\n");
exit(1);
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
index 4e7286e6f..4d1afe2df 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
@@ -2,8 +2,8 @@
/* BSC Multiplexer/NAT Utilities */
/*
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
+ * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -82,10 +82,17 @@ struct bsc_nat *bsc_nat_alloc(void)
if (!nat)
return NULL;
+ nat->main_dest = talloc_zero(nat, struct bsc_msc_dest);
+ if (!nat->main_dest) {
+ talloc_free(nat);
+ return NULL;
+ }
+
INIT_LLIST_HEAD(&nat->sccp_connections);
INIT_LLIST_HEAD(&nat->bsc_connections);
INIT_LLIST_HEAD(&nat->bsc_configs);
INIT_LLIST_HEAD(&nat->access_lists);
+ INIT_LLIST_HEAD(&nat->dests);
nat->stats.sccp.conn = counter_alloc("nat.sccp.conn");
nat->stats.sccp.calls = counter_alloc("nat.sccp.calls");
@@ -93,17 +100,20 @@ struct bsc_nat *bsc_nat_alloc(void)
nat->stats.bsc.auth_fail = counter_alloc("nat.bsc.auth_fail");
nat->stats.msc.reconn = counter_alloc("nat.msc.conn");
nat->stats.ussd.reconn = counter_alloc("nat.ussd.conn");
- nat->msc_ip = talloc_strdup(nat, "127.0.0.1");
- nat->msc_port = 5000;
nat->auth_timeout = 2;
nat->ping_timeout = 20;
nat->pong_timeout = 5;
+
+ llist_add(&nat->main_dest->list, &nat->dests);
+ nat->main_dest->ip = talloc_strdup(nat, "127.0.0.1");
+ nat->main_dest->port = 5000;
+
return nat;
}
void bsc_nat_set_msc_ip(struct bsc_nat *nat, const char *ip)
{
- bsc_replace_string(nat, &nat->msc_ip, ip);
+ bsc_replace_string(nat, &nat->main_dest->ip, ip);
}
struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat)
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
index ef433caed..ffbfe9b3a 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
@@ -69,8 +69,8 @@ static int config_write_nat(struct vty *vty)
struct bsc_nat_acc_lst *lst;
vty_out(vty, "nat%s", VTY_NEWLINE);
- vty_out(vty, " msc ip %s%s", _nat->msc_ip, VTY_NEWLINE);
- vty_out(vty, " msc port %d%s", _nat->msc_port, VTY_NEWLINE);
+ vty_out(vty, " msc ip %s%s", _nat->main_dest->ip, VTY_NEWLINE);
+ vty_out(vty, " msc port %d%s", _nat->main_dest->port, VTY_NEWLINE);
vty_out(vty, " timeout auth %d%s", _nat->auth_timeout, VTY_NEWLINE);
vty_out(vty, " timeout ping %d%s", _nat->ping_timeout, VTY_NEWLINE);
vty_out(vty, " timeout pong %d%s", _nat->pong_timeout, VTY_NEWLINE);
@@ -311,8 +311,7 @@ DEFUN(show_msc,
return CMD_WARNING;
}
- vty_out(vty, "MSC on %s:%d is connected: %d%s\n",
- _nat->msc_con->ip, _nat->msc_con->port,
+ vty_out(vty, "MSC is connected: %d%s\n",
_nat->msc_con->is_connected, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -357,7 +356,7 @@ DEFUN(cfg_nat_msc_port,
"msc port <1-65500>",
"Set the port of the MSC.")
{
- _nat->msc_port = atoi(argv[0]);
+ _nat->main_dest->port = atoi(argv[0]);
return CMD_SUCCESS;
}