Change in libosmo-sccp[master]: add osmo_sccp_addr_cmp(), osmo_sccp_addr_ri_cmp()

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Mon Mar 4 21:56:41 UTC 2019


Neels Hofmeyr has uploaded this change for review. ( https://gerrit.osmocom.org/13118


Change subject: add osmo_sccp_addr_cmp(), osmo_sccp_addr_ri_cmp()
......................................................................

add osmo_sccp_addr_cmp(), osmo_sccp_addr_ri_cmp()

osmo-msc identifies its BSC and RNC peers by SCCP address, and compares those
by memcmp(), which is not really accurate. Rather provide a meaningful
osmo_sccp_addr_cmp() API to determine whether SCCP addresses are identical.

Go for a full cmp that would also allow sorting.

Change-Id: Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5
---
M include/osmocom/sigtran/sccp_sap.h
M src/sccp_user.c
2 files changed, 111 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/18/13118/1

diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h
index 84d762c..f8cb686 100644
--- a/include/osmocom/sigtran/sccp_sap.h
+++ b/include/osmocom/sigtran/sccp_sap.h
@@ -275,5 +275,8 @@
 				      uint32_t ssn);
 
 bool osmo_sccp_check_addr(struct osmo_sccp_addr *addr, uint32_t presence);
+int osmo_sccp_addr_cmp(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b, uint32_t presence_criteria);
+int osmo_sccp_addr_ri_cmp(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b);
+int osmo_sccp_gt_cmp(const struct osmo_sccp_gt *a, const struct osmo_sccp_gt *b);
 
 const char *osmo_sccp_user_name(struct osmo_sccp_user *scu);
diff --git a/src/sccp_user.c b/src/sccp_user.c
index 8a98e46..f4a1730 100644
--- a/src/sccp_user.c
+++ b/src/sccp_user.c
@@ -293,6 +293,114 @@
 	return true;
 }
 
+/*! Compare two SCCP Global Titles.
+ * \param[in] a  left side.
+ * \param[in] b  right side.
+ * \return -1 if a < b, 1 if a > b, and 0 if a == b.
+ */
+int osmo_sccp_gt_cmp(const struct osmo_sccp_gt *a, const struct osmo_sccp_gt *b)
+{
+	if (!a)
+		return b ? -1 : 0;
+	if (!b)
+		return a ? 1 : 0;
+	return memcmp(a, b, sizeof(*a));
+}
+
+/*! Compare two SCCP addresses by given presence criteria.
+ * Any OSMO_SCCP_ADDR_T_* type not set in presence_criteria is ignored.
+ * In case all bits are set in presence_criteria, the comparison is in the order of:
+ * OSMO_SCCP_ADDR_T_GT, OSMO_SCCP_ADDR_T_PC, OSMO_SCCP_ADDR_T_IPv4, OSMO_SCCP_ADDR_T_IPv6, OSMO_SCCP_ADDR_T_SSN.
+ * The SCCP addresses' Routing Indicator is not compared, see osmo_sccp_addr_ri_cmp().
+ * \param[in] a  left side.
+ * \param[in] b  right side.
+ * \param[in] presence_criteria  A bitmask of OSMO_SCCP_ADDR_T_* values, or 0xffffffff to compare all parts, except the
+ *                               routing indicator.
+ * \return -1 if a < b, 1 if a > b, and 0 if all checked values match.
+ */
+int osmo_sccp_addr_cmp(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b, uint32_t presence_criteria)
+{
+	int rc;
+	if (!a)
+		return b ? -1 : 0;
+	if (!b)
+		return a ? 1 : 0;
+
+	if (presence_criteria & OSMO_SCCP_ADDR_T_GT) {
+		if ((a->presence & OSMO_SCCP_ADDR_T_GT) != (b->presence & OSMO_SCCP_ADDR_T_GT))
+			return (b->presence & OSMO_SCCP_ADDR_T_GT) ? -1 : 1;
+		rc = osmo_sccp_gt_cmp(&a->gt, &b->gt);
+		if (rc)
+			return rc;
+	}
+
+	if (presence_criteria & OSMO_SCCP_ADDR_T_PC) {
+		if ((a->presence & OSMO_SCCP_ADDR_T_PC) != (b->presence & OSMO_SCCP_ADDR_T_PC))
+			return (b->presence & OSMO_SCCP_ADDR_T_PC) ? -1 : 1;
+
+		if ((a->presence & OSMO_SCCP_ADDR_T_PC)
+		    && a->pc != b->pc)
+			return (a->pc < b->pc)? -1 : 1;
+	}
+
+	if (presence_criteria & OSMO_SCCP_ADDR_T_IPv4) {
+		if ((a->presence & OSMO_SCCP_ADDR_T_IPv4) != (b->presence & OSMO_SCCP_ADDR_T_IPv4))
+			return (b->presence & OSMO_SCCP_ADDR_T_IPv4) ? -1 : 1;
+		rc = memcmp(&a->ip.v4, &b->ip.v4, sizeof(a->ip.v4));
+	}
+
+	if (presence_criteria & OSMO_SCCP_ADDR_T_IPv6) {
+		if ((a->presence & OSMO_SCCP_ADDR_T_IPv6) != (b->presence & OSMO_SCCP_ADDR_T_IPv6))
+			return (b->presence & OSMO_SCCP_ADDR_T_IPv6) ? -1 : 1;
+		rc = memcmp(&a->ip.v6, &b->ip.v6, sizeof(a->ip.v6));
+	}
+
+	if (presence_criteria & OSMO_SCCP_ADDR_T_SSN) {
+		if ((a->presence & OSMO_SCCP_ADDR_T_SSN) != (b->presence & OSMO_SCCP_ADDR_T_SSN))
+			return (b->presence & OSMO_SCCP_ADDR_T_SSN) ? -1 : 1;
+		if (a->ssn != b->ssn)
+			return (a->ssn < b->ssn) ? -1 : 1;
+	}
+
+	return 0;
+}
+
+/*! Compare the routing information of two SCCP addresses.
+ * Compare the ri of a and b, and, if equal, return osmo_sccp_addr_cmp() with presence criteria selected according to
+ * ri.
+ * \param[in] a  left side.
+ * \param[in] b  right side.
+ * \return -1 if a < b, 1 if a > b, and 0 if a == b.
+ */
+int osmo_sccp_addr_ri_cmp(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b)
+{
+	uint32_t presence_criteria;
+	if (!a)
+		return b ? -1 : 0;
+	if (!b)
+		return a ? 1 : 0;
+	if (a->ri != b->ri)
+		return (a->ri < b->ri) ? -1 : 1;
+	switch (a->ri) {
+	case OSMO_SCCP_RI_NONE:
+		return 0;
+	case OSMO_SCCP_RI_GT:
+		presence_criteria = OSMO_SCCP_ADDR_T_GT;
+		break;
+	case OSMO_SCCP_RI_SSN_PC:
+		presence_criteria = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC;
+		break;
+	case OSMO_SCCP_RI_SSN_IP:
+		/* Pick IPv4 or v6 depending on what a->presence indicates. */
+		presence_criteria = OSMO_SCCP_ADDR_T_SSN | (a->presence & (OSMO_SCCP_ADDR_T_IPv4 | OSMO_SCCP_ADDR_T_IPv6));
+		break;
+	default:
+		return 0;
+	}
+
+	return osmo_sccp_addr_cmp(a, b, presence_criteria);
+}
+
 /*! Compose a human readable string to describe the SCCP user's connection.
  * The output follows ['<scu.name>':]<local-sccp-addr>, e.g.  "'OsmoHNBW':RI=SSN_PC,PC=0.23.5,SSN=RANAP",
  * or just "RI=SSN_PC,PC=0.23.5,SSN=RANAP" if no scu->name is set.

-- 
To view, visit https://gerrit.osmocom.org/13118
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5
Gerrit-Change-Number: 13118
Gerrit-PatchSet: 1
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190304/d08dcb36/attachment.html>


More information about the gerrit-log mailing list