<p>dexter <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-mgw/+/24941">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, but someone else must approve
  daniel: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">mgcp_protocol: refactor MGCP request handling<br><br>At the moment the MGCP request handling and message parsing is not<br>clearly separated. The function mgcp_parse_header() in mgcp_msg.c is<br>also responsible for resolving an endpoint. This leads to unclear layer<br>separation. We eventually end up in a situation where we can not execute<br>any request handler without beeing able to resolve an endpoint, however<br>this is necessary if we want to implement wildcarded DLCX resquests.<br><br>In the current situation a wildcarded DLCX is not possible to implement<br>as we always have to resolve a an to get to the trunk which we need to<br>iterate. However, we just can't resolve a free endpoint in a situation<br>where all endpoints on te trunk are in use.<br><br>We have to refactor the request handler so that the parsing in mgcp_msg<br>only extracts us the endpoint name. The resolving is then done in<br>mgcp_handle_message() in mgcp_protocol.c. Then we are able to decide<br>what to do if we are unable to resolve an endpoint but still be able to<br>resolve the trunk.<br><br>This patch does not change the behaviour of osmo-mgw yet, but it lays<br>the foundation for request handler implementations that can still<br>perform useful actions if no endpoint but a trunk has been resolved. A<br>wilcarded DLCX is such a case. It does not need an endpoint, just the<br>trunk.<br><br>Change-Id: I9f519d8a0ee8a513fa1e74acf3ee7dbc0991cdde<br>Related: SYS#5535<br>---<br>M include/osmocom/mgcp/mgcp_protocol.h<br>M src/libosmo-mgcp/mgcp_msg.c<br>M src/libosmo-mgcp/mgcp_protocol.c<br>M src/libosmo-mgcp/mgcp_sdp.c<br>4 files changed, 208 insertions(+), 139 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/mgcp/mgcp_protocol.h b/include/osmocom/mgcp/mgcp_protocol.h</span><br><span>index cdce02d..7ab283d 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_protocol.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_protocol.h</span><br><span>@@ -3,7 +3,7 @@</span><br><span> /* Internal structure while parsing a request */</span><br><span> struct mgcp_parse_data {</span><br><span>  struct mgcp_config *cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mgcp_endpoint *endp;</span><br><span style="color: hsl(120, 100%, 40%);">+   char *epname;</span><br><span>        char *trans;</span><br><span>         char *save;</span><br><span> };</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_msg.c b/src/libosmo-mgcp/mgcp_msg.c</span><br><span>index 8783e20..f8b486a 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_msg.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_msg.c</span><br><span>@@ -132,24 +132,19 @@</span><br><span> }</span><br><span> </span><br><span> /*! Analyze and parse the the hader of an MGCP messeage string.</span><br><span style="color: hsl(0, 100%, 40%);">- *  \param[out] pdata caller provided memory to store the parsing results</span><br><span style="color: hsl(0, 100%, 40%);">- *  \param[in] data mgcp message string</span><br><span style="color: hsl(0, 100%, 40%);">- *  \returns when the status line was complete and transaction_id and</span><br><span style="color: hsl(0, 100%, 40%);">- *  endp out parameters are set, -1 on error */</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] pdata caller provided memory to store the parsing results.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] data mgcp message string.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 when the status line was complete and parseable, negative (MGCP</span><br><span style="color: hsl(120, 100%, 40%);">+ *  cause code) on error. */</span><br><span> int mgcp_parse_header(struct mgcp_parse_data *pdata, char *data)</span><br><span> {</span><br><span>      int i = 0;</span><br><span>   char *elem, *save = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-       int cause;</span><br><span> </span><br><span>       /*! This function will parse the header part of the received</span><br><span style="color: hsl(0, 100%, 40%);">-     *  MGCP message. The parsing results are stored in pdata.</span><br><span style="color: hsl(0, 100%, 40%);">-       *  The function will also automatically search the pool with</span><br><span style="color: hsl(0, 100%, 40%);">-    *  available endpoints in order to find an endpoint that matches</span><br><span style="color: hsl(0, 100%, 40%);">-        *  the endpoint string in in the header */</span><br><span style="color: hsl(120, 100%, 40%);">+    *  MGCP message. The parsing results are stored in pdata. */</span><br><span> </span><br><span>    OSMO_ASSERT(data);</span><br><span style="color: hsl(0, 100%, 40%);">-      pdata->trans = "000000";</span><br><span> </span><br><span>    for (elem = strtok_r(data, " ", &save); elem;</span><br><span>       elem = strtok_r(NULL, " ", &save)) {</span><br><span>@@ -158,13 +153,7 @@</span><br><span>                       pdata->trans = elem;</span><br><span>                      break;</span><br><span>               case 1:</span><br><span style="color: hsl(0, 100%, 40%);">-                 pdata->endp = mgcp_endp_by_name(&cause, elem, pdata->cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-                    if (!pdata->endp) {</span><br><span style="color: hsl(0, 100%, 40%);">-                          LOGP(DLMGCP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     "Unable to find Endpoint `%s'\n", elem);</span><br><span style="color: hsl(0, 100%, 40%);">-                             OSMO_ASSERT(cause < 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                              return cause;</span><br><span style="color: hsl(0, 100%, 40%);">-                   }</span><br><span style="color: hsl(120, 100%, 40%);">+                     pdata->epname = elem;</span><br><span>                     break;</span><br><span>               case 2:</span><br><span>                      if (strcasecmp("MGCP", elem)) {</span><br><span>@@ -174,11 +163,8 @@</span><br><span>                     }</span><br><span>                    break;</span><br><span>               case 3:</span><br><span style="color: hsl(0, 100%, 40%);">-                 if (strcmp("1.0", elem)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            LOGP(DLMGCP, LOGL_ERROR, "MGCP version `%s' "</span><br><span style="color: hsl(0, 100%, 40%);">-                                  "not supported\n", elem);</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (strcmp("1.0", elem))</span><br><span>                           return -528;</span><br><span style="color: hsl(0, 100%, 40%);">-                    }</span><br><span>                    break;</span><br><span>               }</span><br><span>            i++;</span><br><span>@@ -186,8 +172,6 @@</span><br><span> </span><br><span>       if (i != 4) {</span><br><span>                LOGP(DLMGCP, LOGL_ERROR, "MGCP status line too short.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            pdata->trans = "000000";</span><br><span style="color: hsl(0, 100%, 40%);">-           pdata->endp = NULL;</span><br><span>               return -510;</span><br><span>         }</span><br><span> </span><br><span>diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>index f6daffc..b7ae748 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,27 @@</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%);">+/* Request data passed to the request handler */</span><br><span style="color: hsl(120, 100%, 40%);">+struct mgcp_request_data {</span><br><span style="color: hsl(120, 100%, 40%);">+  /* request name (e.g. "MDCX") */</span><br><span style="color: hsl(120, 100%, 40%);">+    char name[4+1];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* parsing results from the MGCP header (trans id, endpoint name ...) */</span><br><span style="color: hsl(120, 100%, 40%);">+      struct mgcp_parse_data *pdata;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* pointer to endpoint resource (may be NULL for wildcarded requests) */</span><br><span style="color: hsl(120, 100%, 40%);">+      struct mgcp_endpoint *endp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* pointer to trunk resource */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct mgcp_trunk *trunk;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* set to true when the request has been classified as wildcarded */</span><br><span style="color: hsl(120, 100%, 40%);">+  bool wildcarded;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* contains cause code in case of problems during endp/trunk resolution */</span><br><span style="color: hsl(120, 100%, 40%);">+    int mgcp_cause;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Request handler specification, here we specify an array with function</span><br><span>  * pointers to the various MGCP requests implemented below */</span><br><span> struct mgcp_request {</span><br><span>@@ -53,39 +74,49 @@</span><br><span>    char *name;</span><br><span> </span><br><span>      /* function pointer to the request handler */</span><br><span style="color: hsl(0, 100%, 40%);">-   struct msgb *(*handle_request) (struct mgcp_parse_data * data);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msgb *(*handle_request)(struct mgcp_request_data *data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* true if the request requires an endpoint, false if only a trunk</span><br><span style="color: hsl(120, 100%, 40%);">+     * is sufficient. (corner cases, e.g. wildcarded DLCX) */</span><br><span style="color: hsl(120, 100%, 40%);">+     bool require_endp;</span><br><span> </span><br><span>       /* a human readable name that describes the request */</span><br><span>       char *debug_name;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_audit_endpoint(struct mgcp_parse_data *data);</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_create_con(struct mgcp_parse_data *data);</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_delete_con(struct mgcp_parse_data *data);</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_modify_con(struct mgcp_parse_data *data);</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_rsip(struct mgcp_parse_data *data);</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_noti_req(struct mgcp_parse_data *data);</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_audit_endpoint(struct mgcp_request_data *data);</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_create_con(struct mgcp_request_data *data);</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_delete_con(struct mgcp_request_data *data);</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_modify_con(struct mgcp_request_data *data);</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_rsip(struct mgcp_request_data *data);</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_noti_req(struct mgcp_request_data *data);</span><br><span> static const struct mgcp_request mgcp_requests[] = {</span><br><span>  { .name = "AUEP",</span><br><span>    .handle_request = handle_audit_endpoint,</span><br><span style="color: hsl(0, 100%, 40%);">-        .debug_name = "AuditEndpoint" },</span><br><span style="color: hsl(120, 100%, 40%);">+    .debug_name = "AuditEndpoint",</span><br><span style="color: hsl(120, 100%, 40%);">+      .require_endp = true },</span><br><span>    { .name = "CRCX",</span><br><span>    .handle_request = handle_create_con,</span><br><span style="color: hsl(0, 100%, 40%);">-    .debug_name = "CreateConnection" },</span><br><span style="color: hsl(120, 100%, 40%);">+         .debug_name = "CreateConnection",</span><br><span style="color: hsl(120, 100%, 40%);">+   .require_endp = true },</span><br><span>    { .name = "DLCX",</span><br><span>    .handle_request = handle_delete_con,</span><br><span style="color: hsl(0, 100%, 40%);">-    .debug_name = "DeleteConnection" },</span><br><span style="color: hsl(120, 100%, 40%);">+         .debug_name = "DeleteConnection",</span><br><span style="color: hsl(120, 100%, 40%);">+   .require_endp = true },</span><br><span>    { .name = "MDCX",</span><br><span>    .handle_request = handle_modify_con,</span><br><span style="color: hsl(0, 100%, 40%);">-    .debug_name = "ModifiyConnection" },</span><br><span style="color: hsl(120, 100%, 40%);">+        .debug_name = "ModifiyConnection",</span><br><span style="color: hsl(120, 100%, 40%);">+          .require_endp = true },</span><br><span>    { .name = "RQNT",</span><br><span>    .handle_request = handle_noti_req,</span><br><span style="color: hsl(0, 100%, 40%);">-      .debug_name = "NotificationRequest" },</span><br><span style="color: hsl(120, 100%, 40%);">+      .debug_name = "NotificationRequest",</span><br><span style="color: hsl(120, 100%, 40%);">+        .require_endp = true },</span><br><span> </span><br><span>        /* SPEC extension */</span><br><span>         { .name = "RSIP",</span><br><span>    .handle_request = handle_rsip,</span><br><span style="color: hsl(0, 100%, 40%);">-          .debug_name = "ReSetInProgress" },</span><br><span style="color: hsl(120, 100%, 40%);">+          .debug_name = "ReSetInProgress",</span><br><span style="color: hsl(120, 100%, 40%);">+    .require_endp = true },</span><br><span> };</span><br><span> </span><br><span> /* Initalize transcoder */</span><br><span>@@ -295,6 +326,7 @@</span><br><span> {</span><br><span>         struct rate_ctr_group *rate_ctrs = cfg->ratectr.mgcp_general_ctr_group;</span><br><span>   struct mgcp_parse_data pdata;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgcp_request_data rq;</span><br><span>         int rc, i, code, handled = 0;</span><br><span>        struct msgb *resp = NULL;</span><br><span>    char *data;</span><br><span>@@ -322,55 +354,103 @@</span><br><span>                 return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   msg->l3h = &msg->l2h[4];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /*</span><br><span style="color: hsl(0, 100%, 40%);">-       * Check for a duplicate message and respond.</span><br><span style="color: hsl(0, 100%, 40%);">-    */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Parse message, extract endpoint name and transaction identifier and request name etc. */</span><br><span>  memset(&pdata, 0, sizeof(pdata));</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&rq, 0, sizeof(rq));</span><br><span>      pdata.cfg = cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(rq.name, (const char *)&msg->l2h[0], sizeof(rq.name)-1);</span><br><span style="color: hsl(120, 100%, 40%);">+        msg->l3h = &msg->l2h[4];</span><br><span>   data = mgcp_strline((char *)msg->l3h, &pdata.save);</span><br><span>   rc = mgcp_parse_header(&pdata, data);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (pdata.endp && pdata.trans</span><br><span style="color: hsl(0, 100%, 40%);">-       && pdata.endp->last_trans</span><br><span style="color: hsl(0, 100%, 40%);">-            && strcmp(pdata.endp->last_trans, pdata.trans) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-           rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_GENERAL_RX_MSGS_RETRANSMITTED));</span><br><span style="color: hsl(0, 100%, 40%);">-            return do_retransmission(pdata.endp);</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%);">-       /* check for general parser failure */</span><br><span>       if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLMGCP, LOGL_NOTICE, "%s: failed to find the endpoint\n", msg->l2h);</span><br><span style="color: hsl(0, 100%, 40%);">-          rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_GENERAL_RX_FAIL_NO_ENDPOINT));</span><br><span style="color: hsl(0, 100%, 40%);">-              return create_err_response(NULL, -rc, (const char *) msg->l2h, pdata.trans);</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGP(DLMGCP, LOGL_ERROR, "%s: failed to parse MCGP message\n", rq.name);</span><br><span style="color: hsl(120, 100%, 40%);">+            rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_GENERAL_RX_FAIL_MSG_PARSE));</span><br><span style="color: hsl(120, 100%, 40%);">+              return create_err_response(NULL, -rc, rq.name, "000000");</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   for (i = 0; i < ARRAY_SIZE(mgcp_requests); ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (strncmp</span><br><span style="color: hsl(0, 100%, 40%);">-                 (mgcp_requests[i].name, (const char *)&msg->l2h[0],</span><br><span style="color: hsl(0, 100%, 40%);">-               4) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Locate endpoint and trunk, if no endpoint can be located try at least to identify the trunk. */</span><br><span style="color: hsl(120, 100%, 40%);">+    rq.pdata = &pdata;</span><br><span style="color: hsl(120, 100%, 40%);">+        rq.wildcarded = mgcp_endp_is_wildcarded(pdata.epname);</span><br><span style="color: hsl(120, 100%, 40%);">+        rq.endp = mgcp_endp_by_name(&rc, pdata.epname, pdata.cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+        rq.mgcp_cause = rc;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!rq.endp) {</span><br><span style="color: hsl(120, 100%, 40%);">+               rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_GENERAL_RX_FAIL_NO_ENDPOINT));</span><br><span style="color: hsl(120, 100%, 40%);">+            if (rq.wildcarded) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  /* If we are unable to find the endpoint we still may be able to identify the trunk. Some</span><br><span style="color: hsl(120, 100%, 40%);">+                      * request handlers will still be able to perform a useful action if the request refers to</span><br><span style="color: hsl(120, 100%, 40%);">+                     * the whole trunk (wildcarded request). */</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGP(DLMGCP, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                          "%s: cannot find endpoint \"%s\", cause=%d -- trying to identify trunk...\n", rq.name,</span><br><span style="color: hsl(120, 100%, 40%);">+                            pdata.epname, -rq.mgcp_cause);</span><br><span style="color: hsl(120, 100%, 40%);">+                   rq.trunk = mgcp_trunk_by_name(pdata.cfg, pdata.epname);</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (!rq.trunk) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              LOGP(DLMGCP, LOGL_ERROR, "%s: failed to identify trunk for endpoint \"%s\" -- abort\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                rq.name, pdata.epname);</span><br><span style="color: hsl(120, 100%, 40%);">+                          return create_err_response(NULL, -rq.mgcp_cause, rq.name, pdata.trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+             } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* If the endpoint name suggests that the request refers to a specific endpoint, then the</span><br><span style="color: hsl(120, 100%, 40%);">+                      * request cannot be handled and we must stop early. */</span><br><span style="color: hsl(120, 100%, 40%);">+                       LOGP(DLMGCP, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                          "%s: cannot find endpoint \"%s\", cause=%d -- abort\n", rq.name,</span><br><span style="color: hsl(120, 100%, 40%);">+                          pdata.epname, -rq.mgcp_cause);</span><br><span style="color: hsl(120, 100%, 40%);">+                   return create_err_response(NULL, -rq.mgcp_cause, rq.name, pdata.trans);</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              rq.trunk = rq.endp->trunk;</span><br><span style="color: hsl(120, 100%, 40%);">+         rq.mgcp_cause = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Check if we have to retransmit a response from a previous transaction */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (pdata.trans && rq.endp->last_trans && strcmp(rq.endp->last_trans, pdata.trans) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_GENERAL_RX_MSGS_RETRANSMITTED));</span><br><span style="color: hsl(120, 100%, 40%);">+                  return do_retransmission(rq.endp);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Find an appropriate handler for the current request and execute it */</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0; i < ARRAY_SIZE(mgcp_requests); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (strcmp(mgcp_requests[i].name, rq.name) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* Check if the request requires and endpoint, if yes, check if we have it, otherwise don't</span><br><span style="color: hsl(120, 100%, 40%);">+                        * execute the request handler. */</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (mgcp_requests[i].require_endp && !rq.endp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              LOGP(DLMGCP, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   "%s: the request handler \"%s\" requires an endpoint resource for \"%s\", which is not available -- abort\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   rq.name, mgcp_requests[i].debug_name, pdata.epname);</span><br><span style="color: hsl(120, 100%, 40%);">+                             return create_err_response(NULL, -rq.mgcp_cause, rq.name, pdata.trans);</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%);">+                   /* Execute request handler */</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (rq.endp)</span><br><span style="color: hsl(120, 100%, 40%);">+                          LOGP(DLMGCP, LOGL_INFO,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    "%s: executing request handler \"%s\" for endpoint resource \"%s\"\n", rq.name,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 mgcp_requests[i].debug_name, rq.endp->name);</span><br><span style="color: hsl(120, 100%, 40%);">+                  else</span><br><span style="color: hsl(120, 100%, 40%);">+                          LOGP(DLMGCP, LOGL_INFO,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    "%s: executing request handler \"%s\" for trunk resource of endpoint \"%s\"\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 rq.name, mgcp_requests[i].debug_name, pdata.epname);</span><br><span style="color: hsl(120, 100%, 40%);">+                     resp = mgcp_requests[i].handle_request(&rq);</span><br><span>                     handled = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                    resp = mgcp_requests[i].handle_request(&pdata);</span><br><span>                  break;</span><br><span>               }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Check if the MGCP request was handled and increment rate counters accordingly. */</span><br><span>         if (handled) {</span><br><span>               rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_GENERAL_RX_MSGS_HANDLED));</span><br><span>       } else {</span><br><span>             rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_GENERAL_RX_MSGS_UNHANDLED));</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLMGCP, LOGL_NOTICE, "MSG with type: '%.4s' not handled\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   &msg->l2h[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DLMGCP, LOGL_ERROR, "MSG with type: '%.4s' not handled\n", &msg->l2h[0]);</span><br><span>      }</span><br><span> </span><br><span>        return resp;</span><br><span> }</span><br><span> </span><br><span> /* AUEP command handler, processes the received command */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_audit_endpoint(struct mgcp_parse_data *p)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_audit_endpoint(struct mgcp_request_data *rq)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   LOGPENDP(p->endp, DLMGCP, LOGL_NOTICE, "AUEP: auditing endpoint ...\n");</span><br><span style="color: hsl(0, 100%, 40%);">-   return create_ok_response(p->endp, 200, "AUEP", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGPENDP(rq->endp, DLMGCP, LOGL_NOTICE, "AUEP: auditing endpoint ...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        return create_ok_response(rq->endp, 200, "AUEP", rq->pdata->trans);</span><br><span> }</span><br><span> </span><br><span> /* Try to find a free port by attempting to bind on it. Also handle the</span><br><span>@@ -661,9 +741,9 @@</span><br><span> </span><br><span> /* Process codec information contained in CRCX/MDCX */</span><br><span> static int handle_codec_info(struct mgcp_conn_rtp *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                           struct mgcp_parse_data *p, int have_sdp, bool crcx)</span><br><span style="color: hsl(120, 100%, 40%);">+                           struct mgcp_request_data *rq, int have_sdp, bool crcx)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mgcp_endpoint *endp = p->endp;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct mgcp_endpoint *endp = rq->endp;</span><br><span>    int rc;</span><br><span>      char *cmd;</span><br><span> </span><br><span>@@ -677,7 +757,7 @@</span><br><span>                 /* If we have SDP, we ignore the local connection options and</span><br><span>                 * use only the SDP information. */</span><br><span>          mgcp_codec_reset_all(conn);</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = mgcp_parse_sdp_data(endp, conn, p);</span><br><span style="color: hsl(120, 100%, 40%);">+              rc = mgcp_parse_sdp_data(endp, conn, rq->pdata);</span><br><span>          if (rc != 0) {</span><br><span>                       LOGPCONN(conn->conn, DLMGCP,  LOGL_ERROR,</span><br><span>                                  "%s: sdp not parseable\n", cmd);</span><br><span>@@ -743,10 +823,11 @@</span><br><span> }</span><br><span> </span><br><span> /* CRCX command handler, processes the received command */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_create_con(struct mgcp_parse_data *p)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_create_con(struct mgcp_request_data *rq)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    struct mgcp_trunk *trunk = p->endp->trunk;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mgcp_endpoint *endp = p->endp;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct mgcp_parse_data *pdata = rq->pdata;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgcp_trunk *trunk = rq->trunk;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct mgcp_endpoint *endp = rq->endp;</span><br><span>    struct rate_ctr_group *rate_ctrs = trunk->ratectr.mgcp_crcx_ctr_group;</span><br><span>    int error_code = 400;</span><br><span>        const char *local_options = NULL;</span><br><span>@@ -765,11 +846,11 @@</span><br><span>            rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_AVAIL));</span><br><span>               LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "CRCX: selected endpoint not available!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         return create_err_response(NULL, 501, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(NULL, 501, "CRCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        /* parse CallID C: and LocalParameters L: */</span><br><span style="color: hsl(0, 100%, 40%);">-    for_each_line(line, p->save) {</span><br><span style="color: hsl(120, 100%, 40%);">+     for_each_line(line, pdata->save) {</span><br><span>                if (!mgcp_check_param(endp, line))</span><br><span>                   continue;</span><br><span> </span><br><span>@@ -785,7 +866,7 @@</span><br><span>                   * together with a CRCX, the MGW will assign the</span><br><span>                      * connection identifier by itself on CRCX */</span><br><span>                        rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_BAD_ACTION));</span><br><span style="color: hsl(0, 100%, 40%);">-                     return create_err_response(NULL, 523, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(NULL, 523, "CRCX", pdata->trans);</span><br><span>                    break;</span><br><span>               case 'M':</span><br><span>                    mode = (const char *)line + 3;</span><br><span>@@ -793,7 +874,7 @@</span><br><span>                 case 'X':</span><br><span>                    if (strncasecmp("Osmux: ", line + 2, strlen("Osmux: ")) == 0) {</span><br><span>                          /* If osmux is disabled, just skip setting it up */</span><br><span style="color: hsl(0, 100%, 40%);">-                             if (!p->endp->cfg->osmux)</span><br><span style="color: hsl(120, 100%, 40%);">+                            if (!rq->endp->cfg->osmux)</span><br><span>                                  break;</span><br><span>                               osmux_cid = mgcp_osmux_setup(endp, line);</span><br><span>                            break;</span><br><span>@@ -811,7 +892,7 @@</span><br><span>                         LOGPENDP(endp, DLMGCP, LOGL_NOTICE,</span><br><span>                           "CRCX: unhandled option: '%c'/%d\n", *line, *line);</span><br><span>                       rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_UNHANDLED_PARAM));</span><br><span style="color: hsl(0, 100%, 40%);">-                        return create_err_response(NULL, 539, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(NULL, 539, "CRCX", pdata->trans);</span><br><span>                    break;</span><br><span>               }</span><br><span>    }</span><br><span>@@ -822,14 +903,14 @@</span><br><span>            LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "CRCX: insufficient parameters, missing callid\n");</span><br><span>               rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_MISSING_CALLID));</span><br><span style="color: hsl(0, 100%, 40%);">-         return create_err_response(endp, 516, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(endp, 516, "CRCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        if (!mode) {</span><br><span>                 LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "CRCX: insufficient parameters, missing mode\n");</span><br><span>                 rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_INVALID_MODE));</span><br><span style="color: hsl(0, 100%, 40%);">-           return create_err_response(endp, 517, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(endp, 517, "CRCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        /* Check if we are able to accept the creation of another connection */</span><br><span>@@ -846,7 +927,7 @@</span><br><span>                        /* There is no more room for a connection, leave</span><br><span>                      * everything as it is and return with an error */</span><br><span>                   rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_LIMIT_EXCEEDED));</span><br><span style="color: hsl(0, 100%, 40%);">-                 return create_err_response(endp, 540, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(endp, 540, "CRCX", pdata->trans);</span><br><span>            }</span><br><span>    }</span><br><span> </span><br><span>@@ -864,7 +945,7 @@</span><br><span>                  /* This is not our call, leave everything as it is and</span><br><span>                        * return with an error. */</span><br><span>                  rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_UNKNOWN_CALLID));</span><br><span style="color: hsl(0, 100%, 40%);">-                 return create_err_response(endp, 400, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(endp, 400, "CRCX", pdata->trans);</span><br><span>            }</span><br><span>    }</span><br><span> </span><br><span>@@ -875,7 +956,7 @@</span><br><span>          rc = mgcp_endp_claim(endp, callid);</span><br><span>          if (rc != 0) {</span><br><span>                       rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_CLAIM));</span><br><span style="color: hsl(0, 100%, 40%);">-                  return create_err_response(endp, 502, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(endp, 502, "CRCX", pdata->trans);</span><br><span>            }</span><br><span>    }</span><br><span> </span><br><span>@@ -916,7 +997,7 @@</span><br><span> </span><br><span>      /* Set local connection options, if present */</span><br><span>       if (local_options) {</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = set_local_cx_options(endp->trunk->endpoints,</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = set_local_cx_options(trunk->endpoints,</span><br><span>                                         &endp->local_options, local_options);</span><br><span>               if (rc != 0) {</span><br><span>                       LOGPCONN(_conn, DLMGCP, LOGL_ERROR,</span><br><span>@@ -928,7 +1009,7 @@</span><br><span>   }</span><br><span> </span><br><span>        /* Handle codec information and decide for a suitable codec */</span><br><span style="color: hsl(0, 100%, 40%);">-  rc = handle_codec_info(conn, p, have_sdp, true);</span><br><span style="color: hsl(120, 100%, 40%);">+      rc = handle_codec_info(conn, rq, have_sdp, true);</span><br><span>    mgcp_codec_summary(conn);</span><br><span>    if (rc) {</span><br><span>            error_code = rc;</span><br><span>@@ -939,8 +1020,8 @@</span><br><span>      conn->end.fmtp_extra = talloc_strdup(trunk->endpoints,</span><br><span>                                              trunk->audio_fmtp_extra);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (p->cfg->force_ptime) {</span><br><span style="color: hsl(0, 100%, 40%);">-                conn->end.packet_duration_ms = p->cfg->force_ptime;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (pdata->cfg->force_ptime) {</span><br><span style="color: hsl(120, 100%, 40%);">+          conn->end.packet_duration_ms = pdata->cfg->force_ptime;</span><br><span>             conn->end.force_output_ptime = 1;</span><br><span>         }</span><br><span> </span><br><span>@@ -973,16 +1054,16 @@</span><br><span>       }</span><br><span> </span><br><span>        /* policy CB */</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->cfg->policy_cb) {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (pdata->cfg->policy_cb) {</span><br><span>           int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = p->cfg->policy_cb(endp, MGCP_ENDP_CRCX, p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+              rc = pdata->cfg->policy_cb(endp, MGCP_ENDP_CRCX, pdata->trans);</span><br><span>             switch (rc) {</span><br><span>                case MGCP_POLICY_REJECT:</span><br><span>                     LOGPCONN(_conn, DLMGCP, LOGL_NOTICE,</span><br><span>                                  "CRCX: CRCX rejected by policy\n");</span><br><span>                       mgcp_endp_release(endp);</span><br><span>                     rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_REJECTED_BY_POLICY));</span><br><span style="color: hsl(0, 100%, 40%);">-                     return create_err_response(endp, 400, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(endp, 400, "CRCX", pdata->trans);</span><br><span>                    break;</span><br><span>               case MGCP_POLICY_DEFER:</span><br><span>                      /* stop processing */</span><br><span>@@ -996,8 +1077,8 @@</span><br><span> </span><br><span>     LOGPCONN(conn->conn, DLMGCP, LOGL_DEBUG,</span><br><span>           "CRCX: Creating connection: port: %u\n", conn->end.local_port);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (p->cfg->change_cb)</span><br><span style="color: hsl(0, 100%, 40%);">-            p->cfg->change_cb(endp, MGCP_ENDP_CRCX);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (pdata->cfg->change_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+              pdata->cfg->change_cb(endp, MGCP_ENDP_CRCX);</span><br><span> </span><br><span>       /* Send dummy packet, see also comments in mgcp_keepalive_timer_cb() */</span><br><span>      OSMO_ASSERT(trunk->keepalive_interval >= MGCP_KEEPALIVE_ONCE);</span><br><span>@@ -1010,19 +1091,21 @@</span><br><span>                "CRCX: connection successfully created\n");</span><br><span>       rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_SUCCESS));</span><br><span>  mgcp_endp_update(endp);</span><br><span style="color: hsl(0, 100%, 40%);">- return create_response_with_sdp(endp, conn, "CRCX", p->trans, true);</span><br><span style="color: hsl(120, 100%, 40%);">+     return create_response_with_sdp(endp, conn, "CRCX", pdata->trans, true);</span><br><span> error2:</span><br><span>     mgcp_endp_release(endp);</span><br><span>     LOGPENDP(endp, DLMGCP, LOGL_NOTICE,</span><br><span>           "CRCX: unable to create connection\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      return create_err_response(endp, error_code, "CRCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+  return create_err_response(endp, error_code, "CRCX", pdata->trans);</span><br><span> }</span><br><span> </span><br><span> /* MDCX command handler, processes the received command */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_modify_con(struct mgcp_parse_data *p)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_modify_con(struct mgcp_request_data *rq)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct mgcp_endpoint *endp = p->endp;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct rate_ctr_group *rate_ctrs = endp->trunk->ratectr.mgcp_mdcx_ctr_group;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct mgcp_parse_data *pdata = rq->pdata;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgcp_trunk *trunk = rq->trunk;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct mgcp_endpoint *endp = rq->endp;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct rate_ctr_group *rate_ctrs = trunk->ratectr.mgcp_mdcx_ctr_group;</span><br><span>    char new_local_addr[INET6_ADDRSTRLEN];</span><br><span>       int error_code = 500;</span><br><span>        int silent = 0;</span><br><span>@@ -1041,25 +1124,25 @@</span><br><span>            rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_AVAIL));</span><br><span>               LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "MDCX: selected endpoint not available!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         return create_err_response(NULL, 501, "MDCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(NULL, 501, "MDCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        /* Prohibit wildcarded requests */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (endp->wildcarded_req) {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (rq->wildcarded) {</span><br><span>             LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "MDCX: wildcarded endpoint names not supported.\n");</span><br><span>              rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_WILDCARD));</span><br><span style="color: hsl(0, 100%, 40%);">-               return create_err_response(endp, 507, "MDCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(endp, 507, "MDCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        if (llist_count(&endp->conns) <= 0) {</span><br><span>              LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "MDCX: endpoint is not holding a connection.\n");</span><br><span>                 rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_NO_CONN));</span><br><span style="color: hsl(0, 100%, 40%);">-                return create_err_response(endp, 400, "MDCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(endp, 400, "MDCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   for_each_line(line, p->save) {</span><br><span style="color: hsl(120, 100%, 40%);">+     for_each_line(line, pdata->save) {</span><br><span>                if (!mgcp_check_param(endp, line))</span><br><span>                   continue;</span><br><span> </span><br><span>@@ -1090,7 +1173,7 @@</span><br><span>                case 'X':</span><br><span>                    if (strncasecmp("Osmux: ", line + 2, strlen("Osmux: ")) == 0) {</span><br><span>                          /* If osmux is disabled, just skip setting it up */</span><br><span style="color: hsl(0, 100%, 40%);">-                             if (!p->endp->cfg->osmux)</span><br><span style="color: hsl(120, 100%, 40%);">+                            if (!endp->cfg->osmux)</span><br><span>                                         break;</span><br><span>                               osmux_cid = mgcp_osmux_setup(endp, line);</span><br><span>                            break;</span><br><span>@@ -1106,7 +1189,7 @@</span><br><span>                                "MDCX: Unhandled MGCP option: '%c'/%d\n",</span><br><span>                                  line[0], line[0]);</span><br><span>                  rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_UNHANDLED_PARAM));</span><br><span style="color: hsl(0, 100%, 40%);">-                        return create_err_response(NULL, 539, "MDCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(NULL, 539, "MDCX", pdata->trans);</span><br><span>                    break;</span><br><span>               }</span><br><span>    }</span><br><span>@@ -1116,13 +1199,13 @@</span><br><span>          LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "MDCX: insufficient parameters, missing ci (connectionIdentifier)\n");</span><br><span>            rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_NO_CONNID));</span><br><span style="color: hsl(0, 100%, 40%);">-              return create_err_response(endp, 515, "MDCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(endp, 515, "MDCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        conn = mgcp_conn_get_rtp(endp, conn_id);</span><br><span>     if (!conn) {</span><br><span>                 rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_CONN_NOT_FOUND));</span><br><span style="color: hsl(0, 100%, 40%);">-         return create_err_response(endp, 400, "MDCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(endp, 400, "MDCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        mgcp_conn_watchdog_kick(conn->conn);</span><br><span>@@ -1138,7 +1221,7 @@</span><br><span> </span><br><span>  /* Set local connection options, if present */</span><br><span>       if (local_options) {</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = set_local_cx_options(endp->trunk->endpoints,</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = set_local_cx_options(trunk->endpoints,</span><br><span>                                         &endp->local_options, local_options);</span><br><span>               if (rc != 0) {</span><br><span>                       LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,</span><br><span>@@ -1150,7 +1233,7 @@</span><br><span>  }</span><br><span> </span><br><span>        /* Handle codec information and decide for a suitable codec */</span><br><span style="color: hsl(0, 100%, 40%);">-  rc = handle_codec_info(conn, p, have_sdp, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = handle_codec_info(conn, rq, have_sdp, false);</span><br><span>   mgcp_codec_summary(conn);</span><br><span>    if (rc) {</span><br><span>            error_code = rc;</span><br><span>@@ -1209,9 +1292,9 @@</span><br><span> </span><br><span> </span><br><span>     /* policy CB */</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->cfg->policy_cb) {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (pdata->cfg->policy_cb) {</span><br><span>           int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = p->cfg->policy_cb(endp, MGCP_ENDP_MDCX, p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+              rc = pdata->cfg->policy_cb(endp, MGCP_ENDP_MDCX, pdata->trans);</span><br><span>             switch (rc) {</span><br><span>                case MGCP_POLICY_REJECT:</span><br><span>                     LOGPCONN(conn->conn, DLMGCP, LOGL_NOTICE,</span><br><span>@@ -1219,7 +1302,7 @@</span><br><span>                         rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_REJECTED_BY_POLICY));</span><br><span>                  if (silent)</span><br><span>                          goto out_silent;</span><br><span style="color: hsl(0, 100%, 40%);">-                        return create_err_response(endp, 400, "MDCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(endp, 400, "MDCX", pdata->trans);</span><br><span>                    break;</span><br><span>               case MGCP_POLICY_DEFER:</span><br><span>                      /* stop processing */</span><br><span>@@ -1239,14 +1322,14 @@</span><br><span>      /* modify */</span><br><span>         LOGPCONN(conn->conn, DLMGCP, LOGL_DEBUG,</span><br><span>           "MDCX: modified conn:%s\n", mgcp_conn_dump(conn->conn));</span><br><span style="color: hsl(0, 100%, 40%);">-  if (p->cfg->change_cb)</span><br><span style="color: hsl(0, 100%, 40%);">-            p->cfg->change_cb(endp, MGCP_ENDP_MDCX);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (pdata->cfg->change_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+              pdata->cfg->change_cb(endp, MGCP_ENDP_MDCX);</span><br><span> </span><br><span>       /* Send dummy packet, see also comments in mgcp_keepalive_timer_cb() */</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(endp->trunk->keepalive_interval >= MGCP_KEEPALIVE_ONCE);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(trunk->keepalive_interval >= MGCP_KEEPALIVE_ONCE);</span><br><span>         if (conn->conn->mode & MGCP_CONN_RECV_ONLY &&</span><br><span>          mgcp_rtp_end_remote_addr_available(&conn->end) &&</span><br><span style="color: hsl(0, 100%, 40%);">-        endp->trunk->keepalive_interval != MGCP_KEEPALIVE_NEVER)</span><br><span style="color: hsl(120, 100%, 40%);">+        trunk->keepalive_interval != MGCP_KEEPALIVE_NEVER)</span><br><span>            send_dummy(endp, conn);</span><br><span> </span><br><span>  rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_SUCCESS));</span><br><span>@@ -1256,9 +1339,9 @@</span><br><span>  LOGPCONN(conn->conn, DLMGCP, LOGL_NOTICE,</span><br><span>                  "MDCX: connection successfully modified\n");</span><br><span>      mgcp_endp_update(endp);</span><br><span style="color: hsl(0, 100%, 40%);">- return create_response_with_sdp(endp, conn, "MDCX", p->trans, false);</span><br><span style="color: hsl(120, 100%, 40%);">+    return create_response_with_sdp(endp, conn, "MDCX", pdata->trans, false);</span><br><span> error3:</span><br><span style="color: hsl(0, 100%, 40%);">-       return create_err_response(endp, error_code, "MDCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+  return create_err_response(endp, error_code, "MDCX", pdata->trans);</span><br><span> </span><br><span> out_silent:</span><br><span>  LOGPENDP(endp, DLMGCP, LOGL_DEBUG, "MDCX: silent exit\n");</span><br><span>@@ -1266,10 +1349,12 @@</span><br><span> }</span><br><span> </span><br><span> /* DLCX command handler, processes the received command */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_delete_con(struct mgcp_parse_data *p)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_delete_con(struct mgcp_request_data *rq)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct mgcp_endpoint *endp = p->endp;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct rate_ctr_group *rate_ctrs = endp->trunk->ratectr.mgcp_dlcx_ctr_group;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct mgcp_parse_data *pdata = rq->pdata;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgcp_trunk *trunk = rq->trunk;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct mgcp_endpoint *endp = rq->endp;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct rate_ctr_group *rate_ctrs = trunk->ratectr.mgcp_dlcx_ctr_group;</span><br><span>    int error_code = 400;</span><br><span>        int silent = 0;</span><br><span>      char *line;</span><br><span>@@ -1284,7 +1369,7 @@</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 style="color: hsl(0, 100%, 40%);">-         return create_err_response(NULL, 501, "DLCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(NULL, 501, "DLCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        /* Prohibit wildcarded requests */</span><br><span>@@ -1292,17 +1377,17 @@</span><br><span>                 LOGPENDP(endp, DLMGCP, LOGL_ERROR,</span><br><span>                    "DLCX: wildcarded endpoint names not supported.\n");</span><br><span>              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", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(endp, 507, "DLCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span>        if (llist_count(&endp->conns) <= 0) {</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 style="color: hsl(0, 100%, 40%);">-                return create_err_response(endp, 515, "DLCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+         return create_err_response(endp, 515, "DLCX", pdata->trans);</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   for_each_line(line, p->save) {</span><br><span style="color: hsl(120, 100%, 40%);">+     for_each_line(line, pdata->save) {</span><br><span>                if (!mgcp_check_param(endp, line))</span><br><span>                   continue;</span><br><span> </span><br><span>@@ -1329,22 +1414,22 @@</span><br><span>                               "DLCX: Unhandled MGCP option: '%c'/%d\n",</span><br><span>                                  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 style="color: hsl(0, 100%, 40%);">-                        return create_err_response(NULL, 539, "DLCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(NULL, 539, "DLCX", pdata->trans);</span><br><span>                    break;</span><br><span>               }</span><br><span>    }</span><br><span> </span><br><span>        /* policy CB */</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->cfg->policy_cb) {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (pdata->cfg->policy_cb) {</span><br><span>           int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = p->cfg->policy_cb(endp, MGCP_ENDP_DLCX, p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+              rc = pdata->cfg->policy_cb(endp, MGCP_ENDP_DLCX, pdata->trans);</span><br><span>             switch (rc) {</span><br><span>                case MGCP_POLICY_REJECT:</span><br><span>                     LOGPENDP(endp, DLMGCP, LOGL_NOTICE, "DLCX: rejected by policy\n");</span><br><span>                         rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_FAIL_REJECTED_BY_POLICY));</span><br><span>                  if (silent)</span><br><span>                          goto out_silent;</span><br><span style="color: hsl(0, 100%, 40%);">-                        return create_err_response(endp, 400, "DLCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return create_err_response(endp, 400, "DLCX", pdata->trans);</span><br><span>                    break;</span><br><span>               case MGCP_POLICY_DEFER:</span><br><span>                      /* stop processing */</span><br><span>@@ -1374,7 +1459,7 @@</span><br><span>                /* Note: In this case we do not return any statistics,</span><br><span>                * as we assume that the client is not interested in</span><br><span>                  * this case. */</span><br><span style="color: hsl(0, 100%, 40%);">-                return create_ok_response(endp, 200, "DLCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+          return create_ok_response(endp, 200, "DLCX", pdata->trans);</span><br><span>     }</span><br><span> </span><br><span>        /* Find the connection */</span><br><span>@@ -1400,16 +1485,16 @@</span><br><span>          LOGPENDP(endp, DLMGCP, LOGL_DEBUG, "DLCX: endpoint released\n");</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (p->cfg->change_cb)</span><br><span style="color: hsl(0, 100%, 40%);">-            p->cfg->change_cb(endp, MGCP_ENDP_DLCX);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (pdata->cfg->change_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+              pdata->cfg->change_cb(endp, MGCP_ENDP_DLCX);</span><br><span> </span><br><span>       rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_SUCCESS));</span><br><span>  if (silent)</span><br><span>          goto out_silent;</span><br><span style="color: hsl(0, 100%, 40%);">-        return create_ok_resp_with_param(endp, 250, "DLCX", p->trans, stats);</span><br><span style="color: hsl(120, 100%, 40%);">+    return create_ok_resp_with_param(endp, 250, "DLCX", pdata->trans, stats);</span><br><span> </span><br><span> error3:</span><br><span style="color: hsl(0, 100%, 40%);">-   return create_err_response(endp, error_code, "DLCX", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+  return create_err_response(endp, error_code, "DLCX", pdata->trans);</span><br><span> </span><br><span> out_silent:</span><br><span>  LOGPENDP(endp, DLMGCP, LOGL_DEBUG, "DLCX: silent exit\n");</span><br><span>@@ -1417,7 +1502,7 @@</span><br><span> }</span><br><span> </span><br><span> /* RSIP command handler, processes the received command */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_rsip(struct mgcp_parse_data *p)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_rsip(struct mgcp_request_data *rq)</span><br><span> {</span><br><span>    /* TODO: Also implement the resetting of a specific endpoint</span><br><span>          * to make mgcp_send_reset_ep() work. Currently this will call</span><br><span>@@ -1429,8 +1514,8 @@</span><br><span> </span><br><span>   LOGP(DLMGCP, LOGL_NOTICE, "RSIP: resetting all endpoints ...\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (p->cfg->reset_cb)</span><br><span style="color: hsl(0, 100%, 40%);">-             p->cfg->reset_cb(p->endp->trunk);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rq->pdata->cfg->reset_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+                rq->pdata->cfg->reset_cb(rq->endp->trunk);</span><br><span>    return NULL;</span><br><span> }</span><br><span> </span><br><span>@@ -1446,7 +1531,7 @@</span><br><span> /* This can request like DTMF detection and forward, fax detection... it</span><br><span>  * can also request when the notification should be send and such. We don't</span><br><span>  * do this right now. */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct msgb *handle_noti_req(struct mgcp_parse_data *p)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *handle_noti_req(struct mgcp_request_data *rq)</span><br><span> {</span><br><span>       int res = 0;</span><br><span>         char *line;</span><br><span>@@ -1454,7 +1539,7 @@</span><br><span> </span><br><span>      LOGP(DLMGCP, LOGL_NOTICE, "RQNT: processing request for notification ...\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     for_each_line(line, p->save) {</span><br><span style="color: hsl(120, 100%, 40%);">+     for_each_line(line, rq->pdata->save) {</span><br><span>                 switch (toupper(line[0])) {</span><br><span>          case 'S':</span><br><span>                    tone = extract_tone(line);</span><br><span>@@ -1464,14 +1549,14 @@</span><br><span> </span><br><span>     /* we didn't see a signal request with a tone */</span><br><span>         if (tone == CHAR_MAX)</span><br><span style="color: hsl(0, 100%, 40%);">-           return create_ok_response(p->endp, 200, "RQNT", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+            return create_ok_response(rq->endp, 200, "RQNT", rq->pdata->trans);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (p->cfg->rqnt_cb)</span><br><span style="color: hsl(0, 100%, 40%);">-              res = p->cfg->rqnt_cb(p->endp, tone);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (rq->pdata->cfg->rqnt_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+         res = rq->pdata->cfg->rqnt_cb(rq->endp, tone);</span><br><span> </span><br><span>       return res == 0 ?</span><br><span style="color: hsl(0, 100%, 40%);">-           create_ok_response(p->endp, 200, "RQNT", p->trans) :</span><br><span style="color: hsl(0, 100%, 40%);">-            create_err_response(p->endp, res, "RQNT", p->trans);</span><br><span style="color: hsl(120, 100%, 40%);">+          create_ok_response(rq->endp, 200, "RQNT", rq->pdata->trans) :</span><br><span style="color: hsl(120, 100%, 40%);">+      create_err_response(rq->endp, res, "RQNT", rq->pdata->trans);</span><br><span> }</span><br><span> </span><br><span> /* Connection keepalive timer, will take care that dummy packets are send</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_sdp.c b/src/libosmo-mgcp/mgcp_sdp.c</span><br><span>index e98ca94..0759c96 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_sdp.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_sdp.c</span><br><span>@@ -398,7 +398,7 @@</span><br><span>                            return -1;</span><br><span>                   break;</span><br><span>               default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (p->endp)</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (endp)</span><br><span>                            /* TODO: Check spec: We used the bare endpoint number before,</span><br><span>                                 * now we use the endpoint name as a whole? Is this allowed? */</span><br><span>                              LOGP(DLMGCP, LOGL_NOTICE,</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-mgw/+/24941">change 24941</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/+/24941"/><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: I9f519d8a0ee8a513fa1e74acf3ee7dbc0991cdde </div>
<div style="display:none"> Gerrit-Change-Number: 24941 </div>
<div style="display:none"> Gerrit-PatchSet: 9 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>