<p>dexter has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-mgw/+/24973">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">mgcp_protocol: add support for wildcarded DLCX<br><br>The request handler handle_delete_con currently rejects wildcarded DLCX<br>requests even though a wildcarded DLCX would be a valuable tool to<br>remove lingering connections from the trunk in case osmo-bsc has to be<br>restarted.<br><br>Change-Id: I5c2de6b2b61ee64ba9c0618fd20e8fc2fe6a5ed3<br>Related: SYS#5535<br>---<br>M include/osmocom/mgcp/mgcp_ratectr.h<br>M src/libosmo-mgcp/mgcp_protocol.c<br>M src/libosmo-mgcp/mgcp_ratectr.c<br>3 files changed, 49 insertions(+), 20 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/73/24973/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/mgcp/mgcp_ratectr.h b/include/osmocom/mgcp/mgcp_ratectr.h</span><br><span>index 0bd6f88..5212f9b 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_ratectr.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_ratectr.h</span><br><span>@@ -53,7 +53,6 @@</span><br><span> /* Trunk-global MCGP DLCX related rate counters */</span><br><span> enum {</span><br><span>   MGCP_DLCX_SUCCESS,</span><br><span style="color: hsl(0, 100%, 40%);">-      MGCP_DLCX_FAIL_WILDCARD,</span><br><span>     MGCP_DLCX_FAIL_NO_CONN,</span><br><span>      MGCP_DLCX_FAIL_INVALID_CALLID,</span><br><span>       MGCP_DLCX_FAIL_INVALID_CONNID,</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>index 5ff94af..a16e7cd 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>@@ -46,6 +46,14 @@</span><br><span> #include <osmocom/mgcp/mgcp_codec.h></span><br><span> #include <osmocom/mgcp/mgcp_conn.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* A combination of LOGPENDP and LOGPTRUNK that automatically falls back to</span><br><span style="color: hsl(120, 100%, 40%);">+ * LOGPTRUNK when the endp parameter is NULL */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGPEPTR(endp, trunk, cat, level, fmt, args...)  \</span><br><span style="color: hsl(120, 100%, 40%);">+     if (endp) \</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGPENDP(endp, cat, level, fmt, ## args); \</span><br><span style="color: hsl(120, 100%, 40%);">+   else \</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGPTRUNK(trunk, cat, level, fmt, ## args); \</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Request data passed to the request handler */</span><br><span> struct mgcp_request_data {</span><br><span>    /* request name (e.g. "MDCX") */</span><br><span>@@ -102,7 +110,7 @@</span><br><span>     { .name = "DLCX",</span><br><span>    .handle_request = handle_delete_con,</span><br><span>         .debug_name = "DeleteConnection",</span><br><span style="color: hsl(0, 100%, 40%);">-     .require_endp = true },</span><br><span style="color: hsl(120, 100%, 40%);">+       .require_endp = false },</span><br><span>   { .name = "MDCX",</span><br><span>    .handle_request = handle_modify_con,</span><br><span>         .debug_name = "ModifiyConnection",</span><br><span>@@ -1351,26 +1359,21 @@</span><br><span>     char stats[1048];</span><br><span>    const char *conn_id = NULL;</span><br><span>  struct mgcp_conn_rtp *conn = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     LOGPENDP(endp, DLMGCP, LOGL_NOTICE,</span><br><span style="color: hsl(0, 100%, 40%);">-              "DLCX: deleting connection ...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        /* NOTE: In this handler we can not take it for granted that the endp</span><br><span style="color: hsl(120, 100%, 40%);">+  * pointer will be populated, however it is guaranteed that only. */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        if (!mgcp_endp_avail(endp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPEPTR(endp, trunk, DLMGCP, LOGL_NOTICE, "DLCX: deleting connection(s) ...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (endp && !mgcp_endp_avail(endp)) {</span><br><span>                rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_AVAIL));</span><br><span>               LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "DLCX: selected endpoint not available!\n");</span><br><span>              return create_err_response(NULL, 501, "DLCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* Prohibit wildcarded requests */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (endp->wildcarded_req) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                       "DLCX: wildcarded endpoint names not supported.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_WILDCARD));</span><br><span style="color: hsl(0, 100%, 40%);">-               return create_err_response(endp, 507, "DLCX", pdata->trans);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (llist_count(&endp->conns) <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+       if (endp && !rq->wildcarded && llist_empty(&endp->conns)) {</span><br><span>                LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "DLCX: endpoint is not holding a connection.\n");</span><br><span>                 rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_NO_CONN));</span><br><span>@@ -1383,6 +1386,14 @@</span><br><span> </span><br><span>                switch (toupper(line[0])) {</span><br><span>          case 'C':</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* If we have no endpoint, but a call id in the request,</span><br><span style="color: hsl(120, 100%, 40%);">+                         then this request cannot be handled */</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (!endp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          LOGPTRUNK(trunk, DLMGCP, LOGL_NOTICE, "cannot handle requests with call-id (C) without endpoint -- abort!");</span><br><span style="color: hsl(120, 100%, 40%);">+                                rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_UNHANDLED_PARAM));</span><br><span style="color: hsl(120, 100%, 40%);">+                              return create_err_response(NULL, 539, "DLCX", pdata->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                  if (mgcp_verify_call_id(endp, line + 3) != 0) {</span><br><span>                              error_code = 516;</span><br><span>                            rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_INVALID_CALLID));</span><br><span>@@ -1390,6 +1401,14 @@</span><br><span>                     }</span><br><span>                    break;</span><br><span>               case 'I':</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* If we have no endpoint, but a connection id in the request,</span><br><span style="color: hsl(120, 100%, 40%);">+                           then this request cannot be handled */</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (!endp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          LOGPTRUNK(trunk, DLMGCP, LOGL_NOTICE, "cannot handle requests with conn-id (I) without endpoint -- abort!");</span><br><span style="color: hsl(120, 100%, 40%);">+                                rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_UNHANDLED_PARAM));</span><br><span style="color: hsl(120, 100%, 40%);">+                              return create_err_response(NULL, 539, "DLCX", pdata->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                  conn_id = (const char *)line + 3;</span><br><span>                    if ((error_code = mgcp_verify_ci(endp, conn_id))) {</span><br><span>                          rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_INVALID_CONNID));</span><br><span>@@ -1400,9 +1419,7 @@</span><br><span>                      silent = strcasecmp("noanswer", line + 3) == 0;</span><br><span>                    break;</span><br><span>               default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGPENDP(endp, DLMGCP, LOGL_NOTICE,</span><br><span style="color: hsl(0, 100%, 40%);">-                              "DLCX: Unhandled MGCP option: '%c'/%d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                             line[0], line[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGPEPTR(endp, trunk, DLMGCP, LOGL_NOTICE, "DLCX: Unhandled MGCP option: '%c'/%d\n", line[0], line[0]);</span><br><span>                    rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_UNHANDLED_PARAM));</span><br><span>                     return create_err_response(NULL, 539, "DLCX", pdata->trans);</span><br><span>                    break;</span><br><span>@@ -1432,9 +1449,23 @@</span><br><span>              }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Handle wildcarded DLCX that refers to the whole trunk. This means</span><br><span style="color: hsl(120, 100%, 40%);">+   * that we walk over all endpoints on the trunk in order to drop all</span><br><span style="color: hsl(120, 100%, 40%);">+   * connections on the trunk. (see also RFC3435 Annex F.7) */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rq->wildcarded) {</span><br><span style="color: hsl(120, 100%, 40%);">+              int num_conns = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+            for (i = 0; i < trunk->number_endpoints; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 num_conns += llist_count(&trunk->endpoints[i]->conns);</span><br><span style="color: hsl(120, 100%, 40%);">+                      mgcp_endp_release(trunk->endpoints[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             rate_ctr_add(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_SUCCESS), num_conns);</span><br><span style="color: hsl(120, 100%, 40%);">+                return create_ok_response(NULL, 200, "DLCX", pdata->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* When no connection id is supplied, we will interpret this as a</span><br><span style="color: hsl(0, 100%, 40%);">-        * wildcarded DLCX and drop all connections at once. (See also</span><br><span style="color: hsl(0, 100%, 40%);">-   * RFC3435 Section F.7) */</span><br><span style="color: hsl(120, 100%, 40%);">+     * wildcarded DLCX that refers to the selected endpoint. This means</span><br><span style="color: hsl(120, 100%, 40%);">+    * that we drop all connections on that specific endpoint at once.</span><br><span style="color: hsl(120, 100%, 40%);">+     * (See also RFC3435 Section F.7) */</span><br><span>         if (!conn_id) {</span><br><span>              int num_conns = llist_count(&endp->conns);</span><br><span>            LOGPENDP(endp, DLMGCP, LOGL_NOTICE,</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_ratectr.c b/src/libosmo-mgcp/mgcp_ratectr.c</span><br><span>index 740a3b0..8f0924a 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_ratectr.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_ratectr.c</span><br><span>@@ -109,7 +109,6 @@</span><br><span> </span><br><span> static const struct rate_ctr_desc mgcp_dlcx_ctr_desc[] = {</span><br><span>         [MGCP_DLCX_SUCCESS] = { "dlcx:success", "DLCX command processed successfully." },</span><br><span style="color: hsl(0, 100%, 40%);">-   [MGCP_DLCX_FAIL_WILDCARD] = { "dlcx:wildcard", "wildcard names in DLCX commands are unsupported." },</span><br><span>     [MGCP_DLCX_FAIL_NO_CONN] = { "dlcx:no_conn", "endpoint specified in DLCX command has no active connections." },</span><br><span>  [MGCP_DLCX_FAIL_INVALID_CALLID] =</span><br><span>        { "dlcx:callid", "CallId specified in DLCX command mismatches endpoint's CallId ." },</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-mgw/+/24973">change 24973</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/c/osmo-mgw/+/24973"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-mgw </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I5c2de6b2b61ee64ba9c0618fd20e8fc2fe6a5ed3 </div>
<div style="display:none"> Gerrit-Change-Number: 24973 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>