neels has submitted this change. (
https://gerrit.osmocom.org/c/libosmo-sccp/+/32320 )
Change subject: sccp_scoc.c: fix infinite loop on conn ID exhaustion
......................................................................
sccp_scoc.c: fix infinite loop on conn ID exhaustion
Looking for an unused SCCP connection ID has no exit condition if all
connection IDs are in use. However unlikely it is that there are
16777215 active connections on one SCCP instance, add an exit condition.
Do so by implementing the ID lookup in a new separate function, which
qualifies for public API (upcoming patch).
So far, use an exit condition closest to previous behavior: iterate the
entire SCCP conn id number space before exiting in failure.
Change-Id: Ib64e0cb1ae0cc8b7bebcb2a352d4068b496b304a
---
M src/sccp_scoc.c
1 file changed, 41 insertions(+), 6 deletions(-)
Approvals:
laforge: Looks good to me, but someone else must approve
Jenkins Builder: Verified
neels: Looks good to me, approved
diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c
index 1838615..e63ebf8 100644
--- a/src/sccp_scoc.c
+++ b/src/sccp_scoc.c
@@ -539,10 +539,14 @@
return conn;
}
-/* Search for next free connection ID and allocate conn */
-static struct sccp_connection *conn_create(struct osmo_sccp_user *user)
+/* Return an unused SCCP connection ID.
+ * Callers should check the returned value: on negative return value, there are no unused
IDs available.
+ * \param[in] sccp The SCCP instance to determine a new connection ID for.
+ * \return unused ID on success (range [0x0, 0x00fffffe]) or negative on elapsed
max_attempts without an unused id (<0).
+ */
+static int osmo_sccp_instance_next_conn_id(struct osmo_sccp_instance *sccp)
{
- struct osmo_sccp_instance *sccp = user->inst;
+ int max_attempts = 0x00FFFFFE;
/* SUA: RFC3868 sec 3.10.4:
* The source reference number is a 4 octet long integer.
@@ -555,14 +559,26 @@
* Hence, as we currently use the connection ID also as local reference,
* let's simply use 24 bit ids to fit all link types (excluding 0x00ffffff).
*/
- do {
+ while (OSMO_LIKELY((max_attempts--) > 0)) {
/* Optimized modulo operation (% 0x00FFFFFE) using bitwise AND plus CMP: */
sccp->next_id = (sccp->next_id + 1) & 0x00FFFFFF;
if (OSMO_UNLIKELY(sccp->next_id == 0x00FFFFFF))
sccp->next_id = 0;
- } while (conn_find_by_id(sccp, sccp->next_id));
- return conn_create_id(user, sccp->next_id);
+ if (!conn_find_by_id(sccp, sccp->next_id))
+ return sccp->next_id;
+ }
+
+ return -1;
+}
+
+/* Search for next free connection ID and allocate conn */
+static struct sccp_connection *conn_create(struct osmo_sccp_user *user)
+{
+ int conn_id = osmo_sccp_instance_next_conn_id(user->inst);
+ if (conn_id < 0)
+ return NULL;
+ return conn_create_id(user, conn_id);
}
static void conn_opt_data_clear_cache(struct sccp_connection *conn)
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-sccp/+/32320
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Change-Id: Ib64e0cb1ae0cc8b7bebcb2a352d4068b496b304a
Gerrit-Change-Number: 32320
Gerrit-PatchSet: 4
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged