pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/41502?usp=email )
Change subject: ss7_xua_srv: Refactor xua_accept_cb()
......................................................................
ss7_xua_srv: Refactor xua_accept_cb()
Move all "readonly" (no state change) checks at the start of the
function. This simplifies the later code paths in the function, also
allowing for more early return checks. This in turn allows simplifying
different destruction code paths of asp and its osmo_stream.
As a result, we can now call existing ss7_asp_disconnect_stream() API to
close the stream when needed, and also make sure we set
asp->xua_server=NULL and remove asp from oxs->siblings when the conn
disconnects, otherwise it could create unexpected states if the config
of the asp changes transport role client<->server or it gets assigned
due to a different oxs due to change in config too.
The new logic also fixes some corner-case scenarios, like (dis)allwoing
newly created dynamic ASPs for already existing previous conn after the
feature configuration has changed.
Change-Id: I191f97e8545ce2f9899e3cd3cc3a7eed854daf1e
---
M src/ss7_asp.c
M src/ss7_xua_srv.c
2 files changed, 58 insertions(+), 56 deletions(-)
Approvals:
daniel: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
fixeria: Looks good to me, but someone else must approve
Jenkins Builder: Verified
diff --git a/src/ss7_asp.c b/src/ss7_asp.c
index 5325de9..377d9e4 100644
--- a/src/ss7_asp.c
+++ b/src/ss7_asp.c
@@ -756,8 +756,6 @@
osmo_stream_cli_destroy(asp->client);
if (asp->fi)
osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL);
- if (asp->xua_server)
- llist_del(&asp->siblings);
/* unlink from all ASs we are part of */
llist_for_each_entry(as, &asp->inst->as_list, list)
@@ -1360,6 +1358,10 @@
xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION);
asp->server = NULL;
+ if (asp->xua_server) {
+ llist_del(&asp->siblings);
+ asp->xua_server = NULL;
+ }
/* if we were dynamically allocated at accept_cb() time, let's
* self-destruct now. A new connection will re-create the ASP. */
diff --git a/src/ss7_xua_srv.c b/src/ss7_xua_srv.c
index 7e55777..85906b7 100644
--- a/src/ss7_xua_srv.c
+++ b/src/ss7_xua_srv.c
@@ -76,6 +76,7 @@
asp = ss7_asp_find_by_socket_addr(fd, oxs->cfg.trans_proto);
if (asp) {
+ LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", sock_name, asp->cfg.name);
if (!asp->cfg.is_server) {
LOGPASP(asp, DLSS7, LOGL_NOTICE,
"Reject incoming new connection from %s for ASP configured as 'transport-role client'\n",
@@ -92,6 +93,26 @@
talloc_free(sock_name);
return 0;
}
+ /* we need to check if we already have a socket associated, and close it. Otherwise it might
+ * happen that both the listen-fd for this accept() and the old socket are marked 'readable'
+ * during the same scheduling interval, and we're processing them in the "wrong" order, i.e.
+ * we first see the accept of the new fd before we see the close on the old fd */
+ if (asp->server) {
+ LOGPASP(asp, DLSS7, LOGL_FATAL, "accept of new connection from %s before old was closed "
+ "-> close old one\n", sock_name);
+ ss7_asp_disconnect_stream(asp);
+ /* Dynamic ASPs (transport-role=server) may be destroyed as a consequence, re-fetch the ASP: */
+ asp = ss7_asp_find_by_socket_addr(fd, oxs->cfg.trans_proto);
+ }
+ }
+
+ if (!asp && !oxs->cfg.accept_dyn_reg) {
+ LOGP(DLSS7, LOGL_NOTICE, "%s: %s connection without matching "
+ "ASP definition and no dynamic registration enabled, terminating\n",
+ sock_name, proto_name);
+ close(fd);
+ talloc_free(sock_name);
+ return -1;
}
srv = osmo_stream_srv_create2(oxs, link, fd, NULL);
@@ -127,71 +148,50 @@
}
osmo_stream_srv_set_closed_cb(srv, ss7_asp_xua_srv_conn_closed_cb);
- if (asp) {
- LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n",
- sock_name, asp->cfg.name);
- /* we need to check if we already have a socket associated, and close it. Otherwise it might
- * happen that both the listen-fd for this accept() and the old socket are marked 'readable'
- * during the same scheduling interval, and we're processing them in the "wrong" order, i.e.
- * we first see the accept of the new fd before we see the close on the old fd */
- if (asp->server) {
- LOGPASP(asp, DLSS7, LOGL_FATAL, "accept of new connection from %s before old was closed "
- "-> close old one\n", sock_name);
- osmo_stream_srv_set_data(asp->server, NULL);
- osmo_stream_srv_destroy(asp->server);
- asp->server = NULL;
- }
- } else {
- if (!oxs->cfg.accept_dyn_reg) {
- LOGP(DLSS7, LOGL_NOTICE, "%s: %s connection without matching "
- "ASP definition and no dynamic registration enabled, terminating\n",
- sock_name, proto_name);
- } else {
- char namebuf[32];
- static uint32_t dyn_asp_num = 0;
- snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++);
- asp = osmo_ss7_asp_find_or_create2(oxs->inst, namebuf, 0, 0,
- oxs->cfg.trans_proto,
- oxs->cfg.proto);
- if (asp) {
- char hostbuf[INET6_ADDRSTRLEN];
- const char *hostbuf_ptr = &hostbuf[0];
- char portbuf[16];
-
- osmo_sock_get_ip_and_port(fd, hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), false);
- LOGP(DLSS7, LOGL_INFO, "%s: created dynamic ASP %s\n",
- sock_name, asp->cfg.name);
- asp->cfg.is_server = true;
- asp->cfg.role = OSMO_SS7_ASP_ROLE_SG;
- asp->cfg.local.port = oxs->cfg.local.port;
- asp->cfg.remote.port = atoi(portbuf);
- asp->dyn_allocated = true;
- asp->server = srv;
- ss7_asp_peer_set_hosts(&asp->cfg.local, asp,
- (const char * const*)oxs->cfg.local.host,
- oxs->cfg.local.host_cnt);
- ss7_asp_peer_set_hosts(&asp->cfg.remote, asp,
- &hostbuf_ptr, 1);
- if ((rc = xua_asp_fsm_start(asp, asp->cfg.role, LOGL_DEBUG)) < 0) {
- talloc_free(sock_name);
- osmo_ss7_asp_destroy(asp);
- return rc;
- }
- OSMO_ASSERT(asp->fi);
- }
- }
+ if (!asp) {
+ /* Dynamic registration: */
+ char namebuf[32];
+ char hostbuf[INET6_ADDRSTRLEN];
+ const char *hostbuf_ptr = &hostbuf[0];
+ char portbuf[16];
+ static uint32_t dyn_asp_num = 0;
+ snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++);
+ asp = osmo_ss7_asp_find_or_create2(oxs->inst, namebuf, 0, 0,
+ oxs->cfg.trans_proto,
+ oxs->cfg.proto);
if (!asp) {
osmo_stream_srv_destroy(srv);
talloc_free(sock_name);
return -1;
}
- llist_add_tail(&asp->siblings, &oxs->asp_list);
+
+ osmo_sock_get_ip_and_port(fd, hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), false);
+ LOGP(DLSS7, LOGL_INFO, "%s: created dynamic ASP %s\n", sock_name, asp->cfg.name);
+ asp->cfg.is_server = true;
+ asp->cfg.role = OSMO_SS7_ASP_ROLE_SG;
+ asp->cfg.local.port = oxs->cfg.local.port;
+ asp->cfg.remote.port = atoi(portbuf);
+ asp->dyn_allocated = true;
+ asp->server = srv;
+ ss7_asp_peer_set_hosts(&asp->cfg.local, asp,
+ (const char * const*)oxs->cfg.local.host,
+ oxs->cfg.local.host_cnt);
+ ss7_asp_peer_set_hosts(&asp->cfg.remote, asp,
+ &hostbuf_ptr, 1);
+ if ((rc = xua_asp_fsm_start(asp, asp->cfg.role, LOGL_DEBUG)) < 0) {
+ talloc_free(sock_name);
+ osmo_ss7_asp_destroy(asp);
+ return rc;
+ }
+ OSMO_ASSERT(asp->fi);
}
+ OSMO_ASSERT(asp);
/* update the ASP reference back to the server over which the
* connection came in */
asp->server = srv;
asp->xua_server = oxs;
+ llist_add_tail(&asp->siblings, &oxs->asp_list);
/* update the ASP socket name */
talloc_free(asp->sock_name);
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/41502?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I191f97e8545ce2f9899e3cd3cc3a7eed854daf1e
Gerrit-Change-Number: 41502
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: lynxis lazus <lynxis(a)fe80.eu>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Attention is currently required from: pespin.
daniel has posted comments on this change by pespin. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/41512?usp=email )
Change subject: Destroy rkm_dyn_allocated AS automatically when becoming out of ASPs
......................................................................
Patch Set 1: Code-Review+1
(1 comment)
Commit Message:
https://gerrit.osmocom.org/c/libosmo-sigtran/+/41512/comment/727c3392_e1f78… :
PS1, Line 7: becoming
running out of ASPs?
Maybe "when it no longer has any ASPs"
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/41512?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I743af584cd77924654d22ccf5d36d4479ba3b7f5
Gerrit-Change-Number: 41512
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de>
Gerrit-Attention: pespin <pespin(a)sysmocom.de>
Gerrit-Comment-Date: Tue, 25 Nov 2025 19:52:20 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Attention is currently required from: pespin.
daniel has posted comments on this change by pespin. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/41505?usp=email )
Change subject: xua_rkm: remove unneeded check rkm_dyn_allocated
......................................................................
Patch Set 2: Code-Review+1
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/41505?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I2977ddd4aa476172e61b76f7a6501f0af9d25062
Gerrit-Change-Number: 41505
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de>
Gerrit-Attention: pespin <pespin(a)sysmocom.de>
Gerrit-Comment-Date: Tue, 25 Nov 2025 19:42:10 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Attention is currently required from: pespin.
daniel has posted comments on this change by pespin. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/41511?usp=email )
Change subject: ss7_as_vty: Forbid configuring RKM-dynamically allocated AS
......................................................................
Patch Set 1: Code-Review+1
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/41511?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: Ia0c3ce39337de3a10ff0215ccec72c65fab13029
Gerrit-Change-Number: 41511
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de>
Gerrit-Attention: pespin <pespin(a)sysmocom.de>
Gerrit-Comment-Date: Tue, 25 Nov 2025 19:41:05 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/41512?usp=email )
Change subject: Destroy rkm_dyn_allocated AS automatically when becoming out of ASPs
......................................................................
Destroy rkm_dyn_allocated AS automatically when becoming out of ASPs
This allows merging the freeing of AS inside the ASP/AS FSMs.
Change-Id: I743af584cd77924654d22ccf5d36d4479ba3b7f5
---
M src/ss7_as.c
M src/ss7_asp.c
M src/xua_asp_fsm.c
M src/xua_rkm.c
4 files changed, 40 insertions(+), 23 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/12/41512/1
diff --git a/src/ss7_as.c b/src/ss7_as.c
index cd6d66a..440385a 100644
--- a/src/ss7_as.c
+++ b/src/ss7_as.c
@@ -193,10 +193,13 @@
/*! \brief Delete given ASP from given AS
* \param[in] as Application Server from which \ref asp is deleted
* \param[in] asp Application Server Process to delete from \ref as
- * \returns 0 on success; negative in case of error */
+ * \returns 0 on success; negative in case of error
+ *
+ * \ref as may be freed during the function call. */
int ss7_as_del_asp(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp)
{
unsigned int i;
+ bool found = false;
LOGPAS(as, DLSS7, LOGL_INFO, "Removing ASP %s from AS\n", asp->cfg.name);
@@ -211,11 +214,20 @@
for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
if (as->cfg.asps[i] == asp) {
as->cfg.asps[i] = NULL;
- return 0;
+ found = true;
+ break;
}
}
- return -EINVAL;
+ /* RKM-dynamically allocated AS: If there are no other ASPs, destroy the AS.
+ * RFC 4666 4.4.2: "If a Deregistration results in no more ASPs in an
+ * Application Server, an SG MAY delete the Routing Key data."
+ */
+ if (as->rkm_dyn_allocated && osmo_ss7_as_count_asp(as) == 0)
+ osmo_ss7_as_destroy(as);
+
+
+ return found ? 0 : -EINVAL;
}
/*! \brief Delete given ASP from given AS
diff --git a/src/ss7_asp.c b/src/ss7_asp.c
index 377d9e4..076d91f 100644
--- a/src/ss7_asp.c
+++ b/src/ss7_asp.c
@@ -745,7 +745,7 @@
void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp)
{
- struct osmo_ss7_as *as;
+ struct osmo_ss7_as *as, *as2;
OSMO_ASSERT(ss7_initialized);
LOGPASP(asp, DLSS7, LOGL_INFO, "Destroying ASP\n");
@@ -757,8 +757,9 @@
if (asp->fi)
osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL);
- /* unlink from all ASs we are part of */
- llist_for_each_entry(as, &asp->inst->as_list, list)
+ /* Unlink from all ASs we are part of.
+ * Some RKM-dynamically allocated ASs may be freed as a result from this: */
+ llist_for_each_entry_safe(as, as2, &asp->inst->as_list, list)
ss7_as_del_asp(as, asp);
/* unlink from ss7_instance */
@@ -1351,9 +1352,6 @@
/* notify ASP FSM and everyone else */
osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, NULL);
- /* delete any RKM-dynamically allocated ASs for this ASP */
- xua_rkm_cleanup_dyn_as_for_asp(asp);
-
/* send M-SCTP_RELEASE.ind to Layer Manager */
xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION);
diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c
index 17071c3..d10420f 100644
--- a/src/xua_asp_fsm.c
+++ b/src/xua_asp_fsm.c
@@ -514,6 +514,13 @@
struct osmo_ss7_asp *asp = xafp->asp;
xua_t_beat_stop(fi);
dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND, asp);
+ /* RFC 4666 4.4.2: "An ASP SHOULD deregister from all Application Servers of which it is a
+ * member before attempting to move to the ASP-Down state [...]
+ * If a Deregistration results in no more ASPs in an Application Server, an SG MAY delete
+ * the Routing Key data."
+ * In case it didn't deregsitrer explicitly, make sure to implicitly deregister it:
+ */
+ xua_rkm_cleanup_dyn_as_for_asp(asp);
}
static void xua_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@@ -1101,6 +1108,13 @@
struct osmo_ss7_asp *asp = xafp->asp;
ipa_t_beat_stop(fi);
dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND, asp);
+ /* RFC 4666 4.4.2: "An ASP SHOULD deregister from all Application Servers of which it is a
+ * member before attempting to move to the ASP-Down state [...]
+ * If a Deregistration results in no more ASPs in an Application Server, an SG MAY delete
+ * the Routing Key data."
+ * In case it didn't deregsitrer explicitly, make sure to implicitly deregister it:
+ */
+ xua_rkm_cleanup_dyn_as_for_asp(asp);
}
static void ipa_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data)
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index d88fda7..c68eb99 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -422,15 +422,11 @@
LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: De-Registering rctx %u for DPC %s\n",
rctx, osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc));
- /* remove ASP from AS */
- ss7_as_del_asp(as, asp);
- /* FIXME: Rather than spoofing teh ASP-DOWN.ind to the AS here,
- * we should refuse RKM DEREG if the ASP is still ACTIVE */
- osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_DOWN_IND, asp);
-
- /* Release the associated route and destroy the dynamically allocated AS */
+ /* Release the associated route */
ss7_route_destroy(rt);
- osmo_ss7_as_destroy(as);
+ /* Dissassociate the ASP from the dynamically allocated AS AS.
+ * The AS may be freed if it is serving no more ASPs. */
+ ss7_as_del_asp(as, asp);
/* report success */
msgb_append_dereg_res(resp, M3UA_RKM_DEREG_SUCCESS, rctx);
@@ -635,13 +631,10 @@
struct osmo_ss7_as *as, *as2;
llist_for_each_entry_safe(as, as2, &inst->as_list, list) {
- if (!osmo_ss7_as_has_asp(as, asp))
- continue;
if (!as->rkm_dyn_allocated)
continue;
-
- /* If there are no other ASPs, destroy the AS: */
- if (osmo_ss7_as_count_asp(as) == 1)
- osmo_ss7_as_destroy(as);
+ if (!osmo_ss7_as_has_asp(as, asp))
+ continue;
+ ss7_as_del_asp(as, asp);
}
}
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/41512?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I743af584cd77924654d22ccf5d36d4479ba3b7f5
Gerrit-Change-Number: 41512
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>