fix SCCP conn leak on non-graceful HNB shutdown
Clean up SCCP connections when a HNB disconnects. When a HNB disconnects, we clean up all RUA <-> SCCP connection state for that HNB. In that cleanup, discarding the SCCP connection is so far missing. Add a flag indicating true between SCCP CC and DISCONNECT. Hence we can tell during context_map_deactivate() whether the cleanup is graceful (DISCONNECT already sent) or non-graceful (need to DISCONNECT). Change-Id: Icc2db9f6c0b2d0a814ff1110ffbe5e8f7f629222
This commit is contained in:
parent
07d01d50a5
commit
87ecf69b55
|
@ -43,6 +43,10 @@ struct hnbgw_context_map {
|
|||
bool is_ps;
|
||||
/* SCCP User SAP connection ID */
|
||||
uint32_t scu_conn_id;
|
||||
/* Set to true on SCCP Conn Conf, set to false when an OSMO_SCU_PRIM_N_DISCONNECT has been sent for the SCCP
|
||||
* User SAP conn. Useful to avoid leaking SCCP connections: guarantee that an OSMO_SCU_PRIM_N_DISCONNECT gets
|
||||
* sent, even when RUA fails to gracefully disconnect. */
|
||||
bool scu_conn_active;
|
||||
/* Pending data to be sent: when we send an "empty" SCCP CR first, the initial RANAP message will be sent in a
|
||||
* separate DT once the CR is confirmed. This caches the initial RANAP message. */
|
||||
struct msgb *cached_msg;
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
#include <osmocom/sigtran/sccp_helpers.h>
|
||||
|
||||
#include <osmocom/hnbgw/hnbgw.h>
|
||||
#include <osmocom/hnbgw/hnbgw_rua.h>
|
||||
#include <osmocom/hnbgw/context_map.h>
|
||||
|
@ -174,6 +176,12 @@ void context_map_deactivate(struct hnbgw_context_map *map)
|
|||
if (map->state != MAP_S_RESERVED2)
|
||||
map->state = MAP_S_RESERVED1;
|
||||
|
||||
/* Is SCCP still active and needs to be disconnected ungracefully? */
|
||||
if (map->scu_conn_active) {
|
||||
osmo_sccp_tx_disconn(map->hnb_ctx->gw->sccp.cnlink->sccp_user, map->scu_conn_id, NULL, 0);
|
||||
map->scu_conn_active = false;
|
||||
}
|
||||
|
||||
/* a possibly still existing MGW FSM must be terminated when the context
|
||||
* map is deactivated. (this is a cornercase) */
|
||||
if (map->mgw_fi) {
|
||||
|
|
|
@ -337,6 +337,8 @@ static int handle_cn_conn_conf(struct hnbgw_cnlink *cnlink,
|
|||
struct osmo_prim_hdr *oph)
|
||||
{
|
||||
struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(cnlink->gw->sccp.client);
|
||||
struct hnbgw_context_map *map;
|
||||
|
||||
LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() conn_id=%d, addrs: called=%s calling=%s responding=%s\n",
|
||||
param->conn_id,
|
||||
osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, ¶m->called_addr),
|
||||
|
@ -346,9 +348,17 @@ static int handle_cn_conn_conf(struct hnbgw_cnlink *cnlink,
|
|||
/* Nothing needs to happen for RUA, RUA towards the HNB doesn't seem to know any confirmations to its CONNECT
|
||||
* operation. */
|
||||
|
||||
map = context_map_by_cn(cnlink, param->conn_id);
|
||||
if (!map)
|
||||
return 0;
|
||||
|
||||
/* SCCP connection is confirmed. Mark conn as active, i.e. requires a DISCONNECT to clean up the SCCP
|
||||
* connection. */
|
||||
map->scu_conn_active = true;
|
||||
|
||||
/* If our initial SCCP CR was sent without data payload, then the initial RANAP message is cached and waiting to
|
||||
* be sent as soon as the SCCP connection is confirmed. See if that is the case, send cached data. */
|
||||
context_map_send_cached_msg(context_map_by_cn(cnlink, param->conn_id));
|
||||
context_map_send_cached_msg(map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -252,6 +252,9 @@ int rua_to_scu(struct hnb_context *hnb,
|
|||
prim->u.disconnect.conn_id = map->scu_conn_id;
|
||||
prim->u.disconnect.cause = cause;
|
||||
release_context_map = true;
|
||||
/* Mark SCCP conn as gracefully disconnected */
|
||||
if (map)
|
||||
map->scu_conn_active = false;
|
||||
break;
|
||||
case OSMO_SCU_PRIM_N_UNITDATA:
|
||||
prim->u.unitdata.called_addr = *remote_addr;
|
||||
|
|
Loading…
Reference in New Issue