diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2013-08-26 16:11:01 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2013-09-03 16:04:57 +0200 |
commit | 7e5cdb1da017feee6222a33760ad92fae932c453 (patch) | |
tree | 065d0d52bd96923b6674ca97da915449ef31b78d | |
parent | 06173ca459c6ab814b80fa24df4fe1a9c3994b82 (diff) |
nat: Begin to prepare to inspect Call-Control (CC) messages
Begin to inspect Call-Control messages and then hand off the
entire connection to a different/local MSC. In the future this
should work on a per transaction basis (the same applies to the
USSD handling) but the first version will not do that.
-rw-r--r-- | openbsc/include/openbsc/bsc_nat.h | 9 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat.c | 75 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat_call_control.c | 6 |
3 files changed, 71 insertions, 19 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 65a8c90ad..2cb07156c 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -356,6 +356,11 @@ struct bsc_nat_ussd_con { struct osmo_timer_list auth_timeout; }; +struct bsc_nat_cc_con { + struct osmo_wqueue queue; + struct bsc_nat *nat; +}; + struct bsc_nat_reject_cause { int lu_reject_cause; int cm_reject_cause; @@ -458,6 +463,10 @@ int bsc_ussd_init(struct bsc_nat *nat); int bsc_ussd_check(struct nat_sccp_connection *con, struct bsc_nat_parsed *parsed, struct msgb *msg); int bsc_ussd_close_connections(struct bsc_nat *nat); +/** Call-Contrl filtering */ +int bsc_cc_init(struct bsc_nat *nat); +int bsc_cc_check(struct nat_sccp_connection *con, struct bsc_nat_parsed *parse, struct msgb *msg); + void bsc_cc_update_msc_ip(struct bsc_nat *bsc, const char *ip); int bsc_cc_initialize(struct bsc_nat *bsc); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index 9cc02a185..fd9356032 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -85,6 +85,12 @@ static void bsc_send_data(struct bsc_connection *bsc, const uint8_t *data, unsig static void msc_send_reset(struct bsc_msc_connection *con); static void bsc_stat_reject(int filter, struct bsc_connection *bsc, int normal); +static int is_local_connection(struct nat_sccp_connection *con) +{ + return con->con_local == NAT_CON_END_USSD + || con->con_local == NAT_CON_END_CALL; +} + struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num) { struct bsc_config *conf; @@ -221,18 +227,30 @@ static struct msgb *nat_create_rlsd(struct nat_sccp_connection *conn) return msg; } -static void nat_send_rlsd_ussd(struct bsc_nat *nat, struct nat_sccp_connection *conn) +static void nat_send_rlsd(struct osmo_wqueue *queue, struct nat_sccp_connection *conn) { struct msgb *msg; - if (!nat->ussd_con) - return; - msg = nat_create_rlsd(conn); if (!msg) return; - bsc_do_write(&nat->ussd_con->queue, msg, IPAC_PROTO_SCCP); + bsc_do_write(queue, msg, IPAC_PROTO_SCCP); +} + +static void nat_send_rlsd_ussd(struct bsc_nat *nat, struct nat_sccp_connection *conn) +{ + + if (!nat->ussd_con) + return; + return nat_send_rlsd(&nat->ussd_con->queue, conn); +} + +static void nat_send_rlsd_cc(struct bsc_nat *nat, struct nat_sccp_connection *conn) +{ + if (!nat->local_conn) + return; + return nat_send_rlsd(&nat->local_conn->write_queue, conn); } static void nat_send_rlsd_msc(struct nat_sccp_connection *conn) @@ -682,9 +700,13 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb * LOGP(DNAT, LOGL_ERROR, "Failed to assign...\n"); } else LOGP(DNAT, LOGL_ERROR, "Assignment command but no BSC.\n"); - } else if (con && con->con_local == NAT_CON_END_USSD && - parsed->gsm_type == BSS_MAP_MSG_CLEAR_CMD) { - LOGP(DNAT, LOGL_NOTICE, "Clear Command for USSD Connection. Ignoring.\n"); + } else if (con && is_local_connection(con) + && parsed->gsm_type == BSS_MAP_MSG_CLEAR_CMD) { + LOGP(DNAT, LOGL_NOTICE, "Clear Command for local connection. Ignoring.\n"); + con = NULL; + } else if (con && con->con_local == NAT_CON_END_CALL + && parsed->sccp_type == SCCP_MSG_TYPE_RLSD) { + LOGP(DNAT, LOGL_NOTICE, "Ignoring RLSD for local CC connection.\n"); con = NULL; } break; @@ -904,10 +926,20 @@ void bsc_close_connection(struct bsc_connection *connection) if (ctr) rate_ctr_inc(ctr); if (sccp_patch->has_remote_ref) { - if (sccp_patch->con_local == NAT_CON_END_MSC) + switch (sccp_patch->con_local) { + case NAT_CON_END_MSC: nat_send_rlsd_msc(sccp_patch); - else if (sccp_patch->con_local == NAT_CON_END_USSD) + break; + case NAT_CON_END_USSD: nat_send_rlsd_ussd(nat, sccp_patch); + break; + case NAT_CON_END_CALL: + nat_send_rlsd_cc(nat, sccp_patch); + break; + case NAT_CON_END_LOCAL: + /* nothing */ + break; + } } sccp_connection_destroy(sccp_patch); @@ -1104,20 +1136,25 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) goto exit2; } - /* hand data to a side channel */ - if (bsc_ussd_check(con, parsed, msg) == 1) + /* hand data from the various side channels */ + if (bsc_ussd_check(con, parsed, msg) == 1) { con->con_local = NAT_CON_END_USSD; - - /* - * Optionally rewrite setup message. This can - * replace the msg and the parsed structure becomes - * invalid. - */ - msg = bsc_nat_rewrite_msg(bsc->nat, msg, parsed, con->imsi); + } else if (bsc_cc_check(con, parsed, msg) == 1) { + con->con_local = NAT_CON_END_CALL; + } else { + /* + * Optionally rewrite setup message. This can + * replace the msg and the parsed structure becomes + * invalid. + */ + msg = bsc_nat_rewrite_msg(bsc->nat, msg, parsed, con->imsi); + } talloc_free(parsed); parsed = NULL; } else if (con->con_local == NAT_CON_END_USSD) { bsc_ussd_check(con, parsed, msg); + } else if (con->con_local == NAT_CON_END_CALL) { + bsc_cc_check(con, parsed, msg); } con_bsc = con->bsc; diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_call_control.c b/openbsc/src/osmo-bsc_nat/bsc_nat_call_control.c index b9a4bbae1..0328380bb 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_call_control.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_call_control.c @@ -172,3 +172,9 @@ int bsc_cc_initialize(struct bsc_nat *nat) return 0; } + +int bsc_cc_check(struct nat_sccp_connection *con, struct bsc_nat_parsed *parsed, + struct msgb *msg) +{ + return 0; +} |