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 #include +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 - * (C) 2010 by On-Waves + * (C) 2010-2011 by Holger Hans Peter Freyther + * (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 - * (C) 2010 by On-Waves + * (C) 2010-2011 by Holger Hans Peter Freyther + * (C) 2010-2011 by On-Waves * (C) 2009 by Harald Welte * 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 - * (C) 2010 by On-Waves + * (C) 2010-2011 by Holger Hans Peter Freyther + * (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; }