<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>