<p>Neels Hofmeyr has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13118">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add osmo_sccp_addr_cmp(), osmo_sccp_addr_ri_cmp()<br><br>osmo-msc identifies its BSC and RNC peers by SCCP address, and compares those<br>by memcmp(), which is not really accurate. Rather provide a meaningful<br>osmo_sccp_addr_cmp() API to determine whether SCCP addresses are identical.<br><br>Go for a full cmp that would also allow sorting.<br><br>Change-Id: Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5<br>---<br>M include/osmocom/sigtran/sccp_sap.h<br>M src/sccp_user.c<br>2 files changed, 111 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/18/13118/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h</span><br><span>index 84d762c..f8cb686 100644</span><br><span>--- a/include/osmocom/sigtran/sccp_sap.h</span><br><span>+++ b/include/osmocom/sigtran/sccp_sap.h</span><br><span>@@ -275,5 +275,8 @@</span><br><span>                                   uint32_t ssn);</span><br><span> </span><br><span> bool osmo_sccp_check_addr(struct osmo_sccp_addr *addr, uint32_t presence);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sccp_addr_cmp(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b, uint32_t presence_criteria);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sccp_addr_ri_cmp(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sccp_gt_cmp(const struct osmo_sccp_gt *a, const struct osmo_sccp_gt *b);</span><br><span> </span><br><span> const char *osmo_sccp_user_name(struct osmo_sccp_user *scu);</span><br><span>diff --git a/src/sccp_user.c b/src/sccp_user.c</span><br><span>index 8a98e46..f4a1730 100644</span><br><span>--- a/src/sccp_user.c</span><br><span>+++ b/src/sccp_user.c</span><br><span>@@ -293,6 +293,114 @@</span><br><span>      return true;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Compare two SCCP Global Titles.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] a  left side.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] b  right side.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return -1 if a < b, 1 if a > b, and 0 if a == b.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sccp_gt_cmp(const struct osmo_sccp_gt *a, const struct osmo_sccp_gt *b)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!a)</span><br><span style="color: hsl(120, 100%, 40%);">+               return b ? -1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!b)</span><br><span style="color: hsl(120, 100%, 40%);">+               return a ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     return memcmp(a, b, sizeof(*a));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Compare two SCCP addresses by given presence criteria.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Any OSMO_SCCP_ADDR_T_* type not set in presence_criteria is ignored.</span><br><span style="color: hsl(120, 100%, 40%);">+ * In case all bits are set in presence_criteria, the comparison is in the order of:</span><br><span style="color: hsl(120, 100%, 40%);">+ * 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.</span><br><span style="color: hsl(120, 100%, 40%);">+ * The SCCP addresses' Routing Indicator is not compared, see osmo_sccp_addr_ri_cmp().</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] a  left side.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] b  right side.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] presence_criteria  A bitmask of OSMO_SCCP_ADDR_T_* values, or 0xffffffff to compare all parts, except the</span><br><span style="color: hsl(120, 100%, 40%);">+ *                               routing indicator.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return -1 if a < b, 1 if a > b, and 0 if all checked values match.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sccp_addr_cmp(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b, uint32_t presence_criteria)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!a)</span><br><span style="color: hsl(120, 100%, 40%);">+               return b ? -1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!b)</span><br><span style="color: hsl(120, 100%, 40%);">+               return a ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (presence_criteria & OSMO_SCCP_ADDR_T_GT) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if ((a->presence & OSMO_SCCP_ADDR_T_GT) != (b->presence & OSMO_SCCP_ADDR_T_GT))</span><br><span style="color: hsl(120, 100%, 40%);">+                 return (b->presence & OSMO_SCCP_ADDR_T_GT) ? -1 : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+           rc = osmo_sccp_gt_cmp(&a->gt, &b->gt);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+                       return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (presence_criteria & OSMO_SCCP_ADDR_T_PC) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if ((a->presence & OSMO_SCCP_ADDR_T_PC) != (b->presence & OSMO_SCCP_ADDR_T_PC))</span><br><span style="color: hsl(120, 100%, 40%);">+                 return (b->presence & OSMO_SCCP_ADDR_T_PC) ? -1 : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         if ((a->presence & OSMO_SCCP_ADDR_T_PC)</span><br><span style="color: hsl(120, 100%, 40%);">+                    && a->pc != b->pc)</span><br><span style="color: hsl(120, 100%, 40%);">+                  return (a->pc < b->pc)? -1 : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (presence_criteria & OSMO_SCCP_ADDR_T_IPv4) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if ((a->presence & OSMO_SCCP_ADDR_T_IPv4) != (b->presence & OSMO_SCCP_ADDR_T_IPv4))</span><br><span style="color: hsl(120, 100%, 40%);">+                     return (b->presence & OSMO_SCCP_ADDR_T_IPv4) ? -1 : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+         rc = memcmp(&a->ip.v4, &b->ip.v4, sizeof(a->ip.v4));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (presence_criteria & OSMO_SCCP_ADDR_T_IPv6) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if ((a->presence & OSMO_SCCP_ADDR_T_IPv6) != (b->presence & OSMO_SCCP_ADDR_T_IPv6))</span><br><span style="color: hsl(120, 100%, 40%);">+                     return (b->presence & OSMO_SCCP_ADDR_T_IPv6) ? -1 : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+         rc = memcmp(&a->ip.v6, &b->ip.v6, sizeof(a->ip.v6));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (presence_criteria & OSMO_SCCP_ADDR_T_SSN) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if ((a->presence & OSMO_SCCP_ADDR_T_SSN) != (b->presence & OSMO_SCCP_ADDR_T_SSN))</span><br><span style="color: hsl(120, 100%, 40%);">+                       return (b->presence & OSMO_SCCP_ADDR_T_SSN) ? -1 : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          if (a->ssn != b->ssn)</span><br><span style="color: hsl(120, 100%, 40%);">+                   return (a->ssn < b->ssn) ? -1 : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Compare the routing information of two SCCP addresses.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Compare the ri of a and b, and, if equal, return osmo_sccp_addr_cmp() with presence criteria selected according to</span><br><span style="color: hsl(120, 100%, 40%);">+ * ri.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] a  left side.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] b  right side.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return -1 if a < b, 1 if a > b, and 0 if a == b.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sccp_addr_ri_cmp(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint32_t presence_criteria;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!a)</span><br><span style="color: hsl(120, 100%, 40%);">+               return b ? -1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!b)</span><br><span style="color: hsl(120, 100%, 40%);">+               return a ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (a->ri != b->ri)</span><br><span style="color: hsl(120, 100%, 40%);">+             return (a->ri < b->ri) ? -1 : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (a->ri) {</span><br><span style="color: hsl(120, 100%, 40%);">+   case OSMO_SCCP_RI_NONE:</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     case OSMO_SCCP_RI_GT:</span><br><span style="color: hsl(120, 100%, 40%);">+         presence_criteria = OSMO_SCCP_ADDR_T_GT;</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case OSMO_SCCP_RI_SSN_PC:</span><br><span style="color: hsl(120, 100%, 40%);">+             presence_criteria = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC;</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case OSMO_SCCP_RI_SSN_IP:</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Pick IPv4 or v6 depending on what a->presence indicates. */</span><br><span style="color: hsl(120, 100%, 40%);">+             presence_criteria = OSMO_SCCP_ADDR_T_SSN | (a->presence & (OSMO_SCCP_ADDR_T_IPv4 | OSMO_SCCP_ADDR_T_IPv6));</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return osmo_sccp_addr_cmp(a, b, presence_criteria);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Compose a human readable string to describe the SCCP user's connection.</span><br><span>  * The output follows ['<scu.name>':]<local-sccp-addr>, e.g.  "'OsmoHNBW':RI=SSN_PC,PC=0.23.5,SSN=RANAP",</span><br><span>  * or just "RI=SSN_PC,PC=0.23.5,SSN=RANAP" if no scu->name is set.</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13118">change 13118</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13118"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-sccp </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5 </div>
<div style="display:none"> Gerrit-Change-Number: 13118 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>