aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/iuh/hnbgw.h2
-rw-r--r--src/hnbgw.c15
-rw-r--r--src/hnbgw_hnbap.c20
3 files changed, 29 insertions, 8 deletions
diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h
index db49dc1..b79bcc1 100644
--- a/include/osmocom/iuh/hnbgw.h
+++ b/include/osmocom/iuh/hnbgw.h
@@ -161,7 +161,7 @@ struct ue_context *ue_context_alloc(struct hnb_context *hnb, const char *imsi,
void ue_context_free(struct ue_context *ue);
struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_link *link, int new_fd);
-void hnb_context_release(struct hnb_context *ctx);
+void hnb_context_release(struct hnb_context *ctx, bool destroy_conn);
void hnbgw_vty_init(struct hnb_gw *gw, void *tall_ctx);
int hnbgw_vty_go_parent(struct vty *vty);
diff --git a/src/hnbgw.c b/src/hnbgw.c
index cd492bb..c1f1dd4 100644
--- a/src/hnbgw.c
+++ b/src/hnbgw.c
@@ -204,6 +204,11 @@ void ue_context_free(struct ue_context *ue)
}
static int hnb_close_cb(struct osmo_stream_srv *conn)
{
+ struct hnb_context *hnb = osmo_stream_srv_get_data(conn);
+
+ if (hnb)
+ hnb_context_release(hnb, false);
+
return 0;
}
@@ -228,10 +233,10 @@ static int hnb_read_cb(struct osmo_stream_srv *conn)
} else if (rc < 0) {
LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
/* FIXME: clean up after disappeared HNB */
- hnb_context_release(hnb);
+ hnb_context_release(hnb, true);
goto out;
} else if (rc == 0) {
- hnb_context_release(hnb);
+ hnb_context_release(hnb, true);
rc = -1;
goto out;
@@ -288,7 +293,7 @@ struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_
return ctx;
}
-void hnb_context_release(struct hnb_context *ctx)
+void hnb_context_release(struct hnb_context *ctx, bool destroy_conn)
{
struct hnbgw_context_map *map, *map2;
@@ -305,7 +310,9 @@ void hnb_context_release(struct hnb_context *ctx)
context_map_deactivate(map);
}
ue_context_free_by_hnb(ctx->gw, ctx);
- osmo_stream_srv_destroy(ctx->conn);
+
+ if (destroy_conn)
+ osmo_stream_srv_destroy(ctx->conn);
talloc_free(ctx);
}
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index c9a8807..0d5cb96 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -53,7 +53,7 @@ static int hnbgw_tx_hnb_register_rej(struct hnb_context *ctx)
{
HNBRegisterReject_t reject_out;
HNBRegisterRejectIEs_t reject;
- struct msgb *msg;
+ struct msgb *msg, *msg0;
int rc;
reject.presenceMask = 0,
@@ -69,6 +69,10 @@ static int hnbgw_tx_hnb_register_rej(struct hnb_context *ctx)
return rc;
}
+ msg0 = msgb_alloc(0, "zero-length terminating message");
+ if (msg0 == NULL)
+ return -ENOMEM;
+
/* generate a successfull outcome PDU */
msg = hnbap_generate_unsuccessful_outcome(ProcedureCode_id_HNBRegister,
Criticality_reject,
@@ -77,7 +81,17 @@ static int hnbgw_tx_hnb_register_rej(struct hnb_context *ctx)
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_HNBRegisterReject, &reject_out);
- return hnbgw_hnbap_tx(ctx, msg);
+ rc = hnbgw_hnbap_tx(ctx, msg);
+ if (rc == 0) {
+ /* Enqueue a zero-length message to destroy the connection
+ * after sending HNB-REGISTER-REJECT. */
+ if (hnbgw_hnbap_tx(ctx, msg0) != 0)
+ LOGP(DHNBAP, LOGL_ERROR, "Failure to send zero-length message after "
+ "HNB-REGISTER-REJECT to %s: rc=%d; the connection won't be closed "
+ "from our side\n", ctx->identity_info, rc);
+ }
+
+ return rc;
}
static int hnbgw_tx_hnb_register_acc(struct hnb_context *ctx)
@@ -393,7 +407,7 @@ static int hnbgw_rx_hnb_deregister(struct hnb_context *ctx, ANY_t *in)
hnbap_cause_str(&ies.cause));
hnbap_free_hnbde_registeries(&ies);
- hnb_context_release(ctx);
+ hnb_context_release(ctx, true);
return 0;
}